From 4924a2143470af4f7802230a3875e2cf3ddb9a53 Mon Sep 17 00:00:00 2001 From: Wilson Date: Fri, 9 Mar 2018 23:12:15 -0800 Subject: [PATCH 001/814] Improve clarity of Compression Method Asymmetry Between Peers section --- doc/compression.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/compression.md b/doc/compression.md index b8cdfb30485..15e35ae350c 100644 --- a/doc/compression.md +++ b/doc/compression.md @@ -30,7 +30,7 @@ configured: therefore the compression that SHALL be used in the absence of per-RPC compression configuration. + At response time, via: - + For unary RPCs, the {Client,Server}Context instance. + + For unary RPCs, the {Client,Server}Context instance. + For streaming RPCs, the {Client,Server}Writer instance. In this case, configuration is reduced to disabling compression altogether. @@ -41,14 +41,14 @@ of the request, including not performing any compression, regardless of channel and RPC settings (for example, if compression would result in small or negative gains). -When a message from a client compressed with an unsupported algorithm is -processed by a server, it WILL result in an `UNIMPLEMENTED` error status on the -server. The server will then include in its response a `grpc-accept-encoding` -header specifying the algorithms it does accept. If an `UNIMPLEMENTED` error -status is returned from the server despite having used one of the algorithms -from the `grpc-accept-encoding` header, the cause MUST NOT be related to -compression. Data sent from a server compressed with an algorithm not supported -by the client WILL result in an `INTERNAL` error status on the client side. +If a client message is compressed by an algorithm that is not supported +by a server, the message WILL result in an `UNIMPLEMENTED` error status on the +server. The server will then include a `grpc-accept-encoding` response +header which specifies the algorithms that the server accepts. If the client +message is compressed using one of the algorithms from the `grpc-accept-encoding` header +and an `UNIMPLEMENTED` error status is returned from the server, the cause of the error +MUST NOT be related to compression. If a server sent data which is compressed by an algorithm +that is not supported by the client, an `INTERNAL` error status will occur on the client side. Note that a peer MAY choose to not disclose all the encodings it supports. However, if it receives a message compressed in an undisclosed but supported @@ -57,7 +57,7 @@ header. For every message a server is requested to compress using an algorithm it knows the client doesn't support (as indicated by the last `grpc-accept-encoding` -header received from the client), it SHALL send the message uncompressed. +header received from the client), it SHALL send the message uncompressed. ### Specific Disabling of Compression From 82b732313b6eadfd2c464951182705a309d2b567 Mon Sep 17 00:00:00 2001 From: Matt Olson Date: Fri, 3 Aug 2018 12:30:38 -0700 Subject: [PATCH 002/814] Fix default pool keep alive * The default value for the pool_keep_alive param for RpcServer references an incorrect constant. * This means that the default value for the pool keep alive will be 30, which is higher than the default value for the server poll_period, which is 1. --- src/ruby/lib/grpc/generic/rpc_server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index 838ac45927b..1b2bbd83475 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -217,7 +217,7 @@ module GRPC def initialize(pool_size: DEFAULT_POOL_SIZE, max_waiting_requests: DEFAULT_MAX_WAITING_REQUESTS, poll_period: DEFAULT_POLL_PERIOD, - pool_keep_alive: GRPC::RpcServer::DEFAULT_POOL_SIZE, + pool_keep_alive: Pool::DEFAULT_KEEP_ALIVE, connect_md_proc: nil, server_args: {}, interceptors: []) From 118e69a48449b17a5c1fa0d660c119380528c190 Mon Sep 17 00:00:00 2001 From: David Hoover Date: Wed, 12 Sep 2018 13:15:44 -0700 Subject: [PATCH 003/814] Fix backwards logic checking for --call_creds=none release note: no --- test/cpp/util/cli_credentials.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/util/cli_credentials.cc b/test/cpp/util/cli_credentials.cc index 0a922617bb6..b5753a31854 100644 --- a/test/cpp/util/cli_credentials.cc +++ b/test/cpp/util/cli_credentials.cc @@ -118,7 +118,7 @@ std::shared_ptr CliCredentials::GetCallCredentials() if (IsAccessToken(FLAGS_call_creds)) { return grpc::AccessTokenCredentials(AccessToken(FLAGS_call_creds)); } - if (FLAGS_call_creds.compare("none") != 0) { + if (FLAGS_call_creds.compare("none") == 0) { // Nothing to do; creds, if any, are baked into the channel. return std::shared_ptr(); } From 519654b4b2438493d33c07ef4ed6be5a5e72dadf Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Tue, 16 Oct 2018 11:08:41 -0700 Subject: [PATCH 004/814] Initial commit to let lb policy intercept recv trailing metadata --- .../filters/client_channel/client_channel.cc | 15 ++++++- .../ext/filters/client_channel/lb_policy.h | 7 ++++ .../ext/filters/client_channel/subchannel.cc | 39 ++++++++++++++----- .../ext/filters/client_channel/subchannel.h | 6 ++- 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index bb3ea400d15..fc77a51eb31 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1990,6 +1990,16 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { } // Not retrying, so commit the call. retry_commit(elem, retry_state); + // Now that the try is committed, give the trailer to the lb policy as needed + if (calld->pick.recv_trailing_metadata_ready != nullptr) { + GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); + *calld->pick.recv_trailing_metadata = md_batch; + GRPC_CLOSURE_SCHED( + calld->pick.recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); + calld->pick.recv_trailing_metadata = nullptr; + calld->pick.recv_trailing_metadata_ready = nullptr; + } // Run any necessary closures. run_closures_for_completed_call(batch_data, GRPC_ERROR_REF(error)); } @@ -2592,7 +2602,10 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { parent_data_size // parent_data_size }; grpc_error* new_error = calld->pick.connected_subchannel->CreateCall( - call_args, &calld->subchannel_call); + &calld->subchannel_call, + call_args, + &calld->pick.recv_trailing_metadata_ready, + &calld->pick.recv_trailing_metadata); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, calld, calld->subchannel_call, grpc_error_string(new_error)); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 21f80b7b947..9ef0033aebd 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -73,6 +73,13 @@ class LoadBalancingPolicy /// Closure to run when pick is complete, if not completed synchronously. /// If null, pick will fail if a result is not available synchronously. grpc_closure* on_complete; + + // Callback set by lb policy if the trailing metadata should be intercepted. + grpc_closure* recv_trailing_metadata_ready; + // If \a recv_trailing_metadata_ready \a is set, the client_channel sets + // this pointer to the metadata batch and schedules the closure. + grpc_metadata_batch** recv_trailing_metadata; + /// Will be set to the selected subchannel, or nullptr on failure or when /// the LB policy decides to drop the call. RefCountedPtr connected_subchannel; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 3a1c14c6f10..a45c579861e 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -151,6 +151,12 @@ struct grpc_subchannel_call { grpc_closure* original_recv_trailing_metadata; grpc_metadata_batch* recv_trailing_metadata; grpc_millis deadline; + + // state needed to support lb interception of recv trailing metadata. + // This points into grpc_core::LoadBalancingPolicy::PickState to avoid + // creating a circular dependency. + grpc_closure** lb_recv_trailing_metadata_ready; + grpc_metadata_batch*** lb_recv_trailing_metadata; }; #define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ @@ -775,11 +781,20 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { get_call_status(call, md_batch, GRPC_ERROR_REF(error), &status); grpc_core::channelz::SubchannelNode* channelz_subchannel = call->connection->channelz_subchannel(); - GPR_ASSERT(channelz_subchannel != nullptr); - if (status == GRPC_STATUS_OK) { - channelz_subchannel->RecordCallSucceeded(); - } else { - channelz_subchannel->RecordCallFailed(); + if (channelz_subchannel != nullptr) { + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); + } + } + if (*call->lb_recv_trailing_metadata_ready != nullptr) { + GPR_ASSERT(*call->lb_recv_trailing_metadata != nullptr); + **call->lb_recv_trailing_metadata = md_batch; + GRPC_CLOSURE_SCHED(*call->lb_recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); + *call->lb_recv_trailing_metadata = nullptr; + *call->lb_recv_trailing_metadata_ready = nullptr; } GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata, GRPC_ERROR_REF(error)); @@ -793,8 +808,9 @@ static void maybe_intercept_recv_trailing_metadata( if (!batch->recv_trailing_metadata) { return; } - // only add interceptor is channelz is enabled. - if (call->connection->channelz_subchannel() == nullptr) { + // only add interceptor if channelz is enabled or lb policy wants the trailers + if (call->connection->channelz_subchannel() == nullptr && + *call->lb_recv_trailing_metadata_ready == nullptr) { return; } GRPC_CLOSURE_INIT(&call->recv_trailing_metadata_ready, @@ -922,8 +938,11 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate, elem->filter->start_transport_op(elem, op); } -grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, - grpc_subchannel_call** call) { +grpc_error* ConnectedSubchannel::CreateCall( + grpc_subchannel_call** call, + const CallArgs& args, + grpc_closure** lb_recv_trailing_metadata_ready, + grpc_metadata_batch*** lb_recv_trailing_metadata) { size_t allocation_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); if (args.parent_data_size > 0) { @@ -959,6 +978,8 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, return error; } grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); + *(*call)->lb_recv_trailing_metadata_ready = *lb_recv_trailing_metadata_ready; + *(*call)->lb_recv_trailing_metadata = *lb_recv_trailing_metadata; return GRPC_ERROR_NONE; } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index c53b13e37e8..dc5e53be780 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -97,7 +97,11 @@ class ConnectedSubchannel : public RefCountedWithTracing { grpc_connectivity_state* state, grpc_closure* closure); void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); - grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); + grpc_error* CreateCall( + grpc_subchannel_call** call, + const CallArgs& args, + grpc_closure** lb_recv_trailing_metadata_ready, + grpc_metadata_batch*** lb_recv_trailing_metadata); channelz::SubchannelNode* channelz_subchannel() { return channelz_subchannel_.get(); } From 799f8ac60cf6eb1006dbb378ab73ab638cea73fa Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Thu, 18 Oct 2018 17:13:46 -0700 Subject: [PATCH 005/814] undo changes to subchannel --- .../ext/filters/client_channel/subchannel.cc | 39 +++++-------------- .../ext/filters/client_channel/subchannel.h | 6 +-- 2 files changed, 10 insertions(+), 35 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index a45c579861e..3a1c14c6f10 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -151,12 +151,6 @@ struct grpc_subchannel_call { grpc_closure* original_recv_trailing_metadata; grpc_metadata_batch* recv_trailing_metadata; grpc_millis deadline; - - // state needed to support lb interception of recv trailing metadata. - // This points into grpc_core::LoadBalancingPolicy::PickState to avoid - // creating a circular dependency. - grpc_closure** lb_recv_trailing_metadata_ready; - grpc_metadata_batch*** lb_recv_trailing_metadata; }; #define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ @@ -781,20 +775,11 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { get_call_status(call, md_batch, GRPC_ERROR_REF(error), &status); grpc_core::channelz::SubchannelNode* channelz_subchannel = call->connection->channelz_subchannel(); - if (channelz_subchannel != nullptr) { - if (status == GRPC_STATUS_OK) { - channelz_subchannel->RecordCallSucceeded(); - } else { - channelz_subchannel->RecordCallFailed(); - } - } - if (*call->lb_recv_trailing_metadata_ready != nullptr) { - GPR_ASSERT(*call->lb_recv_trailing_metadata != nullptr); - **call->lb_recv_trailing_metadata = md_batch; - GRPC_CLOSURE_SCHED(*call->lb_recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); - *call->lb_recv_trailing_metadata = nullptr; - *call->lb_recv_trailing_metadata_ready = nullptr; + GPR_ASSERT(channelz_subchannel != nullptr); + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); } GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata, GRPC_ERROR_REF(error)); @@ -808,9 +793,8 @@ static void maybe_intercept_recv_trailing_metadata( if (!batch->recv_trailing_metadata) { return; } - // only add interceptor if channelz is enabled or lb policy wants the trailers - if (call->connection->channelz_subchannel() == nullptr && - *call->lb_recv_trailing_metadata_ready == nullptr) { + // only add interceptor is channelz is enabled. + if (call->connection->channelz_subchannel() == nullptr) { return; } GRPC_CLOSURE_INIT(&call->recv_trailing_metadata_ready, @@ -938,11 +922,8 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate, elem->filter->start_transport_op(elem, op); } -grpc_error* ConnectedSubchannel::CreateCall( - grpc_subchannel_call** call, - const CallArgs& args, - grpc_closure** lb_recv_trailing_metadata_ready, - grpc_metadata_batch*** lb_recv_trailing_metadata) { +grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, + grpc_subchannel_call** call) { size_t allocation_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); if (args.parent_data_size > 0) { @@ -978,8 +959,6 @@ grpc_error* ConnectedSubchannel::CreateCall( return error; } grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); - *(*call)->lb_recv_trailing_metadata_ready = *lb_recv_trailing_metadata_ready; - *(*call)->lb_recv_trailing_metadata = *lb_recv_trailing_metadata; return GRPC_ERROR_NONE; } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index dc5e53be780..c53b13e37e8 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -97,11 +97,7 @@ class ConnectedSubchannel : public RefCountedWithTracing { grpc_connectivity_state* state, grpc_closure* closure); void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); - grpc_error* CreateCall( - grpc_subchannel_call** call, - const CallArgs& args, - grpc_closure** lb_recv_trailing_metadata_ready, - grpc_metadata_batch*** lb_recv_trailing_metadata); + grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); channelz::SubchannelNode* channelz_subchannel() { return channelz_subchannel_.get(); } From 7cc2660ae570cd2157a544cd3e4a983613c366f6 Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Thu, 18 Oct 2018 18:24:12 -0700 Subject: [PATCH 006/814] Add a non-retries trailer interceptor --- .../filters/client_channel/client_channel.cc | 61 +++++++++++++++++-- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index fc77a51eb31..f57612b2413 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -932,6 +932,11 @@ typedef struct client_channel_call_data { grpc_core::LoadBalancingPolicy::PickState pick; grpc_closure pick_closure; grpc_closure pick_cancel_closure; + // A closure to fork notifying the lb interceptor and run the original trailer + // interception callback. + grpc_closure lb_intercept_recv_trailing_metadata_ready; + // The original trailer interception callback. + grpc_closure* before_lb_intercept_recv_trailing_metadata_ready; grpc_polling_entity* pollent; bool pollent_added_to_interested_parties; @@ -1268,6 +1273,51 @@ static void resume_pending_batch_in_call_combiner(void* arg, grpc_subchannel_call_process_op(subchannel_call, batch); } +// The callback to intercept trailing metadata if retries is not enabled +static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { + subchannel_batch_data* batch_data = static_cast(arg); + grpc_call_element* elem = batch_data->elem; + call_data* calld = static_cast(elem->call_data); + GPR_ASSERT(calld->pick.recv_trailing_metadata_ready != nullptr); + GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); + + GRPC_CLOSURE_SCHED( + calld->pick.recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); + calld->pick.recv_trailing_metadata = nullptr; + calld->pick.recv_trailing_metadata_ready = nullptr; + + GRPC_CLOSURE_RUN( + calld->before_lb_intercept_recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); +} + +// Installs a interceptor to inform the lb of the trailing metadata, if needed +static void maybe_intercept_trailing_metadata_for_lb( + void* arg, grpc_transport_stream_op_batch* batch) { + subchannel_batch_data* batch_data = static_cast(arg); + grpc_call_element* elem = batch_data->elem; + call_data* calld = static_cast(elem->call_data); + if (calld->pick.recv_trailing_metadata_ready != nullptr) { + GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); + // Unlike the retries case, the location of the trailing metadata is known + // already, so just point to it now. + *calld->pick.recv_trailing_metadata = + batch_data->batch.payload->recv_trailing_metadata + .recv_trailing_metadata; + + // There may be a pre-existing recv_trailing_metadata_ready callback + calld->before_lb_intercept_recv_trailing_metadata_ready = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + + GRPC_CLOSURE_INIT(&calld->lb_intercept_recv_trailing_metadata_ready, + recv_trailing_metadata_ready_for_lb, elem, + grpc_schedule_on_exec_ctx); + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->lb_intercept_recv_trailing_metadata_ready; + } +} + // This is called via the call combiner, so access to calld is synchronized. static void pending_batches_resume(grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); @@ -1292,6 +1342,7 @@ static void pending_batches_resume(grpc_call_element* elem) { pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { + maybe_intercept_trailing_metadata_for_lb(elem, batch); batch->handler_private.extra_arg = calld->subchannel_call; GRPC_CLOSURE_INIT(&batch->handler_private.closure, resume_pending_batch_in_call_combiner, batch, @@ -1947,7 +1998,8 @@ static void run_closures_for_completed_call(subchannel_batch_data* batch_data, // Intercepts recv_trailing_metadata_ready callback for retries. // Commits the call and returns the trailing metadata up the stack. -static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { +static void recv_trailing_metadata_ready_for_retries( + void* arg, grpc_error* error) { subchannel_batch_data* batch_data = static_cast(arg); grpc_call_element* elem = batch_data->elem; channel_data* chand = static_cast(elem->channel_data); @@ -2312,7 +2364,7 @@ static void add_retriable_recv_trailing_metadata_op( batch_data->batch.payload->recv_trailing_metadata.collect_stats = &retry_state->collect_stats; GRPC_CLOSURE_INIT(&retry_state->recv_trailing_metadata_ready, - recv_trailing_metadata_ready, batch_data, + recv_trailing_metadata_ready_for_retries, batch_data, grpc_schedule_on_exec_ctx); batch_data->batch.payload->recv_trailing_metadata .recv_trailing_metadata_ready = @@ -2602,10 +2654,7 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { parent_data_size // parent_data_size }; grpc_error* new_error = calld->pick.connected_subchannel->CreateCall( - &calld->subchannel_call, - call_args, - &calld->pick.recv_trailing_metadata_ready, - &calld->pick.recv_trailing_metadata); + call_args, &calld->subchannel_call); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, calld, calld->subchannel_call, grpc_error_string(new_error)); From 066949ee56a84189006abeab2e947594787738f6 Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Fri, 19 Oct 2018 09:32:06 -0700 Subject: [PATCH 007/814] Address current PR comments. --- .../filters/client_channel/client_channel.cc | 96 ++++++++----------- .../ext/filters/client_channel/lb_policy.h | 7 +- 2 files changed, 46 insertions(+), 57 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index f57612b2413..9732b1753a8 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -934,9 +934,9 @@ typedef struct client_channel_call_data { grpc_closure pick_cancel_closure; // A closure to fork notifying the lb interceptor and run the original trailer // interception callback. - grpc_closure lb_intercept_recv_trailing_metadata_ready; + grpc_closure recv_trailing_metadata_ready_for_lb; // The original trailer interception callback. - grpc_closure* before_lb_intercept_recv_trailing_metadata_ready; + grpc_closure* original_recv_trailing_metadata_ready; grpc_polling_entity* pollent; bool pollent_added_to_interested_parties; @@ -999,6 +999,9 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem); static void on_complete(void* arg, grpc_error* error); static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored); static void start_pick_locked(void* arg, grpc_error* ignored); +static void maybe_intercept_trailing_metadata_for_lb( + void* arg, grpc_transport_stream_op_batch* batch); +static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error); // // send op data caching @@ -1273,51 +1276,6 @@ static void resume_pending_batch_in_call_combiner(void* arg, grpc_subchannel_call_process_op(subchannel_call, batch); } -// The callback to intercept trailing metadata if retries is not enabled -static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); - grpc_call_element* elem = batch_data->elem; - call_data* calld = static_cast(elem->call_data); - GPR_ASSERT(calld->pick.recv_trailing_metadata_ready != nullptr); - GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); - - GRPC_CLOSURE_SCHED( - calld->pick.recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); - calld->pick.recv_trailing_metadata = nullptr; - calld->pick.recv_trailing_metadata_ready = nullptr; - - GRPC_CLOSURE_RUN( - calld->before_lb_intercept_recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); -} - -// Installs a interceptor to inform the lb of the trailing metadata, if needed -static void maybe_intercept_trailing_metadata_for_lb( - void* arg, grpc_transport_stream_op_batch* batch) { - subchannel_batch_data* batch_data = static_cast(arg); - grpc_call_element* elem = batch_data->elem; - call_data* calld = static_cast(elem->call_data); - if (calld->pick.recv_trailing_metadata_ready != nullptr) { - GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); - // Unlike the retries case, the location of the trailing metadata is known - // already, so just point to it now. - *calld->pick.recv_trailing_metadata = - batch_data->batch.payload->recv_trailing_metadata - .recv_trailing_metadata; - - // There may be a pre-existing recv_trailing_metadata_ready callback - calld->before_lb_intercept_recv_trailing_metadata_ready = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - - GRPC_CLOSURE_INIT(&calld->lb_intercept_recv_trailing_metadata_ready, - recv_trailing_metadata_ready_for_lb, elem, - grpc_schedule_on_exec_ctx); - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &calld->lb_intercept_recv_trailing_metadata_ready; - } -} - // This is called via the call combiner, so access to calld is synchronized. static void pending_batches_resume(grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); @@ -2043,15 +2001,12 @@ static void recv_trailing_metadata_ready_for_retries( // Not retrying, so commit the call. retry_commit(elem, retry_state); // Now that the try is committed, give the trailer to the lb policy as needed - if (calld->pick.recv_trailing_metadata_ready != nullptr) { - GPR_ASSERT(calld->pick.recv_trailing_metadata != nullptr); + if (calld->pick.recv_trailing_metadata != nullptr) { *calld->pick.recv_trailing_metadata = md_batch; - GRPC_CLOSURE_SCHED( - calld->pick.recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); - calld->pick.recv_trailing_metadata = nullptr; - calld->pick.recv_trailing_metadata_ready = nullptr; } + GRPC_CLOSURE_SCHED( + calld->pick.recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); // Run any necessary closures. run_closures_for_completed_call(batch_data, GRPC_ERROR_REF(error)); } @@ -2638,6 +2593,39 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { // LB pick // +// The callback to intercept trailing metadata if retries is not enabled +static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { + subchannel_batch_data* batch_data = static_cast(arg); + grpc_call_element* elem = batch_data->elem; + call_data* calld = static_cast(elem->call_data); + if (calld->pick.recv_trailing_metadata != nullptr) { + *calld->pick.recv_trailing_metadata = + batch_data->batch.payload->recv_trailing_metadata + .recv_trailing_metadata; + } + GRPC_CLOSURE_SCHED( + calld->pick.recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); + GRPC_CLOSURE_RUN( + calld->original_recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); +} + +// Installs a interceptor to inform the lb of the trailing metadata, if needed +static void maybe_intercept_trailing_metadata_for_lb( + void* arg, grpc_transport_stream_op_batch* batch) { + subchannel_batch_data* batch_data = static_cast(arg); + grpc_call_element* elem = batch_data->elem; + call_data* calld = static_cast(elem->call_data); + calld->original_recv_trailing_metadata_ready = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, + recv_trailing_metadata_ready_for_lb, elem, + grpc_schedule_on_exec_ctx); + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready_for_lb; +} + static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 9ef0033aebd..6c04b4b54cf 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -74,10 +74,11 @@ class LoadBalancingPolicy /// If null, pick will fail if a result is not available synchronously. grpc_closure* on_complete; - // Callback set by lb policy if the trailing metadata should be intercepted. + // Callback set by lb policy to be notified of trailing metadata. grpc_closure* recv_trailing_metadata_ready; - // If \a recv_trailing_metadata_ready \a is set, the client_channel sets - // this pointer to the metadata batch and schedules the closure. + // If this is not nullptr, then the client channel will point it to the + // call's trailing metadata before invoking recv_trailing_metadata_ready. + // If this is nullptr, then the callback will still be called. grpc_metadata_batch** recv_trailing_metadata; /// Will be set to the selected subchannel, or nullptr on failure or when From c62c3b920c4df9c52a51d3941814317ce8acc483 Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Tue, 23 Oct 2018 16:50:31 -0700 Subject: [PATCH 008/814] Add fake lb policy for test. Tweak existing interception code. --- .../filters/client_channel/client_channel.cc | 53 ++--- test/cpp/end2end/client_lb_end2end_test.cc | 188 +++++++++++++++++- 2 files changed, 216 insertions(+), 25 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 9732b1753a8..5a74ccc2a05 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -937,6 +937,7 @@ typedef struct client_channel_call_data { grpc_closure recv_trailing_metadata_ready_for_lb; // The original trailer interception callback. grpc_closure* original_recv_trailing_metadata_ready; + grpc_transport_stream_op_batch* recv_trailing_metadata_op_batch; grpc_polling_entity* pollent; bool pollent_added_to_interested_parties; @@ -1000,8 +1001,7 @@ static void on_complete(void* arg, grpc_error* error); static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored); static void start_pick_locked(void* arg, grpc_error* ignored); static void maybe_intercept_trailing_metadata_for_lb( - void* arg, grpc_transport_stream_op_batch* batch); -static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error); + grpc_call_element* arg, grpc_transport_stream_op_batch* batch); // // send op data caching @@ -1977,6 +1977,16 @@ static void recv_trailing_metadata_ready_for_retries( grpc_mdelem* server_pushback_md = nullptr; grpc_metadata_batch* md_batch = batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata; + // If the lb policy asks for the trailing metadata, set its receiving ptr + if (calld->pick.recv_trailing_metadata != nullptr) { + *calld->pick.recv_trailing_metadata = md_batch; + } + // We use GRPC_CLOSURE_RUN synchronously on the callback. In the case of + // a retry, we would have already freed the metadata before returning from + // this function. + GRPC_CLOSURE_RUN( + calld->pick.recv_trailing_metadata_ready, + GRPC_ERROR_REF(error)); get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, &server_pushback_md); if (grpc_client_channel_trace.enabled()) { @@ -2000,13 +2010,6 @@ static void recv_trailing_metadata_ready_for_retries( } // Not retrying, so commit the call. retry_commit(elem, retry_state); - // Now that the try is committed, give the trailer to the lb policy as needed - if (calld->pick.recv_trailing_metadata != nullptr) { - *calld->pick.recv_trailing_metadata = md_batch; - } - GRPC_CLOSURE_SCHED( - calld->pick.recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); // Run any necessary closures. run_closures_for_completed_call(batch_data, GRPC_ERROR_REF(error)); } @@ -2595,13 +2598,12 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { // The callback to intercept trailing metadata if retries is not enabled static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { - subchannel_batch_data* batch_data = static_cast(arg); - grpc_call_element* elem = batch_data->elem; + grpc_call_element* elem = static_cast(arg); call_data* calld = static_cast(elem->call_data); if (calld->pick.recv_trailing_metadata != nullptr) { *calld->pick.recv_trailing_metadata = - batch_data->batch.payload->recv_trailing_metadata - .recv_trailing_metadata; + calld->recv_trailing_metadata_op_batch->payload + ->recv_trailing_metadata.recv_trailing_metadata; } GRPC_CLOSURE_SCHED( calld->pick.recv_trailing_metadata_ready, @@ -2611,19 +2613,22 @@ static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { GRPC_ERROR_REF(error)); } -// Installs a interceptor to inform the lb of the trailing metadata, if needed +// If needed, intercepts the recv_trailing_metadata_ready callback to return +// trailing metadata to the LB policy. static void maybe_intercept_trailing_metadata_for_lb( - void* arg, grpc_transport_stream_op_batch* batch) { - subchannel_batch_data* batch_data = static_cast(arg); - grpc_call_element* elem = batch_data->elem; + grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { call_data* calld = static_cast(elem->call_data); - calld->original_recv_trailing_metadata_ready = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, - recv_trailing_metadata_ready_for_lb, elem, - grpc_schedule_on_exec_ctx); - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &calld->recv_trailing_metadata_ready_for_lb; + if (!batch->recv_trailing_metadata) { + return; + } + if (calld->pick.recv_trailing_metadata_ready != nullptr) { + calld->recv_trailing_metadata_op_batch = batch; + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, + recv_trailing_metadata_ready_for_lb, elem, + grpc_schedule_on_exec_ctx); + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready_for_lb; + } } static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index a9d68ab0582..acd8ab46c59 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -36,12 +36,17 @@ #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/channel/channelz.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" +#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/tcp_client.h" - +#include "src/core/lib/transport/connectivity_state.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -996,6 +1001,187 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { WaitForServer(stub, 0, DEBUG_LOCATION); } + +const char intercept_trailing_name[] = "intercept_trailing_metadata"; + +// LoadBalancingPolicy implementations are not designed to be extended. +// A hacky forwarding class to avoid implementing a standalone test LB. +class InterceptTrailing : public grpc_core::LoadBalancingPolicy { + public: + InterceptTrailing(const Args& args) + : grpc_core::LoadBalancingPolicy(args) { + UpdateLocked(*args.args); + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, + intercept_trailing_name); + } + + bool PickLocked(PickState* pick, grpc_error** error) override { + GRPC_CLOSURE_INIT( + &recv_trailing_metadata_ready_, + InterceptTrailing::RecordRecvTrailingMetadata, + /*cb_arg=*/ nullptr, + grpc_schedule_on_exec_ctx); + pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; + pick->recv_trailing_metadata = &recv_trailing_metadata_; + pick->connected_subchannel = + grpc_subchannel_get_connected_subchannel(hardcoded_subchannel_); + + if (pick->connected_subchannel.get() != nullptr) { + *error = GRPC_ERROR_NONE; + return true; + } + + if (pick->on_complete == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "No pick result available but synchronous result required."); + return true; + } else { + on_complete_ = pick->on_complete; + // TODO(zpencer): call on_completed_ at some point + return false; + } + } + + void UpdateLocked(const grpc_channel_args& args) override { + const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); + grpc_lb_addresses* addresses = + static_cast(arg->value.pointer.p); + grpc_arg addr_arg = + grpc_create_subchannel_address_arg(&addresses->addresses[0].address); + static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS, + GRPC_ARG_LB_ADDRESSES}; + grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( + &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1); + gpr_free(addr_arg.value.string); + grpc_subchannel_args sc_args; + memset(&sc_args, 0, sizeof(grpc_subchannel_args)); + sc_args.args = new_args; + if (hardcoded_subchannel_ != nullptr) { + GRPC_SUBCHANNEL_UNREF(hardcoded_subchannel_, "new pick"); + } + hardcoded_subchannel_ = grpc_client_channel_factory_create_subchannel( + client_channel_factory(), &sc_args); + grpc_channel_args_destroy(new_args); + } + + void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) override { + GRPC_ERROR_UNREF(error); + } + + void CancelPickLocked(PickState* pick, + grpc_error* error) override { + pick->connected_subchannel.reset(); + GRPC_CLOSURE_SCHED(pick->on_complete, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick Cancelled", &error, 1)); + + GRPC_ERROR_UNREF(error); + } + + grpc_connectivity_state CheckConnectivityLocked( + grpc_error** error) override { + return grpc_connectivity_state_get(&state_tracker_, error); + } + + void NotifyOnStateChangeLocked(grpc_connectivity_state* current, + grpc_closure* notify) override { + grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, + notify); + } + + void ShutdownLocked() override { + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); + grpc_connectivity_state_set( + &state_tracker_, + GRPC_CHANNEL_SHUTDOWN, + GRPC_ERROR_REF(error), + "intercept_trailing_shutdown"); + } + + ~InterceptTrailing() { + grpc_connectivity_state_destroy(&state_tracker_); + } + + private: + grpc_closure* on_complete_ = nullptr; + grpc_closure recv_trailing_metadata_ready_; + grpc_metadata_batch* recv_trailing_metadata_ = nullptr; + grpc_subchannel* hardcoded_subchannel_ = nullptr; + grpc_connectivity_state_tracker state_tracker_; + + static void RecordRecvTrailingMetadata( + void* ignored_arg, grpc_error* ignored_err) { + gpr_log(GPR_INFO, "trailer intercepted by lb"); + } +}; + +// A factory for a test LB policy that intercepts trailing metadata. +// The LB policy is implemented as a wrapper around a delegate LB policy. +class InterceptTrailingFactory : public grpc_core::LoadBalancingPolicyFactory { + public: + InterceptTrailingFactory(){} + + grpc_core::OrphanablePtr + CreateLoadBalancingPolicy( + const grpc_core::LoadBalancingPolicy::Args& args) const override { + return grpc_core::OrphanablePtr( + grpc_core::New(args)); + } + + const char* name() const override { + return intercept_trailing_name; + } +}; + +class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { + protected: + void SetUp() override { + ClientLbEnd2endTest::SetUp(); + grpc_core::LoadBalancingPolicyRegistry::Builder:: + RegisterLoadBalancingPolicyFactory( + grpc_core::UniquePtr( + grpc_core::New())); + } + + void TearDown() override { + ClientLbEnd2endTest::TearDown(); + } +}; + +TEST_F(ClientLbInterceptTrailingMetadataTest, Intercepts_retries_disabled) { + const int kNumServers = 1; + StartServers(kNumServers); + auto channel = BuildChannel(intercept_trailing_name); + auto stub = BuildStub(channel); + std::vector ports; + for (size_t i = 0; i < servers_.size(); ++i) { + ports.emplace_back(servers_[i]->port_); + } + SetNextResolution(ports); + + for (size_t i = 0; i < servers_.size(); ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + // All requests should have gone to a single server. + bool found = false; + for (size_t i = 0; i < servers_.size(); ++i) { + const int request_count = servers_[i]->service_.request_count(); + if (request_count == kNumServers) { + found = true; + } else { + EXPECT_EQ(0, request_count); + } + } + EXPECT_TRUE(found); + // Check LB policy name for the channel. + EXPECT_EQ( + intercept_trailing_name, + channel->GetLoadBalancingPolicyName()); +} + } // namespace } // namespace testing } // namespace grpc From c9d8237efccd3e434bf4628763fa9cd7fc4c509f Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Wed, 24 Oct 2018 11:39:27 -0700 Subject: [PATCH 009/814] Use channel's combiner --- src/core/ext/filters/client_channel/client_channel.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 5a74ccc2a05..f803b0c265c 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -2617,6 +2617,7 @@ static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { // trailing metadata to the LB policy. static void maybe_intercept_trailing_metadata_for_lb( grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { + channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (!batch->recv_trailing_metadata) { return; @@ -2625,7 +2626,7 @@ static void maybe_intercept_trailing_metadata_for_lb( calld->recv_trailing_metadata_op_batch = batch; GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, recv_trailing_metadata_ready_for_lb, elem, - grpc_schedule_on_exec_ctx); + grpc_combiner_scheduler(chand->combiner)); batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = &calld->recv_trailing_metadata_ready_for_lb; } From 2808bd0ba05fa3ddc0b6ef814db09c435e4e9676 Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Thu, 25 Oct 2018 15:47:13 -0700 Subject: [PATCH 010/814] Use forwarding LB test policy. Fix trailer interception code. --- .../filters/client_channel/client_channel.cc | 11 +- .../ext/filters/client_channel/lb_policy.h | 2 + test/cpp/end2end/client_lb_end2end_test.cc | 267 +++++++++--------- 3 files changed, 150 insertions(+), 130 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index f803b0c265c..0647fb7160c 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -2608,16 +2608,16 @@ static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { GRPC_CLOSURE_SCHED( calld->pick.recv_trailing_metadata_ready, GRPC_ERROR_REF(error)); - GRPC_CLOSURE_RUN( + GRPC_CLOSURE_SCHED( calld->original_recv_trailing_metadata_ready, GRPC_ERROR_REF(error)); + GRPC_ERROR_UNREF(error); } // If needed, intercepts the recv_trailing_metadata_ready callback to return // trailing metadata to the LB policy. static void maybe_intercept_trailing_metadata_for_lb( grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { - channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (!batch->recv_trailing_metadata) { return; @@ -2625,8 +2625,11 @@ static void maybe_intercept_trailing_metadata_for_lb( if (calld->pick.recv_trailing_metadata_ready != nullptr) { calld->recv_trailing_metadata_op_batch = batch; GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, - recv_trailing_metadata_ready_for_lb, elem, - grpc_combiner_scheduler(chand->combiner)); + recv_trailing_metadata_ready_for_lb, + elem, + grpc_schedule_on_exec_ctx); + calld->original_recv_trailing_metadata_ready = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = &calld->recv_trailing_metadata_ready_for_lb; } diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 6c04b4b54cf..fd8464dc08e 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -75,10 +75,12 @@ class LoadBalancingPolicy grpc_closure* on_complete; // Callback set by lb policy to be notified of trailing metadata. + // The callback is scheduled on grpc_schedule_on_exec_ctx. grpc_closure* recv_trailing_metadata_ready; // If this is not nullptr, then the client channel will point it to the // call's trailing metadata before invoking recv_trailing_metadata_ready. // If this is nullptr, then the callback will still be called. + // The lb does not have ownership of the metadata. grpc_metadata_batch** recv_trailing_metadata; /// Will be set to the selected subchannel, or nullptr on failure or when diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index acd8ab46c59..201edfb4963 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -47,11 +47,14 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/status_metadata.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" + #include using grpc::testing::EchoRequest; @@ -1001,139 +1004,77 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { WaitForServer(stub, 0, DEBUG_LOCATION); } - -const char intercept_trailing_name[] = "intercept_trailing_metadata"; - -// LoadBalancingPolicy implementations are not designed to be extended. -// A hacky forwarding class to avoid implementing a standalone test LB. -class InterceptTrailing : public grpc_core::LoadBalancingPolicy { +// A minimal forwarding class to avoid implementing a standalone test LB. +class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { public: - InterceptTrailing(const Args& args) - : grpc_core::LoadBalancingPolicy(args) { - UpdateLocked(*args.args); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, - intercept_trailing_name); - } - - bool PickLocked(PickState* pick, grpc_error** error) override { - GRPC_CLOSURE_INIT( - &recv_trailing_metadata_ready_, - InterceptTrailing::RecordRecvTrailingMetadata, - /*cb_arg=*/ nullptr, - grpc_schedule_on_exec_ctx); - pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; - pick->recv_trailing_metadata = &recv_trailing_metadata_; - pick->connected_subchannel = - grpc_subchannel_get_connected_subchannel(hardcoded_subchannel_); - - if (pick->connected_subchannel.get() != nullptr) { - *error = GRPC_ERROR_NONE; - return true; - } - - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - return true; - } else { - on_complete_ = pick->on_complete; - // TODO(zpencer): call on_completed_ at some point - return false; - } + ForwardingLoadBalancingPolicy( + const Args& args, + const std::string& delegate_policy_name) + : grpc_core::LoadBalancingPolicy(args), args_{args} { + delegate_ = grpc_core::LoadBalancingPolicyRegistry + ::CreateLoadBalancingPolicy(delegate_policy_name.c_str(), args); + grpc_pollset_set_add_pollset_set( + delegate_->interested_parties(), + interested_parties()); } void UpdateLocked(const grpc_channel_args& args) override { - const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES); - grpc_lb_addresses* addresses = - static_cast(arg->value.pointer.p); - grpc_arg addr_arg = - grpc_create_subchannel_address_arg(&addresses->addresses[0].address); - static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS, - GRPC_ARG_LB_ADDRESSES}; - grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( - &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1); - gpr_free(addr_arg.value.string); - grpc_subchannel_args sc_args; - memset(&sc_args, 0, sizeof(grpc_subchannel_args)); - sc_args.args = new_args; - if (hardcoded_subchannel_ != nullptr) { - GRPC_SUBCHANNEL_UNREF(hardcoded_subchannel_, "new pick"); - } - hardcoded_subchannel_ = grpc_client_channel_factory_create_subchannel( - client_channel_factory(), &sc_args); - grpc_channel_args_destroy(new_args); + delegate_->UpdateLocked(args); + } + + bool PickLocked(PickState* pick, grpc_error** error) override { + return delegate_->PickLocked(pick, error); + } + + void CancelPickLocked(PickState* pick, grpc_error* error) override { + delegate_->CancelPickLocked(pick, error); } void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, uint32_t initial_metadata_flags_eq, grpc_error* error) override { - GRPC_ERROR_UNREF(error); + delegate_->CancelMatchingPicksLocked( + initial_metadata_flags_mask, + initial_metadata_flags_eq, + error); } - void CancelPickLocked(PickState* pick, - grpc_error* error) override { - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - - GRPC_ERROR_UNREF(error); + void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) override { + delegate_->NotifyOnStateChangeLocked(state, closure); } grpc_connectivity_state CheckConnectivityLocked( - grpc_error** error) override { - return grpc_connectivity_state_get(&state_tracker_, error); + grpc_error** connectivity_error) override { + return delegate_->CheckConnectivityLocked(connectivity_error); } - void NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* notify) override { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - notify); + void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { + delegate_->HandOffPendingPicksLocked(new_policy); } + void ExitIdleLocked() override{ + delegate_->ExitIdleLocked(); + } + + void ResetBackoffLocked() override { + delegate_->ResetBackoffLocked(); + } + + void FillChildRefsForChannelz( + grpc_core::channelz::ChildRefsList* child_subchannels, + grpc_core::channelz::ChildRefsList* ignored) override { + delegate_->FillChildRefsForChannelz(child_subchannels, ignored); + } + + protected: void ShutdownLocked() override { - grpc_error* error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); - grpc_connectivity_state_set( - &state_tracker_, - GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), - "intercept_trailing_shutdown"); - } - - ~InterceptTrailing() { - grpc_connectivity_state_destroy(&state_tracker_); + // noop } + Args args_; private: - grpc_closure* on_complete_ = nullptr; - grpc_closure recv_trailing_metadata_ready_; - grpc_metadata_batch* recv_trailing_metadata_ = nullptr; - grpc_subchannel* hardcoded_subchannel_ = nullptr; - grpc_connectivity_state_tracker state_tracker_; - - static void RecordRecvTrailingMetadata( - void* ignored_arg, grpc_error* ignored_err) { - gpr_log(GPR_INFO, "trailer intercepted by lb"); - } -}; - -// A factory for a test LB policy that intercepts trailing metadata. -// The LB policy is implemented as a wrapper around a delegate LB policy. -class InterceptTrailingFactory : public grpc_core::LoadBalancingPolicyFactory { - public: - InterceptTrailingFactory(){} - - grpc_core::OrphanablePtr - CreateLoadBalancingPolicy( - const grpc_core::LoadBalancingPolicy::Args& args) const override { - return grpc_core::OrphanablePtr( - grpc_core::New(args)); - } - - const char* name() const override { - return intercept_trailing_name; - } + grpc_core::OrphanablePtr delegate_; }; class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { @@ -1143,43 +1084,117 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { grpc_core::LoadBalancingPolicyRegistry::Builder:: RegisterLoadBalancingPolicyFactory( grpc_core::UniquePtr( - grpc_core::New())); + grpc_core::New(this))); } void TearDown() override { ClientLbEnd2endTest::TearDown(); } + + class InterceptTrailingLb : public ForwardingLoadBalancingPolicy { + public: + InterceptTrailingLb( + const Args& args, + const std::string& delegate_lb_policy_name, + ClientLbInterceptTrailingMetadataTest* test) + : ForwardingLoadBalancingPolicy(args, delegate_lb_policy_name), + test_{test} { + } + + bool PickLocked(PickState* pick, grpc_error** error) override { + bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); + // If these asserts fail, then we will need to add code to + // proxy the results to the delegate LB. + GPR_ASSERT(pick->recv_trailing_metadata == nullptr); + GPR_ASSERT(pick->recv_trailing_metadata_ready == nullptr); + // OK to add add callbacks for test + GRPC_CLOSURE_INIT( + &recv_trailing_metadata_ready_, + InterceptTrailingLb::RecordRecvTrailingMetadata, + this, + grpc_schedule_on_exec_ctx); + pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; + pick->recv_trailing_metadata = &recv_trailing_metadata_; + return ret; + } + + static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { + InterceptTrailingLb* lb = static_cast(arg); + GPR_ASSERT(err == GRPC_ERROR_NONE); + GPR_ASSERT(lb->recv_trailing_metadata_ != nullptr); + // an simple check to make sure the trailing metadata is valid + GPR_ASSERT(grpc_get_status_code_from_metadata( + lb->recv_trailing_metadata_->idx.named.grpc_status->md) == + grpc_status_code::GRPC_STATUS_OK); + GRPC_ERROR_UNREF(err); + lb->test_->ReportTrailerIntercepted(); + } + + private: + grpc_closure recv_trailing_metadata_ready_; + grpc_metadata_batch* recv_trailing_metadata_; + ClientLbInterceptTrailingMetadataTest* test_; + }; + + // A factory for a test LB policy that intercepts trailing metadata. + // The LB policy is implemented as a wrapper around a delegate LB policy. + class InterceptTrailingFactory : + public grpc_core::LoadBalancingPolicyFactory { + public: + InterceptTrailingFactory(ClientLbInterceptTrailingMetadataTest* test): + test_{test} {} + + grpc_core::OrphanablePtr + CreateLoadBalancingPolicy( + const grpc_core::LoadBalancingPolicy::Args& args) const override { + return grpc_core::OrphanablePtr( + grpc_core::New( + args, + /*delegate_lb_policy_name=*/ "pick_first", + test_)); + } + + const char* name() const override { + return "intercept_trailing_metadata_lb"; + } + + private: + ClientLbInterceptTrailingMetadataTest* test_; + }; + + void ReportTrailerIntercepted() { + std::unique_lock lock(mu_); + trailers_intercepted_++; + } + + uint32_t trailers_intercepted() { + std::unique_lock lock(mu_); + return trailers_intercepted_; + } + + private: + std::mutex mu_; + uint32_t trailers_intercepted_ = 0; }; TEST_F(ClientLbInterceptTrailingMetadataTest, Intercepts_retries_disabled) { const int kNumServers = 1; StartServers(kNumServers); - auto channel = BuildChannel(intercept_trailing_name); + auto channel = BuildChannel("intercept_trailing_metadata_lb"); auto stub = BuildStub(channel); std::vector ports; for (size_t i = 0; i < servers_.size(); ++i) { ports.emplace_back(servers_[i]->port_); } SetNextResolution(ports); - for (size_t i = 0; i < servers_.size(); ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); } - // All requests should have gone to a single server. - bool found = false; - for (size_t i = 0; i < servers_.size(); ++i) { - const int request_count = servers_[i]->service_.request_count(); - if (request_count == kNumServers) { - found = true; - } else { - EXPECT_EQ(0, request_count); - } - } - EXPECT_TRUE(found); // Check LB policy name for the channel. EXPECT_EQ( - intercept_trailing_name, + "intercept_trailing_metadata_lb", channel->GetLoadBalancingPolicyName()); + EXPECT_EQ(kNumServers, trailers_intercepted()); } } // namespace From 1e2d43315ed65b3fc94b2f2d8e57830a907bbc0b Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Thu, 25 Oct 2018 15:49:19 -0700 Subject: [PATCH 011/814] fix contract of pick->recv_trailing_metadata_ready --- src/core/ext/filters/client_channel/lb_policy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index fd8464dc08e..67a1b5363f4 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -75,7 +75,7 @@ class LoadBalancingPolicy grpc_closure* on_complete; // Callback set by lb policy to be notified of trailing metadata. - // The callback is scheduled on grpc_schedule_on_exec_ctx. + // The callback must be scheduled on grpc_schedule_on_exec_ctx. grpc_closure* recv_trailing_metadata_ready; // If this is not nullptr, then the client channel will point it to the // call's trailing metadata before invoking recv_trailing_metadata_ready. From cdd698810b99f2be1c67f05c28d031ebddb04cea Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 27 Nov 2018 11:46:05 -0800 Subject: [PATCH 012/814] Move grpc_shutdown internals to a detached thread --- include/grpc/grpc.h | 4 +- src/core/lib/gprpp/thd.h | 39 +++++++- src/core/lib/gprpp/thd_posix.cc | 39 +++++--- src/core/lib/iomgr/fork_posix.cc | 6 +- src/core/lib/surface/init.cc | 88 ++++++++++++++----- src/core/lib/surface/init.h | 1 + test/core/end2end/fuzzers/client_fuzzer.cc | 8 +- test/core/end2end/fuzzers/server_fuzzer.cc | 8 +- test/core/security/alts_credentials_fuzzer.cc | 10 +-- test/core/slice/percent_encode_fuzzer.cc | 6 +- test/core/surface/init_test.cc | 7 ++ test/core/util/BUILD | 5 +- test/core/util/memory_counters.cc | 32 +++++++ test/core/util/memory_counters.h | 18 ++++ test/cpp/naming/address_sorting_test.cc | 6 +- 15 files changed, 206 insertions(+), 71 deletions(-) diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index d3b74cabab5..6ad22a49ed1 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -73,7 +73,9 @@ GRPCAPI void grpc_init(void); Before it's called, there should haven been a matching invocation to grpc_init(). - No memory is used by grpc after this call returns, nor are any instructions + The last call to grpc_shutdown will initiate cleaning up of grpc library + internals, which can happen in another thread. Once the clean-up is done, + no memory is used by grpc after this call returns, nor are any instructions executing within the grpc library. Prior to calling, all application owned grpc objects must have been destroyed. */ diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index caf0652c1a7..c9e2b9ce929 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -47,6 +47,26 @@ class ThreadInternalsInterface { class Thread { public: + class Options { + public: + Options() : joinable_(true), tracked_(true) {} + Options& set_joinable(bool joinable) { + joinable_ = joinable; + return *this; + } + Options& set_tracked(bool tracked) { + tracked_ = tracked; + return *this; + } + bool joinable() const { return joinable_; } + bool tracked() const { return tracked_; } + + private: + bool joinable_; + // Whether this thread is tracked by grpc internals. Should be true for most + // of threads. + bool tracked_; + }; /// Default constructor only to allow use in structs that lack constructors /// Does not produce a validly-constructed thread; must later /// use placement new to construct a real thread. Does not init mu_ and cv_ @@ -57,14 +77,17 @@ class Thread { /// with argument \a arg once it is started. /// The optional \a success argument indicates whether the thread /// is successfully created. + /// The optional \a options can be used to set the thread detachable. Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success = nullptr); + bool* success = nullptr, const Options& options = Options()); /// Move constructor for thread. After this is called, the other thread /// no longer represents a living thread object - Thread(Thread&& other) : state_(other.state_), impl_(other.impl_) { + Thread(Thread&& other) + : state_(other.state_), impl_(other.impl_), options_(other.options_) { other.state_ = MOVED; other.impl_ = nullptr; + other.options_ = Options(); } /// Move assignment operator for thread. After this is called, the other @@ -79,8 +102,10 @@ class Thread { // assert it for the time being. state_ = other.state_; impl_ = other.impl_; + options_ = other.options_; other.state_ = MOVED; other.impl_ = nullptr; + other.options_ = Options(); } return *this; } @@ -95,11 +120,16 @@ class Thread { GPR_ASSERT(state_ == ALIVE); state_ = STARTED; impl_->Start(); + if (!options_.joinable()) { + state_ = DONE; + impl_ = nullptr; + } } else { GPR_ASSERT(state_ == FAILED); } - }; + } + // It is only legal to call Join if the Thread is created as joinable. void Join() { if (impl_ != nullptr) { impl_->Join(); @@ -119,12 +149,13 @@ class Thread { /// FAKE -- just a dummy placeholder Thread created by the default constructor /// ALIVE -- an actual thread of control exists associated with this thread /// STARTED -- the thread of control has been started - /// DONE -- the thread of control has completed and been joined + /// DONE -- the thread of control has completed and been joined/detached /// FAILED -- the thread of control never came alive /// MOVED -- contents were moved out and we're no longer tracking them enum ThreadState { FAKE, ALIVE, STARTED, DONE, FAILED, MOVED }; ThreadState state_; internal::ThreadInternalsInterface* impl_; + Options options_; }; } // namespace grpc_core diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 2751b221a8f..24e235df2d6 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -44,13 +44,15 @@ struct thd_arg { void (*body)(void* arg); /* body of a thread */ void* arg; /* argument to a thread */ const char* name; /* name of thread. Can be nullptr. */ + bool joinable; + bool tracked; }; class ThreadInternalsPosix : public grpc_core::internal::ThreadInternalsInterface { public: ThreadInternalsPosix(const char* thd_name, void (*thd_body)(void* arg), - void* arg, bool* success) + void* arg, bool* success, const Thread::Options& options) : started_(false) { gpr_mu_init(&mu_); gpr_cv_init(&ready_); @@ -63,11 +65,20 @@ class ThreadInternalsPosix info->body = thd_body; info->arg = arg; info->name = thd_name; - grpc_core::Fork::IncThreadCount(); + info->joinable = options.joinable(); + info->tracked = options.tracked(); + if (options.tracked()) { + grpc_core::Fork::IncThreadCount(); + } GPR_ASSERT(pthread_attr_init(&attr) == 0); - GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == - 0); + if (options.joinable()) { + GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == + 0); + } else { + GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == + 0); + } *success = (pthread_create(&pthread_id_, &attr, @@ -98,7 +109,12 @@ class ThreadInternalsPosix gpr_mu_unlock(&arg.thread->mu_); (*arg.body)(arg.arg); - grpc_core::Fork::DecThreadCount(); + if (arg.tracked) { + grpc_core::Fork::DecThreadCount(); + } + if (!arg.joinable) { + grpc_core::Delete(arg.thread); + } return nullptr; }, info) == 0); @@ -108,9 +124,11 @@ class ThreadInternalsPosix if (!(*success)) { /* don't use gpr_free, as this was allocated using malloc (see above) */ free(info); - grpc_core::Fork::DecThreadCount(); + if (options.tracked()) { + grpc_core::Fork::DecThreadCount(); + } } - }; + } ~ThreadInternalsPosix() override { gpr_mu_destroy(&mu_); @@ -136,10 +154,11 @@ class ThreadInternalsPosix } // namespace Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success) { + bool* success, const Options& options) + : options_(options) { bool outcome = false; - impl_ = - grpc_core::New(thd_name, thd_body, arg, &outcome); + impl_ = grpc_core::New(thd_name, thd_body, arg, + &outcome, options); if (outcome) { state_ = ALIVE; } else { diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index e957bad73d3..c0b976f539c 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -35,6 +35,7 @@ #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/timer_manager.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" +#include "src/core/lib/surface/init.h" /* * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK @@ -47,11 +48,12 @@ bool registered_handlers = false; } // namespace void grpc_prefork() { - grpc_core::ExecCtx exec_ctx; - skipped_handler = true; + grpc_maybe_wait_for_async_shutdown(); if (!grpc_is_initialized()) { return; } + grpc_core::ExecCtx exec_ctx; + skipped_handler = true; if (!grpc_core::Fork::Enabled()) { gpr_log(GPR_ERROR, "Fork support not enabled; try running with the " diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index c6198b8ae76..64d8222ce80 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -61,10 +61,15 @@ extern void grpc_register_built_in_plugins(void); static gpr_once g_basic_init = GPR_ONCE_INIT; static gpr_mu g_init_mu; static int g_initializations; +static gpr_cv* g_shutting_down_cv; +static bool g_shutting_down; static void do_basic_init(void) { gpr_log_verbosity_init(); gpr_mu_init(&g_init_mu); + g_shutting_down_cv = static_cast(malloc(sizeof(gpr_cv))); + gpr_cv_init(g_shutting_down_cv); + g_shutting_down = false; grpc_register_built_in_plugins(); grpc_cq_global_init(); g_initializations = 0; @@ -120,6 +125,10 @@ void grpc_init(void) { gpr_mu_lock(&g_init_mu); if (++g_initializations == 1) { + if (g_shutting_down) { + g_shutting_down = false; + gpr_cv_broadcast(g_shutting_down_cv); + } grpc_core::Fork::GlobalInit(); grpc_fork_handlers_auto_register(); gpr_time_init(); @@ -154,34 +163,55 @@ void grpc_init(void) { GRPC_API_TRACE("grpc_init(void)", 0, ()); } -void grpc_shutdown(void) { +void grpc_shutdown_internal(void* ignored) { int i; + GRPC_API_TRACE("grpc_shutdown_internal", 0, ()); + gpr_mu_lock(&g_init_mu); + // We have released lock from the shutdown thread and it is possible that + // another grpc_init has been called, and do nothing if that is the case. + if (--g_initializations != 0) { + gpr_mu_unlock(&g_init_mu); + return; + } + { + grpc_core::ExecCtx exec_ctx(0); + { + grpc_timer_manager_set_threading(false); // shutdown timer_manager thread + grpc_executor_shutdown(); + for (i = g_number_of_plugins; i >= 0; i--) { + if (g_all_of_the_plugins[i].destroy != nullptr) { + g_all_of_the_plugins[i].destroy(); + } + } + } + grpc_iomgr_shutdown(); + gpr_timers_global_destroy(); + grpc_tracer_shutdown(); + grpc_mdctx_global_shutdown(); + grpc_handshaker_factory_registry_shutdown(); + grpc_slice_intern_shutdown(); + grpc_core::channelz::ChannelzRegistry::Shutdown(); + grpc_stats_shutdown(); + grpc_core::Fork::GlobalShutdown(); + } + grpc_core::ExecCtx::GlobalShutdown(); + g_shutting_down = false; + gpr_cv_broadcast(g_shutting_down_cv); + gpr_mu_unlock(&g_init_mu); +} + +void grpc_shutdown(void) { GRPC_API_TRACE("grpc_shutdown(void)", 0, ()); gpr_mu_lock(&g_init_mu); if (--g_initializations == 0) { - { - grpc_core::ExecCtx exec_ctx(0); - { - grpc_timer_manager_set_threading( - false); // shutdown timer_manager thread - grpc_executor_shutdown(); - for (i = g_number_of_plugins; i >= 0; i--) { - if (g_all_of_the_plugins[i].destroy != nullptr) { - g_all_of_the_plugins[i].destroy(); - } - } - } - grpc_iomgr_shutdown(); - gpr_timers_global_destroy(); - grpc_tracer_shutdown(); - grpc_mdctx_global_shutdown(); - grpc_handshaker_factory_registry_shutdown(); - grpc_slice_intern_shutdown(); - grpc_core::channelz::ChannelzRegistry::Shutdown(); - grpc_stats_shutdown(); - grpc_core::Fork::GlobalShutdown(); - } - grpc_core::ExecCtx::GlobalShutdown(); + g_initializations++; + g_shutting_down = true; + // spawn a detached thread to do the actual clean up in case we are + // currently in an executor thread. + grpc_core::Thread cleanup_thread( + "grpc_shutdown", grpc_shutdown_internal, nullptr, nullptr, + grpc_core::Thread::Options().set_joinable(false).set_tracked(false)); + cleanup_thread.Start(); } gpr_mu_unlock(&g_init_mu); } @@ -194,3 +224,13 @@ int grpc_is_initialized(void) { gpr_mu_unlock(&g_init_mu); return r; } + +void grpc_maybe_wait_for_async_shutdown(void) { + gpr_once_init(&g_basic_init, do_basic_init); + gpr_mu_lock(&g_init_mu); + while (g_shutting_down) { + gpr_cv_wait(g_shutting_down_cv, &g_init_mu, + gpr_inf_future(GPR_CLOCK_REALTIME)); + } + gpr_mu_unlock(&g_init_mu); +} diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 193f51447d9..6eaa488d054 100644 --- a/src/core/lib/surface/init.h +++ b/src/core/lib/surface/init.h @@ -22,5 +22,6 @@ void grpc_register_security_filters(void); void grpc_security_pre_init(void); void grpc_security_init(void); +void grpc_maybe_wait_for_async_shutdown(void); #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/test/core/end2end/fuzzers/client_fuzzer.cc b/test/core/end2end/fuzzers/client_fuzzer.cc index e21006bb673..96656502b34 100644 --- a/test/core/end2end/fuzzers/client_fuzzer.cc +++ b/test/core/end2end/fuzzers/client_fuzzer.cc @@ -40,9 +40,8 @@ static void dont_log(gpr_log_func_args* args) {} extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_test_only_set_slice_hash_seed(0); - struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - if (leak_check) grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(leak_check); grpc_init(); { grpc_core::ExecCtx exec_ctx; @@ -160,10 +159,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } } grpc_shutdown(); - if (leak_check) { - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); - } return 0; } diff --git a/test/core/end2end/fuzzers/server_fuzzer.cc b/test/core/end2end/fuzzers/server_fuzzer.cc index bd686215ddb..9cc68512320 100644 --- a/test/core/end2end/fuzzers/server_fuzzer.cc +++ b/test/core/end2end/fuzzers/server_fuzzer.cc @@ -37,9 +37,8 @@ static void dont_log(gpr_log_func_args* args) {} extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_test_only_set_slice_hash_seed(0); - struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - if (leak_check) grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(leak_check); grpc_init(); { grpc_core::ExecCtx exec_ctx; @@ -136,10 +135,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_completion_queue_destroy(cq); } grpc_shutdown(); - if (leak_check) { - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); - } return 0; } diff --git a/test/core/security/alts_credentials_fuzzer.cc b/test/core/security/alts_credentials_fuzzer.cc index bf18f0a589e..abe50031687 100644 --- a/test/core/security/alts_credentials_fuzzer.cc +++ b/test/core/security/alts_credentials_fuzzer.cc @@ -66,10 +66,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { gpr_set_log_function(dont_log); } gpr_free(grpc_trace_fuzzer); - struct grpc_memory_counters counters; - if (leak_check) { - grpc_memory_counters_init(); - } + grpc_core::testing::LeakDetector leak_detector(leak_check); input_stream inp = {data, data + size}; grpc_init(); bool is_on_gcp = grpc_alts_is_running_on_gcp(); @@ -111,10 +108,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { gpr_free(handshaker_service_url); } grpc_shutdown(); - if (leak_check) { - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); - } return 0; } diff --git a/test/core/slice/percent_encode_fuzzer.cc b/test/core/slice/percent_encode_fuzzer.cc index 1fd197e180a..782149cd867 100644 --- a/test/core/slice/percent_encode_fuzzer.cc +++ b/test/core/slice/percent_encode_fuzzer.cc @@ -31,9 +31,8 @@ bool squelch = true; bool leak_check = true; static void test(const uint8_t* data, size_t size, const uint8_t* dict) { - struct grpc_memory_counters counters; + grpc_core::testing::LeakDetector leak_detector(true); grpc_init(); - grpc_memory_counters_init(); grpc_slice input = grpc_slice_from_copied_buffer(reinterpret_cast(data), size); grpc_slice output = grpc_percent_encode_slice(input, dict); @@ -49,10 +48,7 @@ static void test(const uint8_t* data, size_t size, const uint8_t* dict) { grpc_slice_unref(output); grpc_slice_unref(decoded_output); grpc_slice_unref(permissive_decoded_output); - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); grpc_shutdown(); - GPR_ASSERT(counters.total_size_relative == 0); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/test/core/surface/init_test.cc b/test/core/surface/init_test.cc index 5749bc8b36d..8e8e89c4f93 100644 --- a/test/core/surface/init_test.cc +++ b/test/core/surface/init_test.cc @@ -18,6 +18,9 @@ #include #include +#include + +#include "src/core/lib/surface/init.h" #include "test/core/util/test_config.h" static int g_flag; @@ -30,6 +33,7 @@ static void test(int rounds) { for (i = 0; i < rounds; i++) { grpc_shutdown(); } + grpc_maybe_wait_for_async_shutdown(); } static void test_mixed(void) { @@ -39,6 +43,7 @@ static void test_mixed(void) { grpc_init(); grpc_shutdown(); grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); } static void plugin_init(void) { g_flag = 1; } @@ -49,6 +54,7 @@ static void test_plugin() { grpc_init(); GPR_ASSERT(g_flag == 1); grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); GPR_ASSERT(g_flag == 2); } @@ -57,6 +63,7 @@ static void test_repeatedly() { grpc_init(); grpc_shutdown(); } + grpc_maybe_wait_for_async_shutdown(); } int main(int argc, char** argv) { diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 5492dcfa795..a5623299983 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -31,7 +31,10 @@ grpc_cc_library( "memory_counters.h", "test_config.h", ], - deps = ["//:gpr"], + deps = [ + "//:gpr", + "//:grpc_common", + ], data = [ "lsan_suppressions.txt", "tsan_suppressions.txt", diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index 4960fe07572..300cc00e37f 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -16,12 +16,17 @@ * */ +#include #include #include +#include #include +#include #include +#include +#include "src/core/lib/surface/init.h" #include "test/core/util/memory_counters.h" static struct grpc_memory_counters g_memory_counters; @@ -106,3 +111,30 @@ struct grpc_memory_counters grpc_memory_counters_snapshot() { NO_BARRIER_LOAD(&g_memory_counters.total_allocs_absolute); return counters; } + +namespace grpc_core { +namespace testing { + +LeakDetector::LeakDetector(bool enable) : enabled_(enable) { + if (enabled_) { + grpc_memory_counters_init(); + } +} + +LeakDetector::~LeakDetector() { + if (enabled_) { + // Wait for grpc_shutdown() to finish its async work. + grpc_maybe_wait_for_async_shutdown(); + struct grpc_memory_counters counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_snapshot(); + if (counters.total_size_relative != 0) { + gpr_log(GPR_ERROR, "Leaking %" PRIuPTR "bytes", + static_cast(counters.total_size_relative)); + GPR_ASSERT(0); + } + grpc_memory_counters_destroy(); + } +} + +} // namespace testing +} // namespace grpc_core diff --git a/test/core/util/memory_counters.h b/test/core/util/memory_counters.h index c23a13e5c85..c92a001ff13 100644 --- a/test/core/util/memory_counters.h +++ b/test/core/util/memory_counters.h @@ -32,4 +32,22 @@ void grpc_memory_counters_init(); void grpc_memory_counters_destroy(); struct grpc_memory_counters grpc_memory_counters_snapshot(); +namespace grpc_core { +namespace testing { + +// At destruction time, it will check there is no memory leak. +// The object should be created before grpc_init() is called and destroyed after +// grpc_shutdown() is returned. +class LeakDetector { + public: + explicit LeakDetector(bool enable); + ~LeakDetector(); + + private: + const bool enabled_; +}; + +} // namespace testing +} // namespace grpc_core + #endif diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index fc6721d0ba8..130c3d58267 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -46,6 +46,7 @@ #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/surface/init.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -200,7 +201,10 @@ void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs, class AddressSortingTest : public ::testing::Test { protected: void SetUp() override { grpc_init(); } - void TearDown() override { grpc_shutdown(); } + void TearDown() override { + grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); + } }; /* Tests for rule 1 */ From 23a9cf91f292fc1447579a72dc52e9730ece9b57 Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 27 Nov 2018 16:12:44 -0800 Subject: [PATCH 013/814] Fix test --- test/core/handshake/readahead_handshaker_server_ssl.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc index 14d96b5d89c..953b0f7181d 100644 --- a/test/core/handshake/readahead_handshaker_server_ssl.cc +++ b/test/core/handshake/readahead_handshaker_server_ssl.cc @@ -37,6 +37,7 @@ #include "src/core/lib/channel/handshaker_factory.h" #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/security/transport/security_handshaker.h" +#include "src/core/lib/surface/init.h" #include "test/core/handshake/server_ssl_common.h" @@ -97,5 +98,6 @@ int main(int argc, char* argv[]) { const char* full_alpn_list[] = {"grpc-exp", "h2"}; GPR_ASSERT(server_ssl_test(full_alpn_list, 2, "grpc-exp")); grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); return 0; } From bd3bb8e289e0111a3d4e8282c65d977fe447f6b0 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 28 Nov 2018 09:22:27 -0800 Subject: [PATCH 014/814] BUILD fix. --- test/core/util/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/test/core/util/BUILD b/test/core/util/BUILD index a5623299983..f17b6be6e63 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -33,6 +33,7 @@ grpc_cc_library( ], deps = [ "//:gpr", + "//:grpc", "//:grpc_common", ], data = [ From 864cea208136892f405b54edcedf77c899385393 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 29 Nov 2018 11:18:35 -0800 Subject: [PATCH 015/814] clang-format --- src/core/lib/surface/init.cc | 3 +-- test/core/util/memory_counters.cc | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index aa0cf58335f..ec38dfce837 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -177,8 +177,7 @@ void grpc_shutdown_internal(void* ignored) { grpc_core::ExecCtx exec_ctx(0); grpc_iomgr_shutdown_background_closure(); { - grpc_timer_manager_set_threading( - false); // shutdown timer_manager thread + grpc_timer_manager_set_threading(false); // shutdown timer_manager thread grpc_executor_shutdown(); for (i = g_number_of_plugins; i >= 0; i--) { if (g_all_of_the_plugins[i].destroy != nullptr) { diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index 300cc00e37f..a16814febbb 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -126,9 +126,8 @@ LeakDetector::~LeakDetector() { // Wait for grpc_shutdown() to finish its async work. grpc_maybe_wait_for_async_shutdown(); struct grpc_memory_counters counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_snapshot(); if (counters.total_size_relative != 0) { - gpr_log(GPR_ERROR, "Leaking %" PRIuPTR "bytes", + gpr_log(GPR_ERROR, "Leaking %" PRIuPTR " bytes", static_cast(counters.total_size_relative)); GPR_ASSERT(0); } From c9309562897a0916837e433fe2b6bb6ad166b084 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 29 Nov 2018 14:25:23 -0800 Subject: [PATCH 016/814] Fix tests --- src/core/lib/gprpp/thd_posix.cc | 7 ++++--- .../client_channel/resolvers/dns_resolver_cooldown_test.cc | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 24e235df2d6..9c42a049f42 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -108,13 +108,14 @@ class ThreadInternalsPosix } gpr_mu_unlock(&arg.thread->mu_); + if (!arg.joinable) { + grpc_core::Delete(arg.thread); + } + (*arg.body)(arg.arg); if (arg.tracked) { grpc_core::Fork::DecThreadCount(); } - if (!arg.joinable) { - grpc_core::Delete(arg.thread); - } return nullptr; }, info) == 0); diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index 1a7db40f598..cc31019de58 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -26,6 +26,7 @@ #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/surface/init.h" #include "test/core/util/test_config.h" constexpr int kMinResolutionPeriodMs = 1000; @@ -279,6 +280,7 @@ int main(int argc, char** argv) { GRPC_COMBINER_UNREF(g_combiner, "test"); } grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); GPR_ASSERT(g_all_callbacks_invoked); return 0; } From 606be620d8230f43cfeafb858aa7521db7ac954c Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 29 Nov 2018 16:13:34 -0800 Subject: [PATCH 017/814] Fix tests --- test/core/end2end/fuzzers/api_fuzzer.cc | 2 ++ test/core/util/memory_counters.cc | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index e97a544e12c..7774cbf1ba6 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -35,6 +35,7 @@ #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/timer_manager.h" #include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/surface/init.h" #include "src/core/lib/surface/server.h" #include "src/core/lib/transport/metadata.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -1200,5 +1201,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_resource_quota_unref(g_resource_quota); grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); return 0; } diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index a16814febbb..8cc0fedbf0d 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -122,9 +122,9 @@ LeakDetector::LeakDetector(bool enable) : enabled_(enable) { } LeakDetector::~LeakDetector() { + // Wait for grpc_shutdown() to finish its async work. + grpc_maybe_wait_for_async_shutdown(); if (enabled_) { - // Wait for grpc_shutdown() to finish its async work. - grpc_maybe_wait_for_async_shutdown(); struct grpc_memory_counters counters = grpc_memory_counters_snapshot(); if (counters.total_size_relative != 0) { gpr_log(GPR_ERROR, "Leaking %" PRIuPTR " bytes", From b4565f1b19a60f7e89806454b27f83e188381d81 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 5 Dec 2018 15:01:37 -0800 Subject: [PATCH 018/814] Wait for shutdown to finish in TestEnv --- test/core/util/test_config.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index fe80bb2d4d0..f5855a60c98 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -31,6 +31,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/surface/init.h" int64_t g_fixture_slowdown_factor = 1; int64_t g_poller_slowdown_factor = 1; @@ -405,7 +406,9 @@ TestEnvironment::TestEnvironment(int argc, char** argv) { grpc_test_init(argc, argv); } -TestEnvironment::~TestEnvironment() {} +TestEnvironment::~TestEnvironment() { + grpc_maybe_wait_for_async_shutdown(); +} } // namespace testing } // namespace grpc From 5c1ff6cb4a9826b2aad773e3397ea608db543798 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 5 Dec 2018 15:09:12 -0800 Subject: [PATCH 019/814] Make TraceFlag trivially destructible --- src/core/lib/debug/trace.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h index 5ed52454bd7..6108fb239bd 100644 --- a/src/core/lib/debug/trace.h +++ b/src/core/lib/debug/trace.h @@ -53,7 +53,9 @@ void grpc_tracer_enable_flag(grpc_core::TraceFlag* flag); class TraceFlag { public: TraceFlag(bool default_enabled, const char* name); - ~TraceFlag() {} + // TraceFlag needs to be trivially destructible since it is used as global + // variable. + ~TraceFlag() = default; const char* name() const { return name_; } From e1f573a58b9278c7f98011264613ef4e66a028f2 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 5 Dec 2018 15:43:23 -0800 Subject: [PATCH 020/814] clang-format --- test/core/util/test_config.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index f5855a60c98..0c0492fdbbd 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -406,9 +406,7 @@ TestEnvironment::TestEnvironment(int argc, char** argv) { grpc_test_init(argc, argv); } -TestEnvironment::~TestEnvironment() { - grpc_maybe_wait_for_async_shutdown(); -} +TestEnvironment::~TestEnvironment() { grpc_maybe_wait_for_async_shutdown(); } } // namespace testing } // namespace grpc From a4e9f33b85cb9fde3cb1ed51ae4b8e28811967a7 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 13 Nov 2018 16:38:44 -0800 Subject: [PATCH 021/814] Add interop cloud to prod test for GoogleDefaultCredentials --- doc/interop-test-descriptions.md | 38 ++++++++ test/cpp/interop/client.cc | 6 ++ test/cpp/interop/interop_client.cc | 19 ++++ test/cpp/interop/interop_client.h | 2 + .../internal_ci/macos/grpc_interop_toprod.sh | 3 +- tools/run_tests/run_interop_tests.py | 93 ++++++++++--------- 6 files changed, 117 insertions(+), 44 deletions(-) diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md index 1d6535d7ea0..9f6961f5199 100644 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -679,6 +679,44 @@ Client asserts: by the auth library. The client can optionally check the username matches the email address in the key file. +### google_default_credentials + +Similar to the other auth tests, this test should only be run against prod +servers. Different from some of the other auth tests however, this test +may be also run from outside of GCP. + +This test verifies unary calls succeed when the client uses +GoogleDefaultCredentials. The path to a service account key file in the +GOOGLE_APPLICATION_CREDENTIALS environment variable may or may not be +provided by the test runner. For example, the test runner might set +this environment when outside of GCP but keep it unset when on GCP. + +The test uses `--default_service_account` with GCE service account email. + +Server features: +* [UnaryCall][] +* [Echo Authenticated Username][] + +Procedure: + 1. Client configures the channel to use GoogleDefaultCredentials + * Note: the term `GoogleDefaultCredentials` within the context + of this test description refers to an API which encapsulates + both "transport credentials" and "call credentials" and which + is capable of transport creds auto-selection (including ALTS). + Similar APIs involving only auto-selection of OAuth mechanisms + might work for this test but aren't the intended subjects. + 2. Client calls UnaryCall with: + + ``` + { + fill_username: true + } + ``` + +Client asserts: +* call was successful +* received SimpleResponse.username matches the value of + `--default_service_account` ### custom_metadata diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index a4b1a85f856..99315e3c85d 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -54,6 +54,7 @@ DEFINE_string( "custom_metadata: server will echo custom metadata;\n" "empty_stream : bi-di stream with no request/response;\n" "empty_unary : empty (zero bytes) request and response;\n" + "google_default_credentials: large unary using GDC;\n" "half_duplex : half-duplex streaming;\n" "jwt_token_creds: large_unary with JWT token auth;\n" "large_unary : single request and (large) response;\n" @@ -151,6 +152,11 @@ int main(int argc, char** argv) { std::bind(&grpc::testing::InteropClient::DoPerRpcCreds, &client, GetServiceAccountJsonKey()); } + if (FLAGS_custom_credentials_type == "google_default_credentials") { + actions["google_default_credentials"] = + std::bind(&grpc::testing::InteropClient::DoGoogleDefaultCredentials, + &client, FLAGS_default_service_account); + } actions["status_code_and_message"] = std::bind(&grpc::testing::InteropClient::DoStatusWithMessage, &client); actions["custom_metadata"] = diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 4ff153f980a..649abf8a938 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -294,6 +294,25 @@ bool InteropClient::DoJwtTokenCreds(const grpc::string& username) { return true; } +bool InteropClient::DoGoogleDefaultCredentials( + const grpc::string& default_service_account) { + gpr_log(GPR_DEBUG, + "Sending a large unary rpc with GoogleDefaultCredentials..."); + SimpleRequest request; + SimpleResponse response; + request.set_fill_username(true); + + if (!PerformLargeUnary(&request, &response)) { + return false; + } + + gpr_log(GPR_DEBUG, "Got username %s", response.username().c_str()); + GPR_ASSERT(!response.username().empty()); + GPR_ASSERT(response.username().c_str() == default_service_account); + gpr_log(GPR_DEBUG, "Large unary rpc with GoogleDefaultCredentials done."); + return true; +} + bool InteropClient::DoLargeUnary() { gpr_log(GPR_DEBUG, "Sending a large unary rpc..."); SimpleRequest request; diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index 0ceff55c5c2..8644844d952 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -89,6 +89,8 @@ class InteropClient { const grpc::string& oauth_scope); // username is a string containing the user email bool DoPerRpcCreds(const grpc::string& json_key); + // username is the GCE default service account email + bool DoGoogleDefaultCredentials(const grpc::string& username); private: class ServiceStub { diff --git a/tools/internal_ci/macos/grpc_interop_toprod.sh b/tools/internal_ci/macos/grpc_interop_toprod.sh index e748a62e761..d1ab54fe01e 100755 --- a/tools/internal_ci/macos/grpc_interop_toprod.sh +++ b/tools/internal_ci/macos/grpc_interop_toprod.sh @@ -30,7 +30,8 @@ export GRPC_DEFAULT_SSL_ROOTS_FILE_PATH="$(pwd)/etc/roots.pem" # building all languages in the same working copy can also lead to conflicts # due to different compilation flags tools/run_tests/run_interop_tests.py -l c++ \ - --cloud_to_prod --cloud_to_prod_auth --prod_servers default gateway_v4 \ + --cloud_to_prod --cloud_to_prod_auth --on_gce=false \ + --prod_servers default gateway_v4 \ --service_account_key_file="${KOKORO_GFILE_DIR}/GrpcTesting-726eb1347f15.json" \ --skip_compute_engine_creds --internal_ci -t -j 4 || FAILED="true" diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index d026145d66f..de3f01a53e0 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -65,6 +65,12 @@ _SKIP_ADVANCED = [ _SKIP_SPECIAL_STATUS_MESSAGE = ['special_status_message'] +_GOOGLE_DEFAULT_CREDS_TEST_CASE = 'google_default_credentials' + +_SKIP_GOOGLE_DEFAULT_CREDS = [ + _GOOGLE_DEFAULT_CREDS_TEST_CASE, +] + _TEST_TIMEOUT = 3 * 60 # disable this test on core-based languages, @@ -129,7 +135,7 @@ class CSharpLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -158,7 +164,7 @@ class CSharpCoreCLRLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -188,7 +194,7 @@ class DartLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE @@ -223,7 +229,7 @@ class JavaLanguage: return {} def unimplemented_test_cases(self): - return [] + return _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -248,7 +254,7 @@ class JavaOkHttpClient: return {} def unimplemented_test_cases(self): - return _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS def __str__(self): return 'javaokhttp' @@ -279,7 +285,7 @@ class GoLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + return _SKIP_COMPRESSION + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -309,7 +315,7 @@ class Http2Server: return {} def unimplemented_test_cases(self): - return _TEST_CASES + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _TEST_CASES + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return _TEST_CASES @@ -339,7 +345,7 @@ class Http2Client: return {} def unimplemented_test_cases(self): - return _TEST_CASES + _SKIP_SPECIAL_STATUS_MESSAGE + return _TEST_CASES + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return _TEST_CASES @@ -376,7 +382,7 @@ class NodeLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -406,7 +412,7 @@ class NodePureJSLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return [] @@ -431,7 +437,7 @@ class PHPLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return [] @@ -456,7 +462,7 @@ class PHP7Language: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return [] @@ -491,7 +497,7 @@ class ObjcLanguage: # cmdline argument. Here we return all but one test cases as unimplemented, # and depend upon ObjC test's behavior that it runs all cases even when # we tell it to run just one. - return _TEST_CASES[1:] + _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _TEST_CASES[1:] + _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -526,7 +532,7 @@ class RubyLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -571,7 +577,7 @@ class PythonLanguage: } def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_GOOGLE_DEFAULT_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -614,8 +620,11 @@ _TEST_CASES = [ ] _AUTH_TEST_CASES = [ - 'compute_engine_creds', 'jwt_token_creds', 'oauth2_auth_token', - 'per_rpc_creds' + 'compute_engine_creds', + 'jwt_token_creds', + 'oauth2_auth_token', + 'per_rpc_creds', + _GOOGLE_DEFAULT_CREDS_TEST_CASE, ] _HTTP2_TEST_CASES = ['tls', 'framing'] @@ -714,7 +723,7 @@ def compute_engine_creds_required(language, test_case): return False -def auth_options(language, test_case, service_account_key_file=None): +def auth_options(language, test_case, on_gce, service_account_key_file=None): """Returns (cmdline, env) tuple with cloud_to_prod_auth test options.""" language = str(language) @@ -728,9 +737,6 @@ def auth_options(language, test_case, service_account_key_file=None): key_file_arg = '--service_account_key_file=%s' % service_account_key_file default_account_arg = '--default_service_account=830293263384-compute@developer.gserviceaccount.com' - # TODO: When using google_default_credentials outside of cloud-to-prod, the environment variable - # 'GOOGLE_APPLICATION_CREDENTIALS' needs to be set for the test case - # 'jwt_token_creds' to work. if test_case in ['jwt_token_creds', 'per_rpc_creds', 'oauth2_auth_token']: if language in [ 'csharp', 'csharpcoreclr', 'node', 'php', 'php7', 'python', @@ -750,6 +756,11 @@ def auth_options(language, test_case, service_account_key_file=None): if test_case == 'compute_engine_creds': cmdargs += [oauth_scope_arg, default_account_arg] + if test_case == _GOOGLE_DEFAULT_CREDS_TEST_CASE: + if not on_gce: + env['GOOGLE_APPLICATION_CREDENTIALS'] = service_account_key_file + cmdargs += [default_account_arg] + return (cmdargs, env) @@ -767,6 +778,7 @@ def cloud_to_prod_jobspec(language, test_case, server_host_nickname, server_host, + on_gce, docker_image=None, auth=False, manual_cmd_log=None, @@ -793,7 +805,7 @@ def cloud_to_prod_jobspec(language, cmdargs = cmdargs + transport_security_options environ = dict(language.cloud_to_prod_env(), **language.global_env()) if auth: - auth_cmdargs, auth_env = auth_options(language, test_case, + auth_cmdargs, auth_env = auth_options(language, test_case, on_gce, service_account_key_file) cmdargs += auth_cmdargs environ.update(auth_env) @@ -1071,6 +1083,12 @@ argp.add_argument( action='store_const', const=True, help='Run cloud_to_prod_auth tests.') +argp.add_argument( + '--on_gce', + default=True, + action='store_const', + const=True, + help='Whether or not this test script is running on GCE.') argp.add_argument( '--prod_servers', choices=prod_servers.keys(), @@ -1326,6 +1344,7 @@ try: test_case, server_host_nickname, prod_servers[server_host_nickname], + on_gce=args.on_gce, docker_image=docker_images.get(str(language)), manual_cmd_log=client_manual_cmd_log, service_account_key_file=args. @@ -1340,6 +1359,7 @@ try: test_case, server_host_nickname, prod_servers[server_host_nickname], + on_gce=args.on_gce, docker_image=docker_images.get( str(language)), manual_cmd_log=client_manual_cmd_log, @@ -1356,6 +1376,7 @@ try: test_case, server_host_nickname, prod_servers[server_host_nickname], + on_gce=args.on_gce, docker_image=docker_images.get(str(http2Interop)), manual_cmd_log=client_manual_cmd_log, service_account_key_file=args.service_account_key_file, @@ -1374,36 +1395,22 @@ try: not compute_engine_creds_required( language, test_case)): if not test_case in language.unimplemented_test_cases(): - tls_test_job = cloud_to_prod_jobspec( + transport_security = 'tls' + if test_case == _GOOGLE_DEFAULT_CREDS_TEST_CASE: + transport_security = 'google_default_credentials' + test_job = cloud_to_prod_jobspec( language, test_case, server_host_nickname, prod_servers[server_host_nickname], + on_gce=args.on_gce, docker_image=docker_images.get(str(language)), auth=True, manual_cmd_log=client_manual_cmd_log, service_account_key_file=args. service_account_key_file, - transport_security='tls') - jobs.append(tls_test_job) - if str(language) in [ - 'go' - ]: # Add more languages to the list to turn on tests. - google_default_creds_test_job = cloud_to_prod_jobspec( - language, - test_case, - server_host_nickname, - prod_servers[server_host_nickname], - docker_image=docker_images.get( - str(language)), - auth=True, - manual_cmd_log=client_manual_cmd_log, - service_account_key_file=args. - service_account_key_file, - transport_security= - 'google_default_credentials') - jobs.append(google_default_creds_test_job) - + transport_security=transport_security) + jobs.append(test_job) for server in args.override_server: server_name = server[0] (server_host, server_port) = server[1].split(':') From b6ac1cb5b477d0182126a4b51d33ac58e66f3e83 Mon Sep 17 00:00:00 2001 From: Maxim Bunkov Date: Tue, 11 Dec 2018 14:11:00 +0500 Subject: [PATCH 022/814] added support tvos --- gRPC-C++.podspec | 1 + gRPC-Core.podspec | 1 + gRPC-ProtoRPC.podspec | 1 + gRPC-RxLibrary.podspec | 1 + src/objective-c/BoringSSL-GRPC.podspec | 1 + 5 files changed, 5 insertions(+) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 73c87942430..eac7fa7b9c4 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -40,6 +40,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' s.requires_arc = false name = 'grpcpp' diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index ff4d79426fe..284c8fbb3a2 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -40,6 +40,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' s.requires_arc = false name = 'grpc' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index d7050906e43..64e199eabd4 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -35,6 +35,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'ProtoRPC' s.module_name = name diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 955f3682f67..76d023b475b 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -35,6 +35,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'RxLibrary' s.module_name = name diff --git a/src/objective-c/BoringSSL-GRPC.podspec b/src/objective-c/BoringSSL-GRPC.podspec index 04e4d5768f2..3f02268b4fe 100644 --- a/src/objective-c/BoringSSL-GRPC.podspec +++ b/src/objective-c/BoringSSL-GRPC.podspec @@ -80,6 +80,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '5.0' s.osx.deployment_target = '10.7' + s.tvos.deployment_target = '10.0' name = 'openssl_grpc' From 71094e25c5355190eed4463cf3b1e48db053c6e0 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 18 Dec 2018 11:43:53 -0800 Subject: [PATCH 023/814] Remove dependency of grpc.framework.foundation.callable_util * Used in _channel.py, _server.py, and _utilities.py * This API can trace back to 4 years ago * The code change ensures the logging info is exactly the same --- src/python/grpcio/grpc/_channel.py | 9 +++++---- src/python/grpcio/grpc/_server.py | 7 ++++--- src/python/grpcio/grpc/_utilities.py | 16 +++++++++++----- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 96118badada..e8279db51fd 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -22,7 +22,6 @@ import grpc from grpc import _common from grpc import _grpcio_metadata from grpc._cython import cygrpc -from grpc.framework.foundation import callable_util _LOGGER = logging.getLogger(__name__) @@ -871,9 +870,11 @@ def _deliver(state, initial_connectivity, initial_callbacks): while True: for callback in callbacks: cygrpc.block_if_fork_in_progress(state) - callable_util.call_logging_exceptions( - callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE, - connectivity) + try: + callback(connectivity) + except Exception: # pylint: disable=broad-except + _LOGGER.exception( + _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE) with state.lock: callbacks = _deliveries(state) if callbacks: diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index eb750ef1a82..83ccf38232f 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -25,7 +25,6 @@ import grpc from grpc import _common from grpc import _interceptor from grpc._cython import cygrpc -from grpc.framework.foundation import callable_util _LOGGER = logging.getLogger(__name__) @@ -748,8 +747,10 @@ def _process_event_and_continue(state, event): else: rpc_state, callbacks = event.tag(event) for callback in callbacks: - callable_util.call_logging_exceptions(callback, - 'Exception calling callback!') + try: + callback() + except Exception: # pylint: disable=broad-except + _LOGGER.exception('Exception calling callback!') if rpc_state is not None: with state.lock: state.rpc_states.remove(rpc_state) diff --git a/src/python/grpcio/grpc/_utilities.py b/src/python/grpcio/grpc/_utilities.py index d90b34bcbd4..d1f465a83a6 100644 --- a/src/python/grpcio/grpc/_utilities.py +++ b/src/python/grpcio/grpc/_utilities.py @@ -16,12 +16,14 @@ import collections import threading import time +import logging import six import grpc from grpc import _common -from grpc.framework.foundation import callable_util + +_LOGGER = logging.getLogger(__name__) _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE = ( 'Exception calling connectivity future "done" callback!') @@ -98,8 +100,10 @@ class _ChannelReadyFuture(grpc.Future): return for done_callback in done_callbacks: - callable_util.call_logging_exceptions( - done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self) + try: + done_callback(self) + except Exception: # pylint: disable=broad-except + _LOGGER.exception(_DONE_CALLBACK_EXCEPTION_LOG_MESSAGE) def cancel(self): with self._condition: @@ -113,8 +117,10 @@ class _ChannelReadyFuture(grpc.Future): return False for done_callback in done_callbacks: - callable_util.call_logging_exceptions( - done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self) + try: + done_callback(self) + except Exception: # pylint: disable=broad-except + _LOGGER.exception(_DONE_CALLBACK_EXCEPTION_LOG_MESSAGE) return True From 05b61a5199dd69e33011ed0e677d9d43a77c01a4 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 20 Dec 2018 12:10:53 -0800 Subject: [PATCH 024/814] Use Pylint to lint gRPC Python examples --- .pylintrc-examples | 100 ++++++++++++++++++ .../helloworld/greeter_client_with_options.py | 2 +- tools/distrib/pylint_code.sh | 6 ++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 .pylintrc-examples diff --git a/.pylintrc-examples b/.pylintrc-examples new file mode 100644 index 00000000000..9480d6ea56a --- /dev/null +++ b/.pylintrc-examples @@ -0,0 +1,100 @@ +[MASTER] +ignore= + src/python/grpcio/grpc/beta, + src/python/grpcio/grpc/framework, + src/python/grpcio/grpc/framework/common, + src/python/grpcio/grpc/framework/foundation, + src/python/grpcio/grpc/framework/interfaces, + +[VARIABLES] + +# TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection +# not include "unused_" and "ignored_" by default? +dummy-variables-rgx=^ignored_|^unused_ + +[DESIGN] + +# NOTE(nathaniel): Not particularly attached to this value; it just seems to +# be what works for us at the moment (excepting the dead-code-walking Beta +# API). +max-args=6 + +[MISCELLANEOUS] + +# NOTE(nathaniel): We are big fans of "TODO(): " and +# "NOTE(): ". We do not allow "TODO:", +# "TODO():", "FIXME:", or anything else. +notes=FIXME,XXX + +[MESSAGES CONTROL] + +disable= + # -- START OF EXAMPLE-SPECIFIC SUPPRESSIONS -- + no-self-use, + unused-argument, + unused-variable, + # -- END OF EXAMPLE-SPECIFIC SUPPRESSIONS -- + + # TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279): + # Enable cyclic-import after a 1.7-or-later pylint release that + # recognizes our disable=cyclic-import suppressions. + cyclic-import, + # TODO(https://github.com/grpc/grpc/issues/8622): Enable this after the + # Beta API is removed. + duplicate-code, + # TODO(https://github.com/grpc/grpc/issues/261): Doesn't seem to + # understand enum and concurrent.futures; look into this later with the + # latest pylint version. + import-error, + # TODO(https://github.com/grpc/grpc/issues/261): Enable this one. + # Should take a little configuration but not much. + invalid-name, + # TODO(https://github.com/grpc/grpc/issues/261): This doesn't seem to + # work for now? Try with a later pylint? + locally-disabled, + # NOTE(nathaniel): What even is this? *Enabling* an inspection results + # in a warning? How does that encourage more analysis and coverage? + locally-enabled, + # NOTE(nathaniel): We don't write doc strings for most private code + # elements. + missing-docstring, + # NOTE(nathaniel): In numeric comparisons it is better to have the + # lesser (or lesser-or-equal-to) quantity on the left when the + # expression is true than it is to worry about which is an identifier + # and which a literal value. + misplaced-comparison-constant, + # NOTE(nathaniel): Our completely abstract interface classes don't have + # constructors. + no-init, + # TODO(https://github.com/grpc/grpc/issues/261): Doesn't yet play + # nicely with some of our code being implemented in Cython. Maybe in a + # later version? + no-name-in-module, + # TODO(https://github.com/grpc/grpc/issues/261): Suppress these where + # the odd shape of the authentication portion of the API forces them on + # us and enable everywhere else. + protected-access, + # NOTE(nathaniel): Pylint and I will probably never agree on this. + too-few-public-methods, + # NOTE(nathaniel): Pylint and I wil probably never agree on this for + # private classes. For public classes maybe? + too-many-instance-attributes, + # NOTE(nathaniel): Some of our modules have a lot of lines... of + # specification and documentation. Maybe if this were + # lines-of-code-based we would use it. + too-many-lines, + # TODO(https://github.com/grpc/grpc/issues/261): Maybe we could have + # this one if we extracted just a few more helper functions... + too-many-nested-blocks, + # TODO(https://github.com/grpc/grpc/issues/261): Disable unnecessary + # super-init requirement for abstract class implementations for now. + super-init-not-called, + # NOTE(nathaniel): A single statement that always returns program + # control is better than two statements the first of which sometimes + # returns program control and the second of which always returns + # program control. Probably generally, but definitely in the cases of + # if:/else: and for:/else:. + useless-else-on-loop, + no-else-return, + # NOTE(lidiz): Python 3 make object inheritance default, but not PY2 + useless-object-inheritance, diff --git a/examples/python/helloworld/greeter_client_with_options.py b/examples/python/helloworld/greeter_client_with_options.py index d15871b5195..e9ab5508ddd 100644 --- a/examples/python/helloworld/greeter_client_with_options.py +++ b/examples/python/helloworld/greeter_client_with_options.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""The Python implementation of the GRPC helloworld.Greeter client with channel options and call timeout parameters.""" +"""gRPC Python helloworld.Greeter client with channel options and call timeout parameters.""" from __future__ import print_function import logging diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh index 00507775031..abb37dde0ed 100755 --- a/tools/distrib/pylint_code.sh +++ b/tools/distrib/pylint_code.sh @@ -48,4 +48,10 @@ for dir in "${TEST_DIRS[@]}"; do $PYTHON -m pylint --rcfile=.pylintrc-tests -rn "$dir" || EXIT=1 done +find examples/python \ + -iname "*.py" \ + -not -name "*_pb2.py" \ + -not -name "*_pb2_grpc.py" \ + | xargs $PYTHON -m pylint --rcfile=.pylintrc-examples -rn + exit $EXIT From c4c4b9152fb0359f2c1e47191c0c4f7195be859f Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 21 Dec 2018 10:57:54 -0800 Subject: [PATCH 025/814] WIP --- .../filters/client_channel/client_channel.cc | 93 +++------ .../ext/filters/client_channel/lb_policy.h | 5 + test/cpp/end2end/client_lb_end2end_test.cc | 178 ++++++++++-------- 3 files changed, 137 insertions(+), 139 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index fe1a5a2e4eb..cc34178d619 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -545,13 +545,6 @@ struct call_data { bool have_request = false; grpc_closure pick_closure; - // A closure to fork notifying the lb interceptor and run the original trailer - // interception callback. - grpc_closure recv_trailing_metadata_ready_for_lb; - // The original trailer interception callback. - grpc_closure* original_recv_trailing_metadata_ready = nullptr; - grpc_transport_stream_op_batch* recv_trailing_metadata_op_batch = nullptr; - grpc_polling_entity* pollent = nullptr; // Batches are added to this list when received from above. @@ -612,8 +605,6 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem); static void on_complete(void* arg, grpc_error* error); static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored); static void start_pick_locked(void* arg, grpc_error* ignored); -static void maybe_intercept_trailing_metadata_for_lb( - grpc_call_element* arg, grpc_transport_stream_op_batch* batch); // // send op data caching @@ -736,6 +727,25 @@ static void free_cached_send_op_data_for_completed_batch( } } +// +// LB recv_trailing_metadata_ready handling +// + +void maybe_inject_recv_trailing_metadata_ready_for_lb( + const grpc_core::LoadBalancingPolicy::PickState& pick, + grpc_transport_stream_op_batch* batch) { + if (pick.recv_trailing_metadata_ready != nullptr) { + *pick.original_recv_trailing_metadata_ready = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + pick.recv_trailing_metadata_ready; + if (pick.recv_trailing_metadata != nullptr) { + *pick.recv_trailing_metadata = + batch->payload->recv_trailing_metadata.recv_trailing_metadata; + } + } +} + // // pending_batches management // @@ -860,6 +870,10 @@ static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { + if (batch->recv_trailing_metadata) { + maybe_inject_recv_trailing_metadata_ready_for_lb( + *calld->request->pick(), batch); + } batch->handler_private.extra_arg = calld; GRPC_CLOSURE_INIT(&batch->handler_private.closure, fail_pending_batch_in_call_combiner, batch, @@ -912,7 +926,10 @@ static void pending_batches_resume(grpc_call_element* elem) { pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { - maybe_intercept_trailing_metadata_for_lb(elem, batch); + if (batch->recv_trailing_metadata) { + maybe_inject_recv_trailing_metadata_ready_for_lb( + *calld->request->pick(), batch); + } batch->handler_private.extra_arg = calld->subchannel_call; GRPC_CLOSURE_INIT(&batch->handler_private.closure, resume_pending_batch_in_call_combiner, batch, @@ -1582,8 +1599,7 @@ static void run_closures_for_completed_call(subchannel_batch_data* batch_data, // Intercepts recv_trailing_metadata_ready callback for retries. // Commits the call and returns the trailing metadata up the stack. -static void recv_trailing_metadata_ready_for_retries( - void* arg, grpc_error* error) { +static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { subchannel_batch_data* batch_data = static_cast(arg); grpc_call_element* elem = batch_data->elem; channel_data* chand = static_cast(elem->channel_data); @@ -1603,16 +1619,6 @@ static void recv_trailing_metadata_ready_for_retries( grpc_mdelem* server_pushback_md = nullptr; grpc_metadata_batch* md_batch = batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata; - // If the lb policy asks for the trailing metadata, set its receiving ptr - if (calld->pick.recv_trailing_metadata != nullptr) { - *calld->pick.recv_trailing_metadata = md_batch; - } - // We use GRPC_CLOSURE_RUN synchronously on the callback. In the case of - // a retry, we would have already freed the metadata before returning from - // this function. - GRPC_CLOSURE_RUN( - calld->pick.recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, &server_pushback_md); if (grpc_client_channel_trace.enabled()) { @@ -1948,11 +1954,13 @@ static void add_retriable_recv_trailing_metadata_op( batch_data->batch.payload->recv_trailing_metadata.collect_stats = &retry_state->collect_stats; GRPC_CLOSURE_INIT(&retry_state->recv_trailing_metadata_ready, - recv_trailing_metadata_ready_for_retries, batch_data, + recv_trailing_metadata_ready, batch_data, grpc_schedule_on_exec_ctx); batch_data->batch.payload->recv_trailing_metadata .recv_trailing_metadata_ready = &retry_state->recv_trailing_metadata_ready; + maybe_inject_recv_trailing_metadata_ready_for_lb(*calld->request->pick(), + &batch_data->batch); } // Helper function used to start a recv_trailing_metadata batch. This @@ -2222,45 +2230,6 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { // LB pick // -// The callback to intercept trailing metadata if retries is not enabled -static void recv_trailing_metadata_ready_for_lb(void* arg, grpc_error* error) { - grpc_call_element* elem = static_cast(arg); - call_data* calld = static_cast(elem->call_data); - if (calld->pick.recv_trailing_metadata != nullptr) { - *calld->pick.recv_trailing_metadata = - calld->recv_trailing_metadata_op_batch->payload - ->recv_trailing_metadata.recv_trailing_metadata; - } - GRPC_CLOSURE_SCHED( - calld->pick.recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); - GRPC_CLOSURE_SCHED( - calld->original_recv_trailing_metadata_ready, - GRPC_ERROR_REF(error)); - GRPC_ERROR_UNREF(error); -} - -// If needed, intercepts the recv_trailing_metadata_ready callback to return -// trailing metadata to the LB policy. -static void maybe_intercept_trailing_metadata_for_lb( - grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { - call_data* calld = static_cast(elem->call_data); - if (!batch->recv_trailing_metadata) { - return; - } - if (calld->pick.recv_trailing_metadata_ready != nullptr) { - calld->recv_trailing_metadata_op_batch = batch; - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_for_lb, - recv_trailing_metadata_ready_for_lb, - elem, - grpc_schedule_on_exec_ctx); - calld->original_recv_trailing_metadata_ready = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &calld->recv_trailing_metadata_ready_for_lb; - } -} - static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 709eee7de83..dea8f4fa69f 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -77,6 +77,11 @@ class LoadBalancingPolicy : public InternallyRefCounted { // Callback set by lb policy to be notified of trailing metadata. // The callback must be scheduled on grpc_schedule_on_exec_ctx. grpc_closure* recv_trailing_metadata_ready = nullptr; + // The address that will be set to point to the original + // recv_trailing_metadata_ready callback, to be invoked by the LB + // policy's recv_trailing_metadata_ready callback when complete. + // Must be non-null if recv_trailing_metadata_ready is non-null. + grpc_closure** original_recv_trailing_metadata_ready = nullptr; // If this is not nullptr, then the client channel will point it to the // call's trailing metadata before invoking recv_trailing_metadata_ready. // If this is nullptr, then the callback will still be called. diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index bdc4d8edf67..328f28e3db6 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -35,24 +35,25 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channelz.h" -#include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/error.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" -#include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/cpp/client/secure_credentials.h" #include "src/cpp/server/secure_server_credentials.h" @@ -61,7 +62,6 @@ #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" - #include using grpc::testing::EchoRequest; @@ -1231,22 +1231,32 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { EnableDefaultHealthCheckService(false); } +grpc_core::TraceFlag forwarding_lb_tracer(false, "forwarding_lb"); + // A minimal forwarding class to avoid implementing a standalone test LB. class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { public: - ForwardingLoadBalancingPolicy( - const Args& args, - const std::string& delegate_policy_name) - : grpc_core::LoadBalancingPolicy(args), args_{args} { - delegate_ = grpc_core::LoadBalancingPolicyRegistry - ::CreateLoadBalancingPolicy(delegate_policy_name.c_str(), args); - grpc_pollset_set_add_pollset_set( - delegate_->interested_parties(), - interested_parties()); + ForwardingLoadBalancingPolicy(const Args& args, + const std::string& delegate_policy_name) + : grpc_core::LoadBalancingPolicy(args) { + delegate_ = + grpc_core::LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + delegate_policy_name.c_str(), args); + grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), + interested_parties()); + // Give re-resolution closure to delegate. + GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, + OnDelegateRequestReresolutionLocked, this, + grpc_combiner_scheduler(combiner())); + Ref().release(); // held by callback. + delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); } - void UpdateLocked(const grpc_channel_args& args) override { - delegate_->UpdateLocked(args); + const char* name() const override { return delegate_->name(); } + + void UpdateLocked(const grpc_channel_args& args, + grpc_json* lb_config) override { + delegate_->UpdateLocked(args, lb_config); } bool PickLocked(PickState* pick, grpc_error** error) override { @@ -1260,10 +1270,8 @@ class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, uint32_t initial_metadata_flags_eq, grpc_error* error) override { - delegate_->CancelMatchingPicksLocked( - initial_metadata_flags_mask, - initial_metadata_flags_eq, - error); + delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, + initial_metadata_flags_eq, error); } void NotifyOnStateChangeLocked(grpc_connectivity_state* state, @@ -1280,13 +1288,9 @@ class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { delegate_->HandOffPendingPicksLocked(new_policy); } - void ExitIdleLocked() override{ - delegate_->ExitIdleLocked(); - } + void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } - void ResetBackoffLocked() override { - delegate_->ResetBackoffLocked(); - } + void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } void FillChildRefsForChannelz( grpc_core::channelz::ChildRefsList* child_subchannels, @@ -1295,13 +1299,24 @@ class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { } protected: - void ShutdownLocked() override { - // noop - } - Args args_; + void ShutdownLocked() override { delegate_.reset(); } private: + static void OnDelegateRequestReresolutionLocked(void* arg, + grpc_error* error) { + ForwardingLoadBalancingPolicy* self = + static_cast(arg); + if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { + self->Unref(); + return; + } + self->TryReresolutionLocked(&forwarding_lb_tracer, GRPC_ERROR_NONE); + self->delegate_->SetReresolutionClosureLocked( + &self->on_delegate_request_reresolution_); + } + grpc_core::OrphanablePtr delegate_; + grpc_closure on_delegate_request_reresolution_; }; class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { @@ -1314,71 +1329,81 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { grpc_core::New(this))); } - void TearDown() override { - ClientLbEnd2endTest::TearDown(); - } + void TearDown() override { ClientLbEnd2endTest::TearDown(); } class InterceptTrailingLb : public ForwardingLoadBalancingPolicy { public: - InterceptTrailingLb( - const Args& args, - const std::string& delegate_lb_policy_name, - ClientLbInterceptTrailingMetadataTest* test) + InterceptTrailingLb(const Args& args, + const std::string& delegate_lb_policy_name, + ClientLbInterceptTrailingMetadataTest* test) : ForwardingLoadBalancingPolicy(args, delegate_lb_policy_name), - test_{test} { - } + test_(test) {} bool PickLocked(PickState* pick, grpc_error** error) override { bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); - // If these asserts fail, then we will need to add code to - // proxy the results to the delegate LB. - GPR_ASSERT(pick->recv_trailing_metadata == nullptr); - GPR_ASSERT(pick->recv_trailing_metadata_ready == nullptr); - // OK to add add callbacks for test - GRPC_CLOSURE_INIT( - &recv_trailing_metadata_ready_, - InterceptTrailingLb::RecordRecvTrailingMetadata, - this, - grpc_schedule_on_exec_ctx); - pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; - pick->recv_trailing_metadata = &recv_trailing_metadata_; + // Note: This assumes that the delegate policy does not + // intercepting recv_trailing_metadata. If we ever need to use + // this with a delegate policy that does, then we'll need to + // handle async pick returns separately. + new TrailingMetadataHandler(pick, test_); // deletes itself return ret; } - static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { - InterceptTrailingLb* lb = static_cast(arg); - GPR_ASSERT(err == GRPC_ERROR_NONE); - GPR_ASSERT(lb->recv_trailing_metadata_ != nullptr); - // an simple check to make sure the trailing metadata is valid - GPR_ASSERT(grpc_get_status_code_from_metadata( - lb->recv_trailing_metadata_->idx.named.grpc_status->md) == - grpc_status_code::GRPC_STATUS_OK); - GRPC_ERROR_UNREF(err); - lb->test_->ReportTrailerIntercepted(); - } - private: - grpc_closure recv_trailing_metadata_ready_; - grpc_metadata_batch* recv_trailing_metadata_; + class TrailingMetadataHandler { + public: + TrailingMetadataHandler(PickState* pick, + ClientLbInterceptTrailingMetadataTest* test) + : test_(test) { + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, + RecordRecvTrailingMetadata, this, + grpc_schedule_on_exec_ctx); + pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; + pick->original_recv_trailing_metadata_ready = + &original_recv_trailing_metadata_ready_; + pick->recv_trailing_metadata = &recv_trailing_metadata_; + } + + private: + static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { + TrailingMetadataHandler* self = + static_cast(arg); + GPR_ASSERT(self->recv_trailing_metadata_ != nullptr); + // a simple check to make sure the trailing metadata is valid + GPR_ASSERT( + grpc_get_status_code_from_metadata( + self->recv_trailing_metadata_->idx.named.grpc_status->md) == + grpc_status_code::GRPC_STATUS_OK); + self->test_->ReportTrailerIntercepted(); + GRPC_CLOSURE_SCHED(self->original_recv_trailing_metadata_ready_, + GRPC_ERROR_REF(err)); + delete self; + } + + ClientLbInterceptTrailingMetadataTest* test_; + grpc_closure recv_trailing_metadata_ready_; + grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; + grpc_metadata_batch* recv_trailing_metadata_ = nullptr; + }; + ClientLbInterceptTrailingMetadataTest* test_; }; // A factory for a test LB policy that intercepts trailing metadata. // The LB policy is implemented as a wrapper around a delegate LB policy. - class InterceptTrailingFactory : - public grpc_core::LoadBalancingPolicyFactory { + class InterceptTrailingFactory + : public grpc_core::LoadBalancingPolicyFactory { public: - InterceptTrailingFactory(ClientLbInterceptTrailingMetadataTest* test): - test_{test} {} + explicit InterceptTrailingFactory( + ClientLbInterceptTrailingMetadataTest* test) + : test_(test) {} grpc_core::OrphanablePtr CreateLoadBalancingPolicy( const grpc_core::LoadBalancingPolicy::Args& args) const override { return grpc_core::OrphanablePtr( grpc_core::New( - args, - /*delegate_lb_policy_name=*/ "pick_first", - test_)); + args, /*delegate_lb_policy_name=*/ "pick_first", test_)); } const char* name() const override { @@ -1394,14 +1419,14 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { trailers_intercepted_++; } - uint32_t trailers_intercepted() { + int trailers_intercepted() { std::unique_lock lock(mu_); return trailers_intercepted_; } private: std::mutex mu_; - uint32_t trailers_intercepted_ = 0; + int trailers_intercepted_ = 0; }; TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) { @@ -1418,9 +1443,8 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) { CheckRpcSendOk(stub, DEBUG_LOCATION); } // Check LB policy name for the channel. - EXPECT_EQ( - "intercept_trailing_metadata_lb", - channel->GetLoadBalancingPolicyName()); + EXPECT_EQ("intercept_trailing_metadata_lb", + channel->GetLoadBalancingPolicyName()); EXPECT_EQ(kNumServers, trailers_intercepted()); } From 49beab68be9a90de48832404519af9da34e83910 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 21 Dec 2018 14:03:18 -0800 Subject: [PATCH 026/814] Bug fix --- test/core/memory_usage/client.cc | 2 ++ test/core/memory_usage/server.cc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/core/memory_usage/client.cc b/test/core/memory_usage/client.cc index 467586ea5f4..9552e1b88ed 100644 --- a/test/core/memory_usage/client.cc +++ b/test/core/memory_usage/client.cc @@ -29,6 +29,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/surface/init.h" #include "test/core/util/cmdline.h" #include "test/core/util/memory_counters.h" @@ -286,6 +287,7 @@ int main(int argc, char** argv) { grpc_completion_queue_destroy(cq); grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); gpr_log(GPR_INFO, "---------client stats--------"); gpr_log( diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 7424797e6f5..0c67ee4fcdf 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -34,6 +34,7 @@ #include #include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/surface/init.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/cmdline.h" #include "test/core/util/memory_counters.h" @@ -319,6 +320,7 @@ int main(int argc, char** argv) { grpc_server_destroy(server); grpc_completion_queue_destroy(cq); grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); grpc_memory_counters_destroy(); return 0; } From 40f22bfc94304e382be770352ca0e7efd0b1c57d Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 21 Dec 2018 15:09:17 -0800 Subject: [PATCH 027/814] move ForwardingLoadBalancingPolicy to its own library --- CMakeLists.txt | 43 ++++++ Makefile | 60 +++++++- build.yaml | 11 ++ grpc.gyp | 9 ++ test/core/util/BUILD | 10 ++ .../util/forwarding_load_balancing_policy.cc | 25 ++++ .../util/forwarding_load_balancing_policy.h | 129 ++++++++++++++++++ test/cpp/end2end/BUILD | 1 + test/cpp/end2end/client_lb_end2end_test.cc | 104 ++------------ .../generated/sources_and_headers.json | 19 +++ 10 files changed, 312 insertions(+), 99 deletions(-) create mode 100644 test/core/util/forwarding_load_balancing_policy.cc create mode 100644 test/core/util/forwarding_load_balancing_policy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 76886307813..c0ae76d9d71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2824,6 +2824,48 @@ target_link_libraries(test_tcp_server ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_library(forwarding_load_balancing_policy + test/core/util/forwarding_load_balancing_policy.cc +) + +if(WIN32 AND MSVC) + set_target_properties(forwarding_load_balancing_policy PROPERTIES COMPILE_PDB_NAME "forwarding_load_balancing_policy" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/forwarding_load_balancing_policy.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + + +target_include_directories(forwarding_load_balancing_policy + PUBLIC $ $ + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) +target_link_libraries(forwarding_load_balancing_policy + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) add_library(grpc++ @@ -12444,6 +12486,7 @@ target_link_libraries(client_lb_end2end_test grpc++ grpc gpr + forwarding_load_balancing_policy ${_gRPC_GFLAGS_LIBRARIES} ) diff --git a/Makefile b/Makefile index 147e9505a33..a0ed0384380 100644 --- a/Makefile +++ b/Makefile @@ -1424,9 +1424,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc ifeq ($(EMBED_OPENSSL),true) -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a else -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a endif @@ -5254,6 +5254,55 @@ endif endif +LIBFORWARDING_LOAD_BALANCING_POLICY_SRC = \ + test/core/util/forwarding_load_balancing_policy.cc \ + +PUBLIC_HEADERS_CXX += \ + +LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBFORWARDING_LOAD_BALANCING_POLICY_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: openssl_dep_error + + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS:.o=.dep) +endif +endif + + LIBGRPC++_SRC = \ src/cpp/client/insecure_credentials.cc \ src/cpp/client/secure_credentials.cc \ @@ -17477,16 +17526,16 @@ $(BINDIR)/$(CONFIG)/client_lb_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a deps_client_lb_end2end_test: $(CLIENT_LB_END2END_TEST_OBJS:.o=.dep) @@ -25258,6 +25307,7 @@ test/core/end2end/tests/call_creds.cc: $(OPENSSL_DEP) test/core/security/oauth2_utils.cc: $(OPENSSL_DEP) test/core/tsi/alts/crypt/gsec_test_util.cc: $(OPENSSL_DEP) test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc: $(OPENSSL_DEP) +test/core/util/forwarding_load_balancing_policy.cc: $(OPENSSL_DEP) test/core/util/reconnect_server.cc: $(OPENSSL_DEP) test/core/util/test_tcp_server.cc: $(OPENSSL_DEP) test/cpp/end2end/test_health_check_service_impl.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 9d73e31b2e5..b58367f3332 100644 --- a/build.yaml +++ b/build.yaml @@ -1638,6 +1638,16 @@ libs: - grpc_test_util - grpc - gpr +- name: forwarding_load_balancing_policy + build: private + language: c++ + headers: + - test/core/util/forwarding_load_balancing_policy.h + src: + - test/core/util/forwarding_load_balancing_policy.cc + uses: + - grpc_base + - grpc_client_channel - name: grpc++ build: all language: c++ @@ -4449,6 +4459,7 @@ targets: - grpc++ - grpc - gpr + - forwarding_load_balancing_policy - name: codegen_test_full gtest: true build: test diff --git a/grpc.gyp b/grpc.gyp index 80b6d0315a1..9aea11efa2e 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1365,6 +1365,15 @@ 'test/core/util/test_tcp_server.cc', ], }, + { + 'target_name': 'forwarding_load_balancing_policy', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'test/core/util/forwarding_load_balancing_policy.cc', + ], + }, { 'target_name': 'grpc++', 'type': 'static_library', diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 226e41aea7c..8d50dd2bbac 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -154,3 +154,13 @@ sh_library( name = "run_with_poller_sh", srcs = ["run_with_poller.sh"], ) + +grpc_cc_library( + name = "forwarding_load_balancing_policy", + testonly = 1, + srcs = ["forwarding_load_balancing_policy.cc"], + hdrs = ["forwarding_load_balancing_policy.h"], + deps = [ + "//:grpc", + ], +) diff --git a/test/core/util/forwarding_load_balancing_policy.cc b/test/core/util/forwarding_load_balancing_policy.cc new file mode 100644 index 00000000000..e2755bfed0c --- /dev/null +++ b/test/core/util/forwarding_load_balancing_policy.cc @@ -0,0 +1,25 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "test/core/util/forwarding_load_balancing_policy.h" + +namespace grpc_core { + +TraceFlag grpc_trace_forwarding_lb(false, "forwarding_lb"); + +} // namespace grpc_core diff --git a/test/core/util/forwarding_load_balancing_policy.h b/test/core/util/forwarding_load_balancing_policy.h new file mode 100644 index 00000000000..aeb89803c35 --- /dev/null +++ b/test/core/util/forwarding_load_balancing_policy.h @@ -0,0 +1,129 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channelz.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/transport/connectivity_state.h" + +#ifndef GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H +#define GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H + +namespace grpc_core { + +extern TraceFlag grpc_trace_forwarding_lb; + +// A minimal forwarding class to avoid implementing a standalone test LB. +class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { + public: + ForwardingLoadBalancingPolicy(const Args& args, + const std::string& delegate_policy_name) + : LoadBalancingPolicy(args) { + delegate_ = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + delegate_policy_name.c_str(), args); + grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), + interested_parties()); + // Give re-resolution closure to delegate. + GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, + OnDelegateRequestReresolutionLocked, this, + grpc_combiner_scheduler(combiner())); + Ref().release(); // held by callback. + delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); + } + + const char* name() const override { return delegate_->name(); } + + void UpdateLocked(const grpc_channel_args& args, + grpc_json* lb_config) override { + delegate_->UpdateLocked(args, lb_config); + } + + bool PickLocked(PickState* pick, grpc_error** error) override { + return delegate_->PickLocked(pick, error); + } + + void CancelPickLocked(PickState* pick, grpc_error* error) override { + delegate_->CancelPickLocked(pick, error); + } + + void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) override { + delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, + initial_metadata_flags_eq, error); + } + + void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) override { + delegate_->NotifyOnStateChangeLocked(state, closure); + } + + grpc_connectivity_state CheckConnectivityLocked( + grpc_error** connectivity_error) override { + return delegate_->CheckConnectivityLocked(connectivity_error); + } + + void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { + delegate_->HandOffPendingPicksLocked(new_policy); + } + + void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } + + void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } + + void FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) override { + delegate_->FillChildRefsForChannelz(child_subchannels, child_channels); + } + + private: + void ShutdownLocked() override { delegate_.reset(); } + + static void OnDelegateRequestReresolutionLocked(void* arg, + grpc_error* error) { + ForwardingLoadBalancingPolicy* self = + static_cast(arg); + if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { + self->Unref(); + return; + } + self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); + self->delegate_->SetReresolutionClosureLocked( + &self->on_delegate_request_reresolution_); + } + + OrphanablePtr delegate_; + grpc_closure on_delegate_request_reresolution_; +}; + +} // namespace grpc_core + +#endif // GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 762d2302afc..ae204f580b3 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -387,6 +387,7 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", + "//test/core/util:forwarding_load_balancing_policy", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 328f28e3db6..2d474f71982 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -42,6 +42,7 @@ #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channelz.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" @@ -59,6 +60,7 @@ #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" +#include "test/core/util/forwarding_load_balancing_policy.h" #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" @@ -1231,94 +1233,6 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { EnableDefaultHealthCheckService(false); } -grpc_core::TraceFlag forwarding_lb_tracer(false, "forwarding_lb"); - -// A minimal forwarding class to avoid implementing a standalone test LB. -class ForwardingLoadBalancingPolicy : public grpc_core::LoadBalancingPolicy { - public: - ForwardingLoadBalancingPolicy(const Args& args, - const std::string& delegate_policy_name) - : grpc_core::LoadBalancingPolicy(args) { - delegate_ = - grpc_core::LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - delegate_policy_name.c_str(), args); - grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), - interested_parties()); - // Give re-resolution closure to delegate. - GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, - OnDelegateRequestReresolutionLocked, this, - grpc_combiner_scheduler(combiner())); - Ref().release(); // held by callback. - delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); - } - - const char* name() const override { return delegate_->name(); } - - void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override { - delegate_->UpdateLocked(args, lb_config); - } - - bool PickLocked(PickState* pick, grpc_error** error) override { - return delegate_->PickLocked(pick, error); - } - - void CancelPickLocked(PickState* pick, grpc_error* error) override { - delegate_->CancelPickLocked(pick, error); - } - - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override { - delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, error); - } - - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override { - delegate_->NotifyOnStateChangeLocked(state, closure); - } - - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override { - return delegate_->CheckConnectivityLocked(connectivity_error); - } - - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { - delegate_->HandOffPendingPicksLocked(new_policy); - } - - void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } - - void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } - - void FillChildRefsForChannelz( - grpc_core::channelz::ChildRefsList* child_subchannels, - grpc_core::channelz::ChildRefsList* ignored) override { - delegate_->FillChildRefsForChannelz(child_subchannels, ignored); - } - - protected: - void ShutdownLocked() override { delegate_.reset(); } - - private: - static void OnDelegateRequestReresolutionLocked(void* arg, - grpc_error* error) { - ForwardingLoadBalancingPolicy* self = - static_cast(arg); - if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { - self->Unref(); - return; - } - self->TryReresolutionLocked(&forwarding_lb_tracer, GRPC_ERROR_NONE); - self->delegate_->SetReresolutionClosureLocked( - &self->on_delegate_request_reresolution_); - } - - grpc_core::OrphanablePtr delegate_; - grpc_closure on_delegate_request_reresolution_; -}; - class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { protected: void SetUp() override { @@ -1331,12 +1245,14 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { void TearDown() override { ClientLbEnd2endTest::TearDown(); } - class InterceptTrailingLb : public ForwardingLoadBalancingPolicy { + class InterceptRecvTrailingMetadataLoadBalancingPolicy + : public grpc_core::ForwardingLoadBalancingPolicy { public: - InterceptTrailingLb(const Args& args, - const std::string& delegate_lb_policy_name, - ClientLbInterceptTrailingMetadataTest* test) - : ForwardingLoadBalancingPolicy(args, delegate_lb_policy_name), + InterceptRecvTrailingMetadataLoadBalancingPolicy( + const Args& args, const std::string& delegate_lb_policy_name, + ClientLbInterceptTrailingMetadataTest* test) + : grpc_core::ForwardingLoadBalancingPolicy(args, + delegate_lb_policy_name), test_(test) {} bool PickLocked(PickState* pick, grpc_error** error) override { @@ -1402,7 +1318,7 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { CreateLoadBalancingPolicy( const grpc_core::LoadBalancingPolicy::Args& args) const override { return grpc_core::OrphanablePtr( - grpc_core::New( + grpc_core::New( args, /*delegate_lb_policy_name=*/ "pick_first", test_)); } diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 336d499be9d..64d59495ae1 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3297,6 +3297,7 @@ }, { "deps": [ + "forwarding_load_balancing_policy", "gpr", "grpc", "grpc++", @@ -7032,6 +7033,24 @@ "third_party": false, "type": "lib" }, + { + "deps": [ + "grpc_base", + "grpc_client_channel" + ], + "headers": [ + "test/core/util/forwarding_load_balancing_policy.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "forwarding_load_balancing_policy", + "src": [ + "test/core/util/forwarding_load_balancing_policy.cc", + "test/core/util/forwarding_load_balancing_policy.h" + ], + "third_party": false, + "type": "lib" + }, { "deps": [ "gpr", From eedcea98335b518a8bea9f4c654713add86e6e9c Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Thu, 3 Jan 2019 14:06:52 -0800 Subject: [PATCH 028/814] Avoid including old installed headers. Fixes issue 17620. --- templates/Makefile.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/Makefile.template b/templates/Makefile.template index 8bb06176bf8..31cf14a71c1 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -715,7 +715,7 @@ ifeq ($(HAS_PKG_CONFIG),true) PROTOBUF_PKG_CONFIG = true PC_REQUIRES_GRPCXX = protobuf - CPPFLAGS := $(shell $(PKG_CONFIG) --cflags protobuf) $(CPPFLAGS) + CPPFLAGS := $(CPPFLAGS) $(shell $(PKG_CONFIG) --cflags protobuf) LDFLAGS_PROTOBUF_PKG_CONFIG = $(shell $(PKG_CONFIG) --libs-only-L protobuf) ifeq ($(SYSTEM),Linux) ifneq ($(LDFLAGS_PROTOBUF_PKG_CONFIG),) From 0961c2ac5127ff6d844813433fd99556b5faf740 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Thu, 3 Jan 2019 14:08:05 -0800 Subject: [PATCH 029/814] Makefile: regenerate. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b8a1c921862..dec46efcb60 100644 --- a/Makefile +++ b/Makefile @@ -809,7 +809,7 @@ ifeq ($(HAS_SYSTEM_PROTOBUF),true) ifeq ($(HAS_PKG_CONFIG),true) PROTOBUF_PKG_CONFIG = true PC_REQUIRES_GRPCXX = protobuf -CPPFLAGS := $(shell $(PKG_CONFIG) --cflags protobuf) $(CPPFLAGS) +CPPFLAGS := $(CPPFLAGS) $(shell $(PKG_CONFIG) --cflags protobuf) LDFLAGS_PROTOBUF_PKG_CONFIG = $(shell $(PKG_CONFIG) --libs-only-L protobuf) ifeq ($(SYSTEM),Linux) ifneq ($(LDFLAGS_PROTOBUF_PKG_CONFIG),) From a87d0fa8e27988075f956b1e3e4344eff068024c Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Thu, 3 Jan 2019 15:47:37 -0800 Subject: [PATCH 030/814] Bump version to v1.18.x-pre1 --- BUILD | 4 ++-- build.yaml | 4 ++-- doc/g_stands_for.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BUILD b/BUILD index e3c765198b2..bf81f842dd6 100644 --- a/BUILD +++ b/BUILD @@ -66,9 +66,9 @@ config_setting( # This should be updated along with build.yaml g_stands_for = "goose" -core_version = "7.0.0-dev" +core_version = "7.0.0-pre1" -version = "1.18.0-dev" +version = "1.18.0-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index a41decd84f7..92c6c5288c5 100644 --- a/build.yaml +++ b/build.yaml @@ -12,9 +12,9 @@ settings: '#08': Use "-preN" suffixes to identify pre-release versions '#09': Per-language overrides are possible with (eg) ruby_version tag here '#10': See the expand_version.py for all the quirks here - core_version: 7.0.0-dev + core_version: 7.0.0-pre1 g_stands_for: goose - version: 1.18.0-dev + version: 1.18.0-pre1 filegroups: - name: alts_proto headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index 1e49b4d3f17..fa7a02a9766 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -17,4 +17,4 @@ - 1.15 'g' stands for ['glider'](https://github.com/grpc/grpc/tree/v1.15.x) - 1.16 'g' stands for ['gao'](https://github.com/grpc/grpc/tree/v1.16.x) - 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/v1.17.x) -- 1.18 'g' stands for ['goose'](https://github.com/grpc/grpc/tree/master) +- 1.18 'g' stands for ['goose'](https://github.com/grpc/grpc/tree/v1.18.x) From 77e8525640bb0eab6a668a4544fd4a777ab6db2e Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Thu, 3 Jan 2019 15:49:31 -0800 Subject: [PATCH 031/814] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 6 +++--- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 2 +- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 4 ++-- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- tools/doxygen/Doxyfile.core | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- 33 files changed, 39 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48d3d11d238..2b267c429a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.18.0-dev") +set(PACKAGE_VERSION "1.18.0-pre1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index b8a1c921862..e7d50ece9ee 100644 --- a/Makefile +++ b/Makefile @@ -437,9 +437,9 @@ E = @echo Q = @ endif -CORE_VERSION = 7.0.0-dev -CPP_VERSION = 1.18.0-dev -CSHARP_VERSION = 1.18.0-dev +CORE_VERSION = 7.0.0-pre1 +CPP_VERSION = 1.18.0-pre1 +CSHARP_VERSION = 1.18.0-pre1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 29a79dd47ab..0bda8be0a62 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.18.0-dev' - version = '0.0.6-dev' + # version = '1.18.0-pre1' + version = '0.0.6-pre1' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.18.0-dev' + grpc_version = '1.18.0-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 240afbff7e6..41788797a96 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.18.0-dev' + version = '1.18.0-pre1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 13fe3e0b9c0..b6959a7e207 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.18.0-dev' + version = '1.18.0-pre1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index e132ad41b40..3586071addb 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.18.0-dev' + version = '1.18.0-pre1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 940a1ac6217..2f112bda5e3 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.18.0-dev' + version = '1.18.0-pre1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 2632fcb276b..cb12d18d4a4 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.18.0dev - 1.18.0dev + 1.18.0RC1 + 1.18.0RC1 beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 4829cc80a53..4eca622c036 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -23,6 +23,6 @@ #include -const char* grpc_version_string(void) { return "7.0.0-dev"; } +const char* grpc_version_string(void) { return "7.0.0-pre1"; } const char* grpc_g_stands_for(void) { return "goose"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 55da89e6c83..541d4ca19b5 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.18.0-dev"; } +grpc::string Version() { return "1.18.0-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 4fffe4f6448..8ac9ed862db 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.18.0-dev + 1.18.0-pre1 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 633880189ce..edccd7f89e4 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.18.0-dev"; + public const string CurrentVersion = "1.18.0-pre1"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 76d4f143901..13e1a312ccf 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.18.0-dev +set VERSION=1.18.0-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 3334d24c115..da41672848f 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.18.0-dev +set VERSION=1.18.0-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 55ca6048bc3..2ae8c6021f9 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.18.0-dev' + v = '1.18.0-pre1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 0be0e3c9a00..15eafe09abc 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.18.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.18.0-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index f2fd692070b..78de7fb21de 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.18.0-dev" -#define GRPC_C_VERSION_STRING @"7.0.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.18.0-pre1" +#define GRPC_C_VERSION_STRING @"7.0.0-pre1" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 1ddf90a667a..5117bd99393 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.18.0dev" +#define PHP_GRPC_VERSION "1.18.0RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 7a9f173947a..1827b52279d 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.18.0.dev0""" +__version__ = """1.18.0rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 2e91818d2ca..3eac8b93b51 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.18.0rc1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 16356ea4020..303afb98d28 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.18.0rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 85fa762f7e8..4f047a77d53 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.18.0rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index e62ab169a2f..3d89a4bcbd2 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.18.0rc1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index e009843b94f..394f9cefb1f 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.18.0rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 7b4c1695faa..5eb2dd27f5b 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.18.0rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 2fcd1ad617f..4dc0d03ad7c 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.18.0rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index a4ed052d85e..f378961cca9 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.18.0.dev' + VERSION = '1.18.0.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 389fb70684b..692e26d31eb 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.18.0.dev' + VERSION = '1.18.0.pre1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 29b2127960a..b282cdad7c3 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.18.0.dev0' +VERSION = '1.18.0rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 1ab3a394b96..ce27ed540c2 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.18.0-dev +PROJECT_NUMBER = 1.18.0-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 5f488d51940..4fa3da89715 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.18.0-dev +PROJECT_NUMBER = 1.18.0-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 8c557383b2e..545783d12d4 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 7.0.0-dev +PROJECT_NUMBER = 7.0.0-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index ba2eaecafda..2cec7dab5b5 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 7.0.0-dev +PROJECT_NUMBER = 7.0.0-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 814c858f3f2363a1ac59e137aa479a5b29ef0762 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 4 Jan 2019 18:45:01 -0800 Subject: [PATCH 032/814] Enable Python 3 --- BUILD | 5 +++++ src/python/grpcio/grpc/BUILD.bazel | 6 ++++-- .../grpcio/grpc/framework/common/BUILD.bazel | 14 ++++++++------ .../grpcio/grpc/framework/foundation/BUILD.bazel | 6 ++++-- .../grpc/framework/interfaces/base/BUILD.bazel | 13 ++++++++----- .../grpc/framework/interfaces/face/BUILD.bazel | 6 ++++-- src/python/grpcio_tests/tests/interop/BUILD.bazel | 6 ++++-- src/python/grpcio_tests/tests/unit/_api_test.py | 1 + third_party/py/python_configure.bzl | 6 +++--- tools/bazel.rc | 3 +++ 10 files changed, 44 insertions(+), 22 deletions(-) diff --git a/BUILD b/BUILD index e3c765198b2..c00ec27a333 100644 --- a/BUILD +++ b/BUILD @@ -63,6 +63,11 @@ config_setting( values = {"cpu": "x64_windows_msvc"}, ) +config_setting( + name = "python3", + values = {"python_path": "python3"}, +) + # This should be updated along with build.yaml g_stands_for = "goose" diff --git a/src/python/grpcio/grpc/BUILD.bazel b/src/python/grpcio/grpc/BUILD.bazel index 6958ccdfb66..27d5d2e4bb2 100644 --- a/src/python/grpcio/grpc/BUILD.bazel +++ b/src/python/grpcio/grpc/BUILD.bazel @@ -15,9 +15,11 @@ py_library( "//src/python/grpcio/grpc/_cython:cygrpc", "//src/python/grpcio/grpc/experimental", "//src/python/grpcio/grpc/framework", - requirement('enum34'), requirement('six'), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), data = [ "//:grpc", ], diff --git a/src/python/grpcio/grpc/framework/common/BUILD.bazel b/src/python/grpcio/grpc/framework/common/BUILD.bazel index 9d9ef682c90..52fbb2b516c 100644 --- a/src/python/grpcio/grpc/framework/common/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/common/BUILD.bazel @@ -13,15 +13,17 @@ py_library( py_library( name = "cardinality", srcs = ["cardinality.py"], - deps = [ - requirement("enum34"), - ], + deps = select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( name = "style", srcs = ["style.py"], - deps = [ - requirement("enum34"), - ], + deps = select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) diff --git a/src/python/grpcio/grpc/framework/foundation/BUILD.bazel b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel index 1287fdd44ed..98618b769af 100644 --- a/src/python/grpcio/grpc/framework/foundation/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel @@ -23,9 +23,11 @@ py_library( name = "callable_util", srcs = ["callable_util.py"], deps = [ - requirement("enum34"), requirement("six"), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( diff --git a/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel b/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel index 408a66a6310..35cfe877f34 100644 --- a/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel @@ -15,15 +15,18 @@ py_library( srcs = ["base.py"], deps = [ "//src/python/grpcio/grpc/framework/foundation:abandonment", - requirement("enum34"), requirement("six"), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( name = "utilities", srcs = ["utilities.py"], - deps = [ - requirement("enum34"), - ], + deps = select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) diff --git a/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel b/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel index e683e7cc426..83fadb6372e 100644 --- a/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel @@ -16,9 +16,11 @@ py_library( deps = [ "//src/python/grpcio/grpc/framework/foundation", "//src/python/grpcio/grpc/framework/common", - requirement("enum34"), requirement("six"), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( diff --git a/src/python/grpcio_tests/tests/interop/BUILD.bazel b/src/python/grpcio_tests/tests/interop/BUILD.bazel index aebdbf67ebf..edb2e778b08 100644 --- a/src/python/grpcio_tests/tests/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests/interop/BUILD.bazel @@ -34,12 +34,14 @@ py_library( "//src/proto/grpc/testing:py_test_proto", requirement('google-auth'), requirement('requests'), - requirement('enum34'), requirement('urllib3'), requirement('chardet'), requirement('certifi'), requirement('idna'), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), imports=["../../",], ) diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py index 0dc6a8718c3..b06a46249ad 100644 --- a/src/python/grpcio_tests/tests/unit/_api_test.py +++ b/src/python/grpcio_tests/tests/unit/_api_test.py @@ -103,6 +103,7 @@ class ChannelTest(unittest.TestCase): channel = grpc.secure_channel('google.com:443', channel_credentials) channel.close() +print("HELLO", "WORLD", end='!\n') if __name__ == '__main__': logging.basicConfig() diff --git a/third_party/py/python_configure.bzl b/third_party/py/python_configure.bzl index 2ba1e07049c..ae5132e002e 100644 --- a/third_party/py/python_configure.bzl +++ b/third_party/py/python_configure.bzl @@ -139,9 +139,9 @@ def _symlink_genrule_for_dir(repository_ctx, def _get_python_bin(repository_ctx): """Gets the python bin path.""" python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH) - if python_bin != None: - return python_bin - python_bin_path = repository_ctx.which("python") + if python_bin == None: + python_bin = 'python' + python_bin_path = repository_ctx.which(python_bin) if python_bin_path != None: return str(python_bin_path) _fail("Cannot find python in PATH, please make sure " + diff --git a/tools/bazel.rc b/tools/bazel.rc index 59e597b4723..29db17a51cb 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -57,3 +57,6 @@ build:basicprof --copt=-DNDEBUG build:basicprof --copt=-O2 build:basicprof --copt=-DGRPC_BASIC_PROFILER build:basicprof --copt=-DGRPC_TIMERS_RDTSC + +build:python3 --python_path=python3 +build:python3 --action_env=PYTHON_BIN_PATH=python3 From 0d931d9c8f2fedd264bd519abc343627fb42a36c Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 7 Jan 2019 13:41:02 -0800 Subject: [PATCH 033/814] Make Python 3 pass all unit tests --- .../grpc/framework/foundation/BUILD.bazel | 7 ++++--- .../reflection/_reflection_servicer_test.py | 20 ++++++++++++++----- .../grpcio_tests/tests/unit/_api_test.py | 1 - 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/python/grpcio/grpc/framework/foundation/BUILD.bazel b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel index 98618b769af..a447ecded49 100644 --- a/src/python/grpcio/grpc/framework/foundation/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel @@ -41,9 +41,10 @@ py_library( py_library( name = "logging_pool", srcs = ["logging_pool.py"], - deps = [ - requirement("futures"), - ], + deps = select({ + "//conditions:default": [requirement('futures'),], + "//:python3": [], + }), ) py_library( diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py index 560f6d3ddb3..0ee40e6f2da 100644 --- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py +++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py @@ -50,6 +50,16 @@ def _file_descriptor_to_proto(descriptor): class ReflectionServicerTest(unittest.TestCase): + # NOTE(lidiz) Bazel + Python 3 will result in creating two different + # instance of DESCRIPTOR for each message. So, the equal comparision + # between protobuf returned by stub and manually crafted protobuf will + # always fail. + def _assert_sequence_of_proto_equal(self, x, y): + self.assertSequenceEqual( + list(map(lambda x: x.SerializeToString(), x)), + list(map(lambda x: x.SerializeToString(), y)), + ) + def setUp(self): self._server = test_common.test_server() reflection.enable_server_reflection(_SERVICE_NAMES, self._server) @@ -84,7 +94,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testFileBySymbol(self): requests = ( @@ -108,7 +118,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testFileContainingExtension(self): requests = ( @@ -137,7 +147,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testExtensionNumbersOfType(self): requests = ( @@ -162,7 +172,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testListServices(self): requests = (reflection_pb2.ServerReflectionRequest(list_services='',),) @@ -173,7 +183,7 @@ class ReflectionServicerTest(unittest.TestCase): service=tuple( reflection_pb2.ServiceResponse(name=name) for name in _SERVICE_NAMES))),) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testReflectionServiceName(self): self.assertEqual(reflection.SERVICE_NAME, diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py index b06a46249ad..0dc6a8718c3 100644 --- a/src/python/grpcio_tests/tests/unit/_api_test.py +++ b/src/python/grpcio_tests/tests/unit/_api_test.py @@ -103,7 +103,6 @@ class ChannelTest(unittest.TestCase): channel = grpc.secure_channel('google.com:443', channel_credentials) channel.close() -print("HELLO", "WORLD", end='!\n') if __name__ == '__main__': logging.basicConfig() From b8a542cd234d32c8da7cb8474e26c9c21f3c9581 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 8 Jan 2019 09:20:15 -0800 Subject: [PATCH 034/814] Update Send message interception methods docs --- include/grpcpp/impl/codegen/interceptor.h | 27 +++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 5dea796a3b7..32a2d439d94 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -107,6 +107,24 @@ class InterceptorBatchMethods { /// of the hijacking interceptor. virtual void Hijack() = 0; + /// Send Message Methods + /// GetSerializedSendMessage and GetSendMessage/ModifySendMessage are the + /// available methods to view and modify the request payload. An interceptor + /// can access the payload in either serialized form or non-serialized form + /// but not both at the same time. + /// gRPC performs serialization in a lazy manner, which means + /// that a call to GetSerializedSendMessage will result in a serialization + /// operation if the payload stored is not in the serialized form already. The + /// non-serialized form is lost and GetSendMessage will no longer return a + /// valid pointer, and this will remain true for later interceptors too. This + /// can change however if ModifySendMessage is used to replace the current + /// payload. Note that ModifySendMessage requires a new payload message in the + /// non-serialized form. This will overwrite the existing payload irrespective + /// of whether it had been serialized earlier. Also note that gRPC Async API + /// requires early serialization of the payload which means that the payload + /// would be available in the serialized form only unless an interceptor + /// replaces the payload with ModifySendMessage. + /// Returns a modifable ByteBuffer holding the serialized form of the message /// that is going to be sent. Valid for PRE_SEND_MESSAGE interceptions. /// A return value of nullptr indicates that this ByteBuffer is not valid. @@ -114,15 +132,16 @@ class InterceptorBatchMethods { /// Returns a non-modifiable pointer to the non-serialized form of the message /// to be sent. Valid for PRE_SEND_MESSAGE interceptions. A return value of - /// nullptr indicates that this field is not valid. Also note that this is - /// only supported for sync and callback APIs at the present moment. + /// nullptr indicates that this field is not valid. virtual const void* GetSendMessage() = 0; /// Overwrites the message to be sent with \a message. \a message should be in /// the non-serialized form expected by the method. Valid for PRE_SEND_MESSAGE /// interceptions. Note that the interceptor is responsible for maintaining - /// the life of the message for the duration on the send operation, i.e., till - /// POST_SEND_MESSAGE. + /// the life of the message till it is serialized or it receives the + /// POST_SEND_MESSAGE interception point, whichever happens earlier. The + /// modifying interceptor may itself force early serialization by calling + /// GetSerializedSendMessage. virtual void ModifySendMessage(const void* message) = 0; /// Checks whether the SEND MESSAGE op succeeded. Valid for POST_SEND_MESSAGE From 73b1a918e4ae437ec7ac5f1d1c63c9fc2f153073 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 8 Jan 2019 09:28:09 -0800 Subject: [PATCH 035/814] Slight update to grammar. Can probably be improved more --- include/grpcpp/impl/codegen/interceptor.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 32a2d439d94..03520867f9c 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -114,16 +114,16 @@ class InterceptorBatchMethods { /// but not both at the same time. /// gRPC performs serialization in a lazy manner, which means /// that a call to GetSerializedSendMessage will result in a serialization - /// operation if the payload stored is not in the serialized form already. The - /// non-serialized form is lost and GetSendMessage will no longer return a - /// valid pointer, and this will remain true for later interceptors too. This - /// can change however if ModifySendMessage is used to replace the current - /// payload. Note that ModifySendMessage requires a new payload message in the - /// non-serialized form. This will overwrite the existing payload irrespective - /// of whether it had been serialized earlier. Also note that gRPC Async API - /// requires early serialization of the payload which means that the payload - /// would be available in the serialized form only unless an interceptor - /// replaces the payload with ModifySendMessage. + /// operation if the payload stored is not in the serialized form already; the + /// non-serialized form will be lost and GetSendMessage will no longer return + /// a valid pointer, and this will remain true for later interceptors too. + /// This can change however if ModifySendMessage is used to replace the + /// current payload. Note that ModifySendMessage requires a new payload + /// message in the non-serialized form. This will overwrite the existing + /// payload irrespective of whether it had been serialized earlier. Also note + /// that gRPC Async API requires early serialization of the payload which + /// means that the payload would be available in the serialized form only + /// unless an interceptor replaces the payload with ModifySendMessage. /// Returns a modifable ByteBuffer holding the serialized form of the message /// that is going to be sent. Valid for PRE_SEND_MESSAGE interceptions. From 7105626569bd5f829cf40ccd82bd82f5112de025 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 8 Jan 2019 10:07:47 -0800 Subject: [PATCH 036/814] Pump force Python version & simplify code --- third_party/py/python_configure.bzl | 4 +--- tools/bazel.rc | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/third_party/py/python_configure.bzl b/third_party/py/python_configure.bzl index ae5132e002e..6e25cc493b3 100644 --- a/third_party/py/python_configure.bzl +++ b/third_party/py/python_configure.bzl @@ -138,9 +138,7 @@ def _symlink_genrule_for_dir(repository_ctx, def _get_python_bin(repository_ctx): """Gets the python bin path.""" - python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH) - if python_bin == None: - python_bin = 'python' + python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH, 'python') python_bin_path = repository_ctx.which(python_bin) if python_bin_path != None: return str(python_bin_path) diff --git a/tools/bazel.rc b/tools/bazel.rc index 29db17a51cb..99347495361 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -59,4 +59,5 @@ build:basicprof --copt=-DGRPC_BASIC_PROFILER build:basicprof --copt=-DGRPC_TIMERS_RDTSC build:python3 --python_path=python3 +build:python3 --force_python=PY3 build:python3 --action_env=PYTHON_BIN_PATH=python3 From 21446eb35afb8a9a13ed65081f331cb056d383fb Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 8 Jan 2019 14:19:43 -0800 Subject: [PATCH 037/814] Fix build.yaml. --- CMakeLists.txt | 45 +------------- Makefile | 62 +++---------------- build.yaml | 13 +--- gRPC-Core.podspec | 2 + grpc.gyp | 11 +--- .../generated/sources_and_headers.json | 22 +------ 6 files changed, 18 insertions(+), 137 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc2cd1853b7..42904f2c277 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1756,6 +1756,7 @@ add_library(grpc_test_util test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc + test/core/util/forwarding_load_balancing_policy.cc test/core/util/fuzzer_util.cc test/core/util/grpc_profiler.cc test/core/util/histogram.cc @@ -2078,6 +2079,7 @@ add_library(grpc_test_util_unsecure test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc + test/core/util/forwarding_load_balancing_policy.cc test/core/util/fuzzer_util.cc test/core/util/grpc_profiler.cc test/core/util/histogram.cc @@ -2827,48 +2829,6 @@ target_link_libraries(test_tcp_server ) -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - -add_library(forwarding_load_balancing_policy - test/core/util/forwarding_load_balancing_policy.cc -) - -if(WIN32 AND MSVC) - set_target_properties(forwarding_load_balancing_policy PROPERTIES COMPILE_PDB_NAME "forwarding_load_balancing_policy" - COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" - ) - if (gRPC_INSTALL) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/forwarding_load_balancing_policy.pdb - DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL - ) - endif() -endif() - - -target_include_directories(forwarding_load_balancing_policy - PUBLIC $ $ - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} - PRIVATE third_party/googletest/googletest/include - PRIVATE third_party/googletest/googletest - PRIVATE third_party/googletest/googlemock/include - PRIVATE third_party/googletest/googlemock - PRIVATE ${_gRPC_PROTO_GENS_DIR} -) -target_link_libraries(forwarding_load_balancing_policy - ${_gRPC_PROTOBUF_LIBRARIES} - ${_gRPC_ALLTARGETS_LIBRARIES} -) - - endif (gRPC_BUILD_TESTS) add_library(grpc++ @@ -12534,7 +12494,6 @@ target_link_libraries(client_lb_end2end_test grpc++ grpc gpr - forwarding_load_balancing_policy ${_gRPC_GFLAGS_LIBRARIES} ) diff --git a/Makefile b/Makefile index 8a53bff7d62..927c4c5e6f6 100644 --- a/Makefile +++ b/Makefile @@ -1425,9 +1425,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc ifeq ($(EMBED_OPENSSL),true) -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a else -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a endif @@ -4258,6 +4258,7 @@ LIBGRPC_TEST_UTIL_SRC = \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ + test/core/util/forwarding_load_balancing_policy.cc \ test/core/util/fuzzer_util.cc \ test/core/util/grpc_profiler.cc \ test/core/util/histogram.cc \ @@ -4567,6 +4568,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ + test/core/util/forwarding_load_balancing_policy.cc \ test/core/util/fuzzer_util.cc \ test/core/util/grpc_profiler.cc \ test/core/util/histogram.cc \ @@ -5259,55 +5261,6 @@ endif endif -LIBFORWARDING_LOAD_BALANCING_POLICY_SRC = \ - test/core/util/forwarding_load_balancing_policy.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBFORWARDING_LOAD_BALANCING_POLICY_SRC)))) - - -ifeq ($(NO_SECURE),true) - -# You can't build secure libraries if you don't have OpenSSL. - -$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: openssl_dep_error - - -else - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a -endif - - - - -endif - -endif - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(LIBFORWARDING_LOAD_BALANCING_POLICY_OBJS:.o=.dep) -endif -endif - - LIBGRPC++_SRC = \ src/cpp/client/insecure_credentials.cc \ src/cpp/client/secure_credentials.cc \ @@ -17575,16 +17528,16 @@ $(BINDIR)/$(CONFIG)/client_lb_end2end_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a +$(BINDIR)/$(CONFIG)/client_lb_end2end_test: $(PROTOBUF_DEP) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_LB_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_lb_end2end_test endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libforwarding_load_balancing_policy.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_lb_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_client_lb_end2end_test: $(CLIENT_LB_END2END_TEST_OBJS:.o=.dep) @@ -25356,7 +25309,6 @@ test/core/end2end/tests/call_creds.cc: $(OPENSSL_DEP) test/core/security/oauth2_utils.cc: $(OPENSSL_DEP) test/core/tsi/alts/crypt/gsec_test_util.cc: $(OPENSSL_DEP) test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc: $(OPENSSL_DEP) -test/core/util/forwarding_load_balancing_policy.cc: $(OPENSSL_DEP) test/core/util/reconnect_server.cc: $(OPENSSL_DEP) test/core/util/test_tcp_server.cc: $(OPENSSL_DEP) test/cpp/end2end/test_health_check_service_impl.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 84de1828177..0f6e6be4dfa 100644 --- a/build.yaml +++ b/build.yaml @@ -906,6 +906,7 @@ filegroups: - test/core/end2end/fixtures/proxy.h - test/core/iomgr/endpoint_tests.h - test/core/util/debugger_macros.h + - test/core/util/forwarding_load_balancing_policy.h - test/core/util/fuzzer_util.h - test/core/util/grpc_profiler.h - test/core/util/histogram.h @@ -928,6 +929,7 @@ filegroups: - test/core/end2end/fixtures/proxy.cc - test/core/iomgr/endpoint_tests.cc - test/core/util/debugger_macros.cc + - test/core/util/forwarding_load_balancing_policy.cc - test/core/util/fuzzer_util.cc - test/core/util/grpc_profiler.cc - test/core/util/histogram.cc @@ -1638,16 +1640,6 @@ libs: - grpc_test_util - grpc - gpr -- name: forwarding_load_balancing_policy - build: private - language: c++ - headers: - - test/core/util/forwarding_load_balancing_policy.h - src: - - test/core/util/forwarding_load_balancing_policy.cc - uses: - - grpc_base - - grpc_client_channel - name: grpc++ build: all language: c++ @@ -4480,7 +4472,6 @@ targets: - grpc++ - grpc - gpr - - forwarding_load_balancing_policy - name: codegen_test_full gtest: true build: test diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 7ddef6aa441..22521b06d43 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1212,6 +1212,7 @@ Pod::Spec.new do |s| 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', + 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -1240,6 +1241,7 @@ Pod::Spec.new do |s| 'test/core/end2end/fixtures/proxy.h', 'test/core/iomgr/endpoint_tests.h', 'test/core/util/debugger_macros.h', + 'test/core/util/forwarding_load_balancing_policy.h', 'test/core/util/fuzzer_util.h', 'test/core/util/grpc_profiler.h', 'test/core/util/histogram.h', diff --git a/grpc.gyp b/grpc.gyp index 9aea11efa2e..450aa87e40f 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -611,6 +611,7 @@ 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', + 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -853,6 +854,7 @@ 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', + 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -1365,15 +1367,6 @@ 'test/core/util/test_tcp_server.cc', ], }, - { - 'target_name': 'forwarding_load_balancing_policy', - 'type': 'static_library', - 'dependencies': [ - ], - 'sources': [ - 'test/core/util/forwarding_load_balancing_policy.cc', - ], - }, { 'target_name': 'grpc++', 'type': 'static_library', diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 779f724226a..81fe8573c13 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3318,7 +3318,6 @@ }, { "deps": [ - "forwarding_load_balancing_policy", "gpr", "grpc", "grpc++", @@ -7054,24 +7053,6 @@ "third_party": false, "type": "lib" }, - { - "deps": [ - "grpc_base", - "grpc_client_channel" - ], - "headers": [ - "test/core/util/forwarding_load_balancing_policy.h" - ], - "is_filegroup": false, - "language": "c++", - "name": "forwarding_load_balancing_policy", - "src": [ - "test/core/util/forwarding_load_balancing_policy.cc", - "test/core/util/forwarding_load_balancing_policy.h" - ], - "third_party": false, - "type": "lib" - }, { "deps": [ "gpr", @@ -10478,6 +10459,7 @@ "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.h", + "test/core/util/forwarding_load_balancing_policy.h", "test/core/util/fuzzer_util.h", "test/core/util/grpc_profiler.h", "test/core/util/histogram.h", @@ -10511,6 +10493,8 @@ "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.cc", "test/core/util/debugger_macros.h", + "test/core/util/forwarding_load_balancing_policy.cc", + "test/core/util/forwarding_load_balancing_policy.h", "test/core/util/fuzzer_util.cc", "test/core/util/fuzzer_util.h", "test/core/util/grpc_profiler.cc", From a9ce1e05296aefd0213ef42f8bbe01b60a8a3384 Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Wed, 9 Jan 2019 08:45:09 -0700 Subject: [PATCH 038/814] Update Ruby gemspec template Loosen development dependencies for googleauth and signet. --- grpc.gemspec | 4 ++-- templates/grpc.gemspec.template | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/grpc.gemspec b/grpc.gemspec index 42b1db35b4d..bf5a039846b 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -41,8 +41,8 @@ Gem::Specification.new do |s| s.add_development_dependency 'rake-compiler-dock', '~> 0.5.1' s.add_development_dependency 'rspec', '~> 3.6' s.add_development_dependency 'rubocop', '~> 0.49.1' - s.add_development_dependency 'signet', '~> 0.7.0' - s.add_development_dependency 'googleauth', '>= 0.5.1', '< 0.7' + s.add_development_dependency 'signet', '~> 0.7' + s.add_development_dependency 'googleauth', '>= 0.5.1', '< 0.10' s.extensions = %w(src/ruby/ext/grpc/extconf.rb) diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template index 842035b664f..1498a280b0e 100644 --- a/templates/grpc.gemspec.template +++ b/templates/grpc.gemspec.template @@ -43,8 +43,8 @@ s.add_development_dependency 'rake-compiler-dock', '~> 0.5.1' s.add_development_dependency 'rspec', '~> 3.6' s.add_development_dependency 'rubocop', '~> 0.49.1' - s.add_development_dependency 'signet', '~> 0.7.0' - s.add_development_dependency 'googleauth', '>= 0.5.1', '< 0.7' + s.add_development_dependency 'signet', '~> 0.7' + s.add_development_dependency 'googleauth', '>= 0.5.1', '< 0.10' s.extensions = %w(src/ruby/ext/grpc/extconf.rb) From 1c91bcceb06d4cbb06f775d03bda7a86cb19615d Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 9 Jan 2019 10:33:48 -0800 Subject: [PATCH 039/814] correctly name __dealloc__ method --- src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index d72648a35d0..ef74f61e043 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -149,6 +149,6 @@ cdef class Server: grpc_server_destroy(self.c_server) self.c_server = NULL - def __dealloc(self): + def __dealloc__(self): if self.c_server == NULL: grpc_shutdown() From b4818682be9be27398142996e8b02c23624b1184 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 9 Jan 2019 19:41:22 +0100 Subject: [PATCH 040/814] fix #17625 --- tools/run_tests/dockerize/build_interop_image.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh index 0f88787639a..025c532d976 100755 --- a/tools/run_tests/dockerize/build_interop_image.sh +++ b/tools/run_tests/dockerize/build_interop_image.sh @@ -90,9 +90,6 @@ else docker build -t "$BASE_IMAGE" --force-rm=true "tools/dockerfile/interoptest/$BASE_NAME" || exit $? fi -# Create a local branch so the child Docker script won't complain -git branch -f jenkins-docker - CONTAINER_NAME="build_${BASE_NAME}_$(uuidgen)" # Prepare image for interop tests, commit it on success. From 7df3475a9f74839c63702773e9f4a7e4278ea600 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 9 Jan 2019 14:36:23 -0800 Subject: [PATCH 041/814] Enable Bazel Python 3 for every PR * Reverted hack in _reflection_servicer_test.py * To see if Kokoro is happy about it --- .../reflection/_reflection_servicer_test.py | 20 +++++-------------- .../linux/grpc_python_bazel_test_in_docker.sh | 1 + 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py index 0ee40e6f2da..560f6d3ddb3 100644 --- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py +++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py @@ -50,16 +50,6 @@ def _file_descriptor_to_proto(descriptor): class ReflectionServicerTest(unittest.TestCase): - # NOTE(lidiz) Bazel + Python 3 will result in creating two different - # instance of DESCRIPTOR for each message. So, the equal comparision - # between protobuf returned by stub and manually crafted protobuf will - # always fail. - def _assert_sequence_of_proto_equal(self, x, y): - self.assertSequenceEqual( - list(map(lambda x: x.SerializeToString(), x)), - list(map(lambda x: x.SerializeToString(), y)), - ) - def setUp(self): self._server = test_common.test_server() reflection.enable_server_reflection(_SERVICE_NAMES, self._server) @@ -94,7 +84,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self._assert_sequence_of_proto_equal(expected_responses, responses) + self.assertSequenceEqual(expected_responses, responses) def testFileBySymbol(self): requests = ( @@ -118,7 +108,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self._assert_sequence_of_proto_equal(expected_responses, responses) + self.assertSequenceEqual(expected_responses, responses) def testFileContainingExtension(self): requests = ( @@ -147,7 +137,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self._assert_sequence_of_proto_equal(expected_responses, responses) + self.assertSequenceEqual(expected_responses, responses) def testExtensionNumbersOfType(self): requests = ( @@ -172,7 +162,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self._assert_sequence_of_proto_equal(expected_responses, responses) + self.assertSequenceEqual(expected_responses, responses) def testListServices(self): requests = (reflection_pb2.ServerReflectionRequest(list_services='',),) @@ -183,7 +173,7 @@ class ReflectionServicerTest(unittest.TestCase): service=tuple( reflection_pb2.ServiceResponse(name=name) for name in _SERVICE_NAMES))),) - self._assert_sequence_of_proto_equal(expected_responses, responses) + self.assertSequenceEqual(expected_responses, responses) def testReflectionServiceName(self): self.assertEqual(reflection.SERVICE_NAME, diff --git a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh index 156d65955ad..0e0734084dc 100755 --- a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh +++ b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh @@ -25,3 +25,4 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc ${name}') cd /var/local/git/grpc/test bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... From 15be9de11bce4d9fc17a3706854abfbfc988f5e9 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 9 Jan 2019 14:52:56 -0800 Subject: [PATCH 042/814] Bazel clean between builds of Python 2/3 --- tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh index 0e0734084dc..14989648a2a 100755 --- a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh +++ b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh @@ -25,4 +25,5 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc ${name}') cd /var/local/git/grpc/test bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +bazel clean --expunge bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... From 8cd7178afb2cde1e9203c2edd4668f04210484b9 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Jan 2019 09:26:44 -0800 Subject: [PATCH 043/814] Add dtors in LB policy subclasses. --- .../util/forwarding_load_balancing_policy.cc | 36 +++++++++++++++++++ .../util/forwarding_load_balancing_policy.h | 35 +++--------------- test/cpp/end2end/client_lb_end2end_test.cc | 2 ++ 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/test/core/util/forwarding_load_balancing_policy.cc b/test/core/util/forwarding_load_balancing_policy.cc index e2755bfed0c..0da566d2bac 100644 --- a/test/core/util/forwarding_load_balancing_policy.cc +++ b/test/core/util/forwarding_load_balancing_policy.cc @@ -18,8 +18,44 @@ #include "test/core/util/forwarding_load_balancing_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/pollset_set.h" + namespace grpc_core { TraceFlag grpc_trace_forwarding_lb(false, "forwarding_lb"); +ForwardingLoadBalancingPolicy::ForwardingLoadBalancingPolicy( + const Args& args, const std::string& delegate_policy_name) + : LoadBalancingPolicy(args) { + delegate_ = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + delegate_policy_name.c_str(), args); + grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), + interested_parties()); + // Give re-resolution closure to delegate. + GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, + OnDelegateRequestReresolutionLocked, this, + grpc_combiner_scheduler(combiner())); + Ref().release(); // held by callback. + delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); +} + +ForwardingLoadBalancingPolicy::~ForwardingLoadBalancingPolicy() {} + +void ForwardingLoadBalancingPolicy::OnDelegateRequestReresolutionLocked( + void* arg, grpc_error* error) { + ForwardingLoadBalancingPolicy* self = + static_cast(arg); + if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { + self->Unref(); + return; + } + self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); + self->delegate_->SetReresolutionClosureLocked( + &self->on_delegate_request_reresolution_); +} + } // namespace grpc_core diff --git a/test/core/util/forwarding_load_balancing_policy.h b/test/core/util/forwarding_load_balancing_policy.h index aeb89803c35..b387f2e606e 100644 --- a/test/core/util/forwarding_load_balancing_policy.h +++ b/test/core/util/forwarding_load_balancing_policy.h @@ -19,16 +19,12 @@ #include #include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channelz.h" -#include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/error.h" -#include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/json/json.h" #include "src/core/lib/transport/connectivity_state.h" @@ -37,26 +33,13 @@ namespace grpc_core { -extern TraceFlag grpc_trace_forwarding_lb; - // A minimal forwarding class to avoid implementing a standalone test LB. class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { public: ForwardingLoadBalancingPolicy(const Args& args, - const std::string& delegate_policy_name) - : LoadBalancingPolicy(args) { - delegate_ = - LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - delegate_policy_name.c_str(), args); - grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), - interested_parties()); - // Give re-resolution closure to delegate. - GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, - OnDelegateRequestReresolutionLocked, this, - grpc_combiner_scheduler(combiner())); - Ref().release(); // held by callback. - delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); - } + const std::string& delegate_policy_name); + + ~ForwardingLoadBalancingPolicy() override; const char* name() const override { return delegate_->name(); } @@ -108,17 +91,7 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { void ShutdownLocked() override { delegate_.reset(); } static void OnDelegateRequestReresolutionLocked(void* arg, - grpc_error* error) { - ForwardingLoadBalancingPolicy* self = - static_cast(arg); - if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { - self->Unref(); - return; - } - self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); - self->delegate_->SetReresolutionClosureLocked( - &self->on_delegate_request_reresolution_); - } + grpc_error* error); OrphanablePtr delegate_; grpc_closure on_delegate_request_reresolution_; diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 2d474f71982..b14f85100ad 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -1255,6 +1255,8 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { delegate_lb_policy_name), test_(test) {} + ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; + bool PickLocked(PickState* pick, grpc_error** error) override { bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); // Note: This assumes that the delegate policy does not From d6e2b336702fff194ec8d6208f2fe8e8b028672c Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Jan 2019 10:31:16 -0800 Subject: [PATCH 044/814] Move InterceptRecvTrailingMetadataLoadBalancingPolicy to a separate file. This fixes a link error when building with make. --- CMakeLists.txt | 4 +- Makefile | 4 +- build.yaml | 4 +- gRPC-Core.podspec | 4 +- grpc.gyp | 4 +- .../util/forwarding_load_balancing_policy.cc | 61 ----- .../util/forwarding_load_balancing_policy.h | 102 -------- test/core/util/test_lb_policies.cc | 240 ++++++++++++++++++ test/core/util/test_lb_policies.h | 34 +++ test/cpp/end2end/client_lb_end2end_test.cc | 107 +------- .../generated/sources_and_headers.json | 6 +- 11 files changed, 297 insertions(+), 273 deletions(-) delete mode 100644 test/core/util/forwarding_load_balancing_policy.cc delete mode 100644 test/core/util/forwarding_load_balancing_policy.h create mode 100644 test/core/util/test_lb_policies.cc create mode 100644 test/core/util/test_lb_policies.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 42904f2c277..db9ed00b88e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1756,7 +1756,6 @@ add_library(grpc_test_util test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc - test/core/util/forwarding_load_balancing_policy.cc test/core/util/fuzzer_util.cc test/core/util/grpc_profiler.cc test/core/util/histogram.cc @@ -1771,6 +1770,7 @@ add_library(grpc_test_util test/core/util/subprocess_posix.cc test/core/util/subprocess_windows.cc test/core/util/test_config.cc + test/core/util/test_lb_policies.cc test/core/util/tracer_util.cc test/core/util/trickle_endpoint.cc test/core/util/cmdline.cc @@ -2079,7 +2079,6 @@ add_library(grpc_test_util_unsecure test/core/end2end/fixtures/proxy.cc test/core/iomgr/endpoint_tests.cc test/core/util/debugger_macros.cc - test/core/util/forwarding_load_balancing_policy.cc test/core/util/fuzzer_util.cc test/core/util/grpc_profiler.cc test/core/util/histogram.cc @@ -2094,6 +2093,7 @@ add_library(grpc_test_util_unsecure test/core/util/subprocess_posix.cc test/core/util/subprocess_windows.cc test/core/util/test_config.cc + test/core/util/test_lb_policies.cc test/core/util/tracer_util.cc test/core/util/trickle_endpoint.cc test/core/util/cmdline.cc diff --git a/Makefile b/Makefile index 927c4c5e6f6..0d1c83f3787 100644 --- a/Makefile +++ b/Makefile @@ -4258,7 +4258,6 @@ LIBGRPC_TEST_UTIL_SRC = \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ - test/core/util/forwarding_load_balancing_policy.cc \ test/core/util/fuzzer_util.cc \ test/core/util/grpc_profiler.cc \ test/core/util/histogram.cc \ @@ -4273,6 +4272,7 @@ LIBGRPC_TEST_UTIL_SRC = \ test/core/util/subprocess_posix.cc \ test/core/util/subprocess_windows.cc \ test/core/util/test_config.cc \ + test/core/util/test_lb_policies.cc \ test/core/util/tracer_util.cc \ test/core/util/trickle_endpoint.cc \ test/core/util/cmdline.cc \ @@ -4568,7 +4568,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ test/core/end2end/fixtures/proxy.cc \ test/core/iomgr/endpoint_tests.cc \ test/core/util/debugger_macros.cc \ - test/core/util/forwarding_load_balancing_policy.cc \ test/core/util/fuzzer_util.cc \ test/core/util/grpc_profiler.cc \ test/core/util/histogram.cc \ @@ -4583,6 +4582,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ test/core/util/subprocess_posix.cc \ test/core/util/subprocess_windows.cc \ test/core/util/test_config.cc \ + test/core/util/test_lb_policies.cc \ test/core/util/tracer_util.cc \ test/core/util/trickle_endpoint.cc \ test/core/util/cmdline.cc \ diff --git a/build.yaml b/build.yaml index 0f6e6be4dfa..bb96a611266 100644 --- a/build.yaml +++ b/build.yaml @@ -906,7 +906,6 @@ filegroups: - test/core/end2end/fixtures/proxy.h - test/core/iomgr/endpoint_tests.h - test/core/util/debugger_macros.h - - test/core/util/forwarding_load_balancing_policy.h - test/core/util/fuzzer_util.h - test/core/util/grpc_profiler.h - test/core/util/histogram.h @@ -919,6 +918,7 @@ filegroups: - test/core/util/slice_splitter.h - test/core/util/subprocess.h - test/core/util/test_config.h + - test/core/util/test_lb_policies.h - test/core/util/tracer_util.h - test/core/util/trickle_endpoint.h src: @@ -929,7 +929,6 @@ filegroups: - test/core/end2end/fixtures/proxy.cc - test/core/iomgr/endpoint_tests.cc - test/core/util/debugger_macros.cc - - test/core/util/forwarding_load_balancing_policy.cc - test/core/util/fuzzer_util.cc - test/core/util/grpc_profiler.cc - test/core/util/histogram.cc @@ -944,6 +943,7 @@ filegroups: - test/core/util/subprocess_posix.cc - test/core/util/subprocess_windows.cc - test/core/util/test_config.cc + - test/core/util/test_lb_policies.cc - test/core/util/tracer_util.cc - test/core/util/trickle_endpoint.cc deps: diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 22521b06d43..a62595383a4 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1212,7 +1212,6 @@ Pod::Spec.new do |s| 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', - 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -1227,6 +1226,7 @@ Pod::Spec.new do |s| 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', 'test/core/util/test_config.cc', + 'test/core/util/test_lb_policies.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -1241,7 +1241,6 @@ Pod::Spec.new do |s| 'test/core/end2end/fixtures/proxy.h', 'test/core/iomgr/endpoint_tests.h', 'test/core/util/debugger_macros.h', - 'test/core/util/forwarding_load_balancing_policy.h', 'test/core/util/fuzzer_util.h', 'test/core/util/grpc_profiler.h', 'test/core/util/histogram.h', @@ -1254,6 +1253,7 @@ Pod::Spec.new do |s| 'test/core/util/slice_splitter.h', 'test/core/util/subprocess.h', 'test/core/util/test_config.h', + 'test/core/util/test_lb_policies.h', 'test/core/util/tracer_util.h', 'test/core/util/trickle_endpoint.h', 'test/core/util/cmdline.h', diff --git a/grpc.gyp b/grpc.gyp index 450aa87e40f..d9002886280 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -611,7 +611,6 @@ 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', - 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -626,6 +625,7 @@ 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', 'test/core/util/test_config.cc', + 'test/core/util/test_lb_policies.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', @@ -854,7 +854,6 @@ 'test/core/end2end/fixtures/proxy.cc', 'test/core/iomgr/endpoint_tests.cc', 'test/core/util/debugger_macros.cc', - 'test/core/util/forwarding_load_balancing_policy.cc', 'test/core/util/fuzzer_util.cc', 'test/core/util/grpc_profiler.cc', 'test/core/util/histogram.cc', @@ -869,6 +868,7 @@ 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', 'test/core/util/test_config.cc', + 'test/core/util/test_lb_policies.cc', 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', diff --git a/test/core/util/forwarding_load_balancing_policy.cc b/test/core/util/forwarding_load_balancing_policy.cc deleted file mode 100644 index 0da566d2bac..00000000000 --- a/test/core/util/forwarding_load_balancing_policy.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "test/core/util/forwarding_load_balancing_policy.h" - -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" -#include "src/core/lib/debug/trace.h" -#include "src/core/lib/iomgr/combiner.h" -#include "src/core/lib/iomgr/pollset_set.h" - -namespace grpc_core { - -TraceFlag grpc_trace_forwarding_lb(false, "forwarding_lb"); - -ForwardingLoadBalancingPolicy::ForwardingLoadBalancingPolicy( - const Args& args, const std::string& delegate_policy_name) - : LoadBalancingPolicy(args) { - delegate_ = - LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - delegate_policy_name.c_str(), args); - grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), - interested_parties()); - // Give re-resolution closure to delegate. - GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, - OnDelegateRequestReresolutionLocked, this, - grpc_combiner_scheduler(combiner())); - Ref().release(); // held by callback. - delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); -} - -ForwardingLoadBalancingPolicy::~ForwardingLoadBalancingPolicy() {} - -void ForwardingLoadBalancingPolicy::OnDelegateRequestReresolutionLocked( - void* arg, grpc_error* error) { - ForwardingLoadBalancingPolicy* self = - static_cast(arg); - if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { - self->Unref(); - return; - } - self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); - self->delegate_->SetReresolutionClosureLocked( - &self->on_delegate_request_reresolution_); -} - -} // namespace grpc_core diff --git a/test/core/util/forwarding_load_balancing_policy.h b/test/core/util/forwarding_load_balancing_policy.h deleted file mode 100644 index b387f2e606e..00000000000 --- a/test/core/util/forwarding_load_balancing_policy.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/channelz.h" -#include "src/core/lib/gprpp/orphanable.h" -#include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/error.h" -#include "src/core/lib/json/json.h" -#include "src/core/lib/transport/connectivity_state.h" - -#ifndef GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H -#define GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H - -namespace grpc_core { - -// A minimal forwarding class to avoid implementing a standalone test LB. -class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { - public: - ForwardingLoadBalancingPolicy(const Args& args, - const std::string& delegate_policy_name); - - ~ForwardingLoadBalancingPolicy() override; - - const char* name() const override { return delegate_->name(); } - - void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override { - delegate_->UpdateLocked(args, lb_config); - } - - bool PickLocked(PickState* pick, grpc_error** error) override { - return delegate_->PickLocked(pick, error); - } - - void CancelPickLocked(PickState* pick, grpc_error* error) override { - delegate_->CancelPickLocked(pick, error); - } - - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override { - delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, error); - } - - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override { - delegate_->NotifyOnStateChangeLocked(state, closure); - } - - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override { - return delegate_->CheckConnectivityLocked(connectivity_error); - } - - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { - delegate_->HandOffPendingPicksLocked(new_policy); - } - - void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } - - void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } - - void FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) override { - delegate_->FillChildRefsForChannelz(child_subchannels, child_channels); - } - - private: - void ShutdownLocked() override { delegate_.reset(); } - - static void OnDelegateRequestReresolutionLocked(void* arg, - grpc_error* error); - - OrphanablePtr delegate_; - grpc_closure on_delegate_request_reresolution_; -}; - -} // namespace grpc_core - -#endif // GRPC_TEST_CORE_UTIL_FORWARDING_LOAD_BALANCING_POLICY_H diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc new file mode 100644 index 00000000000..6b428af8e71 --- /dev/null +++ b/test/core/util/test_lb_policies.cc @@ -0,0 +1,240 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "test/core/util/test_lb_policies.h" + +#include + +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channelz.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/json/json.h" +#include "src/core/lib/transport/connectivity_state.h" + +namespace grpc_core { + +TraceFlag grpc_trace_forwarding_lb(false, "forwarding_lb"); + +namespace { + +// +// ForwardingLoadBalancingPolicy +// + +// A minimal forwarding class to avoid implementing a standalone test LB. +class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { + public: + ForwardingLoadBalancingPolicy(const Args& args, + const std::string& delegate_policy_name) + : LoadBalancingPolicy(args) { + delegate_ = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + delegate_policy_name.c_str(), args); + grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), + interested_parties()); + // Give re-resolution closure to delegate. + GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, + OnDelegateRequestReresolutionLocked, this, + grpc_combiner_scheduler(combiner())); + Ref().release(); // held by callback. + delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); + } + + ~ForwardingLoadBalancingPolicy() override = default; + + void UpdateLocked(const grpc_channel_args& args, + grpc_json* lb_config) override { + delegate_->UpdateLocked(args, lb_config); + } + + bool PickLocked(PickState* pick, grpc_error** error) override { + return delegate_->PickLocked(pick, error); + } + + void CancelPickLocked(PickState* pick, grpc_error* error) override { + delegate_->CancelPickLocked(pick, error); + } + + void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) override { + delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, + initial_metadata_flags_eq, error); + } + + void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) override { + delegate_->NotifyOnStateChangeLocked(state, closure); + } + + grpc_connectivity_state CheckConnectivityLocked( + grpc_error** connectivity_error) override { + return delegate_->CheckConnectivityLocked(connectivity_error); + } + + void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { + delegate_->HandOffPendingPicksLocked(new_policy); + } + + void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } + + void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } + + void FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) override { + delegate_->FillChildRefsForChannelz(child_subchannels, child_channels); + } + + private: + void ShutdownLocked() override { + delegate_.reset(); + TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_CANCELLED); + } + + static void OnDelegateRequestReresolutionLocked(void* arg, + grpc_error* error) { + ForwardingLoadBalancingPolicy* self = + static_cast(arg); + if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { + self->Unref(); + return; + } + self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); + self->delegate_->SetReresolutionClosureLocked( + &self->on_delegate_request_reresolution_); + } + + OrphanablePtr delegate_; + grpc_closure on_delegate_request_reresolution_; +}; + +// +// InterceptRecvTrailingMetadataLoadBalancingPolicy +// + +constexpr char kInterceptRecvTrailingMetadataLbPolicyName[] = + "intercept_trailing_metadata_lb"; + +class InterceptRecvTrailingMetadataLoadBalancingPolicy + : public ForwardingLoadBalancingPolicy { + public: + InterceptRecvTrailingMetadataLoadBalancingPolicy( + const Args& args, InterceptRecvTrailingMetadataCallback cb, + void* user_data) + : ForwardingLoadBalancingPolicy(args, + /*delegate_lb_policy_name=*/"pick_first"), + cb_(cb), user_data_(user_data) {} + + ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; + + const char* name() const override { + return kInterceptRecvTrailingMetadataLbPolicyName; + } + + bool PickLocked(PickState* pick, grpc_error** error) override { + bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); + // Note: This assumes that the delegate policy does not + // intercepting recv_trailing_metadata. If we ever need to use + // this with a delegate policy that does, then we'll need to + // handle async pick returns separately. + New(pick, cb_, user_data_); // deletes itself + return ret; + } + + private: + class TrailingMetadataHandler { + public: + TrailingMetadataHandler(PickState* pick, + InterceptRecvTrailingMetadataCallback cb, + void* user_data) + : cb_(cb), user_data_(user_data) { + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, + RecordRecvTrailingMetadata, this, + grpc_schedule_on_exec_ctx); + pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; + pick->original_recv_trailing_metadata_ready = + &original_recv_trailing_metadata_ready_; + pick->recv_trailing_metadata = &recv_trailing_metadata_; + } + + private: + static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { + TrailingMetadataHandler* self = + static_cast(arg); + GPR_ASSERT(self->recv_trailing_metadata_ != nullptr); + self->cb_(self->user_data_); + GRPC_CLOSURE_SCHED(self->original_recv_trailing_metadata_ready_, + GRPC_ERROR_REF(err)); + Delete(self); + } + + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; + grpc_closure recv_trailing_metadata_ready_; + grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; + grpc_metadata_batch* recv_trailing_metadata_ = nullptr; + }; + + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; +}; + +class InterceptTrailingFactory : public LoadBalancingPolicyFactory { + public: + explicit InterceptTrailingFactory( + InterceptRecvTrailingMetadataCallback cb, void* user_data) + : cb_(cb), user_data_(user_data) {} + + grpc_core::OrphanablePtr + CreateLoadBalancingPolicy( + const grpc_core::LoadBalancingPolicy::Args& args) const override { + return grpc_core::OrphanablePtr( + grpc_core::New( + args, cb_, user_data_)); + } + + const char* name() const override { + return kInterceptRecvTrailingMetadataLbPolicyName; + } + + private: + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; +}; + +} // namespace + +void RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( + InterceptRecvTrailingMetadataCallback cb, void* user_data) { + grpc_core::LoadBalancingPolicyRegistry::Builder:: + RegisterLoadBalancingPolicyFactory( + grpc_core::UniquePtr( + grpc_core::New(cb, user_data))); +} + +} // namespace grpc_core diff --git a/test/core/util/test_lb_policies.h b/test/core/util/test_lb_policies.h new file mode 100644 index 00000000000..6d2693a0d59 --- /dev/null +++ b/test/core/util/test_lb_policies.h @@ -0,0 +1,34 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_TEST_CORE_UTIL_TEST_LB_POLICIES_H +#define GRPC_TEST_CORE_UTIL_TEST_LB_POLICIES_H + +namespace grpc_core { + +typedef void (*InterceptRecvTrailingMetadataCallback)(void*); + +// Registers an LB policy called "intercept_trailing_metadata_lb" that +// invokes cb with argument user_data when trailing metadata is received +// for each call. +void RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( + InterceptRecvTrailingMetadataCallback cb, void* user_data); + +} // namespace grpc_core + +#endif // GRPC_TEST_CORE_UTIL_TEST_LB_POLICIES_H diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index b14f85100ad..4a6307a22ca 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -60,8 +60,8 @@ #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" -#include "test/core/util/forwarding_load_balancing_policy.h" #include "test/core/util/test_config.h" +#include "test/core/util/test_lb_policies.h" #include "test/cpp/end2end/test_service_impl.h" #include @@ -1237,112 +1237,25 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { protected: void SetUp() override { ClientLbEnd2endTest::SetUp(); - grpc_core::LoadBalancingPolicyRegistry::Builder:: - RegisterLoadBalancingPolicyFactory( - grpc_core::UniquePtr( - grpc_core::New(this))); + grpc_core::RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( + ReportTrailerIntercepted, this); } void TearDown() override { ClientLbEnd2endTest::TearDown(); } - class InterceptRecvTrailingMetadataLoadBalancingPolicy - : public grpc_core::ForwardingLoadBalancingPolicy { - public: - InterceptRecvTrailingMetadataLoadBalancingPolicy( - const Args& args, const std::string& delegate_lb_policy_name, - ClientLbInterceptTrailingMetadataTest* test) - : grpc_core::ForwardingLoadBalancingPolicy(args, - delegate_lb_policy_name), - test_(test) {} - - ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; - - bool PickLocked(PickState* pick, grpc_error** error) override { - bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); - // Note: This assumes that the delegate policy does not - // intercepting recv_trailing_metadata. If we ever need to use - // this with a delegate policy that does, then we'll need to - // handle async pick returns separately. - new TrailingMetadataHandler(pick, test_); // deletes itself - return ret; - } - - private: - class TrailingMetadataHandler { - public: - TrailingMetadataHandler(PickState* pick, - ClientLbInterceptTrailingMetadataTest* test) - : test_(test) { - GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, - RecordRecvTrailingMetadata, this, - grpc_schedule_on_exec_ctx); - pick->recv_trailing_metadata_ready = &recv_trailing_metadata_ready_; - pick->original_recv_trailing_metadata_ready = - &original_recv_trailing_metadata_ready_; - pick->recv_trailing_metadata = &recv_trailing_metadata_; - } - - private: - static void RecordRecvTrailingMetadata(void* arg, grpc_error* err) { - TrailingMetadataHandler* self = - static_cast(arg); - GPR_ASSERT(self->recv_trailing_metadata_ != nullptr); - // a simple check to make sure the trailing metadata is valid - GPR_ASSERT( - grpc_get_status_code_from_metadata( - self->recv_trailing_metadata_->idx.named.grpc_status->md) == - grpc_status_code::GRPC_STATUS_OK); - self->test_->ReportTrailerIntercepted(); - GRPC_CLOSURE_SCHED(self->original_recv_trailing_metadata_ready_, - GRPC_ERROR_REF(err)); - delete self; - } - - ClientLbInterceptTrailingMetadataTest* test_; - grpc_closure recv_trailing_metadata_ready_; - grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; - grpc_metadata_batch* recv_trailing_metadata_ = nullptr; - }; - - ClientLbInterceptTrailingMetadataTest* test_; - }; - - // A factory for a test LB policy that intercepts trailing metadata. - // The LB policy is implemented as a wrapper around a delegate LB policy. - class InterceptTrailingFactory - : public grpc_core::LoadBalancingPolicyFactory { - public: - explicit InterceptTrailingFactory( - ClientLbInterceptTrailingMetadataTest* test) - : test_(test) {} - - grpc_core::OrphanablePtr - CreateLoadBalancingPolicy( - const grpc_core::LoadBalancingPolicy::Args& args) const override { - return grpc_core::OrphanablePtr( - grpc_core::New( - args, /*delegate_lb_policy_name=*/ "pick_first", test_)); - } - - const char* name() const override { - return "intercept_trailing_metadata_lb"; - } - - private: - ClientLbInterceptTrailingMetadataTest* test_; - }; - - void ReportTrailerIntercepted() { - std::unique_lock lock(mu_); - trailers_intercepted_++; - } - int trailers_intercepted() { std::unique_lock lock(mu_); return trailers_intercepted_; } private: + static void ReportTrailerIntercepted(void* arg) { + ClientLbInterceptTrailingMetadataTest* self = + static_cast(arg); + std::unique_lock lock(self->mu_); + self->trailers_intercepted_++; + } + std::mutex mu_; int trailers_intercepted_ = 0; }; diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 81fe8573c13..a0e0a8ae769 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10459,7 +10459,6 @@ "test/core/end2end/fixtures/proxy.h", "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.h", - "test/core/util/forwarding_load_balancing_policy.h", "test/core/util/fuzzer_util.h", "test/core/util/grpc_profiler.h", "test/core/util/histogram.h", @@ -10472,6 +10471,7 @@ "test/core/util/slice_splitter.h", "test/core/util/subprocess.h", "test/core/util/test_config.h", + "test/core/util/test_lb_policies.h", "test/core/util/tracer_util.h", "test/core/util/trickle_endpoint.h" ], @@ -10493,8 +10493,6 @@ "test/core/iomgr/endpoint_tests.h", "test/core/util/debugger_macros.cc", "test/core/util/debugger_macros.h", - "test/core/util/forwarding_load_balancing_policy.cc", - "test/core/util/forwarding_load_balancing_policy.h", "test/core/util/fuzzer_util.cc", "test/core/util/fuzzer_util.h", "test/core/util/grpc_profiler.cc", @@ -10521,6 +10519,8 @@ "test/core/util/subprocess_windows.cc", "test/core/util/test_config.cc", "test/core/util/test_config.h", + "test/core/util/test_lb_policies.cc", + "test/core/util/test_lb_policies.h", "test/core/util/tracer_util.cc", "test/core/util/tracer_util.h", "test/core/util/trickle_endpoint.cc", From d655509e3d965b7b050e1238af5fe7f05c80005b Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Jan 2019 10:52:29 -0800 Subject: [PATCH 045/814] Fix sanity and build. --- test/core/util/BUILD | 6 +++--- test/core/util/test_lb_policies.cc | 14 +++++++------- test/cpp/end2end/BUILD | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 8d50dd2bbac..b931a9d683c 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -156,10 +156,10 @@ sh_library( ) grpc_cc_library( - name = "forwarding_load_balancing_policy", + name = "test_lb_policies", testonly = 1, - srcs = ["forwarding_load_balancing_policy.cc"], - hdrs = ["forwarding_load_balancing_policy.h"], + srcs = ["test_lb_policies.cc"], + hdrs = ["test_lb_policies.h"], deps = [ "//:grpc", ], diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 6b428af8e71..5f042867dd9 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -25,8 +25,8 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channelz.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/combiner.h" @@ -51,9 +51,8 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { ForwardingLoadBalancingPolicy(const Args& args, const std::string& delegate_policy_name) : LoadBalancingPolicy(args) { - delegate_ = - LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - delegate_policy_name.c_str(), args); + delegate_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + delegate_policy_name.c_str(), args); grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), interested_parties()); // Give re-resolution closure to delegate. @@ -148,7 +147,8 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy void* user_data) : ForwardingLoadBalancingPolicy(args, /*delegate_lb_policy_name=*/"pick_first"), - cb_(cb), user_data_(user_data) {} + cb_(cb), + user_data_(user_data) {} ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; @@ -206,8 +206,8 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy class InterceptTrailingFactory : public LoadBalancingPolicyFactory { public: - explicit InterceptTrailingFactory( - InterceptRecvTrailingMetadataCallback cb, void* user_data) + explicit InterceptTrailingFactory(InterceptRecvTrailingMetadataCallback cb, + void* user_data) : cb_(cb), user_data_(user_data) {} grpc_core::OrphanablePtr diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index ae204f580b3..47cb6ba14c3 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -387,8 +387,8 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", - "//test/core/util:forwarding_load_balancing_policy", "//test/core/util:grpc_test_util", + "//test/core/util:test_lb_policies", "//test/cpp/util:test_util", ], ) From 62052d7a12f8dfb12dc7d8c0e933fbb7625c1de1 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Jan 2019 11:22:58 -0800 Subject: [PATCH 046/814] Fix bug in cancellation. --- src/core/ext/filters/client_channel/client_channel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index cc34178d619..35c3efab6aa 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -870,7 +870,7 @@ static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { - if (batch->recv_trailing_metadata) { + if (batch->recv_trailing_metadata && calld->have_request) { maybe_inject_recv_trailing_metadata_ready_for_lb( *calld->request->pick(), batch); } From 6e94552a306e9cfcff834e39bc833bcb8055e6fe Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 17:00:49 -0800 Subject: [PATCH 047/814] Add a caching interceptor to the keyvaluestore example --- examples/BUILD | 3 +- .../cpp/keyvaluestore/caching_interceptor.h | 128 ++++++++++++++++++ examples/cpp/keyvaluestore/client.cc | 19 ++- 3 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 examples/cpp/keyvaluestore/caching_interceptor.h diff --git a/examples/BUILD b/examples/BUILD index 4fee663bd9e..0a1ca94a649 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -101,7 +101,8 @@ cc_binary( cc_binary( name = "keyvaluestore_client", - srcs = ["cpp/keyvaluestore/client.cc"], + srcs = ["cpp/keyvaluestore/caching_interceptor.h", + "cpp/keyvaluestore/client.cc"], defines = ["BAZEL_BUILD"], deps = [":keyvaluestore", "//:grpc++"], ) diff --git a/examples/cpp/keyvaluestore/caching_interceptor.h b/examples/cpp/keyvaluestore/caching_interceptor.h new file mode 100644 index 00000000000..393212b83bb --- /dev/null +++ b/examples/cpp/keyvaluestore/caching_interceptor.h @@ -0,0 +1,128 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/keyvaluestore.grpc.pb.h" +#else +#include "keyvaluestore.grpc.pb.h" +#endif + +// This is a naive implementation of a cache. A new cache is for each call. For +// each new key request, the key is first searched in the map and if found. Only +// if the key is not found in the cache do we make a request. +class CachingInterceptor : public grpc::experimental::Interceptor { + public: + CachingInterceptor(grpc::experimental::ClientRpcInfo* info) {} + + void Intercept( + ::grpc::experimental::InterceptorBatchMethods* methods) override { + bool hijack = false; + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints:: + PRE_SEND_INITIAL_METADATA)) { + // Hijack all calls + hijack = true; + // Create a stream on which this interceptor can make requests + stub_ = keyvaluestore::KeyValueStore::NewStub( + methods->GetInterceptedChannel()); + stream_ = stub_->GetValues(&context_); + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) { + // We know that clients perform a Read and a Write in a loop, so we don't + // need to maintain a list of the responses. + std::string requested_key; + const keyvaluestore::Request* req_msg = + static_cast(methods->GetSendMessage()); + if (req_msg != nullptr) { + requested_key = req_msg->key(); + } else { + // The non-serialized form would not be available in certain scenarios, + // so add a fallback + keyvaluestore::Request req_msg; + auto* buffer = methods->GetSerializedSendMessage(); + auto copied_buffer = *buffer; + GPR_ASSERT( + grpc::SerializationTraits::Deserialize( + &copied_buffer, &req_msg) + .ok()); + requested_key = req_msg.key(); + } + + // Check if the key is present in the map + auto search = cached_map_.find(requested_key); + if (search != cached_map_.end()) { + std::cout << "Key " << requested_key << "found in map"; + response_ = search->second; + } else { + std::cout << "Key " << requested_key << "not found in cache"; + // Key was not found in the cache, so make a request + keyvaluestore::Request req; + req.set_key(requested_key); + stream_->Write(req); + keyvaluestore::Response resp; + stream_->Read(&resp); + response_ = resp.value(); + // Insert the pair in the cache for future requests + cached_map_.insert({requested_key, response_}); + } + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { + stream_->WritesDone(); + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) { + keyvaluestore::Response* resp = + static_cast(methods->GetRecvMessage()); + resp->set_value(response_); + } + if (methods->QueryInterceptionHookPoint( + grpc::experimental::InterceptionHookPoints::PRE_RECV_STATUS)) { + auto* status = methods->GetRecvStatus(); + *status = grpc::Status::OK; + } + if (hijack) { + methods->Hijack(); + } else { + methods->Proceed(); + } + } + + private: + grpc::ClientContext context_; + std::unique_ptr stub_; + std::unique_ptr< + grpc::ClientReaderWriter> + stream_; + std::map cached_map_; + std::string response_; +}; + +class CachingInterceptorFactory + : public grpc::experimental::ClientInterceptorFactoryInterface { + public: + grpc::experimental::Interceptor* CreateClientInterceptor( + grpc::experimental::ClientRpcInfo* info) override { + return new CachingInterceptor(info); + } +}; \ No newline at end of file diff --git a/examples/cpp/keyvaluestore/client.cc b/examples/cpp/keyvaluestore/client.cc index 17e407c273b..57c451cadf3 100644 --- a/examples/cpp/keyvaluestore/client.cc +++ b/examples/cpp/keyvaluestore/client.cc @@ -23,6 +23,8 @@ #include +#include "caching_interceptor.h" + #ifdef BAZEL_BUILD #include "examples/protos/keyvaluestore.grpc.pb.h" #else @@ -77,9 +79,20 @@ int main(int argc, char** argv) { // are created. This channel models a connection to an endpoint (in this case, // localhost at port 50051). We indicate that the channel isn't authenticated // (use of InsecureChannelCredentials()). - KeyValueStoreClient client(grpc::CreateChannel( - "localhost:50051", grpc::InsecureChannelCredentials())); - std::vector keys = {"key1", "key2", "key3", "key4", "key5"}; + // In this example, we are using a cache which has been added in as an + // interceptor. + grpc::ChannelArguments args; + std::vector< + std::unique_ptr> + interceptor_creators; + interceptor_creators.push_back(std::unique_ptr( + new CachingInterceptorFactory())); + auto channel = grpc::experimental::CreateCustomChannelWithInterceptors( + "localhost:50051", grpc::InsecureChannelCredentials(), args, + std::move(interceptor_creators)); + KeyValueStoreClient client(channel); + std::vector keys = {"key1", "key2", "key3", "key4", + "key5", "key1", "key2", "key4"}; client.GetValues(keys); return 0; From 817fb588af4174fe5095a316e60a481f3be220df Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 10 Jan 2019 17:06:41 -0800 Subject: [PATCH 048/814] Adding a new line at the end of the file --- examples/cpp/keyvaluestore/caching_interceptor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cpp/keyvaluestore/caching_interceptor.h b/examples/cpp/keyvaluestore/caching_interceptor.h index 393212b83bb..a5d130da8dd 100644 --- a/examples/cpp/keyvaluestore/caching_interceptor.h +++ b/examples/cpp/keyvaluestore/caching_interceptor.h @@ -125,4 +125,4 @@ class CachingInterceptorFactory grpc::experimental::ClientRpcInfo* info) override { return new CachingInterceptor(info); } -}; \ No newline at end of file +}; From 95965f71d3e99f6baa4a237e0a7046d51cd0441f Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 11 Jan 2019 10:40:20 -0800 Subject: [PATCH 049/814] Remove network_status_tracker Remove network_status_tracker and its unit test as it does nothing. We can add tests for network status change in another commit. --- BUILD | 6 +- CMakeLists.txt | 8 - Makefile | 8 - build.yaml | 2 - config.m4 | 1 - config.w32 | 1 - gRPC-C++.podspec | 2 - gRPC-Core.podspec | 4 - grpc.gemspec | 2 - grpc.gyp | 6 - package.xml | 2 - src/core/lib/iomgr/iomgr.cc | 3 - src/core/lib/iomgr/network_status_tracker.cc | 36 - src/core/lib/iomgr/network_status_tracker.h | 32 - src/core/lib/iomgr/tcp_custom.cc | 4 - src/core/lib/iomgr/tcp_posix.cc | 13 +- src/core/lib/iomgr/tcp_uv.cc | 1 - src/core/lib/iomgr/tcp_windows.cc | 4 - .../CoreCronetEnd2EndTests.mm | 4 - src/python/grpcio/grpc_core_dependencies.py | 1 - test/core/end2end/end2end_nosec_tests.cc | 8 - test/core/end2end/end2end_tests.cc | 8 - test/core/end2end/gen_build_yaml.py | 1 - test/core/end2end/generate_tests.bzl | 1 - .../end2end/tests/network_status_change.cc | 237 ------ tools/doxygen/Doxyfile.c++.internal | 1 - tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 5 - tools/run_tests/generated/tests.json | 789 ------------------ 29 files changed, 6 insertions(+), 1186 deletions(-) delete mode 100644 src/core/lib/iomgr/network_status_tracker.cc delete mode 100644 src/core/lib/iomgr/network_status_tracker.h delete mode 100644 test/core/end2end/tests/network_status_change.cc diff --git a/BUILD b/BUILD index 453c64ab08c..5f53bbc6f0b 100644 --- a/BUILD +++ b/BUILD @@ -724,6 +724,8 @@ grpc_cc_library( "src/core/lib/iomgr/gethostname_fallback.cc", "src/core/lib/iomgr/gethostname_host_name_max.cc", "src/core/lib/iomgr/gethostname_sysconf.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_posix.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc", "src/core/lib/iomgr/internal_errqueue.cc", "src/core/lib/iomgr/iocp_windows.cc", "src/core/lib/iomgr/iomgr.cc", @@ -732,11 +734,8 @@ grpc_cc_library( "src/core/lib/iomgr/iomgr_posix.cc", "src/core/lib/iomgr/iomgr_windows.cc", "src/core/lib/iomgr/is_epollexclusive_available.cc", - "src/core/lib/iomgr/grpc_if_nametoindex_posix.cc", - "src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc", "src/core/lib/iomgr/load_file.cc", "src/core/lib/iomgr/lockfree_event.cc", - "src/core/lib/iomgr/network_status_tracker.cc", "src/core/lib/iomgr/polling_entity.cc", "src/core/lib/iomgr/pollset.cc", "src/core/lib/iomgr/pollset_custom.cc", @@ -886,7 +885,6 @@ grpc_cc_library( "src/core/lib/iomgr/load_file.h", "src/core/lib/iomgr/lockfree_event.h", "src/core/lib/iomgr/nameser.h", - "src/core/lib/iomgr/network_status_tracker.h", "src/core/lib/iomgr/polling_entity.h", "src/core/lib/iomgr/pollset.h", "src/core/lib/iomgr/pollset_custom.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 38f8ad915ff..13d5aca6584 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1008,7 +1008,6 @@ add_library(grpc src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -1432,7 +1431,6 @@ add_library(grpc_cronet src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -1840,7 +1838,6 @@ add_library(grpc_test_util src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -2164,7 +2161,6 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -2465,7 +2461,6 @@ add_library(grpc_unsecure src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -3352,7 +3347,6 @@ add_library(grpc++_cronet src/core/lib/iomgr/is_epollexclusive_available.cc src/core/lib/iomgr/load_file.cc src/core/lib/iomgr/lockfree_event.cc - src/core/lib/iomgr/network_status_tracker.cc src/core/lib/iomgr/polling_entity.cc src/core/lib/iomgr/pollset.cc src/core/lib/iomgr/pollset_custom.cc @@ -5609,7 +5603,6 @@ add_library(end2end_tests test/core/end2end/tests/max_connection_idle.cc test/core/end2end/tests/max_message_length.cc test/core/end2end/tests/negative_deadline.cc - test/core/end2end/tests/network_status_change.cc test/core/end2end/tests/no_error_on_hotpath.cc test/core/end2end/tests/no_logging.cc test/core/end2end/tests/no_op.cc @@ -5733,7 +5726,6 @@ add_library(end2end_nosec_tests test/core/end2end/tests/max_connection_idle.cc test/core/end2end/tests/max_message_length.cc test/core/end2end/tests/negative_deadline.cc - test/core/end2end/tests/network_status_change.cc test/core/end2end/tests/no_error_on_hotpath.cc test/core/end2end/tests/no_logging.cc test/core/end2end/tests/no_op.cc diff --git a/Makefile b/Makefile index 504ef409630..00186d891c6 100644 --- a/Makefile +++ b/Makefile @@ -3525,7 +3525,6 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -3943,7 +3942,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -4344,7 +4342,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -4655,7 +4652,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -4930,7 +4926,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -5794,7 +5789,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ @@ -10379,7 +10373,6 @@ LIBEND2END_TESTS_SRC = \ test/core/end2end/tests/max_connection_idle.cc \ test/core/end2end/tests/max_message_length.cc \ test/core/end2end/tests/negative_deadline.cc \ - test/core/end2end/tests/network_status_change.cc \ test/core/end2end/tests/no_error_on_hotpath.cc \ test/core/end2end/tests/no_logging.cc \ test/core/end2end/tests/no_op.cc \ @@ -10496,7 +10489,6 @@ LIBEND2END_NOSEC_TESTS_SRC = \ test/core/end2end/tests/max_connection_idle.cc \ test/core/end2end/tests/max_message_length.cc \ test/core/end2end/tests/negative_deadline.cc \ - test/core/end2end/tests/network_status_change.cc \ test/core/end2end/tests/no_error_on_hotpath.cc \ test/core/end2end/tests/no_logging.cc \ test/core/end2end/tests/no_op.cc \ diff --git a/build.yaml b/build.yaml index 28375c82589..c7b4d751731 100644 --- a/build.yaml +++ b/build.yaml @@ -289,7 +289,6 @@ filegroups: - src/core/lib/iomgr/is_epollexclusive_available.cc - src/core/lib/iomgr/load_file.cc - src/core/lib/iomgr/lockfree_event.cc - - src/core/lib/iomgr/network_status_tracker.cc - src/core/lib/iomgr/polling_entity.cc - src/core/lib/iomgr/pollset.cc - src/core/lib/iomgr/pollset_custom.cc @@ -465,7 +464,6 @@ filegroups: - src/core/lib/iomgr/load_file.h - src/core/lib/iomgr/lockfree_event.h - src/core/lib/iomgr/nameser.h - - src/core/lib/iomgr/network_status_tracker.h - src/core/lib/iomgr/polling_entity.h - src/core/lib/iomgr/pollset.h - src/core/lib/iomgr/pollset_custom.h diff --git a/config.m4 b/config.m4 index 3c3c0210d87..ccb218a1200 100644 --- a/config.m4 +++ b/config.m4 @@ -141,7 +141,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/is_epollexclusive_available.cc \ src/core/lib/iomgr/load_file.cc \ src/core/lib/iomgr/lockfree_event.cc \ - src/core/lib/iomgr/network_status_tracker.cc \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/pollset.cc \ src/core/lib/iomgr/pollset_custom.cc \ diff --git a/config.w32 b/config.w32 index f87859ad09f..fd48ec6f485 100644 --- a/config.w32 +++ b/config.w32 @@ -116,7 +116,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\is_epollexclusive_available.cc " + "src\\core\\lib\\iomgr\\load_file.cc " + "src\\core\\lib\\iomgr\\lockfree_event.cc " + - "src\\core\\lib\\iomgr\\network_status_tracker.cc " + "src\\core\\lib\\iomgr\\polling_entity.cc " + "src\\core\\lib\\iomgr\\pollset.cc " + "src\\core\\lib\\iomgr\\pollset_custom.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 4e0a471fb44..bf124304487 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -434,7 +434,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/load_file.h', 'src/core/lib/iomgr/lockfree_event.h', 'src/core/lib/iomgr/nameser.h', - 'src/core/lib/iomgr/network_status_tracker.h', 'src/core/lib/iomgr/polling_entity.h', 'src/core/lib/iomgr/pollset.h', 'src/core/lib/iomgr/pollset_custom.h', @@ -628,7 +627,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/load_file.h', 'src/core/lib/iomgr/lockfree_event.h', 'src/core/lib/iomgr/nameser.h', - 'src/core/lib/iomgr/network_status_tracker.h', 'src/core/lib/iomgr/polling_entity.h', 'src/core/lib/iomgr/pollset.h', 'src/core/lib/iomgr/pollset_custom.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 4e4c8662411..60f34ebd6a2 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -428,7 +428,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/load_file.h', 'src/core/lib/iomgr/lockfree_event.h', 'src/core/lib/iomgr/nameser.h', - 'src/core/lib/iomgr/network_status_tracker.h', 'src/core/lib/iomgr/polling_entity.h', 'src/core/lib/iomgr/pollset.h', 'src/core/lib/iomgr/pollset_custom.h', @@ -585,7 +584,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', @@ -1054,7 +1052,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/load_file.h', 'src/core/lib/iomgr/lockfree_event.h', 'src/core/lib/iomgr/nameser.h', - 'src/core/lib/iomgr/network_status_tracker.h', 'src/core/lib/iomgr/polling_entity.h', 'src/core/lib/iomgr/pollset.h', 'src/core/lib/iomgr/pollset_custom.h', @@ -1300,7 +1297,6 @@ Pod::Spec.new do |s| 'test/core/end2end/tests/max_connection_idle.cc', 'test/core/end2end/tests/max_message_length.cc', 'test/core/end2end/tests/negative_deadline.cc', - 'test/core/end2end/tests/network_status_change.cc', 'test/core/end2end/tests/no_error_on_hotpath.cc', 'test/core/end2end/tests/no_logging.cc', 'test/core/end2end/tests/no_op.cc', diff --git a/grpc.gemspec b/grpc.gemspec index 42b1db35b4d..60c5bc480b6 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -364,7 +364,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/load_file.h ) s.files += %w( src/core/lib/iomgr/lockfree_event.h ) s.files += %w( src/core/lib/iomgr/nameser.h ) - s.files += %w( src/core/lib/iomgr/network_status_tracker.h ) s.files += %w( src/core/lib/iomgr/polling_entity.h ) s.files += %w( src/core/lib/iomgr/pollset.h ) s.files += %w( src/core/lib/iomgr/pollset_custom.h ) @@ -521,7 +520,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/is_epollexclusive_available.cc ) s.files += %w( src/core/lib/iomgr/load_file.cc ) s.files += %w( src/core/lib/iomgr/lockfree_event.cc ) - s.files += %w( src/core/lib/iomgr/network_status_tracker.cc ) s.files += %w( src/core/lib/iomgr/polling_entity.cc ) s.files += %w( src/core/lib/iomgr/pollset.cc ) s.files += %w( src/core/lib/iomgr/pollset_custom.cc ) diff --git a/grpc.gyp b/grpc.gyp index 13b9c1bc78b..1f5b6384975 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -323,7 +323,6 @@ 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', @@ -687,7 +686,6 @@ 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', @@ -931,7 +929,6 @@ 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', @@ -1152,7 +1149,6 @@ 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', @@ -2721,7 +2717,6 @@ 'test/core/end2end/tests/max_connection_idle.cc', 'test/core/end2end/tests/max_message_length.cc', 'test/core/end2end/tests/negative_deadline.cc', - 'test/core/end2end/tests/network_status_change.cc', 'test/core/end2end/tests/no_error_on_hotpath.cc', 'test/core/end2end/tests/no_logging.cc', 'test/core/end2end/tests/no_op.cc', @@ -2811,7 +2806,6 @@ 'test/core/end2end/tests/max_connection_idle.cc', 'test/core/end2end/tests/max_message_length.cc', 'test/core/end2end/tests/negative_deadline.cc', - 'test/core/end2end/tests/network_status_change.cc', 'test/core/end2end/tests/no_error_on_hotpath.cc', 'test/core/end2end/tests/no_logging.cc', 'test/core/end2end/tests/no_op.cc', diff --git a/package.xml b/package.xml index de5c56f4511..81a4aabdf5a 100644 --- a/package.xml +++ b/package.xml @@ -369,7 +369,6 @@ - @@ -526,7 +525,6 @@ - diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index a4921468578..dcc69332e0b 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -38,7 +38,6 @@ #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/internal_errqueue.h" #include "src/core/lib/iomgr/iomgr_internal.h" -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/timer_manager.h" @@ -57,7 +56,6 @@ void grpc_iomgr_init() { grpc_timer_list_init(); g_root_object.next = g_root_object.prev = &g_root_object; g_root_object.name = (char*)"root"; - grpc_network_status_init(); grpc_iomgr_platform_init(); grpc_core::grpc_errqueue_init(); } @@ -152,7 +150,6 @@ void grpc_iomgr_shutdown() { gpr_mu_unlock(&g_mu); grpc_iomgr_platform_shutdown(); - grpc_network_status_shutdown(); gpr_mu_destroy(&g_mu); gpr_cv_destroy(&g_rcv); } diff --git a/src/core/lib/iomgr/network_status_tracker.cc b/src/core/lib/iomgr/network_status_tracker.cc deleted file mode 100644 index d4b7f4a57d1..00000000000 --- a/src/core/lib/iomgr/network_status_tracker.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/lib/iomgr/endpoint.h" -#include "src/core/lib/iomgr/network_status_tracker.h" - -void grpc_network_status_shutdown(void) {} - -void grpc_network_status_init(void) { - // TODO(makarandd): Install callback with OS to monitor network status. -} - -void grpc_destroy_network_status_monitor() {} - -void grpc_network_status_register_endpoint(grpc_endpoint* ep) { (void)ep; } - -void grpc_network_status_unregister_endpoint(grpc_endpoint* ep) { (void)ep; } - -void grpc_network_status_shutdown_all_endpoints() {} diff --git a/src/core/lib/iomgr/network_status_tracker.h b/src/core/lib/iomgr/network_status_tracker.h deleted file mode 100644 index 198877f60f8..00000000000 --- a/src/core/lib/iomgr/network_status_tracker.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H -#define GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H -#include - -#include "src/core/lib/iomgr/endpoint.h" - -void grpc_network_status_init(void); -void grpc_network_status_shutdown(void); - -void grpc_network_status_register_endpoint(grpc_endpoint* ep); -void grpc_network_status_unregister_endpoint(grpc_endpoint* ep); -void grpc_network_status_shutdown_all_endpoints(); - -#endif /* GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H */ diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc index f7a5f36cdcd..1e5696e1279 100644 --- a/src/core/lib/iomgr/tcp_custom.cc +++ b/src/core/lib/iomgr/tcp_custom.cc @@ -31,7 +31,6 @@ #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/iomgr_custom.h" -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/iomgr/tcp_custom.h" @@ -309,7 +308,6 @@ static void custom_close_callback(grpc_custom_socket* socket) { } static void endpoint_destroy(grpc_endpoint* ep) { - grpc_network_status_unregister_endpoint(ep); custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep; grpc_custom_socket_vtable->close(tcp->socket, custom_close_callback); } @@ -361,8 +359,6 @@ grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket, tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); grpc_resource_user_slice_allocator_init( &tcp->slice_allocator, tcp->resource_user, tcp_read_allocation_done, tcp); - /* Tell network status tracking code about the new endpoint */ - grpc_network_status_register_endpoint(&tcp->base); return &tcp->base; } diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index c268c18664a..d0642c015ff 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -22,7 +22,6 @@ #ifdef GRPC_POSIX_SOCKET_TCP -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/tcp_posix.h" #include @@ -127,9 +126,8 @@ struct grpc_tcp { bool socket_ts_enabled; /* True if timestamping options are set on the socket */ bool ts_capable; /* Cache whether we can set timestamping options */ - gpr_atm - stop_error_notification; /* Set to 1 if we do not want to be notified on - errors anymore */ + gpr_atm stop_error_notification; /* Set to 1 if we do not want to be notified + on errors anymore */ }; struct backup_poller { @@ -388,7 +386,6 @@ static void tcp_ref(grpc_tcp* tcp) { gpr_ref(&tcp->refcount); } #endif static void tcp_destroy(grpc_endpoint* ep) { - grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = reinterpret_cast(ep); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { @@ -701,7 +698,8 @@ static void process_errors(grpc_tcp* tcp) { union { char rbuf[1024 /*CMSG_SPACE(sizeof(scm_timestamping)) + - CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in))*/]; + CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in))*/ + ]; struct cmsghdr align; } aligned_buf; memset(&aligned_buf, 0, sizeof(aligned_buf)); @@ -1131,8 +1129,6 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); grpc_resource_user_slice_allocator_init( &tcp->slice_allocator, tcp->resource_user, tcp_read_allocation_done, tcp); - /* Tell network status tracker about new endpoint */ - grpc_network_status_register_endpoint(&tcp->base); grpc_resource_quota_unref_internal(resource_quota); gpr_mu_init(&tcp->tb_mu); tcp->tb_head = nullptr; @@ -1159,7 +1155,6 @@ int grpc_tcp_fd(grpc_endpoint* ep) { void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, grpc_closure* done) { - grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = reinterpret_cast(ep); GPR_ASSERT(ep->vtable == &vtable); tcp->release_fd = fd; diff --git a/src/core/lib/iomgr/tcp_uv.cc b/src/core/lib/iomgr/tcp_uv.cc index 8d0e4a5e79e..e53ff472fef 100644 --- a/src/core/lib/iomgr/tcp_uv.cc +++ b/src/core/lib/iomgr/tcp_uv.cc @@ -33,7 +33,6 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/iomgr_custom.h" -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/resolve_address_custom.h" #include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/tcp_custom.h" diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 86ee1010cf7..43817c5a024 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -24,7 +24,6 @@ #include -#include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/sockaddr_windows.h" #include @@ -470,7 +469,6 @@ static void win_shutdown(grpc_endpoint* ep, grpc_error* why) { } static void win_destroy(grpc_endpoint* ep) { - grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = (grpc_tcp*)ep; grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); TCP_UNREF(tcp, "destroy"); @@ -526,8 +524,6 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, tcp->peer_string = gpr_strdup(peer_string); grpc_slice_buffer_init(&tcp->last_read_buffer); tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string); - /* Tell network status tracking code about the new endpoint */ - grpc_network_status_register_endpoint(&tcp->base); grpc_resource_quota_unref_internal(resource_quota); return &tcp->base; diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm index fe85e915d4d..2fac1be3d0e 100644 --- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm @@ -318,10 +318,6 @@ static char *roots_filename; [self testIndividualCase:(char *)"negative_deadline"]; } -- (void)testNetworkStatusChange { - [self testIndividualCase:(char *)"network_status_change"]; -} - - (void)testNoOp { [self testIndividualCase:(char *)"no_op"]; } diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 06de23903cb..f5e43ca657e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -115,7 +115,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/is_epollexclusive_available.cc', 'src/core/lib/iomgr/load_file.cc', 'src/core/lib/iomgr/lockfree_event.cc', - 'src/core/lib/iomgr/network_status_tracker.cc', 'src/core/lib/iomgr/polling_entity.cc', 'src/core/lib/iomgr/pollset.cc', 'src/core/lib/iomgr/pollset_custom.cc', diff --git a/test/core/end2end/end2end_nosec_tests.cc b/test/core/end2end/end2end_nosec_tests.cc index c6a4005fb3e..614d1f98e2b 100644 --- a/test/core/end2end/end2end_nosec_tests.cc +++ b/test/core/end2end/end2end_nosec_tests.cc @@ -98,8 +98,6 @@ extern void max_message_length(grpc_end2end_test_config config); extern void max_message_length_pre_init(void); extern void negative_deadline(grpc_end2end_test_config config); extern void negative_deadline_pre_init(void); -extern void network_status_change(grpc_end2end_test_config config); -extern void network_status_change_pre_init(void); extern void no_error_on_hotpath(grpc_end2end_test_config config); extern void no_error_on_hotpath_pre_init(void); extern void no_logging(grpc_end2end_test_config config); @@ -223,7 +221,6 @@ void grpc_end2end_tests_pre_init(void) { max_connection_idle_pre_init(); max_message_length_pre_init(); negative_deadline_pre_init(); - network_status_change_pre_init(); no_error_on_hotpath_pre_init(); no_logging_pre_init(); no_op_pre_init(); @@ -309,7 +306,6 @@ void grpc_end2end_tests(int argc, char **argv, max_connection_idle(config); max_message_length(config); negative_deadline(config); - network_status_change(config); no_error_on_hotpath(config); no_logging(config); no_op(config); @@ -492,10 +488,6 @@ void grpc_end2end_tests(int argc, char **argv, negative_deadline(config); continue; } - if (0 == strcmp("network_status_change", argv[i])) { - network_status_change(config); - continue; - } if (0 == strcmp("no_error_on_hotpath", argv[i])) { no_error_on_hotpath(config); continue; diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc index 7748a39cb59..9d3d231b3c5 100644 --- a/test/core/end2end/end2end_tests.cc +++ b/test/core/end2end/end2end_tests.cc @@ -100,8 +100,6 @@ extern void max_message_length(grpc_end2end_test_config config); extern void max_message_length_pre_init(void); extern void negative_deadline(grpc_end2end_test_config config); extern void negative_deadline_pre_init(void); -extern void network_status_change(grpc_end2end_test_config config); -extern void network_status_change_pre_init(void); extern void no_error_on_hotpath(grpc_end2end_test_config config); extern void no_error_on_hotpath_pre_init(void); extern void no_logging(grpc_end2end_test_config config); @@ -226,7 +224,6 @@ void grpc_end2end_tests_pre_init(void) { max_connection_idle_pre_init(); max_message_length_pre_init(); negative_deadline_pre_init(); - network_status_change_pre_init(); no_error_on_hotpath_pre_init(); no_logging_pre_init(); no_op_pre_init(); @@ -313,7 +310,6 @@ void grpc_end2end_tests(int argc, char **argv, max_connection_idle(config); max_message_length(config); negative_deadline(config); - network_status_change(config); no_error_on_hotpath(config); no_logging(config); no_op(config); @@ -500,10 +496,6 @@ void grpc_end2end_tests(int argc, char **argv, negative_deadline(config); continue; } - if (0 == strcmp("network_status_change", argv[i])) { - network_status_change(config); - continue; - } if (0 == strcmp("no_error_on_hotpath", argv[i])) { no_error_on_hotpath(config); continue; diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 28a7a4e25d6..0ff1b7ee796 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -146,7 +146,6 @@ END2END_TESTS = { proxyable=False, exclude_iomgrs=['uv'], cpu_cost=LOWCPU), 'max_message_length': default_test_options._replace(cpu_cost=LOWCPU), 'negative_deadline': default_test_options, - 'network_status_change': default_test_options._replace(cpu_cost=LOWCPU), 'no_error_on_hotpath': default_test_options._replace(proxyable=False), 'no_logging': default_test_options._replace(traceable=False), 'no_op': default_test_options, diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 853619fcdaf..ec32aa5102c 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -234,7 +234,6 @@ END2END_TESTS = { "max_connection_idle": _test_options(needs_fullstack = True, proxyable = False), "max_message_length": _test_options(), "negative_deadline": _test_options(), - "network_status_change": _test_options(), "no_error_on_hotpath": _test_options(proxyable = False), "no_logging": _test_options(traceable = False), "no_op": _test_options(), diff --git a/test/core/end2end/tests/network_status_change.cc b/test/core/end2end/tests/network_status_change.cc deleted file mode 100644 index 98a95582046..00000000000 --- a/test/core/end2end/tests/network_status_change.cc +++ /dev/null @@ -1,237 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "test/core/end2end/end2end_tests.h" - -#include -#include - -#include -#include -#include -#include -#include "test/core/end2end/cq_verifier.h" - -/* this is a private API but exposed here for testing*/ -extern void grpc_network_status_shutdown_all_endpoints(); - -static void* tag(intptr_t t) { return (void*)t; } - -static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, - const char* test_name, - grpc_channel_args* client_args, - grpc_channel_args* server_args) { - grpc_end2end_test_fixture f; - gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); - f = config.create_fixture(client_args, server_args); - config.init_server(&f, server_args); - config.init_client(&f, client_args); - return f; -} - -static gpr_timespec n_seconds_from_now(int n) { - return grpc_timeout_seconds_to_deadline(n); -} - -static gpr_timespec five_seconds_from_now(void) { - return n_seconds_from_now(500); -} - -static void drain_cq(grpc_completion_queue* cq) { - grpc_event ev; - do { - ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); - } while (ev.type != GRPC_QUEUE_SHUTDOWN); -} - -static void shutdown_server(grpc_end2end_test_fixture* f) { - if (!f->server) return; - grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); - GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), - grpc_timeout_seconds_to_deadline(5), - nullptr) - .type == GRPC_OP_COMPLETE); - grpc_server_destroy(f->server); - f->server = nullptr; -} - -static void shutdown_client(grpc_end2end_test_fixture* f) { - if (!f->client) return; - grpc_channel_destroy(f->client); - f->client = nullptr; -} - -static void end_test(grpc_end2end_test_fixture* f) { - shutdown_server(f); - shutdown_client(f); - - grpc_completion_queue_shutdown(f->cq); - drain_cq(f->cq); - grpc_completion_queue_destroy(f->cq); - grpc_completion_queue_destroy(f->shutdown_cq); -} - -/* Client sends a request with payload, server reads then returns status. */ -static void test_invoke_network_status_change(grpc_end2end_test_config config) { - grpc_call* c; - grpc_call* s; - grpc_slice request_payload_slice = - grpc_slice_from_copied_string("hello world"); - grpc_byte_buffer* request_payload = - grpc_raw_byte_buffer_create(&request_payload_slice, 1); - grpc_end2end_test_fixture f = - begin_test(config, "test_invoke_request_with_payload", nullptr, nullptr); - cq_verifier* cqv = cq_verifier_create(f.cq); - grpc_op ops[6]; - grpc_op* op; - grpc_metadata_array initial_metadata_recv; - grpc_metadata_array trailing_metadata_recv; - grpc_metadata_array request_metadata_recv; - grpc_byte_buffer* request_payload_recv = nullptr; - grpc_call_details call_details; - grpc_status_code status; - grpc_call_error error; - grpc_slice details; - int was_cancelled = 2; - - gpr_timespec deadline = five_seconds_from_now(); - c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), nullptr, - deadline, nullptr); - GPR_ASSERT(c); - - grpc_metadata_array_init(&initial_metadata_recv); - grpc_metadata_array_init(&trailing_metadata_recv); - grpc_metadata_array_init(&request_metadata_recv); - grpc_call_details_init(&call_details); - - memset(ops, 0, sizeof(ops)); - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_MESSAGE; - op->data.send_message.send_message = request_payload; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_INITIAL_METADATA; - op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; - op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; - op->data.recv_status_on_client.status = &status; - op->data.recv_status_on_client.status_details = &details; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(c, ops, static_cast(op - ops), tag(1), - nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( - f.server, &s, &call_details, - &request_metadata_recv, f.cq, f.cq, tag(101))); - CQ_EXPECT_COMPLETION(cqv, tag(101), 1); - cq_verify(cqv); - - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message.recv_message = &request_payload_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(102), - nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - CQ_EXPECT_COMPLETION(cqv, tag(102), 1); - cq_verify(cqv); - - // Simulate the network loss event - grpc_network_status_shutdown_all_endpoints(); - - op = ops; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; - op->data.send_status_from_server.trailing_metadata_count = 0; - op->data.send_status_from_server.status = GRPC_STATUS_OK; - grpc_slice status_details = grpc_slice_from_static_string("xyz"); - op->data.send_status_from_server.status_details = &status_details; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(103), - nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - CQ_EXPECT_COMPLETION(cqv, tag(103), 1); - CQ_EXPECT_COMPLETION(cqv, tag(1), 1); - cq_verify(cqv); - - // TODO(makdharma) Update this when the shutdown_all_endpoints is implemented. - // Expected behavior of a RPC when network is lost. - // GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); - GPR_ASSERT(status == GRPC_STATUS_OK); - - GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); - - grpc_slice_unref(details); - grpc_metadata_array_destroy(&initial_metadata_recv); - grpc_metadata_array_destroy(&trailing_metadata_recv); - grpc_metadata_array_destroy(&request_metadata_recv); - grpc_call_details_destroy(&call_details); - - grpc_call_unref(c); - grpc_call_unref(s); - - cq_verifier_destroy(cqv); - - grpc_byte_buffer_destroy(request_payload); - grpc_byte_buffer_destroy(request_payload_recv); - - end_test(&f); - config.tear_down_data(&f); -} - -void network_status_change(grpc_end2end_test_config config) { - if (config.feature_mask & - FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE) { - return; - } - test_invoke_network_status_change(config); -} - -void network_status_change_pre_init(void) {} diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index a76a261d071..363df22aa15 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1111,7 +1111,6 @@ src/core/lib/iomgr/is_epollexclusive_available.h \ src/core/lib/iomgr/load_file.h \ src/core/lib/iomgr/lockfree_event.h \ src/core/lib/iomgr/nameser.h \ -src/core/lib/iomgr/network_status_tracker.h \ src/core/lib/iomgr/polling_entity.h \ src/core/lib/iomgr/pollset.h \ src/core/lib/iomgr/pollset_custom.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 38d17b6f21f..bb350550e94 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1238,8 +1238,6 @@ src/core/lib/iomgr/load_file.h \ src/core/lib/iomgr/lockfree_event.cc \ src/core/lib/iomgr/lockfree_event.h \ src/core/lib/iomgr/nameser.h \ -src/core/lib/iomgr/network_status_tracker.cc \ -src/core/lib/iomgr/network_status_tracker.h \ src/core/lib/iomgr/polling_entity.cc \ src/core/lib/iomgr/polling_entity.h \ src/core/lib/iomgr/pollset.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 1478ac2cd5e..197de64dbe1 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8809,7 +8809,6 @@ "test/core/end2end/tests/max_connection_idle.cc", "test/core/end2end/tests/max_message_length.cc", "test/core/end2end/tests/negative_deadline.cc", - "test/core/end2end/tests/network_status_change.cc", "test/core/end2end/tests/no_error_on_hotpath.cc", "test/core/end2end/tests/no_logging.cc", "test/core/end2end/tests/no_op.cc", @@ -8908,7 +8907,6 @@ "test/core/end2end/tests/max_connection_idle.cc", "test/core/end2end/tests/max_message_length.cc", "test/core/end2end/tests/negative_deadline.cc", - "test/core/end2end/tests/network_status_change.cc", "test/core/end2end/tests/no_error_on_hotpath.cc", "test/core/end2end/tests/no_logging.cc", "test/core/end2end/tests/no_op.cc", @@ -9416,7 +9414,6 @@ "src/core/lib/iomgr/is_epollexclusive_available.cc", "src/core/lib/iomgr/load_file.cc", "src/core/lib/iomgr/lockfree_event.cc", - "src/core/lib/iomgr/network_status_tracker.cc", "src/core/lib/iomgr/polling_entity.cc", "src/core/lib/iomgr/pollset.cc", "src/core/lib/iomgr/pollset_custom.cc", @@ -9593,7 +9590,6 @@ "src/core/lib/iomgr/load_file.h", "src/core/lib/iomgr/lockfree_event.h", "src/core/lib/iomgr/nameser.h", - "src/core/lib/iomgr/network_status_tracker.h", "src/core/lib/iomgr/polling_entity.h", "src/core/lib/iomgr/pollset.h", "src/core/lib/iomgr/pollset_custom.h", @@ -9747,7 +9743,6 @@ "src/core/lib/iomgr/load_file.h", "src/core/lib/iomgr/lockfree_event.h", "src/core/lib/iomgr/nameser.h", - "src/core/lib/iomgr/network_status_tracker.h", "src/core/lib/iomgr/polling_entity.h", "src/core/lib/iomgr/pollset.h", "src/core/lib/iomgr/pollset_custom.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index f2d0cab5ede..6c667f10c48 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -8183,29 +8183,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_census_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -9958,29 +9935,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_compress_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -11675,28 +11629,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_fakesec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -13266,29 +13198,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_fd_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -14627,29 +14536,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -16258,25 +16144,6 @@ "linux" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_full+pipe_test", - "platforms": [ - "linux" - ] - }, { "args": [ "no_error_on_hotpath" @@ -17842,29 +17709,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -19594,29 +19438,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full+workarounds_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -21400,30 +21221,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_http_proxy_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -23191,29 +22988,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_local_ipv4_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -24916,29 +24690,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_local_ipv6_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -26641,29 +26392,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_local_uds_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -28447,30 +28175,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_oauth2_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -30127,30 +29831,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_proxy_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_logging" @@ -31327,30 +31007,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -32575,30 +32231,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair+trace_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -33857,32 +33489,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "msan" - ], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_1byte_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -35264,29 +34870,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_ssl_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -36902,30 +36485,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_ssl_proxy_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_logging" @@ -38165,29 +37724,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_uds_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -39660,29 +39196,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -40883,29 +40396,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_census_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -42635,29 +42125,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_compress_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -44222,29 +43689,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_fd_nosec_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -45560,29 +45004,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -47172,25 +46593,6 @@ "linux" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_full+pipe_nosec_test", - "platforms": [ - "linux" - ] - }, { "args": [ "no_error_on_hotpath" @@ -48733,29 +48135,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -50462,29 +49841,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "h2_full+workarounds_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -52244,30 +51600,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_http_proxy_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -53924,30 +53256,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_proxy_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_logging" @@ -55100,30 +54408,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -56324,30 +55608,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair+trace_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -57580,32 +56840,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [ - "msan" - ], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_sockpair_1byte_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" @@ -58914,29 +58148,6 @@ "posix" ] }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "language": "c", - "name": "h2_uds_nosec_test", - "platforms": [ - "linux", - "mac", - "posix" - ] - }, { "args": [ "no_error_on_hotpath" From 09f72a105763c38acc059f826fadcdfc85f1ac50 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 11 Jan 2019 13:35:02 -0800 Subject: [PATCH 050/814] avoid AttributeError when object init fails --- src/python/grpcio/grpc/_channel.py | 2 +- src/python/grpcio/grpc/_server.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 8051fb306cd..3685969c7fe 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -1063,5 +1063,5 @@ class Channel(grpc.Channel): cygrpc.fork_unregister_channel(self) # This prevent the failed-at-initializing object removal from failing. # Though the __init__ failed, the removal will still trigger __del__. - if _moot is not None and hasattr(self, "_connectivity_state"): + if _moot is not None and hasattr(self, '_connectivity_state'): _moot(self._connectivity_state) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index eb750ef1a82..c3ff1fa6bd3 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -860,9 +860,10 @@ class _Server(grpc.Server): return _stop(self._state, grace) def __del__(self): - # We can not grab a lock in __del__(), so set a flag to signal the - # serving daemon thread (if it exists) to initiate shutdown. - self._state.server_deallocated = True + if hasattr(self, '_state'): + # We can not grab a lock in __del__(), so set a flag to signal the + # serving daemon thread (if it exists) to initiate shutdown. + self._state.server_deallocated = True def create_server(thread_pool, generic_rpc_handlers, interceptors, options, From 222db627212b331381d97468813233738d720e75 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 11 Jan 2019 17:01:54 -0800 Subject: [PATCH 051/814] Revert the compare of protobuf message to comparing encoded result --- .../reflection/_reflection_servicer_test.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py index 560f6d3ddb3..0ee40e6f2da 100644 --- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py +++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py @@ -50,6 +50,16 @@ def _file_descriptor_to_proto(descriptor): class ReflectionServicerTest(unittest.TestCase): + # NOTE(lidiz) Bazel + Python 3 will result in creating two different + # instance of DESCRIPTOR for each message. So, the equal comparision + # between protobuf returned by stub and manually crafted protobuf will + # always fail. + def _assert_sequence_of_proto_equal(self, x, y): + self.assertSequenceEqual( + list(map(lambda x: x.SerializeToString(), x)), + list(map(lambda x: x.SerializeToString(), y)), + ) + def setUp(self): self._server = test_common.test_server() reflection.enable_server_reflection(_SERVICE_NAMES, self._server) @@ -84,7 +94,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testFileBySymbol(self): requests = ( @@ -108,7 +118,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testFileContainingExtension(self): requests = ( @@ -137,7 +147,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testExtensionNumbersOfType(self): requests = ( @@ -162,7 +172,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testListServices(self): requests = (reflection_pb2.ServerReflectionRequest(list_services='',),) @@ -173,7 +183,7 @@ class ReflectionServicerTest(unittest.TestCase): service=tuple( reflection_pb2.ServiceResponse(name=name) for name in _SERVICE_NAMES))),) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testReflectionServiceName(self): self.assertEqual(reflection.SERVICE_NAME, From 67b8d4d33bd7f4850eb1d21ab2f2d41ef00d0777 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 14 Jan 2019 10:25:43 -0800 Subject: [PATCH 052/814] update default settings for RBE --- third_party/toolchains/BUILD | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index a1bee7f1f68..5c95f02a65f 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -48,6 +48,18 @@ platform( name: "gceMachineType" # Small machines for majority of tests. value: "n1-highmem-2" } + properties: { + name: "dockerSiblingContainers" + value: "false" + } + properties: { + name: "dockerDropCapabilities" + value: "SYS_PTRACE" + } + properties: { + name: "dockerNetwork" + value: "off" + } """, ) @@ -71,6 +83,18 @@ platform( name: "gceMachineType" # Large machines for some resource demanding tests (TSAN). value: "n1-standard-8" } + properties: { + name: "dockerSiblingContainers" + value: "false" + } + properties: { + name: "dockerDropCapabilities" + value: "SYS_PTRACE" + } + properties: { + name: "dockerNetwork" + value: "off" + } """, ) From 3868a229c43679045926e63c9e2e3646ea5f899f Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Mon, 14 Jan 2019 11:11:47 -0800 Subject: [PATCH 053/814] Bump version 1.18.x to remove -pre1 --- BUILD | 4 ++-- build.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BUILD b/BUILD index bf81f842dd6..fcaf8f82336 100644 --- a/BUILD +++ b/BUILD @@ -66,9 +66,9 @@ config_setting( # This should be updated along with build.yaml g_stands_for = "goose" -core_version = "7.0.0-pre1" +core_version = "7.0.0" -version = "1.18.0-pre1" +version = "1.18.0" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 92c6c5288c5..a6e9f948753 100644 --- a/build.yaml +++ b/build.yaml @@ -12,9 +12,9 @@ settings: '#08': Use "-preN" suffixes to identify pre-release versions '#09': Per-language overrides are possible with (eg) ruby_version tag here '#10': See the expand_version.py for all the quirks here - core_version: 7.0.0-pre1 + core_version: 7.0.0 g_stands_for: goose - version: 1.18.0-pre1 + version: 1.18.0 filegroups: - name: alts_proto headers: From ad54166f92b64e4008c8059825a158874a4b111d Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Mon, 14 Jan 2019 11:17:29 -0800 Subject: [PATCH 054/814] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 6 +++--- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 2 +- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 4 ++-- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- tools/doxygen/Doxyfile.core | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- 33 files changed, 41 insertions(+), 41 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b267c429a2..e1013dc561a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.18.0-pre1") +set(PACKAGE_VERSION "1.18.0") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index e7d50ece9ee..7ed6a6a85f0 100644 --- a/Makefile +++ b/Makefile @@ -437,9 +437,9 @@ E = @echo Q = @ endif -CORE_VERSION = 7.0.0-pre1 -CPP_VERSION = 1.18.0-pre1 -CSHARP_VERSION = 1.18.0-pre1 +CORE_VERSION = 7.0.0 +CPP_VERSION = 1.18.0 +CSHARP_VERSION = 1.18.0 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 0bda8be0a62..0257f4713e8 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.18.0-pre1' - version = '0.0.6-pre1' + # version = '1.18.0' + version = '0.0.6' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.18.0-pre1' + grpc_version = '1.18.0' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 41788797a96..d3bb0c093cb 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.18.0-pre1' + version = '1.18.0' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index b6959a7e207..67c28d5f941 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.18.0-pre1' + version = '1.18.0' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 3586071addb..902297d4f26 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.18.0-pre1' + version = '1.18.0' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 2f112bda5e3..16e0c55c49f 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.18.0-pre1' + version = '1.18.0' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index cb12d18d4a4..dafbc92c95d 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.18.0RC1 - 1.18.0RC1 + 1.18.0 + 1.18.0 - beta - beta + stable + stable Apache 2.0 diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 4eca622c036..fac938992d3 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -23,6 +23,6 @@ #include -const char* grpc_version_string(void) { return "7.0.0-pre1"; } +const char* grpc_version_string(void) { return "7.0.0"; } const char* grpc_g_stands_for(void) { return "goose"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 541d4ca19b5..768b0c6c932 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.18.0-pre1"; } +grpc::string Version() { return "1.18.0"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 8ac9ed862db..9ee28509007 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.18.0-pre1 + 1.18.0 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index edccd7f89e4..e5e8e45088b 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.18.0-pre1"; + public const string CurrentVersion = "1.18.0"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 13e1a312ccf..0e6b21b4580 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.18.0-pre1 +set VERSION=1.18.0 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index da41672848f..ef4969ada28 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.18.0-pre1 +set VERSION=1.18.0 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 2ae8c6021f9..3e2e023abf7 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.18.0-pre1' + v = '1.18.0' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 15eafe09abc..c92f18ba6d9 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.18.0-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.18.0" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 78de7fb21de..28c243cd4fd 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.18.0-pre1" -#define GRPC_C_VERSION_STRING @"7.0.0-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.18.0" +#define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 5117bd99393..9536d035b14 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.18.0RC1" +#define PHP_GRPC_VERSION "1.18.0" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 1827b52279d..f07fb395b75 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.18.0rc1""" +__version__ = """1.18.0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 3eac8b93b51..b190a7b794f 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.18.0rc1' +VERSION = '1.18.0' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 303afb98d28..346f00c6978 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.18.0rc1' +VERSION = '1.18.0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 4f047a77d53..3bc78218178 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.18.0rc1' +VERSION = '1.18.0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 3d89a4bcbd2..dddef02f214 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.18.0rc1' +VERSION = '1.18.0' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 394f9cefb1f..c6310c0e2b5 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.18.0rc1' +VERSION = '1.18.0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 5eb2dd27f5b..d52e4f1015e 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.18.0rc1' +VERSION = '1.18.0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 4dc0d03ad7c..b2cc9c0fe1d 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.18.0rc1' +VERSION = '1.18.0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index f378961cca9..78bc3d3c0a4 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.18.0.pre1' + VERSION = '1.18.0' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 692e26d31eb..a80ab84d981 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.18.0.pre1' + VERSION = '1.18.0' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index b282cdad7c3..03827a4e99d 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.18.0rc1' +VERSION = '1.18.0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index ce27ed540c2..ba5fbb58ce5 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.18.0-pre1 +PROJECT_NUMBER = 1.18.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 4fa3da89715..e6657ea4c16 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.18.0-pre1 +PROJECT_NUMBER = 1.18.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 545783d12d4..7235c7b1539 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 7.0.0-pre1 +PROJECT_NUMBER = 7.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 2cec7dab5b5..ca61471cc81 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 7.0.0-pre1 +PROJECT_NUMBER = 7.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 919f9f76b30bd77bdd0be7635ecafb01e7d48cd7 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 14 Jan 2019 11:50:18 -0800 Subject: [PATCH 055/814] attempt to disable PTREACE for ASAN --- tools/remote_build/rbe_common.bazelrc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 8cf17a30860..c4928fb83a7 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -1,3 +1,4 @@ +#@IgnoreInspection BashAddShebang # Copyright 2018 The gRPC Authors # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,6 +50,12 @@ build:asan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:asan --test_timeout=3600 build:asan --test_tag_filters=-qps_json_driver +build:asan --host_platform_remote_properties_override=''' + properties: { + name: "dockerDropCapabilities" + value: "" + } +''' # memory sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific From c27db3ed0c7964c28e537709ff4847b8eabc69b0 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 21 Dec 2018 14:43:35 -0800 Subject: [PATCH 056/814] Fix windows thd, I think --- src/core/lib/gprpp/thd_windows.cc | 78 +++++++++++++++++++------------ 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index 71584fd358e..703da74e051 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -48,6 +48,7 @@ struct thd_info { void (*body)(void* arg); /* body of a thread */ void* arg; /* argument to a thread */ HANDLE join_event; /* the join event */ + bool joinable; /* whether it is joinable */ }; thread_local struct thd_info* g_thd_info; @@ -55,7 +56,8 @@ thread_local struct thd_info* g_thd_info; class ThreadInternalsWindows : public grpc_core::internal::ThreadInternalsInterface { public: - ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success) + ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success, + const grpc_core::Thread::Options& options) : started_(false) { gpr_mu_init(&mu_); gpr_cv_init(&ready_); @@ -65,35 +67,46 @@ class ThreadInternalsWindows info_->thread = this; info_->body = thd_body; info_->arg = arg; - - info_->join_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (info_->join_event == nullptr) { - gpr_free(info_); + info_->join_event = nullptr; + info_->joinable = options.joinable(); + if (info_->joinable) { + info_->join_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + if (info_->join_event == nullptr) { + gpr_free(info_); + *success = false; + return; + } + } + handle = CreateThread(nullptr, 64 * 1024, + [](void* v) WIN_LAMBDA -> DWORD { + g_thd_info = static_cast(v); + gpr_mu_lock(&g_thd_info->thread->mu_); + while (!g_thd_info->thread->started_) { + gpr_cv_wait(&g_thd_info->thread->ready_, + &g_thd_info->thread->mu_, + gpr_inf_future(GPR_CLOCK_MONOTONIC)); + } + gpr_mu_unlock(&g_thd_info->thread->mu_); + if (!g_thd_info->joinable) { + grpc_core::Delete(g_thd_info->thread); + g_thd_info->thread = nullptr; + } + g_thd_info->body(g_thd_info->arg); + if (g_thd_info->joinable) { + BOOL ret = SetEvent(g_thd_info->join_event); + GPR_ASSERT(ret); + } else { + gpr_free(g_thd_info); + } + return 0; + }, + info_, 0, nullptr); + if (handle == nullptr) { + destroy_thread(); *success = false; } else { - handle = CreateThread( - nullptr, 64 * 1024, - [](void* v) WIN_LAMBDA -> DWORD { - g_thd_info = static_cast(v); - gpr_mu_lock(&g_thd_info->thread->mu_); - while (!g_thd_info->thread->started_) { - gpr_cv_wait(&g_thd_info->thread->ready_, &g_thd_info->thread->mu_, - gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - gpr_mu_unlock(&g_thd_info->thread->mu_); - g_thd_info->body(g_thd_info->arg); - BOOL ret = SetEvent(g_thd_info->join_event); - GPR_ASSERT(ret); - return 0; - }, - info_, 0, nullptr); - if (handle == nullptr) { - destroy_thread(); - *success = false; - } else { - CloseHandle(handle); - *success = true; - } + CloseHandle(handle); + *success = true; } } @@ -117,7 +130,9 @@ class ThreadInternalsWindows private: void destroy_thread() { - CloseHandle(info_->join_event); + if (info_ != nullptr && info_->joinable) { + CloseHandle(info_->join_event); + } gpr_free(info_); } @@ -132,9 +147,10 @@ class ThreadInternalsWindows namespace grpc_core { Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success) { + bool* success, const Options& options) : options_(options) { bool outcome = false; - impl_ = grpc_core::New(thd_body, arg, &outcome); + impl_ = + grpc_core::New(thd_body, arg, &outcome, options); if (outcome) { state_ = ALIVE; } else { From f47e2057765d8a857647f20d8f23dd6816c2909e Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 14 Jan 2019 15:07:07 -0800 Subject: [PATCH 057/814] removed ptrace --- third_party/toolchains/BUILD | 8 -------- 1 file changed, 8 deletions(-) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 5c95f02a65f..04fd795b566 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -52,10 +52,6 @@ platform( name: "dockerSiblingContainers" value: "false" } - properties: { - name: "dockerDropCapabilities" - value: "SYS_PTRACE" - } properties: { name: "dockerNetwork" value: "off" @@ -87,10 +83,6 @@ platform( name: "dockerSiblingContainers" value: "false" } - properties: { - name: "dockerDropCapabilities" - value: "SYS_PTRACE" - } properties: { name: "dockerNetwork" value: "off" From 8ce2783b4bc6d4507232362430554c6462790ce6 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Tue, 15 Jan 2019 11:30:32 -0500 Subject: [PATCH 058/814] Correct a format string Use a format string macro from inttypes.h when printfing thread IDs on non-Windows, non-Linux platforms. This silences a -Wformat trigger when cross-compiling for macOS. --- src/core/lib/gpr/log_posix.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/gpr/log_posix.cc b/src/core/lib/gpr/log_posix.cc index 0acb2255724..b6edc14ab6b 100644 --- a/src/core/lib/gpr/log_posix.cc +++ b/src/core/lib/gpr/log_posix.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -83,7 +84,7 @@ void gpr_default_log(gpr_log_func_args* args) { } char* prefix; - gpr_asprintf(&prefix, "%s%s.%09d %7tu %s:%d]", + gpr_asprintf(&prefix, "%s%s.%09d %7" PRIdPTR " %s:%d]", gpr_log_severity_string(args->severity), time_buffer, (int)(now.tv_nsec), gettid(), display_file, args->line); From 08f94b16238503d252b33b1208b2b2873dca712a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 15 Jan 2019 08:32:18 -0800 Subject: [PATCH 059/814] Clean up test. --- test/cpp/end2end/client_lb_end2end_test.cc | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 4a6307a22ca..d52f16d8f20 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -35,26 +35,17 @@ #include #include -#include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/channelz.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" -#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/core/lib/transport/connectivity_state.h" -#include "src/core/lib/transport/static_metadata.h" -#include "src/core/lib/transport/status_metadata.h" #include "src/cpp/client/secure_credentials.h" #include "src/cpp/server/secure_server_credentials.h" @@ -1260,23 +1251,20 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { int trailers_intercepted_ = 0; }; -TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) { +TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetries) { const int kNumServers = 1; + const int kNumRpcs = 10; StartServers(kNumServers); auto channel = BuildChannel("intercept_trailing_metadata_lb"); auto stub = BuildStub(channel); - std::vector ports; - for (size_t i = 0; i < servers_.size(); ++i) { - ports.emplace_back(servers_[i]->port_); - } - SetNextResolution(ports); - for (size_t i = 0; i < servers_.size(); ++i) { + SetNextResolution(GetServersPorts()); + for (size_t i = 0; i < kNumRpcs; ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); } // Check LB policy name for the channel. EXPECT_EQ("intercept_trailing_metadata_lb", channel->GetLoadBalancingPolicyName()); - EXPECT_EQ(kNumServers, trailers_intercepted()); + EXPECT_EQ(kNumRpcs, trailers_intercepted()); } } // namespace From 206a76b332dbc0c1e2127e03857831225003f092 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 15 Jan 2019 10:04:00 -0800 Subject: [PATCH 060/814] Upgrade Bazel to 21.0 --- tools/dockerfile/test/bazel/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index 0aa6209f4fd..05c187894cc 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -46,7 +46,7 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Bazel installation RUN apt-get update && apt-get install -y wget && apt-get clean -RUN wget -q https://github.com/bazelbuild/bazel/releases/download/0.17.1/bazel-0.17.1-linux-x86_64 -O /usr/local/bin/bazel +RUN wget -q https://github.com/bazelbuild/bazel/releases/download/0.21.0/bazel-0.21.0-linux-x86_64 -O /usr/local/bin/bazel RUN chmod 755 /usr/local/bin/bazel From b3c0b91db18d81ddff973f2f640619819d47672d Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 15 Jan 2019 10:47:35 -0800 Subject: [PATCH 061/814] Remove force_creation param from subchannel index --- .../client_channel/subchannel_index.cc | 8 ------ .../filters/client_channel/subchannel_index.h | 9 ------- test/cpp/end2end/client_lb_end2end_test.cc | 26 +++---------------- 3 files changed, 3 insertions(+), 40 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc index d0ceda8312c..1c839ddd6a3 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ b/src/core/ext/filters/client_channel/subchannel_index.cc @@ -42,8 +42,6 @@ struct grpc_subchannel_key { grpc_channel_args* args; }; -static bool g_force_creation = false; - static grpc_subchannel_key* create_key( const grpc_channel_args* args, grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)) { @@ -63,8 +61,6 @@ static grpc_subchannel_key* subchannel_key_copy(grpc_subchannel_key* k) { int grpc_subchannel_key_compare(const grpc_subchannel_key* a, const grpc_subchannel_key* b) { - // To pretend the keys are different, return a non-zero value. - if (GPR_UNLIKELY(g_force_creation)) return 1; return grpc_channel_args_compare(a->args, b->args); } @@ -224,7 +220,3 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key, grpc_avl_unref(index, nullptr); } } - -void grpc_subchannel_index_test_only_set_force_creation(bool force_creation) { - g_force_creation = force_creation; -} diff --git a/src/core/ext/filters/client_channel/subchannel_index.h b/src/core/ext/filters/client_channel/subchannel_index.h index 429634bd54c..1aeb51e6535 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.h +++ b/src/core/ext/filters/client_channel/subchannel_index.h @@ -63,13 +63,4 @@ void grpc_subchannel_index_ref(void); to zero, unref the subchannel index and destroy its mutex. */ void grpc_subchannel_index_unref(void); -/** \em TEST ONLY. - * If \a force_creation is true, all keys are regarded different, resulting in - * new subchannels always being created. Otherwise, the keys will be compared as - * usual. - * - * Tests using this function \em MUST run tests with and without \a - * force_creation set. */ -void grpc_subchannel_index_test_only_set_force_creation(bool force_creation); - #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H */ diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 929c2bb5899..9783f51ab7d 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -38,7 +38,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" @@ -662,30 +661,14 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } -class ClientLbEnd2endWithParamTest - : public ClientLbEnd2endTest, - public ::testing::WithParamInterface { - protected: - void SetUp() override { - grpc_subchannel_index_test_only_set_force_creation(GetParam()); - ClientLbEnd2endTest::SetUp(); - } - - void TearDown() override { - ClientLbEnd2endTest::TearDown(); - grpc_subchannel_index_test_only_set_force_creation(false); - } -}; - -TEST_P(ClientLbEnd2endWithParamTest, PickFirstManyUpdates) { - gpr_log(GPR_INFO, "subchannel force creation: %d", GetParam()); - // Start servers and send one RPC per server. +TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { + const int kNumUpdates = 1000; const int kNumServers = 3; StartServers(kNumServers); auto channel = BuildChannel("pick_first"); auto stub = BuildStub(channel); std::vector ports = GetServersPorts(); - for (size_t i = 0; i < 1000; ++i) { + for (size_t i = 0; i < kNumUpdates; ++i) { std::shuffle(ports.begin(), ports.end(), std::mt19937(std::random_device()())); SetNextResolution(ports); @@ -697,9 +680,6 @@ TEST_P(ClientLbEnd2endWithParamTest, PickFirstManyUpdates) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } -INSTANTIATE_TEST_CASE_P(SubchannelForceCreation, ClientLbEnd2endWithParamTest, - ::testing::Bool()); - TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { // Prepare the ports for up servers and down servers. const int kNumServers = 3; From bf273ff00f6b955ecd1f2e9f64f0c2907d358840 Mon Sep 17 00:00:00 2001 From: "Penn (Dapeng) Zhang" Date: Tue, 15 Jan 2019 11:01:03 -0800 Subject: [PATCH 062/814] Add grpc-java 1.18.0 to interop matrix release note: no --- tools/interop_matrix/client_matrix.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 655c7c7b6bf..318e1da00f0 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -139,6 +139,7 @@ LANG_RELEASE_MATRIX = { ('v1.15.0', ReleaseInfo()), ('v1.16.1', ReleaseInfo()), ('v1.17.1', ReleaseInfo()), + ('v1.18.0', ReleaseInfo()), ]), 'python': OrderedDict([ From 30a95d354c045d7e0127ad18857b099117330683 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 15 Jan 2019 13:04:34 -0800 Subject: [PATCH 063/814] rename census context hooks --- src/python/grpcio/grpc/_channel.py | 8 ++++---- src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi | 4 ++-- src/python/grpcio/grpc/_server.py | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 3685969c7fe..f7da028e3a7 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -499,7 +499,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer - self._context = cygrpc.build_context() + self._context = cygrpc.build_census_context() def _prepare(self, request, timeout, metadata, wait_for_ready): deadline, serialized_request, rendezvous = _start_unary_request( @@ -590,7 +590,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer - self._context = cygrpc.build_context() + self._context = cygrpc.build_census_context() def __call__(self, request, @@ -637,7 +637,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer - self._context = cygrpc.build_context() + self._context = cygrpc.build_census_context() def _blocking(self, request_iterator, timeout, metadata, credentials, wait_for_ready): @@ -714,7 +714,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): self._method = method self._request_serializer = request_serializer self._response_deserializer = response_deserializer - self._context = cygrpc.build_context() + self._context = cygrpc.build_census_context() def __call__(self, request_iterator, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi index cd4a51a635e..6d1c36b2b35 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi @@ -16,13 +16,13 @@ cdef object _custom_op_on_c_call(int op, grpc_call *call): raise NotImplementedError("No custom hooks are implemented") -def install_census_context_from_call(Call call): +def install_context_from_call(Call call): pass def uninstall_context(): pass -def build_context(): +def build_census_context(): pass cdef class CensusContext: diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index c3ff1fa6bd3..5cdd58ec954 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -484,7 +484,7 @@ def _status(rpc_event, state, serialized_response): def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - cygrpc.install_census_context_from_call(rpc_event.call) + cygrpc.install_context_from_call(rpc_event.call) try: argument = argument_thunk() if argument is not None: @@ -501,7 +501,7 @@ def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - cygrpc.install_census_context_from_call(rpc_event.call) + cygrpc.install_context_from_call(rpc_event.call) try: argument = argument_thunk() if argument is not None: From f821b384d9df63ba18f31ffa5953829854327bad Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 15 Jan 2019 13:26:28 -0800 Subject: [PATCH 064/814] The error description should be the error string --- src/core/lib/iomgr/error.cc | 2 +- src/core/lib/iomgr/resolve_address_posix.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index 6ae077fd548..59236b20c59 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -765,7 +765,7 @@ grpc_error* grpc_os_error(const char* file, int line, int err, grpc_error_set_str( grpc_error_set_int( grpc_error_create(file, line, - grpc_slice_from_static_string("OS Error"), + grpc_slice_from_static_string(strerror(err)), nullptr, 0), GRPC_ERROR_INT_ERRNO, err), GRPC_ERROR_STR_OS_ERROR, diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc index c285d7eca66..2a03244ff7d 100644 --- a/src/core/lib/iomgr/resolve_address_posix.cc +++ b/src/core/lib/iomgr/resolve_address_posix.cc @@ -105,7 +105,7 @@ static grpc_error* posix_blocking_resolve_address( grpc_error_set_str( grpc_error_set_str( grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("OS Error"), + GRPC_ERROR_CREATE_FROM_STATIC_STRING(gai_strerror(s)), GRPC_ERROR_INT_ERRNO, s), GRPC_ERROR_STR_OS_ERROR, grpc_slice_from_static_string(gai_strerror(s))), From bbe2587c39d60709358842f49aa46f91cc577ef7 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 15 Jan 2019 13:59:59 -0800 Subject: [PATCH 065/814] Enable per-channel subchannel pool --- BUILD | 8 +- CMakeLists.txt | 24 ++- Makefile | 24 ++- build.yaml | 8 +- config.m4 | 4 +- config.w32 | 4 +- gRPC-C++.podspec | 4 +- gRPC-Core.podspec | 12 +- grpc.gemspec | 8 +- grpc.gyp | 16 +- include/grpc/impl/codegen/grpc_types.h | 3 + package.xml | 8 +- .../client_channel/client_channel_plugin.cc | 6 +- .../client_channel/global_subchannel_pool.cc | 177 ++++++++++++++++++ .../client_channel/global_subchannel_pool.h | 68 +++++++ .../ext/filters/client_channel/lb_policy.cc | 2 + .../ext/filters/client_channel/lb_policy.h | 11 ++ .../client_channel/lb_policy/grpclb/grpclb.cc | 4 +- .../lb_policy/pick_first/pick_first.cc | 3 - .../lb_policy/round_robin/round_robin.cc | 3 - .../lb_policy/subchannel_list.h | 5 +- .../client_channel/lb_policy/xds/xds.cc | 4 +- .../client_channel/local_subchannel_pool.cc | 96 ++++++++++ .../client_channel/local_subchannel_pool.h | 56 ++++++ .../filters/client_channel/request_routing.cc | 16 +- .../filters/client_channel/request_routing.h | 6 +- .../ext/filters/client_channel/subchannel.cc | 44 +++-- .../ext/filters/client_channel/subchannel.h | 6 +- .../subchannel_pool_interface.cc | 97 ++++++++++ .../subchannel_pool_interface.h | 94 ++++++++++ src/python/grpcio/grpc_core_dependencies.py | 4 +- test/cpp/end2end/client_lb_end2end_test.cc | 63 +++++++ test/cpp/end2end/grpclb_end2end_test.cc | 3 +- tools/doxygen/Doxyfile.core.internal | 8 +- .../generated/sources_and_headers.json | 12 +- 35 files changed, 832 insertions(+), 79 deletions(-) create mode 100644 src/core/ext/filters/client_channel/global_subchannel_pool.cc create mode 100644 src/core/ext/filters/client_channel/global_subchannel_pool.h create mode 100644 src/core/ext/filters/client_channel/local_subchannel_pool.cc create mode 100644 src/core/ext/filters/client_channel/local_subchannel_pool.h create mode 100644 src/core/ext/filters/client_channel/subchannel_pool_interface.cc create mode 100644 src/core/ext/filters/client_channel/subchannel_pool_interface.h diff --git a/BUILD b/BUILD index 5f53bbc6f0b..03dc449cb02 100644 --- a/BUILD +++ b/BUILD @@ -1049,11 +1049,13 @@ grpc_cc_library( "src/core/ext/filters/client_channel/client_channel_factory.cc", "src/core/ext/filters/client_channel/client_channel_plugin.cc", "src/core/ext/filters/client_channel/connector.cc", + "src/core/ext/filters/client_channel/global_subchannel_pool.cc", "src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_proxy.cc", "src/core/ext/filters/client_channel/lb_policy.cc", "src/core/ext/filters/client_channel/lb_policy_registry.cc", + "src/core/ext/filters/client_channel/local_subchannel_pool.cc", "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/proxy_mapper.cc", "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", @@ -1064,7 +1066,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/server_address.cc", "src/core/ext/filters/client_channel/subchannel.cc", - "src/core/ext/filters/client_channel/subchannel_index.cc", + "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", ], hdrs = [ "src/core/ext/filters/client_channel/backup_poller.h", @@ -1072,12 +1074,14 @@ grpc_cc_library( "src/core/ext/filters/client_channel/client_channel_channelz.h", "src/core/ext/filters/client_channel/client_channel_factory.h", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", "src/core/ext/filters/client_channel/lb_policy_factory.h", "src/core/ext/filters/client_channel/lb_policy_registry.h", + "src/core/ext/filters/client_channel/local_subchannel_pool.h", "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", @@ -1089,7 +1093,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", - "src/core/ext/filters/client_channel/subchannel_index.h", + "src/core/ext/filters/client_channel/subchannel_pool_interface.h", ], language = "c++", deps = [ diff --git a/CMakeLists.txt b/CMakeLists.txt index 13d5aca6584..bb1caaaf565 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1212,11 +1212,13 @@ add_library(grpc src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -1227,7 +1229,7 @@ add_library(grpc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c src/core/tsi/fake_transport_security.cc @@ -1566,11 +1568,13 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -1581,7 +1585,7 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -1941,11 +1945,13 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -1956,7 +1962,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -2264,11 +2270,13 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -2279,7 +2287,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -2599,11 +2607,13 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -2614,7 +2624,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -3455,11 +3465,13 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy_registry.cc + src/core/ext/filters/client_channel/local_subchannel_pool.cc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -3470,7 +3482,7 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_index.cc + src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc diff --git a/Makefile b/Makefile index 00186d891c6..1a64c9e9683 100644 --- a/Makefile +++ b/Makefile @@ -3729,11 +3729,13 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -3744,7 +3746,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/fake_transport_security.cc \ @@ -4077,11 +4079,13 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -4092,7 +4096,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -4445,11 +4449,13 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -4460,7 +4466,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -4755,11 +4761,13 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -4770,7 +4778,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -5064,11 +5072,13 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -5079,7 +5089,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -5897,11 +5907,13 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -5912,7 +5924,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc \ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc \ diff --git a/build.yaml b/build.yaml index c7b4d751731..8f310e0e59d 100644 --- a/build.yaml +++ b/build.yaml @@ -576,12 +576,14 @@ filegroups: - src/core/ext/filters/client_channel/client_channel_channelz.h - src/core/ext/filters/client_channel/client_channel_factory.h - src/core/ext/filters/client_channel/connector.h + - src/core/ext/filters/client_channel/global_subchannel_pool.h - src/core/ext/filters/client_channel/health/health_check_client.h - src/core/ext/filters/client_channel/http_connect_handshaker.h - src/core/ext/filters/client_channel/http_proxy.h - src/core/ext/filters/client_channel/lb_policy.h - src/core/ext/filters/client_channel/lb_policy_factory.h - src/core/ext/filters/client_channel/lb_policy_registry.h + - src/core/ext/filters/client_channel/local_subchannel_pool.h - src/core/ext/filters/client_channel/parse_address.h - src/core/ext/filters/client_channel/proxy_mapper.h - src/core/ext/filters/client_channel/proxy_mapper_registry.h @@ -593,7 +595,7 @@ filegroups: - src/core/ext/filters/client_channel/retry_throttle.h - src/core/ext/filters/client_channel/server_address.h - src/core/ext/filters/client_channel/subchannel.h - - src/core/ext/filters/client_channel/subchannel_index.h + - src/core/ext/filters/client_channel/subchannel_pool_interface.h src: - src/core/ext/filters/client_channel/backup_poller.cc - src/core/ext/filters/client_channel/channel_connectivity.cc @@ -602,11 +604,13 @@ filegroups: - src/core/ext/filters/client_channel/client_channel_factory.cc - src/core/ext/filters/client_channel/client_channel_plugin.cc - src/core/ext/filters/client_channel/connector.cc + - src/core/ext/filters/client_channel/global_subchannel_pool.cc - src/core/ext/filters/client_channel/health/health_check_client.cc - src/core/ext/filters/client_channel/http_connect_handshaker.cc - src/core/ext/filters/client_channel/http_proxy.cc - src/core/ext/filters/client_channel/lb_policy.cc - src/core/ext/filters/client_channel/lb_policy_registry.cc + - src/core/ext/filters/client_channel/local_subchannel_pool.cc - src/core/ext/filters/client_channel/parse_address.cc - src/core/ext/filters/client_channel/proxy_mapper.cc - src/core/ext/filters/client_channel/proxy_mapper_registry.cc @@ -617,7 +621,7 @@ filegroups: - src/core/ext/filters/client_channel/retry_throttle.cc - src/core/ext/filters/client_channel/server_address.cc - src/core/ext/filters/client_channel/subchannel.cc - - src/core/ext/filters/client_channel/subchannel_index.cc + - src/core/ext/filters/client_channel/subchannel_pool_interface.cc plugin: grpc_client_channel uses: - grpc_base diff --git a/config.m4 b/config.m4 index ccb218a1200..46597e6f0e3 100644 --- a/config.m4 +++ b/config.m4 @@ -345,11 +345,13 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ + src/core/ext/filters/client_channel/local_subchannel_pool.cc \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ @@ -360,7 +362,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ - src/core/ext/filters/client_channel/subchannel_index.cc \ + src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/fake_transport_security.cc \ diff --git a/config.w32 b/config.w32 index fd48ec6f485..00b92e88a05 100644 --- a/config.w32 +++ b/config.w32 @@ -320,11 +320,13 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\client_channel_factory.cc " + "src\\core\\ext\\filters\\client_channel\\client_channel_plugin.cc " + "src\\core\\ext\\filters\\client_channel\\connector.cc " + + "src\\core\\ext\\filters\\client_channel\\global_subchannel_pool.cc " + "src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " + "src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " + "src\\core\\ext\\filters\\client_channel\\http_proxy.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " + + "src\\core\\ext\\filters\\client_channel\\local_subchannel_pool.cc " + "src\\core\\ext\\filters\\client_channel\\parse_address.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " + @@ -335,7 +337,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " + "src\\core\\ext\\filters\\client_channel\\server_address.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel.cc " + - "src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " + + "src\\core\\ext\\filters\\client_channel\\subchannel_pool_interface.cc " + "src\\core\\ext\\filters\\deadline\\deadline_filter.cc " + "src\\core\\ext\\filters\\client_channel\\health\\health.pb.c " + "src\\core\\tsi\\fake_transport_security.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index bf124304487..481892b63c7 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -346,12 +346,14 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', 'src/core/ext/filters/client_channel/lb_policy_factory.h', 'src/core/ext/filters/client_channel/lb_policy_registry.h', + 'src/core/ext/filters/client_channel/local_subchannel_pool.h', 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', @@ -363,7 +365,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', - 'src/core/ext/filters/client_channel/subchannel_index.h', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 60f34ebd6a2..5bb6a514bb9 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -340,12 +340,14 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', 'src/core/ext/filters/client_channel/lb_policy_factory.h', 'src/core/ext/filters/client_channel/lb_policy_registry.h', + 'src/core/ext/filters/client_channel/local_subchannel_pool.h', 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', @@ -357,7 +359,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', - 'src/core/ext/filters/client_channel/subchannel_index.h', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', @@ -785,11 +787,13 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -800,7 +804,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', @@ -964,12 +968,14 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', 'src/core/ext/filters/client_channel/lb_policy_factory.h', 'src/core/ext/filters/client_channel/lb_policy_registry.h', + 'src/core/ext/filters/client_channel/local_subchannel_pool.h', 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', @@ -981,7 +987,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', - 'src/core/ext/filters/client_channel/subchannel_index.h', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', diff --git a/grpc.gemspec b/grpc.gemspec index 60c5bc480b6..5e5eb65ed2f 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -276,12 +276,14 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/client_channel_channelz.h ) s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h ) s.files += %w( src/core/ext/filters/client_channel/connector.h ) + s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.h ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.h ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.h ) + s.files += %w( src/core/ext/filters/client_channel/local_subchannel_pool.h ) s.files += %w( src/core/ext/filters/client_channel/parse_address.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h ) @@ -293,7 +295,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h ) s.files += %w( src/core/ext/filters/client_channel/server_address.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel.h ) - s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h ) + s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.h ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.h ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.h ) s.files += %w( src/core/tsi/fake_transport_security.h ) @@ -724,11 +726,13 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.cc ) s.files += %w( src/core/ext/filters/client_channel/client_channel_plugin.cc ) s.files += %w( src/core/ext/filters/client_channel/connector.cc ) + s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.cc ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.cc ) + s.files += %w( src/core/ext/filters/client_channel/local_subchannel_pool.cc ) s.files += %w( src/core/ext/filters/client_channel/parse_address.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.cc ) @@ -739,7 +743,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc ) s.files += %w( src/core/ext/filters/client_channel/server_address.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel.cc ) - s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc ) + s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.cc ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.c ) s.files += %w( src/core/tsi/fake_transport_security.cc ) diff --git a/grpc.gyp b/grpc.gyp index 1f5b6384975..060af57efff 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -527,11 +527,13 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -542,7 +544,7 @@ 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', @@ -789,11 +791,13 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -804,7 +808,7 @@ 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', @@ -1032,11 +1036,13 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -1047,7 +1053,7 @@ 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', @@ -1287,11 +1293,13 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -1302,7 +1310,7 @@ 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 5d577eb8557..f9929186d58 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -355,6 +355,9 @@ typedef struct { * is 10000. Setting this to "0" will disable c-ares query timeouts * entirely. */ #define GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS "grpc.dns_ares_query_timeout" +/** If set, uses a local subchannel pool within the channel. Otherwise, uses the + * global subchannel pool. */ +#define GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL "grpc.use_local_subchannel_pool" /** gRPC Objective-C channel pooling domain string. */ #define GRPC_ARG_CHANNEL_POOL_DOMAIN "grpc.channel_pooling_domain" /** gRPC Objective-C channel pooling id. */ diff --git a/package.xml b/package.xml index 81a4aabdf5a..523f78f1db6 100644 --- a/package.xml +++ b/package.xml @@ -281,12 +281,14 @@ + + @@ -298,7 +300,7 @@ - + @@ -729,11 +731,13 @@ + + @@ -744,7 +748,7 @@ - + diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index e0784b7e5c1..2031ab449f5 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -26,13 +26,13 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/http_proxy.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/surface/channel_init.h" static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { @@ -54,7 +54,7 @@ void grpc_client_channel_init(void) { grpc_core::internal::ServerRetryThrottleMap::Init(); grpc_proxy_mapper_registry_init(); grpc_register_http_proxy_mapper(); - grpc_subchannel_index_init(); + grpc_core::GlobalSubchannelPool::Init(); grpc_channel_init_register_stage( GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, append_filter, (void*)&grpc_client_channel_filter); @@ -62,7 +62,7 @@ void grpc_client_channel_init(void) { } void grpc_client_channel_shutdown(void) { - grpc_subchannel_index_shutdown(); + grpc_core::GlobalSubchannelPool::Shutdown(); grpc_channel_init_shutdown(); grpc_proxy_mapper_registry_shutdown(); grpc_core::internal::ServerRetryThrottleMap::Shutdown(); diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.cc b/src/core/ext/filters/client_channel/global_subchannel_pool.cc new file mode 100644 index 00000000000..a41d993fe66 --- /dev/null +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.cc @@ -0,0 +1,177 @@ +// +// +// Copyright 2018 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// + +#include + +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" + +#include "src/core/ext/filters/client_channel/subchannel.h" + +namespace grpc_core { + +GlobalSubchannelPool::GlobalSubchannelPool() { + subchannel_map_ = grpc_avl_create(&subchannel_avl_vtable_); + gpr_mu_init(&mu_); +} + +GlobalSubchannelPool::~GlobalSubchannelPool() { + gpr_mu_destroy(&mu_); + grpc_avl_unref(subchannel_map_, nullptr); +} + +void GlobalSubchannelPool::Init() { + instance_ = New>( + MakeRefCounted()); +} + +void GlobalSubchannelPool::Shutdown() { + // To ensure Init() was called before. + GPR_ASSERT(instance_ != nullptr); + // To ensure Shutdown() was not called before. + GPR_ASSERT(*instance_ != nullptr); + instance_->reset(); + Delete(instance_); +} + +RefCountedPtr GlobalSubchannelPool::instance() { + GPR_ASSERT(instance_ != nullptr); + GPR_ASSERT(*instance_ != nullptr); + return *instance_; +} + +grpc_subchannel* GlobalSubchannelPool::RegisterSubchannel( + SubchannelKey* key, grpc_subchannel* constructed) { + grpc_subchannel* c = nullptr; + // Compare and swap (CAS) loop: + while (c == nullptr) { + // Ref the shared map to have a local copy. + gpr_mu_lock(&mu_); + grpc_avl old_map = grpc_avl_ref(subchannel_map_, nullptr); + gpr_mu_unlock(&mu_); + // Check to see if a subchannel already exists. + c = static_cast(grpc_avl_get(old_map, key, nullptr)); + if (c != nullptr) { + // The subchannel already exists. Reuse it. + c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "subchannel_register+reuse"); + GRPC_SUBCHANNEL_UNREF(constructed, "subchannel_register+found_existing"); + // Exit the CAS loop without modifying the shared map. + } else { + // There hasn't been such subchannel. Add one. + // Note that we should ref the old map first because grpc_avl_add() will + // unref it while we still need to access it later. + grpc_avl new_map = grpc_avl_add( + grpc_avl_ref(old_map, nullptr), New(*key), + GRPC_SUBCHANNEL_WEAK_REF(constructed, "subchannel_register+new"), + nullptr); + // Try to publish the change to the shared map. It may happen (but + // unlikely) that some other thread has changed the shared map, so compare + // to make sure it's unchanged before swapping. Retry if it's changed. + gpr_mu_lock(&mu_); + if (old_map.root == subchannel_map_.root) { + GPR_SWAP(grpc_avl, new_map, subchannel_map_); + c = constructed; + } + gpr_mu_unlock(&mu_); + grpc_avl_unref(new_map, nullptr); + } + grpc_avl_unref(old_map, nullptr); + } + return c; +} + +void GlobalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { + bool done = false; + // Compare and swap (CAS) loop: + while (!done) { + // Ref the shared map to have a local copy. + gpr_mu_lock(&mu_); + grpc_avl old_map = grpc_avl_ref(subchannel_map_, nullptr); + gpr_mu_unlock(&mu_); + // Remove the subchannel. + // Note that we should ref the old map first because grpc_avl_remove() will + // unref it while we still need to access it later. + grpc_avl new_map = + grpc_avl_remove(grpc_avl_ref(old_map, nullptr), key, nullptr); + // Try to publish the change to the shared map. It may happen (but + // unlikely) that some other thread has changed the shared map, so compare + // to make sure it's unchanged before swapping. Retry if it's changed. + gpr_mu_lock(&mu_); + if (old_map.root == subchannel_map_.root) { + GPR_SWAP(grpc_avl, new_map, subchannel_map_); + done = true; + } + gpr_mu_unlock(&mu_); + grpc_avl_unref(new_map, nullptr); + grpc_avl_unref(old_map, nullptr); + } +} + +grpc_subchannel* GlobalSubchannelPool::FindSubchannel(SubchannelKey* key) { + // Lock, and take a reference to the subchannel map. + // We don't need to do the search under a lock as AVL's are immutable. + gpr_mu_lock(&mu_); + grpc_avl index = grpc_avl_ref(subchannel_map_, nullptr); + gpr_mu_unlock(&mu_); + grpc_subchannel* c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF( + static_cast(grpc_avl_get(index, key, nullptr)), + "found_from_pool"); + grpc_avl_unref(index, nullptr); + return c; +} + +RefCountedPtr* GlobalSubchannelPool::instance_ = nullptr; + +namespace { + +void sck_avl_destroy(void* p, void* user_data) { + SubchannelKey* key = static_cast(p); + Delete(key); +} + +void* sck_avl_copy(void* p, void* unused) { + const SubchannelKey* key = static_cast(p); + auto* new_key = New(*key); + return static_cast(new_key); +} + +long sck_avl_compare(void* a, void* b, void* unused) { + const SubchannelKey* key_a = static_cast(a); + const SubchannelKey* key_b = static_cast(b); + return key_a->Cmp(*key_b); +} + +void scv_avl_destroy(void* p, void* user_data) { + GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "global_subchannel_pool"); +} + +void* scv_avl_copy(void* p, void* unused) { + GRPC_SUBCHANNEL_WEAK_REF((grpc_subchannel*)p, "global_subchannel_pool"); + return p; +} + +} // namespace + +const grpc_avl_vtable GlobalSubchannelPool::subchannel_avl_vtable_ = { + sck_avl_destroy, // destroy_key + sck_avl_copy, // copy_key + sck_avl_compare, // compare_keys + scv_avl_destroy, // destroy_value + scv_avl_copy // copy_value +}; + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.h b/src/core/ext/filters/client_channel/global_subchannel_pool.h new file mode 100644 index 00000000000..0deb3769360 --- /dev/null +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.h @@ -0,0 +1,68 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_GLOBAL_SUBCHANNEL_POOL_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_GLOBAL_SUBCHANNEL_POOL_H + +#include + +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" + +namespace grpc_core { + +// The global subchannel pool. It shares subchannels among channels. There +// should be only one instance of this class. Init() should be called once at +// the filter initialization time; Shutdown() should be called once at the +// filter shutdown time. +// TODO(juanlishen): Enable subchannel retention. +class GlobalSubchannelPool final : public SubchannelPoolInterface { + public: + // The ctor and dtor are not intended to use directly. + GlobalSubchannelPool(); + ~GlobalSubchannelPool() override; + + // Should be called exactly once at filter initialization time. + static void Init(); + // Should be called exactly once at filter shutdown time. + static void Shutdown(); + + // Gets the singleton instance. + static RefCountedPtr instance(); + + // Implements interface methods. + grpc_subchannel* RegisterSubchannel(SubchannelKey* key, + grpc_subchannel* constructed) override; + void UnregisterSubchannel(SubchannelKey* key) override; + grpc_subchannel* FindSubchannel(SubchannelKey* key) override; + + private: + // The singleton instance. (It's a pointer to RefCountedPtr so that this + // non-local static object can be trivially destructible.) + static RefCountedPtr* instance_; + + // The vtable for subchannel operations in an AVL tree. + static const grpc_avl_vtable subchannel_avl_vtable_; + // A map from subchannel key to subchannel. + grpc_avl subchannel_map_; + // To protect subchannel_map_. + gpr_mu mu_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_GLOBAL_SUBCHANNEL_POOL_H */ diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index b4e803689e9..31b0399d874 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -19,6 +19,7 @@ #include #include "src/core/ext/filters/client_channel/lb_policy.h" + #include "src/core/lib/iomgr/combiner.h" grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount( @@ -30,6 +31,7 @@ LoadBalancingPolicy::LoadBalancingPolicy(const Args& args) : InternallyRefCounted(&grpc_trace_lb_policy_refcount), combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), client_channel_factory_(args.client_channel_factory), + subchannel_pool_(*args.subchannel_pool), interested_parties_(grpc_pollset_set_create()), request_reresolution_(nullptr) {} diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 293d8e960cf..b9d97e092af 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -24,6 +24,7 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -53,6 +54,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_combiner* combiner = nullptr; /// Used to create channels and subchannels. grpc_client_channel_factory* client_channel_factory = nullptr; + /// Subchannel pool. + RefCountedPtr* subchannel_pool; /// Channel args from the resolver. /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. @@ -171,6 +174,12 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_pollset_set* interested_parties() const { return interested_parties_; } + /// Returns a pointer to the subchannel pool of type + /// RefCountedPtr. + RefCountedPtr* subchannel_pool() { + return &subchannel_pool_; + } + GRPC_ABSTRACT_BASE_CLASS protected: @@ -204,6 +213,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_combiner* combiner_; /// Client channel factory, used to create channels and subchannels. grpc_client_channel_factory* client_channel_factory_; + /// Subchannel pool. + RefCountedPtr subchannel_pool_; /// Owned pointer to interested parties in load balancing decisions. grpc_pollset_set* interested_parties_; /// Callback to force a re-resolution. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index ba40febd534..40bf9c65644 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -85,7 +85,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" @@ -988,7 +987,6 @@ GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args) 1000)) { // Initialization. gpr_mu_init(&lb_channel_mu_); - grpc_subchannel_index_ref(); GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); @@ -1032,7 +1030,6 @@ GrpcLb::~GrpcLb() { if (serverlist_ != nullptr) { grpc_grpclb_destroy_serverlist(serverlist_); } - grpc_subchannel_index_unref(); } void GrpcLb::ShutdownLocked() { @@ -1699,6 +1696,7 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { lb_policy_args.combiner = combiner(); lb_policy_args.client_channel_factory = client_channel_factory(); lb_policy_args.args = args; + lb_policy_args.subchannel_pool = subchannel_pool(); CreateRoundRobinPolicyLocked(lb_policy_args); } grpc_channel_args_destroy(args); diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index d6ff74ec7f7..75eacb2e17e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -26,7 +26,6 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/iomgr/combiner.h" @@ -164,7 +163,6 @@ PickFirst::PickFirst(const Args& args) : LoadBalancingPolicy(args) { gpr_log(GPR_INFO, "Pick First %p created.", this); } UpdateLocked(*args.args, args.lb_config); - grpc_subchannel_index_ref(); } PickFirst::~PickFirst() { @@ -176,7 +174,6 @@ PickFirst::~PickFirst() { GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); GPR_ASSERT(pending_picks_ == nullptr); grpc_connectivity_state_destroy(&state_tracker_); - grpc_subchannel_index_unref(); } void PickFirst::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 3bcb33ef11c..5143c6d8380 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -33,7 +33,6 @@ #include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/mutex_lock.h" @@ -221,7 +220,6 @@ RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) { gpr_log(GPR_INFO, "[RR %p] Created with %" PRIuPTR " subchannels", this, subchannel_list_->num_subchannels()); } - grpc_subchannel_index_ref(); } RoundRobin::~RoundRobin() { @@ -233,7 +231,6 @@ RoundRobin::~RoundRobin() { GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); GPR_ASSERT(pending_picks_ == nullptr); grpc_connectivity_state_destroy(&state_tracker_); - grpc_subchannel_index_unref(); } void RoundRobin::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 1d0ecbe3f64..55f5d6da85a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -514,6 +514,9 @@ SubchannelList::SubchannelList( // policy, which does not use a SubchannelList. GPR_ASSERT(!addresses[i].IsBalancer()); InlinedVector args_to_add; + args_to_add.emplace_back(SubchannelPoolInterface::CreateChannelArg( + policy_->subchannel_pool()->get())); + const size_t subchannel_address_arg_index = args_to_add.size(); args_to_add.emplace_back( grpc_create_subchannel_address_arg(&addresses[i].address())); if (addresses[i].args() != nullptr) { @@ -524,7 +527,7 @@ SubchannelList::SubchannelList( grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); - gpr_free(args_to_add[0].value.string); + gpr_free(args_to_add[subchannel_address_arg_index].value.string); grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( client_channel_factory, new_args); grpc_channel_args_destroy(new_args); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 8787f5bcc24..63bd8be011b 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -80,7 +80,6 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" @@ -905,7 +904,6 @@ XdsLb::XdsLb(const LoadBalancingPolicy::Args& args) .set_max_backoff(GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { // Initialization. gpr_mu_init(&lb_channel_mu_); - grpc_subchannel_index_ref(); GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &XdsLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); @@ -949,7 +947,6 @@ XdsLb::~XdsLb() { if (serverlist_ != nullptr) { xds_grpclb_destroy_serverlist(serverlist_); } - grpc_subchannel_index_unref(); } void XdsLb::ShutdownLocked() { @@ -1526,6 +1523,7 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); lb_policy_args.client_channel_factory = client_channel_factory(); + lb_policy_args.subchannel_pool = subchannel_pool(); lb_policy_args.args = args; CreateChildPolicyLocked(lb_policy_args); if (grpc_lb_xds_trace.enabled()) { diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.cc b/src/core/ext/filters/client_channel/local_subchannel_pool.cc new file mode 100644 index 00000000000..145fa4e0374 --- /dev/null +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.cc @@ -0,0 +1,96 @@ +// +// +// Copyright 2018 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// + +#include + +#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" + +#include "src/core/ext/filters/client_channel/subchannel.h" + +namespace grpc_core { + +LocalSubchannelPool::LocalSubchannelPool() { + subchannel_map_ = grpc_avl_create(&subchannel_avl_vtable_); +} + +LocalSubchannelPool::~LocalSubchannelPool() { + grpc_avl_unref(subchannel_map_, nullptr); +} + +grpc_subchannel* LocalSubchannelPool::RegisterSubchannel( + SubchannelKey* key, grpc_subchannel* constructed) { + // Check to see if a subchannel already exists. + grpc_subchannel* c = static_cast( + grpc_avl_get(subchannel_map_, key, nullptr)); + if (c != nullptr) { + // The subchannel already exists. Reuse it. + c = GRPC_SUBCHANNEL_REF(c, "subchannel_register+reuse"); + GRPC_SUBCHANNEL_UNREF(constructed, "subchannel_register+found_existing"); + } else { + // There hasn't been such subchannel. Add one. + subchannel_map_ = grpc_avl_add(subchannel_map_, New(*key), + constructed, nullptr); + c = constructed; + } + return c; +} + +void LocalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { + subchannel_map_ = grpc_avl_remove(subchannel_map_, key, nullptr); +} + +grpc_subchannel* LocalSubchannelPool::FindSubchannel(SubchannelKey* key) { + grpc_subchannel* c = static_cast( + grpc_avl_get(subchannel_map_, key, nullptr)); + return c == nullptr ? c : GRPC_SUBCHANNEL_REF(c, "found_from_pool"); +} + +namespace { + +void sck_avl_destroy(void* p, void* user_data) { + SubchannelKey* key = static_cast(p); + Delete(key); +} + +void* sck_avl_copy(void* p, void* unused) { + const SubchannelKey* key = static_cast(p); + auto new_key = New(*key); + return static_cast(new_key); +} + +long sck_avl_compare(void* a, void* b, void* unused) { + const SubchannelKey* key_a = static_cast(a); + const SubchannelKey* key_b = static_cast(b); + return key_a->Cmp(*key_b); +} + +void scv_avl_destroy(void* p, void* user_data) {} + +void* scv_avl_copy(void* p, void* unused) { return p; } + +} // namespace + +const grpc_avl_vtable LocalSubchannelPool::subchannel_avl_vtable_ = { + sck_avl_destroy, // destroy_key + sck_avl_copy, // copy_key + sck_avl_compare, // compare_keys + scv_avl_destroy, // destroy_value + scv_avl_copy // copy_value +}; + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.h b/src/core/ext/filters/client_channel/local_subchannel_pool.h new file mode 100644 index 00000000000..9929cdb3627 --- /dev/null +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.h @@ -0,0 +1,56 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LOCAL_SUBCHANNEL_POOL_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LOCAL_SUBCHANNEL_POOL_H + +#include + +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" + +namespace grpc_core { + +// The local subchannel pool that is owned by a single channel. It doesn't +// support subchannel sharing with other channels by nature. Nor does it support +// subchannel retention when a subchannel is not used. The only real purpose of +// using this subchannel pool is to allow subchannel reuse within the channel +// when an incoming resolver update contains some addresses for which the +// channel has already created subchannels. +// Thread-unsafe. +class LocalSubchannelPool final : public SubchannelPoolInterface { + public: + LocalSubchannelPool(); + ~LocalSubchannelPool() override; + + // Implements interface methods. + // Thread-unsafe. Intended to be invoked within the client_channel combiner. + grpc_subchannel* RegisterSubchannel(SubchannelKey* key, + grpc_subchannel* constructed) override; + void UnregisterSubchannel(SubchannelKey* key) override; + grpc_subchannel* FindSubchannel(SubchannelKey* key) override; + + private: + // The vtable for subchannel operations in an AVL tree. + static const grpc_avl_vtable subchannel_avl_vtable_; + // A map from subchannel key to subchannel. + grpc_avl subchannel_map_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LOCAL_SUBCHANNEL_POOL_H */ diff --git a/src/core/ext/filters/client_channel/request_routing.cc b/src/core/ext/filters/client_channel/request_routing.cc index f9a7e164e75..5e52456859e 100644 --- a/src/core/ext/filters/client_channel/request_routing.cc +++ b/src/core/ext/filters/client_channel/request_routing.cc @@ -32,8 +32,10 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" @@ -517,6 +519,14 @@ RequestRouter::RequestRouter( tracer_(tracer), process_resolver_result_(process_resolver_result), process_resolver_result_user_data_(process_resolver_result_user_data) { + // Get subchannel pool. + const grpc_arg* arg = + grpc_channel_args_find(args, GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL); + if (grpc_channel_arg_get_bool(arg, false)) { + subchannel_pool_ = MakeRefCounted(); + } else { + subchannel_pool_ = GlobalSubchannelPool::instance(); + } GRPC_CLOSURE_INIT(&on_resolver_result_changed_, &RequestRouter::OnResolverResultChangedLocked, this, grpc_combiner_scheduler(combiner)); @@ -666,6 +676,7 @@ void RequestRouter::CreateNewLbPolicyLocked( LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner_; lb_policy_args.client_channel_factory = client_channel_factory_; + lb_policy_args.subchannel_pool = &subchannel_pool_; lb_policy_args.args = resolver_result_; lb_policy_args.lb_config = lb_config; OrphanablePtr new_lb_policy = @@ -751,9 +762,8 @@ void RequestRouter::ConcatenateAndAddChannelTraceLocked( char* flat; size_t flat_len = 0; flat = gpr_strvec_flatten(&v, &flat_len); - channelz_node_->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_new(flat, flat_len, gpr_free)); + channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info, + grpc_slice_new(flat, flat_len, gpr_free)); gpr_strvec_destroy(&v); } } diff --git a/src/core/ext/filters/client_channel/request_routing.h b/src/core/ext/filters/client_channel/request_routing.h index 0c671229c8e..0027163869e 100644 --- a/src/core/ext/filters/client_channel/request_routing.h +++ b/src/core/ext/filters/client_channel/request_routing.h @@ -25,6 +25,7 @@ #include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/lb_policy.h" #include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/debug/trace.h" @@ -126,7 +127,7 @@ class RequestRouter { LoadBalancingPolicy* lb_policy() const { return lb_policy_.get(); } private: - using TraceStringVector = grpc_core::InlinedVector; + using TraceStringVector = InlinedVector; class ReresolutionRequestHandler; class LbConnectivityWatcher; @@ -169,6 +170,9 @@ class RequestRouter { OrphanablePtr lb_policy_; bool exit_idle_when_lb_policy_arrives_ = false; + // Subchannel pool to pass to LB policy. + RefCountedPtr subchannel_pool_; + grpc_connectivity_state_tracker state_tracker_; }; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 640a052e91e..0c75ee046d9 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -33,7 +33,7 @@ #include "src/core/ext/filters/client_channel/health/health_check_client.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" -#include "src/core/ext/filters/client_channel/subchannel_index.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" @@ -80,6 +80,9 @@ class ConnectedSubchannelStateWatcher; } // namespace grpc_core struct grpc_subchannel { + /** The subchannel pool this subchannel is in */ + grpc_core::RefCountedPtr subchannel_pool; + grpc_connector* connector; /** refcount @@ -92,7 +95,7 @@ struct grpc_subchannel { /** channel arguments */ grpc_channel_args* args; - grpc_subchannel_key* key; + grpc_core::SubchannelKey* key; /** set during connection */ grpc_connect_out_args connecting_result; @@ -375,7 +378,7 @@ static void subchannel_destroy(void* arg, grpc_error* error) { grpc_connectivity_state_destroy(&c->state_and_health_tracker); grpc_connector_unref(c->connector); grpc_pollset_set_destroy(c->pollset_set); - grpc_subchannel_key_destroy(c->key); + grpc_core::Delete(c->key); gpr_mu_destroy(&c->mu); gpr_free(c); } @@ -428,7 +431,12 @@ grpc_subchannel* grpc_subchannel_ref_from_weak_ref( } static void disconnect(grpc_subchannel* c) { - grpc_subchannel_index_unregister(c->key, c); + // The subchannel_pool is only used once here in this subchannel, so the + // access can be outside of the lock. + if (c->subchannel_pool != nullptr) { + c->subchannel_pool->UnregisterSubchannel(c->key); + c->subchannel_pool.reset(); + } gpr_mu_lock(&c->mu); GPR_ASSERT(!c->disconnected); c->disconnected = true; @@ -538,13 +546,17 @@ struct HealthCheckParams { grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, const grpc_channel_args* args) { - grpc_subchannel_key* key = grpc_subchannel_key_create(args); - grpc_subchannel* c = grpc_subchannel_index_find(key); - if (c) { - grpc_subchannel_key_destroy(key); + grpc_core::SubchannelKey* key = + grpc_core::New(args); + grpc_core::SubchannelPoolInterface* subchannel_pool = + grpc_core::SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs( + args); + GPR_ASSERT(subchannel_pool != nullptr); + grpc_subchannel* c = subchannel_pool->FindSubchannel(key); + if (c != nullptr) { + grpc_core::Delete(key); return c; } - GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED(); c = static_cast(gpr_zalloc(sizeof(*c))); c->key = key; @@ -616,8 +628,13 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Subchannel created")); } - - return grpc_subchannel_index_register(key, c); + // Try to register the subchannel before setting the subchannel pool. + // Otherwise, in case of a registration race, unreffing c in + // RegisterSubchannel() will cause c to be tried to be unregistered, while its + // key maps to a different subchannel. + grpc_subchannel* registered = subchannel_pool->RegisterSubchannel(key, c); + if (registered == c) c->subchannel_pool = subchannel_pool->Ref(); + return registered; } grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( @@ -983,11 +1000,6 @@ grpc_subchannel_get_connected_subchannel(grpc_subchannel* c) { return copy; } -const grpc_subchannel_key* grpc_subchannel_get_key( - const grpc_subchannel* subchannel) { - return subchannel->key; -} - void* grpc_connected_subchannel_call_get_parent_data( grpc_subchannel_call* subchannel_call) { grpc_channel_stack* chanstk = subchannel_call->connection->channel_stack(); diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 8c994c64f50..fac515eee5c 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -23,6 +23,7 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/connector.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/gpr/arena.h" #include "src/core/lib/gprpp/ref_counted.h" @@ -38,7 +39,6 @@ address. Provides a target for load balancing. */ typedef struct grpc_subchannel grpc_subchannel; typedef struct grpc_subchannel_call grpc_subchannel_call; -typedef struct grpc_subchannel_key grpc_subchannel_key; #ifndef NDEBUG #define GRPC_SUBCHANNEL_REF(p, r) \ @@ -162,10 +162,6 @@ void grpc_subchannel_notify_on_state_change( grpc_core::RefCountedPtr grpc_subchannel_get_connected_subchannel(grpc_subchannel* c); -/** return the subchannel index key for \a subchannel */ -const grpc_subchannel_key* grpc_subchannel_get_key( - const grpc_subchannel* subchannel); - // Resets the connection backoff of the subchannel. // TODO(roth): Move connection backoff out of subchannels and up into LB // policy code (probably by adding a SubchannelGroup between diff --git a/src/core/ext/filters/client_channel/subchannel_pool_interface.cc b/src/core/ext/filters/client_channel/subchannel_pool_interface.cc new file mode 100644 index 00000000000..bb35f228b70 --- /dev/null +++ b/src/core/ext/filters/client_channel/subchannel_pool_interface.cc @@ -0,0 +1,97 @@ +// +// +// Copyright 2018 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// + +#include + +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" + +#include "src/core/lib/gpr/useful.h" + +// The subchannel pool to reuse subchannels. +#define GRPC_ARG_SUBCHANNEL_POOL "grpc.subchannel_pool" +// The subchannel key ID that is only used in test to make each key unique. +#define GRPC_ARG_SUBCHANNEL_KEY_TEST_ONLY_ID "grpc.subchannel_key_test_only_id" + +namespace grpc_core { + +TraceFlag grpc_subchannel_pool_trace(false, "subchannel_pool"); + +SubchannelKey::SubchannelKey(const grpc_channel_args* args) { + Init(args, grpc_channel_args_normalize); +} + +SubchannelKey::~SubchannelKey() { + grpc_channel_args_destroy(const_cast(args_)); +} + +SubchannelKey::SubchannelKey(const SubchannelKey& other) { + Init(other.args_, grpc_channel_args_copy); +} + +SubchannelKey& SubchannelKey::operator=(const SubchannelKey& other) { + grpc_channel_args_destroy(const_cast(args_)); + Init(other.args_, grpc_channel_args_copy); + return *this; +} + +int SubchannelKey::Cmp(const SubchannelKey& other) const { + return grpc_channel_args_compare(args_, other.args_); +} + +void SubchannelKey::Init( + const grpc_channel_args* args, + grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)) { + args_ = copy_channel_args(args); +} + +namespace { + +void* arg_copy(void* p) { + auto* subchannel_pool = static_cast(p); + subchannel_pool->Ref().release(); + return p; +} + +void arg_destroy(void* p) { + auto* subchannel_pool = static_cast(p); + subchannel_pool->Unref(); +} + +int arg_cmp(void* a, void* b) { return GPR_ICMP(a, b); } + +const grpc_arg_pointer_vtable subchannel_pool_arg_vtable = { + arg_copy, arg_destroy, arg_cmp}; + +} // namespace + +grpc_arg SubchannelPoolInterface::CreateChannelArg( + SubchannelPoolInterface* subchannel_pool) { + return grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_SUBCHANNEL_POOL), subchannel_pool, + &subchannel_pool_arg_vtable); +} + +SubchannelPoolInterface* +SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs( + const grpc_channel_args* args) { + const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_POOL); + if (arg == nullptr || arg->type != GRPC_ARG_POINTER) return nullptr; + return static_cast(arg->value.pointer.p); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel_pool_interface.h b/src/core/ext/filters/client_channel/subchannel_pool_interface.h new file mode 100644 index 00000000000..21597bf4276 --- /dev/null +++ b/src/core/ext/filters/client_channel/subchannel_pool_interface.h @@ -0,0 +1,94 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_POOL_INTERFACE_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_POOL_INTERFACE_H + +#include + +#include "src/core/lib/avl/avl.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/abstract.h" +#include "src/core/lib/gprpp/ref_counted.h" + +struct grpc_subchannel; + +namespace grpc_core { + +extern TraceFlag grpc_subchannel_pool_trace; + +// A key that can uniquely identify a subchannel. +class SubchannelKey { + public: + explicit SubchannelKey(const grpc_channel_args* args); + ~SubchannelKey(); + + // Copyable. + SubchannelKey(const SubchannelKey& other); + SubchannelKey& operator=(const SubchannelKey& other); + // Not movable. + SubchannelKey(SubchannelKey&&) = delete; + SubchannelKey& operator=(SubchannelKey&&) = delete; + + int Cmp(const SubchannelKey& other) const; + + private: + // Initializes the subchannel key with the given \a args and the function to + // copy channel args. + void Init( + const grpc_channel_args* args, + grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)); + + const grpc_channel_args* args_; +}; + +// Interface for subchannel pool. +// TODO(juanlishen): This refcounting mechanism may lead to memory leak. +// To solve that, we should force polling to flush any pending callbacks, then +// shut down safely. See https://github.com/grpc/grpc/issues/12560. +class SubchannelPoolInterface : public RefCounted { + public: + SubchannelPoolInterface() : RefCounted(&grpc_subchannel_pool_trace) {} + virtual ~SubchannelPoolInterface() {} + + // Registers a subchannel against a key. Returns the subchannel registered + // with \a key, which may be different from \a constructed because we reuse + // (instead of update) any existing subchannel already registered with \a key. + virtual grpc_subchannel* RegisterSubchannel( + SubchannelKey* key, grpc_subchannel* constructed) GRPC_ABSTRACT; + + // Removes the registered subchannel found by \a key. + virtual void UnregisterSubchannel(SubchannelKey* key) GRPC_ABSTRACT; + + // Finds the subchannel registered for the given subchannel key. Returns NULL + // if no such channel exists. Thread-safe. + virtual grpc_subchannel* FindSubchannel(SubchannelKey* key) GRPC_ABSTRACT; + + // Creates a channel arg from \a subchannel pool. + static grpc_arg CreateChannelArg(SubchannelPoolInterface* subchannel_pool); + + // Gets the subchannel pool from the channel args. + static SubchannelPoolInterface* GetSubchannelPoolFromChannelArgs( + const grpc_channel_args* args); + + GRPC_ABSTRACT_BASE_CLASS +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_POOL_INTERFACE_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index f5e43ca657e..0272aae690d 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -319,11 +319,13 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy_registry.cc', + 'src/core/ext/filters/client_channel/local_subchannel_pool.cc', 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', @@ -334,7 +336,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', - 'src/core/ext/filters/client_channel/subchannel_index.cc', + 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 9783f51ab7d..aa8a6a96c4b 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,7 @@ #include #include +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" @@ -96,6 +98,7 @@ class MyTestServiceImpl : public TestServiceImpl { std::unique_lock lock(mu_); ++request_count_; } + AddClient(context->peer()); return TestServiceImpl::Echo(context, request, response); } @@ -109,9 +112,21 @@ class MyTestServiceImpl : public TestServiceImpl { request_count_ = 0; } + std::set clients() { + std::unique_lock lock(clients_mu_); + return clients_; + } + private: + void AddClient(const grpc::string& client) { + std::unique_lock lock(clients_mu_); + clients_.insert(client); + } + std::mutex mu_; int request_count_; + std::mutex clients_mu_; + std::set clients_; }; class ClientLbEnd2endTest : public ::testing::Test { @@ -661,6 +676,54 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } +TEST_F(ClientLbEnd2endTest, PickFirstGlobalSubchannelPool) { + // Start one server. + const int kNumServers = 1; + StartServers(kNumServers); + std::vector ports = GetServersPorts(); + // Create two channels that (by default) use the global subchannel pool. + auto channel1 = BuildChannel("pick_first"); + auto stub1 = BuildStub(channel1); + SetNextResolution(ports); + auto channel2 = BuildChannel("pick_first"); + auto stub2 = BuildStub(channel2); + SetNextResolution(ports); + WaitForServer(stub1, 0, DEBUG_LOCATION); + // Send one RPC on each channel. + CheckRpcSendOk(stub1, DEBUG_LOCATION); + CheckRpcSendOk(stub2, DEBUG_LOCATION); + // The server receives two requests. + EXPECT_EQ(2, servers_[0]->service_.request_count()); + // The two requests are from the same client port, because the two channels + // share subchannels via the global subchannel pool. + EXPECT_EQ(1UL, servers_[0]->service_.clients().size()); +} + +TEST_F(ClientLbEnd2endTest, PickFirstLocalSubchannelPool) { + // Start one server. + const int kNumServers = 1; + StartServers(kNumServers); + std::vector ports = GetServersPorts(); + // Create two channels that use local subchannel pool. + ChannelArguments args; + args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1); + auto channel1 = BuildChannel("pick_first", args); + auto stub1 = BuildStub(channel1); + SetNextResolution(ports); + auto channel2 = BuildChannel("pick_first", args); + auto stub2 = BuildStub(channel2); + SetNextResolution(ports); + WaitForServer(stub1, 0, DEBUG_LOCATION); + // Send one RPC on each channel. + CheckRpcSendOk(stub1, DEBUG_LOCATION); + CheckRpcSendOk(stub2, DEBUG_LOCATION); + // The server receives two requests. + EXPECT_EQ(2, servers_[0]->service_.request_count()); + // The two requests are from two client ports, because the two channels didn't + // share subchannels with each other. + EXPECT_EQ(2UL, servers_[0]->service_.clients().size()); +} + TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { const int kNumUpdates = 1000; const int kNumServers = 3; diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index f739ed032bb..b589cd4044a 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -40,9 +40,8 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/cpp/server/secure_server_credentials.h" - #include "src/cpp/client/secure_credentials.h" +#include "src/cpp/server/secure_server_credentials.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index bb350550e94..51b9eda22b6 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -886,6 +886,8 @@ src/core/ext/filters/client_channel/client_channel_factory.h \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.h \ +src/core/ext/filters/client_channel/global_subchannel_pool.cc \ +src/core/ext/filters/client_channel/global_subchannel_pool.h \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/ext/filters/client_channel/health/health.pb.h \ src/core/ext/filters/client_channel/health/health_check_client.cc \ @@ -926,6 +928,8 @@ src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h \ src/core/ext/filters/client_channel/lb_policy_factory.h \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ src/core/ext/filters/client_channel/lb_policy_registry.h \ +src/core/ext/filters/client_channel/local_subchannel_pool.cc \ +src/core/ext/filters/client_channel/local_subchannel_pool.h \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/parse_address.h \ src/core/ext/filters/client_channel/proxy_mapper.cc \ @@ -964,8 +968,8 @@ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/server_address.h \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel.h \ -src/core/ext/filters/client_channel/subchannel_index.cc \ -src/core/ext/filters/client_channel/subchannel_index.h \ +src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ +src/core/ext/filters/client_channel/subchannel_pool_interface.h \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/deadline/deadline_filter.h \ src/core/ext/filters/http/client/http_client_filter.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 197de64dbe1..8ab9c57142e 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9883,12 +9883,14 @@ "src/core/ext/filters/client_channel/client_channel_channelz.h", "src/core/ext/filters/client_channel/client_channel_factory.h", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", "src/core/ext/filters/client_channel/lb_policy_factory.h", "src/core/ext/filters/client_channel/lb_policy_registry.h", + "src/core/ext/filters/client_channel/local_subchannel_pool.h", "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", @@ -9900,7 +9902,7 @@ "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", - "src/core/ext/filters/client_channel/subchannel_index.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], "is_filegroup": true, "language": "c", @@ -9918,6 +9920,8 @@ "src/core/ext/filters/client_channel/client_channel_plugin.cc", "src/core/ext/filters/client_channel/connector.cc", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/global_subchannel_pool.cc", + "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", @@ -9929,6 +9933,8 @@ "src/core/ext/filters/client_channel/lb_policy_factory.h", "src/core/ext/filters/client_channel/lb_policy_registry.cc", "src/core/ext/filters/client_channel/lb_policy_registry.h", + "src/core/ext/filters/client_channel/local_subchannel_pool.cc", + "src/core/ext/filters/client_channel/local_subchannel_pool.h", "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.cc", @@ -9950,8 +9956,8 @@ "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.h", - "src/core/ext/filters/client_channel/subchannel_index.cc", - "src/core/ext/filters/client_channel/subchannel_index.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", + "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], "third_party": false, "type": "filegroup" From 18859648238bb38449574fe38a03d9e2a038e6a6 Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 15 Jan 2019 14:04:53 -0800 Subject: [PATCH 066/814] clang-format and wait in atexit handler --- src/core/lib/gprpp/thd_windows.cc | 3 ++- test/core/util/port.cc | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index 703da74e051..b7828660eba 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -147,7 +147,8 @@ class ThreadInternalsWindows namespace grpc_core { Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success, const Options& options) : options_(options) { + bool* success, const Options& options) + : options_(options) { bool outcome = false; impl_ = grpc_core::New(thd_body, arg, &outcome, options); diff --git a/test/core/util/port.cc b/test/core/util/port.cc index 303306de452..14d648b7eaf 100644 --- a/test/core/util/port.cc +++ b/test/core/util/port.cc @@ -34,6 +34,7 @@ #include "src/core/lib/http/httpcli.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/surface/init.h" #include "test/core/util/port_server_client.h" static int* chosen_ports = nullptr; @@ -67,6 +68,7 @@ static void free_chosen_ports(void) { grpc_free_port_using_server(chosen_ports[i]); } grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); gpr_free(chosen_ports); } From c55ff1b96eecc75fe238bbc5ae535047d850a140 Mon Sep 17 00:00:00 2001 From: Yuxuan Li Date: Tue, 15 Jan 2019 17:33:37 -0800 Subject: [PATCH 067/814] Add v1.18.0 releases of grpc-go --- tools/interop_matrix/client_matrix.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 318e1da00f0..cd542b0f4c5 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -118,6 +118,7 @@ LANG_RELEASE_MATRIX = { ('v1.15.0', ReleaseInfo(runtime_subset=['go1.8'])), ('v1.16.0', ReleaseInfo(runtime_subset=['go1.8'])), ('v1.17.0', ReleaseInfo(runtime_subset=['go1.11'])), + ('v1.18.0', ReleaseInfo(runtime_subset=['go1.11'])), ]), 'java': OrderedDict([ From 9c51ff9b331a07938525c49c3146a7ebbe1d0e57 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Jan 2019 22:32:06 +0100 Subject: [PATCH 068/814] Make C# ServerCallContext implementation agnostic --- .../TestServerCallContext.cs | 21 +--- .../Grpc.Core/Internal/CallSafeHandle.cs | 1 + .../Internal/IServerResponseStream.cs | 38 +++++++ .../Internal/ServerCallContextExtraData.cs | 97 +++++++++++++++++ .../Grpc.Core/Internal/ServerCallHandler.cs | 10 +- .../Internal/ServerResponseStream.cs | 2 +- src/csharp/Grpc.Core/ServerCallContext.cs | 101 +++++++----------- 7 files changed, 182 insertions(+), 88 deletions(-) create mode 100644 src/csharp/Grpc.Core/Internal/IServerResponseStream.cs create mode 100644 src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs index 5418417d7ed..d72e98e75a2 100644 --- a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs +++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs @@ -37,22 +37,11 @@ namespace Grpc.Core.Testing Func writeHeadersFunc, Func writeOptionsGetter, Action writeOptionsSetter) { return new ServerCallContext(null, method, host, deadline, requestHeaders, cancellationToken, - writeHeadersFunc, new WriteOptionsHolder(writeOptionsGetter, writeOptionsSetter), - () => peer, () => authContext, () => contextPropagationToken); - } - - private class WriteOptionsHolder : IHasWriteOptions - { - Func writeOptionsGetter; - Action writeOptionsSetter; - - public WriteOptionsHolder(Func writeOptionsGetter, Action writeOptionsSetter) - { - this.writeOptionsGetter = writeOptionsGetter; - this.writeOptionsSetter = writeOptionsSetter; - } - - public WriteOptions WriteOptions { get => writeOptionsGetter(); set => writeOptionsSetter(value); } + (ctx, extraData, headers) => writeHeadersFunc(headers), + (ctx, extraData) => writeOptionsGetter(), + (ctx, extraData, options) => writeOptionsSetter(options), + (ctx, extraData) => peer, (ctx, callHandle) => authContext, + (ctx, callHandle, options) => contextPropagationToken); } } } diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index a3ef3e61ee1..7154ddae30b 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -18,6 +18,7 @@ using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; +using System.Threading; using Grpc.Core; using Grpc.Core.Utils; using Grpc.Core.Profiling; diff --git a/src/csharp/Grpc.Core/Internal/IServerResponseStream.cs b/src/csharp/Grpc.Core/Internal/IServerResponseStream.cs new file mode 100644 index 00000000000..874aae703a2 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/IServerResponseStream.cs @@ -0,0 +1,38 @@ +#region Copyright notice and license +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +using System; +using System.Threading.Tasks; +using Grpc.Core.Internal; + +namespace Grpc.Core.Internal +{ + /// + /// Exposes non-generic members of ServerReponseStream. + /// + internal interface IServerResponseStream + { + /// + /// Asynchronously sends response headers for the current call to the client. See ServerCallContext.WriteResponseHeadersAsync for exact semantics. + /// + Task WriteResponseHeadersAsync(Metadata responseHeaders); + + /// + /// Gets or sets the write options. + /// + WriteOptions WriteOptions { get; set; } + } +} diff --git a/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs b/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs new file mode 100644 index 00000000000..97b95e66df9 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs @@ -0,0 +1,97 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Grpc.Core.Internal +{ + /// + /// Additional state for ServerCallContext. + /// Storing the extra state outside of ServerCallContext allows it to be implementation-agnostic. + /// + internal class ServerCallContextExtraData + { + readonly CallSafeHandle callHandle; + readonly IServerResponseStream serverResponseStream; + readonly Lazy cachedAuthContext; + + public ServerCallContextExtraData(CallSafeHandle callHandle, IServerResponseStream serverResponseStream) + { + this.callHandle = callHandle; + this.serverResponseStream = serverResponseStream; + // TODO(jtattermusch): avoid unnecessary allocation of factory function and the lazy object. + this.cachedAuthContext = new Lazy(GetAuthContextEager); + } + + public ServerCallContext NewServerCallContext(ServerRpcNew newRpc, CancellationToken cancellationToken) + { + DateTime realtimeDeadline = newRpc.Deadline.ToClockType(ClockType.Realtime).ToDateTime(); + + return new ServerCallContext(this, newRpc.Method, newRpc.Host, realtimeDeadline, + newRpc.RequestMetadata, cancellationToken, + ServerCallContext_WriteHeadersFunc, ServerCallContext_WriteOptionsGetter, ServerCallContext_WriteOptionsSetter, + ServerCallContext_PeerGetter, ServerCallContext_AuthContextGetter, ServerCallContext_ContextPropagationTokenFactory); + } + + private AuthContext GetAuthContextEager() + { + using (var authContextNative = callHandle.GetAuthContext()) + { + return authContextNative.ToAuthContext(); + } + } + + // Implementors of ServerCallContext's members are pre-allocated to avoid unneccessary delegate allocations. + readonly static Func ServerCallContext_WriteHeadersFunc = (ctx, extraData, headers) => + { + return ((ServerCallContextExtraData)extraData).serverResponseStream.WriteResponseHeadersAsync(headers); + }; + + readonly static Func ServerCallContext_WriteOptionsGetter = (ctx, extraData) => + { + + return ((ServerCallContextExtraData)extraData).serverResponseStream.WriteOptions; + }; + + readonly static Action ServerCallContext_WriteOptionsSetter = (ctx, extraData, options) => + { + ((ServerCallContextExtraData)extraData).serverResponseStream.WriteOptions = options; + }; + + readonly static Func ServerCallContext_PeerGetter = (ctx, extraData) => + { + // Getting the peer lazily is fine as the native call is guaranteed + // not to be disposed before user-supplied server side handler returns. + // Most users won't need to read this field anyway. + return ((ServerCallContextExtraData)extraData).callHandle.GetPeer(); + }; + + readonly static Func ServerCallContext_AuthContextGetter = (ctx, extraData) => + { + return ((ServerCallContextExtraData)extraData).cachedAuthContext.Value; + }; + + readonly static Func ServerCallContext_ContextPropagationTokenFactory = (ctx, extraData, options) => + { + var callHandle = ((ServerCallContextExtraData)extraData).callHandle; + return new ContextPropagationToken(callHandle, ctx.Deadline, ctx.CancellationToken, options); + }; + } +} diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index ec732e8c7f4..ae586f7d1c4 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -71,7 +71,7 @@ namespace Grpc.Core.Internal var response = await handler(request, context).ConfigureAwait(false); status = context.Status; responseWithFlags = new AsyncCallServer.ResponseWithFlags(response, HandlerUtils.GetWriteFlags(context.WriteOptions)); - } + } catch (Exception e) { if (!(e is RpcException)) @@ -345,14 +345,12 @@ namespace Grpc.Core.Internal return writeOptions != null ? writeOptions.Flags : default(WriteFlags); } - public static ServerCallContext NewContext(ServerRpcNew newRpc, ServerResponseStream serverResponseStream, CancellationToken cancellationToken) - where TRequest : class - where TResponse : class + public static ServerCallContext NewContext(ServerRpcNew newRpc, IServerResponseStream serverResponseStream, CancellationToken cancellationToken) { DateTime realtimeDeadline = newRpc.Deadline.ToClockType(ClockType.Realtime).ToDateTime(); - return new ServerCallContext(newRpc.Call, newRpc.Method, newRpc.Host, realtimeDeadline, - newRpc.RequestMetadata, cancellationToken, serverResponseStream.WriteResponseHeadersAsync, serverResponseStream); + var contextExtraData = new ServerCallContextExtraData(newRpc.Call, serverResponseStream); + return contextExtraData.NewServerCallContext(newRpc, cancellationToken); } } } diff --git a/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs b/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs index 352b98829c7..079849e4c61 100644 --- a/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs +++ b/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs @@ -23,7 +23,7 @@ namespace Grpc.Core.Internal /// /// Writes responses asynchronously to an underlying AsyncCallServer object. /// - internal class ServerResponseStream : IServerStreamWriter, IHasWriteOptions + internal class ServerResponseStream : IServerStreamWriter, IServerResponseStream where TRequest : class where TResponse : class { diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs index 74a7deabea0..05c20ca75f8 100644 --- a/src/csharp/Grpc.Core/ServerCallContext.cs +++ b/src/csharp/Grpc.Core/ServerCallContext.cs @@ -21,6 +21,7 @@ using System.Threading; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Utils; namespace Grpc.Core { @@ -29,45 +30,49 @@ namespace Grpc.Core /// public class ServerCallContext { - private readonly CallSafeHandle callHandle; + private readonly object extraData; private readonly string method; private readonly string host; private readonly DateTime deadline; private readonly Metadata requestHeaders; private readonly CancellationToken cancellationToken; private readonly Metadata responseTrailers = new Metadata(); - private readonly Func writeHeadersFunc; - private readonly IHasWriteOptions writeOptionsHolder; - private readonly Lazy authContext; - private readonly Func testingOnlyPeerGetter; - private readonly Func testingOnlyAuthContextGetter; - private readonly Func testingOnlyContextPropagationTokenFactory; + private readonly Func writeHeadersFunc; + private readonly Func writeOptionsGetter; + private readonly Action writeOptionsSetter; + + private readonly Func peerGetter; + private readonly Func authContextGetter; + private readonly Func contextPropagationTokenFactory; private Status status = Status.DefaultSuccess; - internal ServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, - Func writeHeadersFunc, IHasWriteOptions writeOptionsHolder) - : this(callHandle, method, host, deadline, requestHeaders, cancellationToken, writeHeadersFunc, writeOptionsHolder, null, null, null) + /// + /// Creates a new instance of ServerCallContext. + /// To allow reuse of ServerCallContext API by different gRPC implementations, the implementation of some members is provided externally. + /// To provide state, this ServerCallContext instance and extraData will be passed to the member implementations. + /// + internal ServerCallContext(object extraData, + string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, + Func writeHeadersFunc, + Func writeOptionsGetter, + Action writeOptionsSetter, + Func peerGetter, + Func authContextGetter, + Func contextPropagationTokenFactory) { - } - - // Additional constructor params should be used for testing only - internal ServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, - Func writeHeadersFunc, IHasWriteOptions writeOptionsHolder, - Func testingOnlyPeerGetter, Func testingOnlyAuthContextGetter, Func testingOnlyContextPropagationTokenFactory) - { - this.callHandle = callHandle; + this.extraData = extraData; this.method = method; this.host = host; this.deadline = deadline; this.requestHeaders = requestHeaders; this.cancellationToken = cancellationToken; - this.writeHeadersFunc = writeHeadersFunc; - this.writeOptionsHolder = writeOptionsHolder; - this.authContext = new Lazy(GetAuthContextEager); - this.testingOnlyPeerGetter = testingOnlyPeerGetter; - this.testingOnlyAuthContextGetter = testingOnlyAuthContextGetter; - this.testingOnlyContextPropagationTokenFactory = testingOnlyContextPropagationTokenFactory; + this.writeHeadersFunc = GrpcPreconditions.CheckNotNull(writeHeadersFunc); + this.writeOptionsGetter = GrpcPreconditions.CheckNotNull(writeOptionsGetter); + this.writeOptionsSetter = GrpcPreconditions.CheckNotNull(writeOptionsSetter); + this.peerGetter = GrpcPreconditions.CheckNotNull(peerGetter); + this.authContextGetter = GrpcPreconditions.CheckNotNull(authContextGetter); + this.contextPropagationTokenFactory = GrpcPreconditions.CheckNotNull(contextPropagationTokenFactory); } /// @@ -79,7 +84,7 @@ namespace Grpc.Core /// The task that finished once response headers have been written. public Task WriteResponseHeadersAsync(Metadata responseHeaders) { - return writeHeadersFunc(responseHeaders); + return writeHeadersFunc(this, extraData, responseHeaders); } /// @@ -87,13 +92,9 @@ namespace Grpc.Core /// public ContextPropagationToken CreatePropagationToken(ContextPropagationOptions options = null) { - if (testingOnlyContextPropagationTokenFactory != null) - { - return testingOnlyContextPropagationTokenFactory(); - } - return new ContextPropagationToken(callHandle, deadline, cancellationToken, options); + return contextPropagationTokenFactory(this, extraData, options); } - + /// Name of method called in this RPC. public string Method { @@ -117,14 +118,7 @@ namespace Grpc.Core { get { - if (testingOnlyPeerGetter != null) - { - return testingOnlyPeerGetter(); - } - // Getting the peer lazily is fine as the native call is guaranteed - // not to be disposed before user-supplied server side handler returns. - // Most users won't need to read this field anyway. - return this.callHandle.GetPeer(); + return peerGetter(this, extraData); } } @@ -187,12 +181,12 @@ namespace Grpc.Core { get { - return writeOptionsHolder.WriteOptions; + return writeOptionsGetter(this, extraData); } set { - writeOptionsHolder.WriteOptions = value; + writeOptionsSetter(this, extraData, value); } } @@ -204,31 +198,8 @@ namespace Grpc.Core { get { - if (testingOnlyAuthContextGetter != null) - { - return testingOnlyAuthContextGetter(); - } - return authContext.Value; + return authContextGetter(this, extraData); } } - - private AuthContext GetAuthContextEager() - { - using (var authContextNative = callHandle.GetAuthContext()) - { - return authContextNative.ToAuthContext(); - } - } - } - - /// - /// Allows sharing write options between ServerCallContext and other objects. - /// - internal interface IHasWriteOptions - { - /// - /// Gets or sets the write options. - /// - WriteOptions WriteOptions { get; set; } } } From e8cd36924e4b2eb9d04a8d580579327976d99244 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 16 Jan 2019 10:19:14 -0800 Subject: [PATCH 069/814] Add test for retry code path. --- src/core/lib/transport/service_config.h | 1 + test/cpp/end2end/client_lb_end2end_test.cc | 34 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h index 2c0dd758453..0d78016ab05 100644 --- a/src/core/lib/transport/service_config.h +++ b/src/core/lib/transport/service_config.h @@ -240,6 +240,7 @@ RefCountedPtr ServiceConfig::MethodConfigTableLookup( value = table.Get(wildcard_path); grpc_slice_unref_internal(wildcard_path); gpr_free(path_str); + if (value == nullptr) return nullptr; } return RefCountedPtr(*value); } diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index d52f16d8f20..b4c1d8594cd 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -1251,7 +1251,7 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest { int trailers_intercepted_ = 0; }; -TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetries) { +TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) { const int kNumServers = 1; const int kNumRpcs = 10; StartServers(kNumServers); @@ -1267,6 +1267,38 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetries) { EXPECT_EQ(kNumRpcs, trailers_intercepted()); } +TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesEnabled) { + const int kNumServers = 1; + const int kNumRpcs = 10; + StartServers(kNumServers); + ChannelArguments args; + args.SetServiceConfigJSON( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"grpc.testing.EchoTestService\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"); + auto channel = BuildChannel("intercept_trailing_metadata_lb", args); + auto stub = BuildStub(channel); + SetNextResolution(GetServersPorts()); + for (size_t i = 0; i < kNumRpcs; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + // Check LB policy name for the channel. + EXPECT_EQ("intercept_trailing_metadata_lb", + channel->GetLoadBalancingPolicyName()); + EXPECT_EQ(kNumRpcs, trailers_intercepted()); +} + } // namespace } // namespace testing } // namespace grpc From 0579dcaed6fbfa88765e5640c9262dd3bcc8801d Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 16 Jan 2019 10:26:59 -0800 Subject: [PATCH 070/814] Escalate the failure of protoc execution --- tools/distrib/python/grpcio_tools/grpc_tools/command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/command.py b/tools/distrib/python/grpcio_tools/grpc_tools/command.py index 7ede05f1404..93503c4cc36 100644 --- a/tools/distrib/python/grpcio_tools/grpc_tools/command.py +++ b/tools/distrib/python/grpcio_tools/grpc_tools/command.py @@ -42,7 +42,7 @@ def build_package_protos(package_root): '--grpc_python_out={}'.format(inclusion_root), ] + [proto_file] if protoc.main(command) != 0: - sys.stderr.write('warning: {} failed'.format(command)) + raise RuntimeError('error: {} failed'.format(command)) class BuildPackageProtos(setuptools.Command): From 109a6a9a09320e48fbd8e8f73ca98425d150f2a1 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 16 Jan 2019 10:32:18 -0800 Subject: [PATCH 071/814] Revert "Upgrade Bazel to 21.0" This reverts commit 206a76b332dbc0c1e2127e03857831225003f092. --- tools/dockerfile/test/bazel/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index 05c187894cc..0aa6209f4fd 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -46,7 +46,7 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Bazel installation RUN apt-get update && apt-get install -y wget && apt-get clean -RUN wget -q https://github.com/bazelbuild/bazel/releases/download/0.21.0/bazel-0.21.0-linux-x86_64 -O /usr/local/bin/bazel +RUN wget -q https://github.com/bazelbuild/bazel/releases/download/0.17.1/bazel-0.17.1-linux-x86_64 -O /usr/local/bin/bazel RUN chmod 755 /usr/local/bin/bazel From 17fa4b0caf059791e66ae5edf7c9c1a82db94d7b Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 16 Jan 2019 10:43:15 -0800 Subject: [PATCH 072/814] Use monkey patch function to solve namespace package issue --- .../grpcio_status/grpc_status/rpc_status.py | 5 --- src/python/grpcio_tests/tests/BUILD.bazel | 8 +++++ src/python/grpcio_tests/tests/bazel_patch.py | 32 +++++++++++++++++++ .../grpcio_tests/tests/interop/BUILD.bazel | 1 + .../grpcio_tests/tests/interop/methods.py | 3 ++ .../grpcio_tests/tests/status/BUILD.bazel | 1 + .../tests/status/_grpc_status_test.py | 3 ++ 7 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 src/python/grpcio_tests/tests/BUILD.bazel create mode 100644 src/python/grpcio_tests/tests/bazel_patch.py diff --git a/src/python/grpcio_status/grpc_status/rpc_status.py b/src/python/grpcio_status/grpc_status/rpc_status.py index 87618fa5412..76891e2422e 100644 --- a/src/python/grpcio_status/grpc_status/rpc_status.py +++ b/src/python/grpcio_status/grpc_status/rpc_status.py @@ -17,11 +17,6 @@ import collections import grpc -# TODO(https://github.com/bazelbuild/bazel/issues/6844) -# Due to Bazel issue, the namespace packages won't resolve correctly. -# Adding this unused-import as a workaround to avoid module-not-found error -# under Bazel builds. -import google.protobuf # pylint: disable=unused-import from google.rpc import status_pb2 _CODE_TO_GRPC_CODE_MAPPING = {x.value[0]: x for x in grpc.StatusCode} diff --git a/src/python/grpcio_tests/tests/BUILD.bazel b/src/python/grpcio_tests/tests/BUILD.bazel new file mode 100644 index 00000000000..118cd0ea0dd --- /dev/null +++ b/src/python/grpcio_tests/tests/BUILD.bazel @@ -0,0 +1,8 @@ +py_library( + name = "bazel_patch", + srcs = ["bazel_patch.py"], + visibility = ["//visibility:public"], + data=[ + "//src/python/grpcio_tests/tests/unit/credentials", + ], +) diff --git a/src/python/grpcio_tests/tests/bazel_patch.py b/src/python/grpcio_tests/tests/bazel_patch.py new file mode 100644 index 00000000000..af48697de30 --- /dev/null +++ b/src/python/grpcio_tests/tests/bazel_patch.py @@ -0,0 +1,32 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import site +import sys + + +# TODO(https://github.com/bazelbuild/bazel/issues/6844) Bazel failed to +# interpret namespace packages correctly. This monkey patch will force the +# Python process to parse the .pth file in the sys.path to resolve namespace +# package in the right place. +# Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 +def bazel_patch(): + """Add valid sys.path item to site directory to parse the .pth files.""" + for item in sys.path: + if os.path.exists(item): + # The only difference between sys.path and site-directory is + # whether the .pth file will be parsed or not. A site-directory + # will always exist in sys.path, but not another way around. + site.addsitedir(item) diff --git a/src/python/grpcio_tests/tests/interop/BUILD.bazel b/src/python/grpcio_tests/tests/interop/BUILD.bazel index edb2e778b08..bb5f0f344e2 100644 --- a/src/python/grpcio_tests/tests/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests/interop/BUILD.bazel @@ -29,6 +29,7 @@ py_library( srcs = ["methods.py"], deps = [ "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests:bazel_patch", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing:py_messages_proto", "//src/proto/grpc/testing:py_test_proto", diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index c11f6c8fad7..e037046691b 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -13,6 +13,9 @@ # limitations under the License. """Implementations of interoperability test methods.""" +from tests.bazel_patch import bazel_patch +bazel_patch() + import enum import json import os diff --git a/src/python/grpcio_tests/tests/status/BUILD.bazel b/src/python/grpcio_tests/tests/status/BUILD.bazel index 937e50498e0..21dea5a76dc 100644 --- a/src/python/grpcio_tests/tests/status/BUILD.bazel +++ b/src/python/grpcio_tests/tests/status/BUILD.bazel @@ -10,6 +10,7 @@ py_test( deps = [ "//src/python/grpcio/grpc:grpcio", "//src/python/grpcio_status/grpc_status:grpc_status", + "//src/python/grpcio_tests/tests:bazel_patch", "//src/python/grpcio_tests/tests/unit:test_common", "//src/python/grpcio_tests/tests/unit/framework/common:common", requirement('protobuf'), diff --git a/src/python/grpcio_tests/tests/status/_grpc_status_test.py b/src/python/grpcio_tests/tests/status/_grpc_status_test.py index 519c372a960..67b1785becb 100644 --- a/src/python/grpcio_tests/tests/status/_grpc_status_test.py +++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py @@ -13,6 +13,9 @@ # limitations under the License. """Tests of grpc_status.""" +from tests.bazel_patch import bazel_patch +bazel_patch() + import unittest import logging From 2dbabc7a8f92d5fe6d3aef8a30297979e5073a9b Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 16 Jan 2019 12:07:50 -0800 Subject: [PATCH 073/814] Add new grpc_tools setuptools command BuildPackageProtosStrict --- .../python/grpcio_tools/grpc_tools/command.py | 100 ++++++++++++++++-- 1 file changed, 89 insertions(+), 11 deletions(-) diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/command.py b/tools/distrib/python/grpcio_tools/grpc_tools/command.py index 93503c4cc36..ee311144225 100644 --- a/tools/distrib/python/grpcio_tools/grpc_tools/command.py +++ b/tools/distrib/python/grpcio_tools/grpc_tools/command.py @@ -15,11 +15,36 @@ import os import pkg_resources import sys +import tempfile import setuptools from grpc_tools import protoc +_WELL_KNOWN_PROTOS_INCLUDE = pkg_resources.resource_filename( + 'grpc_tools', '_proto') + + +def _compile_proto(proto_file, + include='', + python_out='', + grpc_python_out='', + strict=False): + command = [ + 'grpc_tools.protoc', + '--proto_path={}'.format(include), + '--proto_path={}'.format(_WELL_KNOWN_PROTOS_INCLUDE), + '--python_out={}'.format(python_out), + '--grpc_python_out={}'.format(grpc_python_out), + ] + [proto_file] + if protoc.main(command) != 0: + if strict: + sys.stderr.write('error: {} failed'.format(command)) + else: + sys.stderr.write('warning: {} failed'.format(command)) + return False + return True + def build_package_protos(package_root): proto_files = [] @@ -30,19 +55,49 @@ def build_package_protos(package_root): proto_files.append( os.path.abspath(os.path.join(root, filename))) - well_known_protos_include = pkg_resources.resource_filename( - 'grpc_tools', '_proto') + for proto_file in proto_files: + _compile_proto( + proto_file, + include=inclusion_root, + python_out=inclusion_root, + grpc_python_out=inclusion_root, + strict=False, + ) + + +def build_package_protos_strict(package_root): + proto_files = [] + inclusion_root = os.path.abspath(package_root) + for root, _, files in os.walk(inclusion_root): + for filename in files: + if filename.endswith('.proto'): + proto_files.append( + os.path.abspath(os.path.join(root, filename))) + + tmp_out_directory = tempfile.mkdtemp() + compile_failed = False + for proto_file in proto_files: + # Output all the errors across all the files instead of exiting on the + # first error proto file. + compile_failed |= not _compile_proto( + proto_file, + include=inclusion_root, + python_out=tmp_out_directory, + grpc_python_out=tmp_out_directory, + strict=True, + ) + + if compile_failed: + sys.exit(1) for proto_file in proto_files: - command = [ - 'grpc_tools.protoc', - '--proto_path={}'.format(inclusion_root), - '--proto_path={}'.format(well_known_protos_include), - '--python_out={}'.format(inclusion_root), - '--grpc_python_out={}'.format(inclusion_root), - ] + [proto_file] - if protoc.main(command) != 0: - raise RuntimeError('error: {} failed'.format(command)) + _compile_proto( + proto_file, + include=inclusion_root, + python_out=inclusion_root, + grpc_python_out=inclusion_root, + strict=False, + ) class BuildPackageProtos(setuptools.Command): @@ -63,3 +118,26 @@ class BuildPackageProtos(setuptools.Command): # to `self.distribution.package_dir` (and get a key error if it's not # there). build_package_protos(self.distribution.package_dir['']) + + +class BuildPackageProtosStrict(setuptools.Command): + """Command to strictly generate project *_pb2.py modules from proto files. + + The generation will abort if any of the proto files contains error. + """ + + description = 'strictly build grpc protobuf modules' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + # due to limitations of the proto generator, we require that only *one* + # directory is provided as an 'include' directory. We assume it's the '' key + # to `self.distribution.package_dir` (and get a key error if it's not + # there). + build_package_protos_strict(self.distribution.package_dir['']) From 60e4ec2caf8beb496f96e75067366704a84f1693 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 16 Jan 2019 13:22:10 -0800 Subject: [PATCH 074/814] Clean up debug messages --- src/objective-c/GRPCClient/GRPCCall.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index e8fae09a1f8..16c01d01ce7 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -599,7 +599,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; dispatch_async(_callQueue, ^{ __weak GRPCCall *weakSelf = self; [self startReadWithHandler:^(grpc_byte_buffer *message) { - NSLog(@"message received"); if (message == NULL) { // No more messages from the server return; @@ -773,7 +772,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; __weak GRPCCall *weakSelf = self; [self invokeCallWithHeadersHandler:^(NSDictionary *headers) { // Response headers received. - NSLog(@"response received"); __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { strongSelf.responseHeaders = headers; @@ -781,7 +779,6 @@ const char *kCFStreamVarName = "grpc_cfstream"; } } completionHandler:^(NSError *error, NSDictionary *trailers) { - NSLog(@"completion received"); __strong GRPCCall *strongSelf = weakSelf; if (strongSelf) { strongSelf.responseTrailers = trailers; From e4d89692a703f0d946ec6ad0e3be4968b2c31b2a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 16 Jan 2019 13:36:11 -0800 Subject: [PATCH 075/814] Increase C++ podspec version --- gRPC-C++.podspec | 2 +- templates/gRPC-C++.podspec.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 0257f4713e8..b2f427fed12 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -24,7 +24,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized # version = '1.18.0' - version = '0.0.6' + version = '0.0.7' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template index 1c03cb3e840..fc786a5b435 100644 --- a/templates/gRPC-C++.podspec.template +++ b/templates/gRPC-C++.podspec.template @@ -140,7 +140,7 @@ s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized # version = '${settings.version}' - version = '${modify_podspec_version_string('0.0.6', settings.version)}' + version = '${modify_podspec_version_string('0.0.7', settings.version)}' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' From 7dd938d5f4b74b080f47a2cfa349486503292985 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 16 Jan 2019 14:27:10 -0800 Subject: [PATCH 076/814] Reviewer comments --- examples/cpp/keyvaluestore/caching_interceptor.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/cpp/keyvaluestore/caching_interceptor.h b/examples/cpp/keyvaluestore/caching_interceptor.h index a5d130da8dd..8ecdafaf159 100644 --- a/examples/cpp/keyvaluestore/caching_interceptor.h +++ b/examples/cpp/keyvaluestore/caching_interceptor.h @@ -27,7 +27,7 @@ #endif // This is a naive implementation of a cache. A new cache is for each call. For -// each new key request, the key is first searched in the map and if found. Only +// each new key request, the key is first searched in the map and if found, the interceptor feeds in the value. Only // if the key is not found in the cache do we make a request. class CachingInterceptor : public grpc::experimental::Interceptor { public: @@ -102,8 +102,10 @@ class CachingInterceptor : public grpc::experimental::Interceptor { *status = grpc::Status::OK; } if (hijack) { + // Hijack is called only once when PRE_SEND_INITIAL_METADATA is present in the hook points methods->Hijack(); } else { + // Proceed is an indicator that the interceptor is done intercepting the batch. methods->Proceed(); } } From 92c4dffc174491d056207699fb93731d942cd7cf Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 16 Jan 2019 15:10:48 -0800 Subject: [PATCH 077/814] Remove uneeded lock --- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 40bf9c65644..31b454098e1 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1208,7 +1208,6 @@ void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_channels) { // delegate to the RoundRobin to fill the children subchannels. rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); - MutexLock lock(&lb_channel_mu_); if (lb_channel_ != nullptr) { grpc_core::channelz::ChannelNode* channel_node = grpc_channel_get_channelz_node(lb_channel_); From 6e3fee6f2aeeccca2b6e63b7be2a72c0db51bd84 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 16 Jan 2019 15:27:21 -0800 Subject: [PATCH 078/814] Add additional nullptr check --- .../ext/filters/client_channel/lb_policy/grpclb/grpclb.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 31b454098e1..78de8b35659 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1207,7 +1207,9 @@ void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { // delegate to the RoundRobin to fill the children subchannels. - rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + if (rr_policy_ != nullptr) { + rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + } if (lb_channel_ != nullptr) { grpc_core::channelz::ChannelNode* channel_node = grpc_channel_get_channelz_node(lb_channel_); From 993d624236dd35645acf7fb35de71660aefde1d6 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Fri, 4 Jan 2019 09:21:17 +0000 Subject: [PATCH 079/814] Pin bundler in ruby interop build --- tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh index 67f66090ae9..e71ad91499a 100755 --- a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh @@ -30,4 +30,4 @@ cd /var/local/git/grpc rvm --default use ruby-2.5 # build Ruby interop client and server -(cd src/ruby && gem update bundler && bundle && rake compile) +(cd src/ruby && gem install bundler -v 1.17.3 && bundle && rake compile) From 1b07aba6af03626a8dc24a895f349648e4aebaa1 Mon Sep 17 00:00:00 2001 From: Maxim Bunkov Date: Thu, 17 Jan 2019 10:24:39 +0500 Subject: [PATCH 080/814] Update templates for supprt tvOS --- templates/gRPC-C++.podspec.template | 2 + templates/gRPC-Core.podspec.template | 2 + templates/gRPC-ProtoRPC.podspec.template | 1 + templates/gRPC-RxLibrary.podspec.template | 1 + templates/gRPC.podspec.template | 1 + ...!ProtoCompiler-gRPCPlugin.podspec.template | 1 + .../BoringSSL-GRPC.podspec.template | 6069 ++++++++++++----- 7 files changed, 4529 insertions(+), 1548 deletions(-) diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template index 94d5a4fb09e..371d25cd6ba 100644 --- a/templates/gRPC-C++.podspec.template +++ b/templates/gRPC-C++.podspec.template @@ -156,6 +156,8 @@ s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' + s.requires_arc = false name = 'grpcpp' diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 98b6344a4bf..7a1d3b1acdc 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -99,6 +99,8 @@ s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' + s.requires_arc = false name = 'grpc' diff --git a/templates/gRPC-ProtoRPC.podspec.template b/templates/gRPC-ProtoRPC.podspec.template index 96966784f18..9d7e392a24a 100644 --- a/templates/gRPC-ProtoRPC.podspec.template +++ b/templates/gRPC-ProtoRPC.podspec.template @@ -37,6 +37,7 @@ s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'ProtoRPC' s.module_name = name diff --git a/templates/gRPC-RxLibrary.podspec.template b/templates/gRPC-RxLibrary.podspec.template index 14147d7dc1b..0973b6551db 100644 --- a/templates/gRPC-RxLibrary.podspec.template +++ b/templates/gRPC-RxLibrary.podspec.template @@ -37,6 +37,7 @@ s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'RxLibrary' s.module_name = name diff --git a/templates/gRPC.podspec.template b/templates/gRPC.podspec.template index a3190c2d8e6..7cbd52157f5 100644 --- a/templates/gRPC.podspec.template +++ b/templates/gRPC.podspec.template @@ -36,6 +36,7 @@ s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'GRPCClient' s.module_name = name diff --git a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template index 30b6c5684cc..3e095d7aab7 100644 --- a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template +++ b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template @@ -107,6 +107,7 @@ # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' # Restrict the gRPC runtime version to the one supported by this plugin. s.dependency 'gRPC-ProtoRPC', v diff --git a/templates/src/objective-c/BoringSSL-GRPC.podspec.template b/templates/src/objective-c/BoringSSL-GRPC.podspec.template index 2b3bb8d97a4..42e3c7a82ea 100644 --- a/templates/src/objective-c/BoringSSL-GRPC.podspec.template +++ b/templates/src/objective-c/BoringSSL-GRPC.podspec.template @@ -4,1559 +4,4532 @@ def expand_symbol_list(symbol_list): return ',\n '.join("'#define %s GRPC_SHADOW_%s'" % (symbol, symbol) for symbol in symbol_list) %> - # This file has been automatically generated from a template file. - # Please make modifications to - # `templates/src/objective-c/BoringSSL-GRPC.podspec.template` instead. This - # file can be regenerated from the template by running - # `tools/buildgen/generate_projects.sh`. - # BoringSSL CocoaPods podspec +# This file has been automatically generated from a template file. +# Please make modifications to +# `templates/src/objective-c/BoringSSL-GRPC.podspec.template` instead. This +# file can be regenerated from the template by running +# `tools/buildgen/generate_projects.sh`. - # Copyright 2015, Google Inc. - # All rights reserved. +# BoringSSL CocoaPods podspec + +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Pod::Spec.new do |s| + s.name = 'BoringSSL-GRPC' + version = '0.0.2' + s.version = version + s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.' + # Adapted from the homepage: + s.description = <<-DESC + BoringSSL is a fork of OpenSSL that is designed to meet Google's needs. + + Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. + We don't recommend that third parties depend upon it. Doing so is likely to be frustrating + because there are no guarantees of API stability. Only the latest version of this pod is + supported, and every new version is a new major version. + + We update Google libraries and programs that use BoringSSL as needed when deciding to make API + changes. This allows us to mostly avoid compromises in the name of compatibility. It works for + us, but it may not work for you. + + As a Cocoapods pod, it has the advantage over OpenSSL's pods that the library doesn't need to + be precompiled. This eliminates the 10 - 20 minutes of wait the first time a user does "pod + install", lets it be used as a dynamic framework (pending solution of Cocoapods' issue #4605), + and works with bitcode automatically. It's also thought to be smaller than OpenSSL (which takes + 1MB - 2MB per ARM architecture), but we don't have specific numbers yet. + + BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built + up a large number of patches that were maintained while tracking upstream OpenSSL. As Google's + product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved + in maintaining all these patches in multiple places was growing steadily. + + Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's not part of the + NDK) and a number of other apps/programs. + DESC + s.homepage = 'https://github.com/google/boringssl' + s.license = { :type => 'Mixed', :file => 'LICENSE' } + # "The name and email addresses of the library maintainers, not the Podspec maintainer." + s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite' + + s.source = { + :git => 'https://github.com/google/boringssl.git', + :commit => "b29b21a81b32ec273f118f589f46d56ad3332420", + } + + s.ios.deployment_target = '5.0' + s.osx.deployment_target = '10.7' + s.tvos.deployment_target = '10.0' + + name = 'openssl_grpc' + + # When creating a dynamic framework, name it openssl.framework instead of BoringSSL.framework. + # This lets users write their includes like `#include ` as opposed to `#include + # `. + s.module_name = name + + # When creating a dynamic framework, copy the headers under `include/openssl/` into the root of + # the `Headers/` directory of the framework (i.e., not under `Headers/include/openssl`). # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are - # met: - # - # * Redistributions of source code must retain the above copyright - # notice, this list of conditions and the following disclaimer. - # * Redistributions in binary form must reproduce the above - # copyright notice, this list of conditions and the following disclaimer - # in the documentation and/or other materials provided with the - # distribution. - # * Neither the name of Google Inc. nor the names of its - # contributors may be used to endorse or promote products derived from - # this software without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # TODO(jcanizales): Debug why this doesn't work on macOS. + s.header_mappings_dir = 'include/openssl' - Pod::Spec.new do |s| - s.name = 'BoringSSL-GRPC' - version = '0.0.2' - s.version = version - s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.' - # Adapted from the homepage: - s.description = <<-DESC - BoringSSL is a fork of OpenSSL that is designed to meet Google's needs. + # The above has an undesired effect when creating a static library: It forces users to write + # includes like `#include `. `s.header_dir` adds a path prefix to that, and + # because Cocoapods lets omit the pod name when including headers of static libraries, the + # following lets users write `#include `. + s.header_dir = name - Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. - We don't recommend that third parties depend upon it. Doing so is likely to be frustrating - because there are no guarantees of API stability. Only the latest version of this pod is - supported, and every new version is a new major version. + # The module map and umbrella header created automatically by Cocoapods don't work for C libraries + # like this one. The following file, and a correct umbrella header, are created on the fly by the + # `prepare_command` of this pod. + s.module_map = 'include/openssl/BoringSSL.modulemap' - We update Google libraries and programs that use BoringSSL as needed when deciding to make API - changes. This allows us to mostly avoid compromises in the name of compatibility. It works for - us, but it may not work for you. + # We don't need to inhibit all warnings; only -Wno-shorten-64-to-32. But Cocoapods' linter doesn't + # want that for some reason. + s.compiler_flags = '-DOPENSSL_NO_ASM', '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w' + s.requires_arc = false - As a Cocoapods pod, it has the advantage over OpenSSL's pods that the library doesn't need to - be precompiled. This eliminates the 10 - 20 minutes of wait the first time a user does "pod - install", lets it be used as a dynamic framework (pending solution of Cocoapods' issue #4605), - and works with bitcode automatically. It's also thought to be smaller than OpenSSL (which takes - 1MB - 2MB per ARM architecture), but we don't have specific numbers yet. - - BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built - up a large number of patches that were maintained while tracking upstream OpenSSL. As Google's - product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved - in maintaining all these patches in multiple places was growing steadily. - - Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's not part of the - NDK) and a number of other apps/programs. - DESC - s.homepage = 'https://github.com/google/boringssl' - s.license = { :type => 'Mixed', :file => 'LICENSE' } - # "The name and email addresses of the library maintainers, not the Podspec maintainer." - s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite' - - s.source = { - :git => 'https://github.com/google/boringssl.git', - :commit => "b29b21a81b32ec273f118f589f46d56ad3332420", - } - - s.ios.deployment_target = '5.0' - s.osx.deployment_target = '10.7' - - name = 'openssl_grpc' - - # When creating a dynamic framework, name it openssl.framework instead of BoringSSL.framework. - # This lets users write their includes like `#include ` as opposed to `#include - # `. - s.module_name = name - - # When creating a dynamic framework, copy the headers under `include/openssl/` into the root of - # the `Headers/` directory of the framework (i.e., not under `Headers/include/openssl`). - # - # TODO(jcanizales): Debug why this doesn't work on macOS. - s.header_mappings_dir = 'include/openssl' - - # The above has an undesired effect when creating a static library: It forces users to write - # includes like `#include `. `s.header_dir` adds a path prefix to that, and - # because Cocoapods lets omit the pod name when including headers of static libraries, the - # following lets users write `#include `. - s.header_dir = name - - # The module map and umbrella header created automatically by Cocoapods don't work for C libraries - # like this one. The following file, and a correct umbrella header, are created on the fly by the - # `prepare_command` of this pod. - s.module_map = 'include/openssl/BoringSSL.modulemap' - - # We don't need to inhibit all warnings; only -Wno-shorten-64-to-32. But Cocoapods' linter doesn't - # want that for some reason. - s.compiler_flags = '-DOPENSSL_NO_ASM', '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w' - s.requires_arc = false - - # Like many other C libraries, BoringSSL has its public headers under `include//` and its - # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't - # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in - # practice). Because we need our `header_mappings_dir` to be `include/openssl/` for the reason - # mentioned above, we work around the linter limitation by dividing the pod into two subspecs, one - # for public headers and the other for implementation. Each gets its own `header_mappings_dir`, - # making the linter happy. - s.subspec 'Interface' do |ss| - ss.header_mappings_dir = 'include/openssl' - ss.source_files = 'include/openssl/*.h' - end - s.subspec 'Implementation' do |ss| - ss.header_mappings_dir = '.' - ss.source_files = 'ssl/*.{h,cc}', - 'ssl/**/*.{h,cc}', - '*.{h,c}', - 'crypto/*.{h,c}', - 'crypto/**/*.{h,c}', - 'third_party/fiat/*.{h,c}' - ss.private_header_files = 'ssl/*.h', - 'ssl/**/*.h', - '*.h', - 'crypto/*.h', - 'crypto/**/*.h' - # bcm.c includes other source files, creating duplicated symbols. Since it is not used, we - # explicitly exclude it from the pod. - # TODO (mxyan): Work with BoringSSL team to remove this hack. - ss.exclude_files = 'crypto/fipsmodule/bcm.c', - '**/*_test.*', - '**/test_*.*', - '**/test/*.*' - - ss.dependency "#{s.name}/Interface", version - end - - s.prepare_command = <<-END_OF_COMMAND - # Add a module map and an umbrella header - cat > include/openssl/umbrella.h < include/openssl/BoringSSL.modulemap < err_data.c < - #include - #include - - - OPENSSL_COMPILE_ASSERT(ERR_LIB_NONE == 1, library_values_changed_1); - OPENSSL_COMPILE_ASSERT(ERR_LIB_SYS == 2, library_values_changed_2); - OPENSSL_COMPILE_ASSERT(ERR_LIB_BN == 3, library_values_changed_3); - OPENSSL_COMPILE_ASSERT(ERR_LIB_RSA == 4, library_values_changed_4); - OPENSSL_COMPILE_ASSERT(ERR_LIB_DH == 5, library_values_changed_5); - OPENSSL_COMPILE_ASSERT(ERR_LIB_EVP == 6, library_values_changed_6); - OPENSSL_COMPILE_ASSERT(ERR_LIB_BUF == 7, library_values_changed_7); - OPENSSL_COMPILE_ASSERT(ERR_LIB_OBJ == 8, library_values_changed_8); - OPENSSL_COMPILE_ASSERT(ERR_LIB_PEM == 9, library_values_changed_9); - OPENSSL_COMPILE_ASSERT(ERR_LIB_DSA == 10, library_values_changed_10); - OPENSSL_COMPILE_ASSERT(ERR_LIB_X509 == 11, library_values_changed_11); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ASN1 == 12, library_values_changed_12); - OPENSSL_COMPILE_ASSERT(ERR_LIB_CONF == 13, library_values_changed_13); - OPENSSL_COMPILE_ASSERT(ERR_LIB_CRYPTO == 14, library_values_changed_14); - OPENSSL_COMPILE_ASSERT(ERR_LIB_EC == 15, library_values_changed_15); - OPENSSL_COMPILE_ASSERT(ERR_LIB_SSL == 16, library_values_changed_16); - OPENSSL_COMPILE_ASSERT(ERR_LIB_BIO == 17, library_values_changed_17); - OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS7 == 18, library_values_changed_18); - OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS8 == 19, library_values_changed_19); - OPENSSL_COMPILE_ASSERT(ERR_LIB_X509V3 == 20, library_values_changed_20); - OPENSSL_COMPILE_ASSERT(ERR_LIB_RAND == 21, library_values_changed_21); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ENGINE == 22, library_values_changed_22); - OPENSSL_COMPILE_ASSERT(ERR_LIB_OCSP == 23, library_values_changed_23); - OPENSSL_COMPILE_ASSERT(ERR_LIB_UI == 24, library_values_changed_24); - OPENSSL_COMPILE_ASSERT(ERR_LIB_COMP == 25, library_values_changed_25); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDSA == 26, library_values_changed_26); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDH == 27, library_values_changed_27); - OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28); - OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29); - OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30); - OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31); - OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32); - OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num); - - const uint32_t kOpenSSLReasonValues[] = { - 0xc320838, - 0xc328852, - 0xc330861, - 0xc338871, - 0xc340880, - 0xc348899, - 0xc3508a5, - 0xc3588c2, - 0xc3608e2, - 0xc3688f0, - 0xc370900, - 0xc37890d, - 0xc38091d, - 0xc388928, - 0xc39093e, - 0xc39894d, - 0xc3a0961, - 0xc3a8845, - 0xc3b00ea, - 0xc3b88d4, - 0x10320845, - 0x10329513, - 0x1033151f, - 0x10339538, - 0x1034154b, - 0x10348eed, - 0x10350c5e, - 0x1035955e, - 0x10361573, - 0x10369586, - 0x103715a5, - 0x103795be, - 0x103815d3, - 0x103895f1, - 0x10391600, - 0x1039961c, - 0x103a1637, - 0x103a9646, - 0x103b1662, - 0x103b967d, - 0x103c1694, - 0x103c80ea, - 0x103d16a5, - 0x103d96b9, - 0x103e16d8, - 0x103e96e7, - 0x103f16fe, - 0x103f9711, - 0x10400c22, - 0x10409724, - 0x10411742, - 0x10419755, - 0x1042176f, - 0x1042977f, - 0x10431793, - 0x104397a9, - 0x104417c1, - 0x104497d6, - 0x104517ea, - 0x104597fc, - 0x104605fb, - 0x1046894d, - 0x10471811, - 0x10479828, - 0x1048183d, - 0x1048984b, - 0x10490e4f, - 0x14320c05, - 0x14328c13, - 0x14330c22, - 0x14338c34, - 0x143400ac, - 0x143480ea, - 0x18320083, - 0x18328f43, - 0x183300ac, - 0x18338f59, - 0x18340f6d, - 0x183480ea, - 0x18350f82, - 0x18358f9a, - 0x18360faf, - 0x18368fc3, - 0x18370fe7, - 0x18378ffd, - 0x18381011, - 0x18389021, - 0x18390a73, - 0x18399031, - 0x183a1059, - 0x183a907f, - 0x183b0c6a, - 0x183b90b4, - 0x183c10c6, - 0x183c90d1, - 0x183d10e1, - 0x183d90f2, - 0x183e1103, - 0x183e9115, - 0x183f113e, - 0x183f9157, - 0x1840116f, - 0x184086d3, - 0x184110a2, - 0x1841906d, - 0x1842108c, - 0x18429046, - 0x20321196, - 0x243211a2, - 0x24328993, - 0x243311b4, - 0x243391c1, - 0x243411ce, - 0x243491e0, - 0x243511ef, - 0x2435920c, - 0x24361219, - 0x24369227, - 0x24371235, - 0x24379243, - 0x2438124c, - 0x24389259, - 0x2439126c, - 0x28320c52, - 0x28328c6a, - 0x28330c22, - 0x28338c7d, - 0x28340c5e, - 0x283480ac, - 0x283500ea, - 0x2c322c30, - 0x2c329283, - 0x2c332c3e, - 0x2c33ac50, - 0x2c342c64, - 0x2c34ac76, - 0x2c352c91, - 0x2c35aca3, - 0x2c362cb6, - 0x2c36832d, - 0x2c372cc3, - 0x2c37acd5, - 0x2c382cfa, - 0x2c38ad11, - 0x2c392d1f, - 0x2c39ad2f, - 0x2c3a2d41, - 0x2c3aad55, - 0x2c3b2d66, - 0x2c3bad85, - 0x2c3c1295, - 0x2c3c92ab, - 0x2c3d2d99, - 0x2c3d92c4, - 0x2c3e2db6, - 0x2c3eadc4, - 0x2c3f2ddc, - 0x2c3fadf4, - 0x2c402e01, - 0x2c409196, - 0x2c412e12, - 0x2c41ae25, - 0x2c42116f, - 0x2c42ae36, - 0x2c430720, - 0x2c43ad77, - 0x2c442ce8, - 0x30320000, - 0x30328015, - 0x3033001f, - 0x30338038, - 0x3034004a, - 0x30348064, - 0x3035006b, - 0x30358083, - 0x30360094, - 0x303680ac, - 0x303700b9, - 0x303780c8, - 0x303800ea, - 0x303880f7, - 0x3039010a, - 0x30398125, - 0x303a013a, - 0x303a814e, - 0x303b0162, - 0x303b8173, - 0x303c018c, - 0x303c81a9, - 0x303d01b7, - 0x303d81cb, - 0x303e01db, - 0x303e81f4, - 0x303f0204, - 0x303f8217, - 0x30400226, - 0x30408232, - 0x30410247, - 0x30418257, - 0x3042026e, - 0x3042827b, - 0x3043028e, - 0x3043829d, - 0x304402b2, - 0x304482d3, - 0x304502e6, - 0x304582f9, - 0x30460312, - 0x3046832d, - 0x3047034a, - 0x30478363, - 0x30480371, - 0x30488382, - 0x30490391, - 0x304983a9, - 0x304a03bb, - 0x304a83cf, - 0x304b03ee, - 0x304b8401, - 0x304c040c, - 0x304c841d, - 0x304d0429, - 0x304d843f, - 0x304e044d, - 0x304e8463, - 0x304f0475, - 0x304f8487, - 0x3050049a, - 0x305084ad, - 0x305104be, - 0x305184ce, - 0x305204e6, - 0x305284fb, - 0x30530513, - 0x30538527, - 0x3054053f, - 0x30548558, - 0x30550571, - 0x3055858e, - 0x30560599, - 0x305685b1, - 0x305705c1, - 0x305785d2, - 0x305805e5, - 0x305885fb, - 0x30590604, - 0x30598619, - 0x305a062c, - 0x305a863b, - 0x305b065b, - 0x305b866a, - 0x305c068b, - 0x305c86a7, - 0x305d06b3, - 0x305d86d3, - 0x305e06ef, - 0x305e8700, - 0x305f0716, - 0x305f8720, - 0x34320b63, - 0x34328b77, - 0x34330b94, - 0x34338ba7, - 0x34340bb6, - 0x34348bef, - 0x34350bd3, - 0x3c320083, - 0x3c328ca7, - 0x3c330cc0, - 0x3c338cdb, - 0x3c340cf8, - 0x3c348d22, - 0x3c350d3d, - 0x3c358d63, - 0x3c360d7c, - 0x3c368d94, - 0x3c370da5, - 0x3c378db3, - 0x3c380dc0, - 0x3c388dd4, - 0x3c390c6a, - 0x3c398de8, - 0x3c3a0dfc, - 0x3c3a890d, - 0x3c3b0e0c, - 0x3c3b8e27, - 0x3c3c0e39, - 0x3c3c8e6c, - 0x3c3d0e76, - 0x3c3d8e8a, - 0x3c3e0e98, - 0x3c3e8ebd, - 0x3c3f0c93, - 0x3c3f8ea6, - 0x3c4000ac, - 0x3c4080ea, - 0x3c410d13, - 0x3c418d52, - 0x3c420e4f, - 0x403218a4, - 0x403298ba, - 0x403318e8, - 0x403398f2, - 0x40341909, - 0x40349927, - 0x40351937, - 0x40359949, - 0x40361956, - 0x40369962, - 0x40371977, - 0x40379989, - 0x40381994, - 0x403899a6, - 0x40390eed, - 0x403999b6, - 0x403a19c9, - 0x403a99ea, - 0x403b19fb, - 0x403b9a0b, - 0x403c0064, - 0x403c8083, - 0x403d1a8f, - 0x403d9aa5, - 0x403e1ab4, - 0x403e9aec, - 0x403f1b06, - 0x403f9b14, - 0x40401b29, - 0x40409b3d, - 0x40411b5a, - 0x40419b75, - 0x40421b8e, - 0x40429ba1, - 0x40431bb5, - 0x40439bcd, - 0x40441be4, - 0x404480ac, - 0x40451bf9, - 0x40459c0b, - 0x40461c2f, - 0x40469c4f, - 0x40471c5d, - 0x40479c84, - 0x40481cc1, - 0x40489cda, - 0x40491cf1, - 0x40499d0b, - 0x404a1d22, - 0x404a9d40, - 0x404b1d58, - 0x404b9d6f, - 0x404c1d85, - 0x404c9d97, - 0x404d1db8, - 0x404d9dda, - 0x404e1dee, - 0x404e9dfb, - 0x404f1e28, - 0x404f9e51, - 0x40501e8c, - 0x40509ea0, - 0x40511ebb, - 0x40521ecb, - 0x40529eef, - 0x40531f07, - 0x40539f1a, - 0x40541f2f, - 0x40549f52, - 0x40551f60, - 0x40559f7d, - 0x40561f8a, - 0x40569fa3, - 0x40571fbb, - 0x40579fce, - 0x40581fe3, - 0x4058a00a, - 0x40592039, - 0x4059a066, - 0x405a207a, - 0x405aa08a, - 0x405b20a2, - 0x405ba0b3, - 0x405c20c6, - 0x405ca105, - 0x405d2112, - 0x405da129, - 0x405e2167, - 0x405e8ab1, - 0x405f2188, - 0x405fa195, - 0x406021a3, - 0x4060a1c5, - 0x40612209, - 0x4061a241, - 0x40622258, - 0x4062a269, - 0x4063227a, - 0x4063a28f, - 0x406422a6, - 0x4064a2d2, - 0x406522ed, - 0x4065a304, - 0x4066231c, - 0x4066a346, - 0x40672371, - 0x4067a392, - 0x406823b9, - 0x4068a3da, - 0x4069240c, - 0x4069a43a, - 0x406a245b, - 0x406aa47b, - 0x406b2603, - 0x406ba626, - 0x406c263c, - 0x406ca8b7, - 0x406d28e6, - 0x406da90e, - 0x406e293c, - 0x406ea989, - 0x406f29a8, - 0x406fa9e0, - 0x407029f3, - 0x4070aa10, - 0x40710800, - 0x4071aa22, - 0x40722a35, - 0x4072aa4e, - 0x40732a66, - 0x40739482, - 0x40742a7a, - 0x4074aa94, - 0x40752aa5, - 0x4075aab9, - 0x40762ac7, - 0x40769259, - 0x40772aec, - 0x4077ab0e, - 0x40782b29, - 0x4078ab62, - 0x40792b79, - 0x4079ab8f, - 0x407a2b9b, - 0x407aabae, - 0x407b2bc3, - 0x407babd5, - 0x407c2c06, - 0x407cac0f, - 0x407d23f5, - 0x407d9e61, - 0x407e2b3e, - 0x407ea01a, - 0x407f1c71, - 0x407f9a31, - 0x40801e38, - 0x40809c99, - 0x40811edd, - 0x40819e12, - 0x40822927, - 0x40829a17, - 0x40831ff5, - 0x4083a2b7, - 0x40841cad, - 0x4084a052, - 0x408520d7, - 0x4085a1ed, - 0x40862149, - 0x40869e7b, - 0x4087296d, - 0x4087a21e, - 0x40881a78, - 0x4088a3a5, - 0x40891ac7, - 0x40899a54, - 0x408a265c, - 0x408a9862, - 0x408b2bea, - 0x408ba9bd, - 0x408c20e7, - 0x408c987e, - 0x41f4252e, - 0x41f925c0, - 0x41fe24b3, - 0x41fea6a8, - 0x41ff2799, - 0x42032547, - 0x42082569, - 0x4208a5a5, - 0x42092497, - 0x4209a5df, - 0x420a24ee, - 0x420aa4ce, - 0x420b250e, - 0x420ba587, - 0x420c27b5, - 0x420ca675, - 0x420d268f, - 0x420da6c6, - 0x421226e0, - 0x4217277c, - 0x4217a722, - 0x421c2744, - 0x421f26ff, - 0x422127cc, - 0x4226275f, - 0x422b289b, - 0x422ba849, - 0x422c2883, - 0x422ca808, - 0x422d27e7, - 0x422da868, - 0x422e282e, - 0x422ea954, - 0x4432072b, - 0x4432873a, - 0x44330746, - 0x44338754, - 0x44340767, - 0x44348778, - 0x4435077f, - 0x44358789, - 0x4436079c, - 0x443687b2, - 0x443707c4, - 0x443787d1, - 0x443807e0, - 0x443887e8, - 0x44390800, - 0x4439880e, - 0x443a0821, - 0x48321283, - 0x48329295, - 0x483312ab, - 0x483392c4, - 0x4c3212e9, - 0x4c3292f9, - 0x4c33130c, - 0x4c33932c, - 0x4c3400ac, - 0x4c3480ea, - 0x4c351338, - 0x4c359346, - 0x4c361362, - 0x4c369375, - 0x4c371384, - 0x4c379392, - 0x4c3813a7, - 0x4c3893b3, - 0x4c3913d3, - 0x4c3993fd, - 0x4c3a1416, - 0x4c3a942f, - 0x4c3b05fb, - 0x4c3b9448, - 0x4c3c145a, - 0x4c3c9469, - 0x4c3d1482, - 0x4c3d8c45, - 0x4c3e14db, - 0x4c3e9491, - 0x4c3f14fd, - 0x4c3f9259, - 0x4c4014a7, - 0x4c4092d5, - 0x4c4114cb, - 0x50322e48, - 0x5032ae57, - 0x50332e62, - 0x5033ae72, - 0x50342e8b, - 0x5034aea5, - 0x50352eb3, - 0x5035aec9, - 0x50362edb, - 0x5036aef1, - 0x50372f0a, - 0x5037af1d, - 0x50382f35, - 0x5038af46, - 0x50392f5b, - 0x5039af6f, - 0x503a2f8f, - 0x503aafa5, - 0x503b2fbd, - 0x503bafcf, - 0x503c2feb, - 0x503cb002, - 0x503d301b, - 0x503db031, - 0x503e303e, - 0x503eb054, - 0x503f3066, - 0x503f8382, - 0x50403079, - 0x5040b089, - 0x504130a3, - 0x5041b0b2, - 0x504230cc, - 0x5042b0e9, - 0x504330f9, - 0x5043b109, - 0x50443118, - 0x5044843f, - 0x5045312c, - 0x5045b14a, - 0x5046315d, - 0x5046b173, - 0x50473185, - 0x5047b19a, - 0x504831c0, - 0x5048b1ce, - 0x504931e1, - 0x5049b1f6, - 0x504a320c, - 0x504ab21c, - 0x504b323c, - 0x504bb24f, - 0x504c3272, - 0x504cb2a0, - 0x504d32b2, - 0x504db2cf, - 0x504e32ea, - 0x504eb306, - 0x504f3318, - 0x504fb32f, - 0x5050333e, - 0x505086ef, - 0x50513351, - 0x58320f2b, - 0x68320eed, - 0x68328c6a, - 0x68330c7d, - 0x68338efb, - 0x68340f0b, - 0x683480ea, - 0x6c320ec9, - 0x6c328c34, - 0x6c330ed4, - 0x74320a19, - 0x743280ac, - 0x74330c45, - 0x7832097e, - 0x78328993, - 0x7833099f, - 0x78338083, - 0x783409ae, - 0x783489c3, - 0x783509e2, - 0x78358a04, - 0x78360a19, - 0x78368a2f, - 0x78370a3f, - 0x78378a60, - 0x78380a73, - 0x78388a85, - 0x78390a92, - 0x78398ab1, - 0x783a0ac6, - 0x783a8ad4, - 0x783b0ade, - 0x783b8af2, - 0x783c0b09, - 0x783c8b1e, - 0x783d0b35, - 0x783d8b4a, - 0x783e0aa0, - 0x783e8a52, - 0x7c321185, - }; - - const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); - - const char kOpenSSLReasonStringData[] = - "ASN1_LENGTH_MISMATCH\\0" - "AUX_ERROR\\0" - "BAD_GET_ASN1_OBJECT_CALL\\0" - "BAD_OBJECT_HEADER\\0" - "BMPSTRING_IS_WRONG_LENGTH\\0" - "BN_LIB\\0" - "BOOLEAN_IS_WRONG_LENGTH\\0" - "BUFFER_TOO_SMALL\\0" - "CONTEXT_NOT_INITIALISED\\0" - "DECODE_ERROR\\0" - "DEPTH_EXCEEDED\\0" - "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\\0" - "ENCODE_ERROR\\0" - "ERROR_GETTING_TIME\\0" - "EXPECTING_AN_ASN1_SEQUENCE\\0" - "EXPECTING_AN_INTEGER\\0" - "EXPECTING_AN_OBJECT\\0" - "EXPECTING_A_BOOLEAN\\0" - "EXPECTING_A_TIME\\0" - "EXPLICIT_LENGTH_MISMATCH\\0" - "EXPLICIT_TAG_NOT_CONSTRUCTED\\0" - "FIELD_MISSING\\0" - "FIRST_NUM_TOO_LARGE\\0" - "HEADER_TOO_LONG\\0" - "ILLEGAL_BITSTRING_FORMAT\\0" - "ILLEGAL_BOOLEAN\\0" - "ILLEGAL_CHARACTERS\\0" - "ILLEGAL_FORMAT\\0" - "ILLEGAL_HEX\\0" - "ILLEGAL_IMPLICIT_TAG\\0" - "ILLEGAL_INTEGER\\0" - "ILLEGAL_NESTED_TAGGING\\0" - "ILLEGAL_NULL\\0" - "ILLEGAL_NULL_VALUE\\0" - "ILLEGAL_OBJECT\\0" - "ILLEGAL_OPTIONAL_ANY\\0" - "ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE\\0" - "ILLEGAL_TAGGED_ANY\\0" - "ILLEGAL_TIME_VALUE\\0" - "INTEGER_NOT_ASCII_FORMAT\\0" - "INTEGER_TOO_LARGE_FOR_LONG\\0" - "INVALID_BIT_STRING_BITS_LEFT\\0" - "INVALID_BMPSTRING_LENGTH\\0" - "INVALID_DIGIT\\0" - "INVALID_MODIFIER\\0" - "INVALID_NUMBER\\0" - "INVALID_OBJECT_ENCODING\\0" - "INVALID_SEPARATOR\\0" - "INVALID_TIME_FORMAT\\0" - "INVALID_UNIVERSALSTRING_LENGTH\\0" - "INVALID_UTF8STRING\\0" - "LIST_ERROR\\0" - "MISSING_ASN1_EOS\\0" - "MISSING_EOC\\0" - "MISSING_SECOND_NUMBER\\0" - "MISSING_VALUE\\0" - "MSTRING_NOT_UNIVERSAL\\0" - "MSTRING_WRONG_TAG\\0" - "NESTED_ASN1_ERROR\\0" - "NESTED_ASN1_STRING\\0" - "NON_HEX_CHARACTERS\\0" - "NOT_ASCII_FORMAT\\0" - "NOT_ENOUGH_DATA\\0" - "NO_MATCHING_CHOICE_TYPE\\0" - "NULL_IS_WRONG_LENGTH\\0" - "OBJECT_NOT_ASCII_FORMAT\\0" - "ODD_NUMBER_OF_CHARS\\0" - "SECOND_NUMBER_TOO_LARGE\\0" - "SEQUENCE_LENGTH_MISMATCH\\0" - "SEQUENCE_NOT_CONSTRUCTED\\0" - "SEQUENCE_OR_SET_NEEDS_CONFIG\\0" - "SHORT_LINE\\0" - "STREAMING_NOT_SUPPORTED\\0" - "STRING_TOO_LONG\\0" - "STRING_TOO_SHORT\\0" - "TAG_VALUE_TOO_HIGH\\0" - "TIME_NOT_ASCII_FORMAT\\0" - "TOO_LONG\\0" - "TYPE_NOT_CONSTRUCTED\\0" - "TYPE_NOT_PRIMITIVE\\0" - "UNEXPECTED_EOC\\0" - "UNIVERSALSTRING_IS_WRONG_LENGTH\\0" - "UNKNOWN_FORMAT\\0" - "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\\0" - "UNKNOWN_SIGNATURE_ALGORITHM\\0" - "UNKNOWN_TAG\\0" - "UNSUPPORTED_ANY_DEFINED_BY_TYPE\\0" - "UNSUPPORTED_PUBLIC_KEY_TYPE\\0" - "UNSUPPORTED_TYPE\\0" - "WRONG_PUBLIC_KEY_TYPE\\0" - "WRONG_TAG\\0" - "WRONG_TYPE\\0" - "BAD_FOPEN_MODE\\0" - "BROKEN_PIPE\\0" - "CONNECT_ERROR\\0" - "ERROR_SETTING_NBIO\\0" - "INVALID_ARGUMENT\\0" - "IN_USE\\0" - "KEEPALIVE\\0" - "NBIO_CONNECT_ERROR\\0" - "NO_HOSTNAME_SPECIFIED\\0" - "NO_PORT_SPECIFIED\\0" - "NO_SUCH_FILE\\0" - "NULL_PARAMETER\\0" - "SYS_LIB\\0" - "UNABLE_TO_CREATE_SOCKET\\0" - "UNINITIALIZED\\0" - "UNSUPPORTED_METHOD\\0" - "WRITE_TO_READ_ONLY_BIO\\0" - "ARG2_LT_ARG3\\0" - "BAD_ENCODING\\0" - "BAD_RECIPROCAL\\0" - "BIGNUM_TOO_LONG\\0" - "BITS_TOO_SMALL\\0" - "CALLED_WITH_EVEN_MODULUS\\0" - "DIV_BY_ZERO\\0" - "EXPAND_ON_STATIC_BIGNUM_DATA\\0" - "INPUT_NOT_REDUCED\\0" - "INVALID_INPUT\\0" - "INVALID_RANGE\\0" - "NEGATIVE_NUMBER\\0" - "NOT_A_SQUARE\\0" - "NOT_INITIALIZED\\0" - "NO_INVERSE\\0" - "PRIVATE_KEY_TOO_LARGE\\0" - "P_IS_NOT_PRIME\\0" - "TOO_MANY_ITERATIONS\\0" - "TOO_MANY_TEMPORARY_VARIABLES\\0" - "AES_KEY_SETUP_FAILED\\0" - "BAD_DECRYPT\\0" - "BAD_KEY_LENGTH\\0" - "CTRL_NOT_IMPLEMENTED\\0" - "CTRL_OPERATION_NOT_IMPLEMENTED\\0" - "DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH\\0" - "INITIALIZATION_ERROR\\0" - "INPUT_NOT_INITIALIZED\\0" - "INVALID_AD_SIZE\\0" - "INVALID_KEY_LENGTH\\0" - "INVALID_NONCE\\0" - "INVALID_NONCE_SIZE\\0" - "INVALID_OPERATION\\0" - "IV_TOO_LARGE\\0" - "NO_CIPHER_SET\\0" - "NO_DIRECTION_SET\\0" - "OUTPUT_ALIASES_INPUT\\0" - "TAG_TOO_LARGE\\0" - "TOO_LARGE\\0" - "UNSUPPORTED_AD_SIZE\\0" - "UNSUPPORTED_INPUT_SIZE\\0" - "UNSUPPORTED_KEY_SIZE\\0" - "UNSUPPORTED_NONCE_SIZE\\0" - "UNSUPPORTED_TAG_SIZE\\0" - "WRONG_FINAL_BLOCK_LENGTH\\0" - "LIST_CANNOT_BE_NULL\\0" - "MISSING_CLOSE_SQUARE_BRACKET\\0" - "MISSING_EQUAL_SIGN\\0" - "NO_CLOSE_BRACE\\0" - "UNABLE_TO_CREATE_NEW_SECTION\\0" - "VARIABLE_EXPANSION_TOO_LONG\\0" - "VARIABLE_HAS_NO_VALUE\\0" - "BAD_GENERATOR\\0" - "INVALID_PUBKEY\\0" - "MODULUS_TOO_LARGE\\0" - "NO_PRIVATE_VALUE\\0" - "UNKNOWN_HASH\\0" - "BAD_Q_VALUE\\0" - "BAD_VERSION\\0" - "MISSING_PARAMETERS\\0" - "NEED_NEW_SETUP_VALUES\\0" - "BIGNUM_OUT_OF_RANGE\\0" - "COORDINATES_OUT_OF_RANGE\\0" - "D2I_ECPKPARAMETERS_FAILURE\\0" - "EC_GROUP_NEW_BY_NAME_FAILURE\\0" - "GROUP2PKPARAMETERS_FAILURE\\0" - "GROUP_MISMATCH\\0" - "I2D_ECPKPARAMETERS_FAILURE\\0" - "INCOMPATIBLE_OBJECTS\\0" - "INVALID_COFACTOR\\0" - "INVALID_COMPRESSED_POINT\\0" - "INVALID_COMPRESSION_BIT\\0" - "INVALID_ENCODING\\0" - "INVALID_FIELD\\0" - "INVALID_FORM\\0" - "INVALID_GROUP_ORDER\\0" - "INVALID_PRIVATE_KEY\\0" - "MISSING_PRIVATE_KEY\\0" - "NON_NAMED_CURVE\\0" - "PKPARAMETERS2GROUP_FAILURE\\0" - "POINT_AT_INFINITY\\0" - "POINT_IS_NOT_ON_CURVE\\0" - "PUBLIC_KEY_VALIDATION_FAILED\\0" - "SLOT_FULL\\0" - "UNDEFINED_GENERATOR\\0" - "UNKNOWN_GROUP\\0" - "UNKNOWN_ORDER\\0" - "WRONG_CURVE_PARAMETERS\\0" - "WRONG_ORDER\\0" - "KDF_FAILED\\0" - "POINT_ARITHMETIC_FAILURE\\0" - "BAD_SIGNATURE\\0" - "NOT_IMPLEMENTED\\0" - "RANDOM_NUMBER_GENERATION_FAILED\\0" - "OPERATION_NOT_SUPPORTED\\0" - "COMMAND_NOT_SUPPORTED\\0" - "DIFFERENT_KEY_TYPES\\0" - "DIFFERENT_PARAMETERS\\0" - "EXPECTING_AN_EC_KEY_KEY\\0" - "EXPECTING_AN_RSA_KEY\\0" - "EXPECTING_A_DSA_KEY\\0" - "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\\0" - "INVALID_DIGEST_LENGTH\\0" - "INVALID_DIGEST_TYPE\\0" - "INVALID_KEYBITS\\0" - "INVALID_MGF1_MD\\0" - "INVALID_PADDING_MODE\\0" - "INVALID_PARAMETERS\\0" - "INVALID_PSS_SALTLEN\\0" - "INVALID_SIGNATURE\\0" - "KEYS_NOT_SET\\0" - "MEMORY_LIMIT_EXCEEDED\\0" - "NOT_A_PRIVATE_KEY\\0" - "NO_DEFAULT_DIGEST\\0" - "NO_KEY_SET\\0" - "NO_MDC2_SUPPORT\\0" - "NO_NID_FOR_CURVE\\0" - "NO_OPERATION_SET\\0" - "NO_PARAMETERS_SET\\0" - "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\\0" - "OPERATON_NOT_INITIALIZED\\0" - "UNKNOWN_PUBLIC_KEY_TYPE\\0" - "UNSUPPORTED_ALGORITHM\\0" - "OUTPUT_TOO_LARGE\\0" - "UNKNOWN_NID\\0" - "BAD_BASE64_DECODE\\0" - "BAD_END_LINE\\0" - "BAD_IV_CHARS\\0" - "BAD_PASSWORD_READ\\0" - "CIPHER_IS_NULL\\0" - "ERROR_CONVERTING_PRIVATE_KEY\\0" - "NOT_DEK_INFO\\0" - "NOT_ENCRYPTED\\0" - "NOT_PROC_TYPE\\0" - "NO_START_LINE\\0" - "READ_KEY\\0" - "SHORT_HEADER\\0" - "UNSUPPORTED_CIPHER\\0" - "UNSUPPORTED_ENCRYPTION\\0" - "BAD_PKCS7_VERSION\\0" - "NOT_PKCS7_SIGNED_DATA\\0" - "NO_CERTIFICATES_INCLUDED\\0" - "NO_CRLS_INCLUDED\\0" - "BAD_ITERATION_COUNT\\0" - "BAD_PKCS12_DATA\\0" - "BAD_PKCS12_VERSION\\0" - "CIPHER_HAS_NO_OBJECT_IDENTIFIER\\0" - "CRYPT_ERROR\\0" - "ENCRYPT_ERROR\\0" - "ERROR_SETTING_CIPHER_PARAMS\\0" - "INCORRECT_PASSWORD\\0" - "KEYGEN_FAILURE\\0" - "KEY_GEN_ERROR\\0" - "METHOD_NOT_SUPPORTED\\0" - "MISSING_MAC\\0" - "MULTIPLE_PRIVATE_KEYS_IN_PKCS12\\0" - "PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED\\0" - "PKCS12_TOO_DEEPLY_NESTED\\0" - "PRIVATE_KEY_DECODE_ERROR\\0" - "PRIVATE_KEY_ENCODE_ERROR\\0" - "UNKNOWN_ALGORITHM\\0" - "UNKNOWN_CIPHER\\0" - "UNKNOWN_CIPHER_ALGORITHM\\0" - "UNKNOWN_DIGEST\\0" - "UNSUPPORTED_KEYLENGTH\\0" - "UNSUPPORTED_KEY_DERIVATION_FUNCTION\\0" - "UNSUPPORTED_PRF\\0" - "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\\0" - "UNSUPPORTED_SALT_TYPE\\0" - "BAD_E_VALUE\\0" - "BAD_FIXED_HEADER_DECRYPT\\0" - "BAD_PAD_BYTE_COUNT\\0" - "BAD_RSA_PARAMETERS\\0" - "BLOCK_TYPE_IS_NOT_01\\0" - "BN_NOT_INITIALIZED\\0" - "CANNOT_RECOVER_MULTI_PRIME_KEY\\0" - "CRT_PARAMS_ALREADY_GIVEN\\0" - "CRT_VALUES_INCORRECT\\0" - "DATA_LEN_NOT_EQUAL_TO_MOD_LEN\\0" - "DATA_TOO_LARGE\\0" - "DATA_TOO_LARGE_FOR_KEY_SIZE\\0" - "DATA_TOO_LARGE_FOR_MODULUS\\0" - "DATA_TOO_SMALL\\0" - "DATA_TOO_SMALL_FOR_KEY_SIZE\\0" - "DIGEST_TOO_BIG_FOR_RSA_KEY\\0" - "D_E_NOT_CONGRUENT_TO_1\\0" - "EMPTY_PUBLIC_KEY\\0" - "FIRST_OCTET_INVALID\\0" - "INCONSISTENT_SET_OF_CRT_VALUES\\0" - "INTERNAL_ERROR\\0" - "INVALID_MESSAGE_LENGTH\\0" - "KEY_SIZE_TOO_SMALL\\0" - "LAST_OCTET_INVALID\\0" - "MUST_HAVE_AT_LEAST_TWO_PRIMES\\0" - "NO_PUBLIC_EXPONENT\\0" - "NULL_BEFORE_BLOCK_MISSING\\0" - "N_NOT_EQUAL_P_Q\\0" - "OAEP_DECODING_ERROR\\0" - "ONLY_ONE_OF_P_Q_GIVEN\\0" - "OUTPUT_BUFFER_TOO_SMALL\\0" - "PADDING_CHECK_FAILED\\0" - "PKCS_DECODING_ERROR\\0" - "SLEN_CHECK_FAILED\\0" - "SLEN_RECOVERY_FAILED\\0" - "UNKNOWN_ALGORITHM_TYPE\\0" - "UNKNOWN_PADDING_TYPE\\0" - "VALUE_MISSING\\0" - "WRONG_SIGNATURE_LENGTH\\0" - "ALPN_MISMATCH_ON_EARLY_DATA\\0" - "APPLICATION_DATA_INSTEAD_OF_HANDSHAKE\\0" - "APP_DATA_IN_HANDSHAKE\\0" - "ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT\\0" - "BAD_ALERT\\0" - "BAD_CHANGE_CIPHER_SPEC\\0" - "BAD_DATA_RETURNED_BY_CALLBACK\\0" - "BAD_DH_P_LENGTH\\0" - "BAD_DIGEST_LENGTH\\0" - "BAD_ECC_CERT\\0" - "BAD_ECPOINT\\0" - "BAD_HANDSHAKE_RECORD\\0" - "BAD_HELLO_REQUEST\\0" - "BAD_LENGTH\\0" - "BAD_PACKET_LENGTH\\0" - "BAD_RSA_ENCRYPT\\0" - "BAD_SRTP_MKI_VALUE\\0" - "BAD_SRTP_PROTECTION_PROFILE_LIST\\0" - "BAD_SSL_FILETYPE\\0" - "BAD_WRITE_RETRY\\0" - "BIO_NOT_SET\\0" - "BLOCK_CIPHER_PAD_IS_WRONG\\0" - "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\\0" - "CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD\\0" - "CANNOT_PARSE_LEAF_CERT\\0" - "CA_DN_LENGTH_MISMATCH\\0" - "CA_DN_TOO_LONG\\0" - "CCS_RECEIVED_EARLY\\0" - "CERTIFICATE_AND_PRIVATE_KEY_MISMATCH\\0" - "CERTIFICATE_VERIFY_FAILED\\0" - "CERT_CB_ERROR\\0" - "CERT_LENGTH_MISMATCH\\0" - "CHANNEL_ID_NOT_P256\\0" - "CHANNEL_ID_SIGNATURE_INVALID\\0" - "CIPHER_OR_HASH_UNAVAILABLE\\0" - "CLIENTHELLO_PARSE_FAILED\\0" - "CLIENTHELLO_TLSEXT\\0" - "CONNECTION_REJECTED\\0" - "CONNECTION_TYPE_NOT_SET\\0" - "CUSTOM_EXTENSION_ERROR\\0" - "DATA_LENGTH_TOO_LONG\\0" - "DECRYPTION_FAILED\\0" - "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\\0" - "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\\0" - "DH_P_TOO_LONG\\0" - "DIGEST_CHECK_FAILED\\0" - "DOWNGRADE_DETECTED\\0" - "DTLS_MESSAGE_TOO_BIG\\0" - "DUPLICATE_EXTENSION\\0" - "DUPLICATE_KEY_SHARE\\0" - "ECC_CERT_NOT_FOR_SIGNING\\0" - "EMS_STATE_INCONSISTENT\\0" - "ENCRYPTED_LENGTH_TOO_LONG\\0" - "ERROR_ADDING_EXTENSION\\0" - "ERROR_IN_RECEIVED_CIPHER_LIST\\0" - "ERROR_PARSING_EXTENSION\\0" - "EXCESSIVE_MESSAGE_SIZE\\0" - "EXTRA_DATA_IN_MESSAGE\\0" - "FRAGMENT_MISMATCH\\0" - "GOT_NEXT_PROTO_WITHOUT_EXTENSION\\0" - "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\\0" - "HTTPS_PROXY_REQUEST\\0" - "HTTP_REQUEST\\0" - "INAPPROPRIATE_FALLBACK\\0" - "INVALID_ALPN_PROTOCOL\\0" - "INVALID_COMMAND\\0" - "INVALID_COMPRESSION_LIST\\0" - "INVALID_MESSAGE\\0" - "INVALID_OUTER_RECORD_TYPE\\0" - "INVALID_SCT_LIST\\0" - "INVALID_SSL_SESSION\\0" - "INVALID_TICKET_KEYS_LENGTH\\0" - "LENGTH_MISMATCH\\0" - "MISSING_EXTENSION\\0" - "MISSING_KEY_SHARE\\0" - "MISSING_RSA_CERTIFICATE\\0" - "MISSING_TMP_DH_KEY\\0" - "MISSING_TMP_ECDH_KEY\\0" - "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\\0" - "MTU_TOO_SMALL\\0" - "NEGOTIATED_BOTH_NPN_AND_ALPN\\0" - "NESTED_GROUP\\0" - "NO_CERTIFICATES_RETURNED\\0" - "NO_CERTIFICATE_ASSIGNED\\0" - "NO_CERTIFICATE_SET\\0" - "NO_CIPHERS_AVAILABLE\\0" - "NO_CIPHERS_PASSED\\0" - "NO_CIPHERS_SPECIFIED\\0" - "NO_CIPHER_MATCH\\0" - "NO_COMMON_SIGNATURE_ALGORITHMS\\0" - "NO_COMPRESSION_SPECIFIED\\0" - "NO_GROUPS_SPECIFIED\\0" - "NO_METHOD_SPECIFIED\\0" - "NO_P256_SUPPORT\\0" - "NO_PRIVATE_KEY_ASSIGNED\\0" - "NO_RENEGOTIATION\\0" - "NO_REQUIRED_DIGEST\\0" - "NO_SHARED_CIPHER\\0" - "NO_SHARED_GROUP\\0" - "NO_SUPPORTED_VERSIONS_ENABLED\\0" - "NULL_SSL_CTX\\0" - "NULL_SSL_METHOD_PASSED\\0" - "OLD_SESSION_CIPHER_NOT_RETURNED\\0" - "OLD_SESSION_PRF_HASH_MISMATCH\\0" - "OLD_SESSION_VERSION_NOT_RETURNED\\0" - "PARSE_TLSEXT\\0" - "PATH_TOO_LONG\\0" - "PEER_DID_NOT_RETURN_A_CERTIFICATE\\0" - "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\\0" - "PRE_SHARED_KEY_MUST_BE_LAST\\0" - "PROTOCOL_IS_SHUTDOWN\\0" - "PSK_IDENTITY_BINDER_COUNT_MISMATCH\\0" - "PSK_IDENTITY_NOT_FOUND\\0" - "PSK_NO_CLIENT_CB\\0" - "PSK_NO_SERVER_CB\\0" - "READ_TIMEOUT_EXPIRED\\0" - "RECORD_LENGTH_MISMATCH\\0" - "RECORD_TOO_LARGE\\0" - "RENEGOTIATION_EMS_MISMATCH\\0" - "RENEGOTIATION_ENCODING_ERR\\0" - "RENEGOTIATION_MISMATCH\\0" - "REQUIRED_CIPHER_MISSING\\0" - "RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION\\0" - "RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION\\0" - "SCSV_RECEIVED_WHEN_RENEGOTIATING\\0" - "SERVERHELLO_TLSEXT\\0" - "SERVER_CERT_CHANGED\\0" - "SESSION_ID_CONTEXT_UNINITIALIZED\\0" - "SESSION_MAY_NOT_BE_CREATED\\0" - "SHUTDOWN_WHILE_IN_INIT\\0" - "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\\0" - "SRTP_COULD_NOT_ALLOCATE_PROFILES\\0" - "SRTP_UNKNOWN_PROTECTION_PROFILE\\0" - "SSL3_EXT_INVALID_SERVERNAME\\0" - "SSLV3_ALERT_BAD_CERTIFICATE\\0" - "SSLV3_ALERT_BAD_RECORD_MAC\\0" - "SSLV3_ALERT_CERTIFICATE_EXPIRED\\0" - "SSLV3_ALERT_CERTIFICATE_REVOKED\\0" - "SSLV3_ALERT_CERTIFICATE_UNKNOWN\\0" - "SSLV3_ALERT_CLOSE_NOTIFY\\0" - "SSLV3_ALERT_DECOMPRESSION_FAILURE\\0" - "SSLV3_ALERT_HANDSHAKE_FAILURE\\0" - "SSLV3_ALERT_ILLEGAL_PARAMETER\\0" - "SSLV3_ALERT_NO_CERTIFICATE\\0" - "SSLV3_ALERT_UNEXPECTED_MESSAGE\\0" - "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\\0" - "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\\0" - "SSL_HANDSHAKE_FAILURE\\0" - "SSL_SESSION_ID_CONTEXT_TOO_LONG\\0" - "TICKET_ENCRYPTION_FAILED\\0" - "TLSV1_ALERT_ACCESS_DENIED\\0" - "TLSV1_ALERT_DECODE_ERROR\\0" - "TLSV1_ALERT_DECRYPTION_FAILED\\0" - "TLSV1_ALERT_DECRYPT_ERROR\\0" - "TLSV1_ALERT_EXPORT_RESTRICTION\\0" - "TLSV1_ALERT_INAPPROPRIATE_FALLBACK\\0" - "TLSV1_ALERT_INSUFFICIENT_SECURITY\\0" - "TLSV1_ALERT_INTERNAL_ERROR\\0" - "TLSV1_ALERT_NO_RENEGOTIATION\\0" - "TLSV1_ALERT_PROTOCOL_VERSION\\0" - "TLSV1_ALERT_RECORD_OVERFLOW\\0" - "TLSV1_ALERT_UNKNOWN_CA\\0" - "TLSV1_ALERT_USER_CANCELLED\\0" - "TLSV1_BAD_CERTIFICATE_HASH_VALUE\\0" - "TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\\0" - "TLSV1_CERTIFICATE_REQUIRED\\0" - "TLSV1_CERTIFICATE_UNOBTAINABLE\\0" - "TLSV1_UNKNOWN_PSK_IDENTITY\\0" - "TLSV1_UNRECOGNIZED_NAME\\0" - "TLSV1_UNSUPPORTED_EXTENSION\\0" - "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\\0" - "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\\0" - "TOO_MANY_EMPTY_FRAGMENTS\\0" - "TOO_MANY_KEY_UPDATES\\0" - "TOO_MANY_WARNING_ALERTS\\0" - "TOO_MUCH_READ_EARLY_DATA\\0" - "TOO_MUCH_SKIPPED_EARLY_DATA\\0" - "UNABLE_TO_FIND_ECDH_PARAMETERS\\0" - "UNEXPECTED_EXTENSION\\0" - "UNEXPECTED_EXTENSION_ON_EARLY_DATA\\0" - "UNEXPECTED_MESSAGE\\0" - "UNEXPECTED_OPERATOR_IN_GROUP\\0" - "UNEXPECTED_RECORD\\0" - "UNKNOWN_ALERT_TYPE\\0" - "UNKNOWN_CERTIFICATE_TYPE\\0" - "UNKNOWN_CIPHER_RETURNED\\0" - "UNKNOWN_CIPHER_TYPE\\0" - "UNKNOWN_KEY_EXCHANGE_TYPE\\0" - "UNKNOWN_PROTOCOL\\0" - "UNKNOWN_SSL_VERSION\\0" - "UNKNOWN_STATE\\0" - "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\\0" - "UNSUPPORTED_COMPRESSION_ALGORITHM\\0" - "UNSUPPORTED_ELLIPTIC_CURVE\\0" - "UNSUPPORTED_PROTOCOL\\0" - "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\\0" - "WRONG_CERTIFICATE_TYPE\\0" - "WRONG_CIPHER_RETURNED\\0" - "WRONG_CURVE\\0" - "WRONG_MESSAGE_TYPE\\0" - "WRONG_SIGNATURE_TYPE\\0" - "WRONG_SSL_VERSION\\0" - "WRONG_VERSION_NUMBER\\0" - "WRONG_VERSION_ON_EARLY_DATA\\0" - "X509_LIB\\0" - "X509_VERIFICATION_SETUP_PROBLEMS\\0" - "AKID_MISMATCH\\0" - "BAD_X509_FILETYPE\\0" - "BASE64_DECODE_ERROR\\0" - "CANT_CHECK_DH_KEY\\0" - "CERT_ALREADY_IN_HASH_TABLE\\0" - "CRL_ALREADY_DELTA\\0" - "CRL_VERIFY_FAILURE\\0" - "IDP_MISMATCH\\0" - "INVALID_DIRECTORY\\0" - "INVALID_FIELD_NAME\\0" - "INVALID_PARAMETER\\0" - "INVALID_PSS_PARAMETERS\\0" - "INVALID_TRUST\\0" - "ISSUER_MISMATCH\\0" - "KEY_TYPE_MISMATCH\\0" - "KEY_VALUES_MISMATCH\\0" - "LOADING_CERT_DIR\\0" - "LOADING_DEFAULTS\\0" - "NAME_TOO_LONG\\0" - "NEWER_CRL_NOT_NEWER\\0" - "NO_CERT_SET_FOR_US_TO_VERIFY\\0" - "NO_CRL_NUMBER\\0" - "PUBLIC_KEY_DECODE_ERROR\\0" - "PUBLIC_KEY_ENCODE_ERROR\\0" - "SHOULD_RETRY\\0" - "UNKNOWN_KEY_TYPE\\0" - "UNKNOWN_PURPOSE_ID\\0" - "UNKNOWN_TRUST_ID\\0" - "WRONG_LOOKUP_TYPE\\0" - "BAD_IP_ADDRESS\\0" - "BAD_OBJECT\\0" - "BN_DEC2BN_ERROR\\0" - "BN_TO_ASN1_INTEGER_ERROR\\0" - "CANNOT_FIND_FREE_FUNCTION\\0" - "DIRNAME_ERROR\\0" - "DISTPOINT_ALREADY_SET\\0" - "DUPLICATE_ZONE_ID\\0" - "ERROR_CONVERTING_ZONE\\0" - "ERROR_CREATING_EXTENSION\\0" - "ERROR_IN_EXTENSION\\0" - "EXPECTED_A_SECTION_NAME\\0" - "EXTENSION_EXISTS\\0" - "EXTENSION_NAME_ERROR\\0" - "EXTENSION_NOT_FOUND\\0" - "EXTENSION_SETTING_NOT_SUPPORTED\\0" - "EXTENSION_VALUE_ERROR\\0" - "ILLEGAL_EMPTY_EXTENSION\\0" - "ILLEGAL_HEX_DIGIT\\0" - "INCORRECT_POLICY_SYNTAX_TAG\\0" - "INVALID_BOOLEAN_STRING\\0" - "INVALID_EXTENSION_STRING\\0" - "INVALID_MULTIPLE_RDNS\\0" - "INVALID_NAME\\0" - "INVALID_NULL_ARGUMENT\\0" - "INVALID_NULL_NAME\\0" - "INVALID_NULL_VALUE\\0" - "INVALID_NUMBERS\\0" - "INVALID_OBJECT_IDENTIFIER\\0" - "INVALID_OPTION\\0" - "INVALID_POLICY_IDENTIFIER\\0" - "INVALID_PROXY_POLICY_SETTING\\0" - "INVALID_PURPOSE\\0" - "INVALID_SECTION\\0" - "INVALID_SYNTAX\\0" - "ISSUER_DECODE_ERROR\\0" - "NEED_ORGANIZATION_AND_NUMBERS\\0" - "NO_CONFIG_DATABASE\\0" - "NO_ISSUER_CERTIFICATE\\0" - "NO_ISSUER_DETAILS\\0" - "NO_POLICY_IDENTIFIER\\0" - "NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED\\0" - "NO_PUBLIC_KEY\\0" - "NO_SUBJECT_DETAILS\\0" - "ODD_NUMBER_OF_DIGITS\\0" - "OPERATION_NOT_DEFINED\\0" - "OTHERNAME_ERROR\\0" - "POLICY_LANGUAGE_ALREADY_DEFINED\\0" - "POLICY_PATH_LENGTH\\0" - "POLICY_PATH_LENGTH_ALREADY_DEFINED\\0" - "POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY\\0" - "SECTION_NOT_FOUND\\0" - "UNABLE_TO_GET_ISSUER_DETAILS\\0" - "UNABLE_TO_GET_ISSUER_KEYID\\0" - "UNKNOWN_BIT_STRING_ARGUMENT\\0" - "UNKNOWN_EXTENSION\\0" - "UNKNOWN_EXTENSION_NAME\\0" - "UNKNOWN_OPTION\\0" - "UNSUPPORTED_OPTION\\0" - "USER_TOO_LONG\\0" - ""; - EOF - - sed -i'.back' '/^#define \\([A-Za-z0-9_]*\\) \\1/d' include/openssl/ssl.h - sed -i'.back' 'N;/^#define \\([A-Za-z0-9_]*\\) *\\\\\\n *\\1/d' include/openssl/ssl.h - sed -i'.back' 's/#ifndef md5_block_data_order/#ifndef GRPC_SHADOW_md5_block_data_order/g' crypto/fipsmodule/md5/md5.c - find . -type f \\( -path '*.h' -or -path '*.cc' -or -path '*.c' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include /` and its + # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't + # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in + # practice). Because we need our `header_mappings_dir` to be `include/openssl/` for the reason + # mentioned above, we work around the linter limitation by dividing the pod into two subspecs, one + # for public headers and the other for implementation. Each gets its own `header_mappings_dir`, + # making the linter happy. + s.subspec 'Interface' do |ss| + ss.header_mappings_dir = 'include/openssl' + ss.source_files = 'include/openssl/*.h' end + s.subspec 'Implementation' do |ss| + ss.header_mappings_dir = '.' + ss.source_files = 'ssl/*.{h,cc}', + 'ssl/**/*.{h,cc}', + '*.{h,c}', + 'crypto/*.{h,c}', + 'crypto/**/*.{h,c}', + 'third_party/fiat/*.{h,c}' + ss.private_header_files = 'ssl/*.h', + 'ssl/**/*.h', + '*.h', + 'crypto/*.h', + 'crypto/**/*.h' + # bcm.c includes other source files, creating duplicated symbols. Since it is not used, we + # explicitly exclude it from the pod. + # TODO (mxyan): Work with BoringSSL team to remove this hack. + ss.exclude_files = 'crypto/fipsmodule/bcm.c', + '**/*_test.*', + '**/test_*.*', + '**/test/*.*' + + ss.dependency "#{s.name}/Interface", version + end + + s.prepare_command = <<-END_OF_COMMAND + # Add a module map and an umbrella header + cat > include/openssl/umbrella.h < include/openssl/BoringSSL.modulemap < err_data.c < + #include + #include + + + OPENSSL_COMPILE_ASSERT(ERR_LIB_NONE == 1, library_values_changed_1); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SYS == 2, library_values_changed_2); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BN == 3, library_values_changed_3); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RSA == 4, library_values_changed_4); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DH == 5, library_values_changed_5); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EVP == 6, library_values_changed_6); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BUF == 7, library_values_changed_7); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OBJ == 8, library_values_changed_8); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PEM == 9, library_values_changed_9); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DSA == 10, library_values_changed_10); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509 == 11, library_values_changed_11); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ASN1 == 12, library_values_changed_12); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CONF == 13, library_values_changed_13); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CRYPTO == 14, library_values_changed_14); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EC == 15, library_values_changed_15); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SSL == 16, library_values_changed_16); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BIO == 17, library_values_changed_17); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS7 == 18, library_values_changed_18); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS8 == 19, library_values_changed_19); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509V3 == 20, library_values_changed_20); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RAND == 21, library_values_changed_21); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ENGINE == 22, library_values_changed_22); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OCSP == 23, library_values_changed_23); + OPENSSL_COMPILE_ASSERT(ERR_LIB_UI == 24, library_values_changed_24); + OPENSSL_COMPILE_ASSERT(ERR_LIB_COMP == 25, library_values_changed_25); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDSA == 26, library_values_changed_26); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDH == 27, library_values_changed_27); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31); + OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32); + OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num); + + const uint32_t kOpenSSLReasonValues[] = { + 0xc320838, + 0xc328852, + 0xc330861, + 0xc338871, + 0xc340880, + 0xc348899, + 0xc3508a5, + 0xc3588c2, + 0xc3608e2, + 0xc3688f0, + 0xc370900, + 0xc37890d, + 0xc38091d, + 0xc388928, + 0xc39093e, + 0xc39894d, + 0xc3a0961, + 0xc3a8845, + 0xc3b00ea, + 0xc3b88d4, + 0x10320845, + 0x10329513, + 0x1033151f, + 0x10339538, + 0x1034154b, + 0x10348eed, + 0x10350c5e, + 0x1035955e, + 0x10361573, + 0x10369586, + 0x103715a5, + 0x103795be, + 0x103815d3, + 0x103895f1, + 0x10391600, + 0x1039961c, + 0x103a1637, + 0x103a9646, + 0x103b1662, + 0x103b967d, + 0x103c1694, + 0x103c80ea, + 0x103d16a5, + 0x103d96b9, + 0x103e16d8, + 0x103e96e7, + 0x103f16fe, + 0x103f9711, + 0x10400c22, + 0x10409724, + 0x10411742, + 0x10419755, + 0x1042176f, + 0x1042977f, + 0x10431793, + 0x104397a9, + 0x104417c1, + 0x104497d6, + 0x104517ea, + 0x104597fc, + 0x104605fb, + 0x1046894d, + 0x10471811, + 0x10479828, + 0x1048183d, + 0x1048984b, + 0x10490e4f, + 0x14320c05, + 0x14328c13, + 0x14330c22, + 0x14338c34, + 0x143400ac, + 0x143480ea, + 0x18320083, + 0x18328f43, + 0x183300ac, + 0x18338f59, + 0x18340f6d, + 0x183480ea, + 0x18350f82, + 0x18358f9a, + 0x18360faf, + 0x18368fc3, + 0x18370fe7, + 0x18378ffd, + 0x18381011, + 0x18389021, + 0x18390a73, + 0x18399031, + 0x183a1059, + 0x183a907f, + 0x183b0c6a, + 0x183b90b4, + 0x183c10c6, + 0x183c90d1, + 0x183d10e1, + 0x183d90f2, + 0x183e1103, + 0x183e9115, + 0x183f113e, + 0x183f9157, + 0x1840116f, + 0x184086d3, + 0x184110a2, + 0x1841906d, + 0x1842108c, + 0x18429046, + 0x20321196, + 0x243211a2, + 0x24328993, + 0x243311b4, + 0x243391c1, + 0x243411ce, + 0x243491e0, + 0x243511ef, + 0x2435920c, + 0x24361219, + 0x24369227, + 0x24371235, + 0x24379243, + 0x2438124c, + 0x24389259, + 0x2439126c, + 0x28320c52, + 0x28328c6a, + 0x28330c22, + 0x28338c7d, + 0x28340c5e, + 0x283480ac, + 0x283500ea, + 0x2c322c30, + 0x2c329283, + 0x2c332c3e, + 0x2c33ac50, + 0x2c342c64, + 0x2c34ac76, + 0x2c352c91, + 0x2c35aca3, + 0x2c362cb6, + 0x2c36832d, + 0x2c372cc3, + 0x2c37acd5, + 0x2c382cfa, + 0x2c38ad11, + 0x2c392d1f, + 0x2c39ad2f, + 0x2c3a2d41, + 0x2c3aad55, + 0x2c3b2d66, + 0x2c3bad85, + 0x2c3c1295, + 0x2c3c92ab, + 0x2c3d2d99, + 0x2c3d92c4, + 0x2c3e2db6, + 0x2c3eadc4, + 0x2c3f2ddc, + 0x2c3fadf4, + 0x2c402e01, + 0x2c409196, + 0x2c412e12, + 0x2c41ae25, + 0x2c42116f, + 0x2c42ae36, + 0x2c430720, + 0x2c43ad77, + 0x2c442ce8, + 0x30320000, + 0x30328015, + 0x3033001f, + 0x30338038, + 0x3034004a, + 0x30348064, + 0x3035006b, + 0x30358083, + 0x30360094, + 0x303680ac, + 0x303700b9, + 0x303780c8, + 0x303800ea, + 0x303880f7, + 0x3039010a, + 0x30398125, + 0x303a013a, + 0x303a814e, + 0x303b0162, + 0x303b8173, + 0x303c018c, + 0x303c81a9, + 0x303d01b7, + 0x303d81cb, + 0x303e01db, + 0x303e81f4, + 0x303f0204, + 0x303f8217, + 0x30400226, + 0x30408232, + 0x30410247, + 0x30418257, + 0x3042026e, + 0x3042827b, + 0x3043028e, + 0x3043829d, + 0x304402b2, + 0x304482d3, + 0x304502e6, + 0x304582f9, + 0x30460312, + 0x3046832d, + 0x3047034a, + 0x30478363, + 0x30480371, + 0x30488382, + 0x30490391, + 0x304983a9, + 0x304a03bb, + 0x304a83cf, + 0x304b03ee, + 0x304b8401, + 0x304c040c, + 0x304c841d, + 0x304d0429, + 0x304d843f, + 0x304e044d, + 0x304e8463, + 0x304f0475, + 0x304f8487, + 0x3050049a, + 0x305084ad, + 0x305104be, + 0x305184ce, + 0x305204e6, + 0x305284fb, + 0x30530513, + 0x30538527, + 0x3054053f, + 0x30548558, + 0x30550571, + 0x3055858e, + 0x30560599, + 0x305685b1, + 0x305705c1, + 0x305785d2, + 0x305805e5, + 0x305885fb, + 0x30590604, + 0x30598619, + 0x305a062c, + 0x305a863b, + 0x305b065b, + 0x305b866a, + 0x305c068b, + 0x305c86a7, + 0x305d06b3, + 0x305d86d3, + 0x305e06ef, + 0x305e8700, + 0x305f0716, + 0x305f8720, + 0x34320b63, + 0x34328b77, + 0x34330b94, + 0x34338ba7, + 0x34340bb6, + 0x34348bef, + 0x34350bd3, + 0x3c320083, + 0x3c328ca7, + 0x3c330cc0, + 0x3c338cdb, + 0x3c340cf8, + 0x3c348d22, + 0x3c350d3d, + 0x3c358d63, + 0x3c360d7c, + 0x3c368d94, + 0x3c370da5, + 0x3c378db3, + 0x3c380dc0, + 0x3c388dd4, + 0x3c390c6a, + 0x3c398de8, + 0x3c3a0dfc, + 0x3c3a890d, + 0x3c3b0e0c, + 0x3c3b8e27, + 0x3c3c0e39, + 0x3c3c8e6c, + 0x3c3d0e76, + 0x3c3d8e8a, + 0x3c3e0e98, + 0x3c3e8ebd, + 0x3c3f0c93, + 0x3c3f8ea6, + 0x3c4000ac, + 0x3c4080ea, + 0x3c410d13, + 0x3c418d52, + 0x3c420e4f, + 0x403218a4, + 0x403298ba, + 0x403318e8, + 0x403398f2, + 0x40341909, + 0x40349927, + 0x40351937, + 0x40359949, + 0x40361956, + 0x40369962, + 0x40371977, + 0x40379989, + 0x40381994, + 0x403899a6, + 0x40390eed, + 0x403999b6, + 0x403a19c9, + 0x403a99ea, + 0x403b19fb, + 0x403b9a0b, + 0x403c0064, + 0x403c8083, + 0x403d1a8f, + 0x403d9aa5, + 0x403e1ab4, + 0x403e9aec, + 0x403f1b06, + 0x403f9b14, + 0x40401b29, + 0x40409b3d, + 0x40411b5a, + 0x40419b75, + 0x40421b8e, + 0x40429ba1, + 0x40431bb5, + 0x40439bcd, + 0x40441be4, + 0x404480ac, + 0x40451bf9, + 0x40459c0b, + 0x40461c2f, + 0x40469c4f, + 0x40471c5d, + 0x40479c84, + 0x40481cc1, + 0x40489cda, + 0x40491cf1, + 0x40499d0b, + 0x404a1d22, + 0x404a9d40, + 0x404b1d58, + 0x404b9d6f, + 0x404c1d85, + 0x404c9d97, + 0x404d1db8, + 0x404d9dda, + 0x404e1dee, + 0x404e9dfb, + 0x404f1e28, + 0x404f9e51, + 0x40501e8c, + 0x40509ea0, + 0x40511ebb, + 0x40521ecb, + 0x40529eef, + 0x40531f07, + 0x40539f1a, + 0x40541f2f, + 0x40549f52, + 0x40551f60, + 0x40559f7d, + 0x40561f8a, + 0x40569fa3, + 0x40571fbb, + 0x40579fce, + 0x40581fe3, + 0x4058a00a, + 0x40592039, + 0x4059a066, + 0x405a207a, + 0x405aa08a, + 0x405b20a2, + 0x405ba0b3, + 0x405c20c6, + 0x405ca105, + 0x405d2112, + 0x405da129, + 0x405e2167, + 0x405e8ab1, + 0x405f2188, + 0x405fa195, + 0x406021a3, + 0x4060a1c5, + 0x40612209, + 0x4061a241, + 0x40622258, + 0x4062a269, + 0x4063227a, + 0x4063a28f, + 0x406422a6, + 0x4064a2d2, + 0x406522ed, + 0x4065a304, + 0x4066231c, + 0x4066a346, + 0x40672371, + 0x4067a392, + 0x406823b9, + 0x4068a3da, + 0x4069240c, + 0x4069a43a, + 0x406a245b, + 0x406aa47b, + 0x406b2603, + 0x406ba626, + 0x406c263c, + 0x406ca8b7, + 0x406d28e6, + 0x406da90e, + 0x406e293c, + 0x406ea989, + 0x406f29a8, + 0x406fa9e0, + 0x407029f3, + 0x4070aa10, + 0x40710800, + 0x4071aa22, + 0x40722a35, + 0x4072aa4e, + 0x40732a66, + 0x40739482, + 0x40742a7a, + 0x4074aa94, + 0x40752aa5, + 0x4075aab9, + 0x40762ac7, + 0x40769259, + 0x40772aec, + 0x4077ab0e, + 0x40782b29, + 0x4078ab62, + 0x40792b79, + 0x4079ab8f, + 0x407a2b9b, + 0x407aabae, + 0x407b2bc3, + 0x407babd5, + 0x407c2c06, + 0x407cac0f, + 0x407d23f5, + 0x407d9e61, + 0x407e2b3e, + 0x407ea01a, + 0x407f1c71, + 0x407f9a31, + 0x40801e38, + 0x40809c99, + 0x40811edd, + 0x40819e12, + 0x40822927, + 0x40829a17, + 0x40831ff5, + 0x4083a2b7, + 0x40841cad, + 0x4084a052, + 0x408520d7, + 0x4085a1ed, + 0x40862149, + 0x40869e7b, + 0x4087296d, + 0x4087a21e, + 0x40881a78, + 0x4088a3a5, + 0x40891ac7, + 0x40899a54, + 0x408a265c, + 0x408a9862, + 0x408b2bea, + 0x408ba9bd, + 0x408c20e7, + 0x408c987e, + 0x41f4252e, + 0x41f925c0, + 0x41fe24b3, + 0x41fea6a8, + 0x41ff2799, + 0x42032547, + 0x42082569, + 0x4208a5a5, + 0x42092497, + 0x4209a5df, + 0x420a24ee, + 0x420aa4ce, + 0x420b250e, + 0x420ba587, + 0x420c27b5, + 0x420ca675, + 0x420d268f, + 0x420da6c6, + 0x421226e0, + 0x4217277c, + 0x4217a722, + 0x421c2744, + 0x421f26ff, + 0x422127cc, + 0x4226275f, + 0x422b289b, + 0x422ba849, + 0x422c2883, + 0x422ca808, + 0x422d27e7, + 0x422da868, + 0x422e282e, + 0x422ea954, + 0x4432072b, + 0x4432873a, + 0x44330746, + 0x44338754, + 0x44340767, + 0x44348778, + 0x4435077f, + 0x44358789, + 0x4436079c, + 0x443687b2, + 0x443707c4, + 0x443787d1, + 0x443807e0, + 0x443887e8, + 0x44390800, + 0x4439880e, + 0x443a0821, + 0x48321283, + 0x48329295, + 0x483312ab, + 0x483392c4, + 0x4c3212e9, + 0x4c3292f9, + 0x4c33130c, + 0x4c33932c, + 0x4c3400ac, + 0x4c3480ea, + 0x4c351338, + 0x4c359346, + 0x4c361362, + 0x4c369375, + 0x4c371384, + 0x4c379392, + 0x4c3813a7, + 0x4c3893b3, + 0x4c3913d3, + 0x4c3993fd, + 0x4c3a1416, + 0x4c3a942f, + 0x4c3b05fb, + 0x4c3b9448, + 0x4c3c145a, + 0x4c3c9469, + 0x4c3d1482, + 0x4c3d8c45, + 0x4c3e14db, + 0x4c3e9491, + 0x4c3f14fd, + 0x4c3f9259, + 0x4c4014a7, + 0x4c4092d5, + 0x4c4114cb, + 0x50322e48, + 0x5032ae57, + 0x50332e62, + 0x5033ae72, + 0x50342e8b, + 0x5034aea5, + 0x50352eb3, + 0x5035aec9, + 0x50362edb, + 0x5036aef1, + 0x50372f0a, + 0x5037af1d, + 0x50382f35, + 0x5038af46, + 0x50392f5b, + 0x5039af6f, + 0x503a2f8f, + 0x503aafa5, + 0x503b2fbd, + 0x503bafcf, + 0x503c2feb, + 0x503cb002, + 0x503d301b, + 0x503db031, + 0x503e303e, + 0x503eb054, + 0x503f3066, + 0x503f8382, + 0x50403079, + 0x5040b089, + 0x504130a3, + 0x5041b0b2, + 0x504230cc, + 0x5042b0e9, + 0x504330f9, + 0x5043b109, + 0x50443118, + 0x5044843f, + 0x5045312c, + 0x5045b14a, + 0x5046315d, + 0x5046b173, + 0x50473185, + 0x5047b19a, + 0x504831c0, + 0x5048b1ce, + 0x504931e1, + 0x5049b1f6, + 0x504a320c, + 0x504ab21c, + 0x504b323c, + 0x504bb24f, + 0x504c3272, + 0x504cb2a0, + 0x504d32b2, + 0x504db2cf, + 0x504e32ea, + 0x504eb306, + 0x504f3318, + 0x504fb32f, + 0x5050333e, + 0x505086ef, + 0x50513351, + 0x58320f2b, + 0x68320eed, + 0x68328c6a, + 0x68330c7d, + 0x68338efb, + 0x68340f0b, + 0x683480ea, + 0x6c320ec9, + 0x6c328c34, + 0x6c330ed4, + 0x74320a19, + 0x743280ac, + 0x74330c45, + 0x7832097e, + 0x78328993, + 0x7833099f, + 0x78338083, + 0x783409ae, + 0x783489c3, + 0x783509e2, + 0x78358a04, + 0x78360a19, + 0x78368a2f, + 0x78370a3f, + 0x78378a60, + 0x78380a73, + 0x78388a85, + 0x78390a92, + 0x78398ab1, + 0x783a0ac6, + 0x783a8ad4, + 0x783b0ade, + 0x783b8af2, + 0x783c0b09, + 0x783c8b1e, + 0x783d0b35, + 0x783d8b4a, + 0x783e0aa0, + 0x783e8a52, + 0x7c321185, + }; + + const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); + + const char kOpenSSLReasonStringData[] = + "ASN1_LENGTH_MISMATCH\\0" + "AUX_ERROR\\0" + "BAD_GET_ASN1_OBJECT_CALL\\0" + "BAD_OBJECT_HEADER\\0" + "BMPSTRING_IS_WRONG_LENGTH\\0" + "BN_LIB\\0" + "BOOLEAN_IS_WRONG_LENGTH\\0" + "BUFFER_TOO_SMALL\\0" + "CONTEXT_NOT_INITIALISED\\0" + "DECODE_ERROR\\0" + "DEPTH_EXCEEDED\\0" + "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\\0" + "ENCODE_ERROR\\0" + "ERROR_GETTING_TIME\\0" + "EXPECTING_AN_ASN1_SEQUENCE\\0" + "EXPECTING_AN_INTEGER\\0" + "EXPECTING_AN_OBJECT\\0" + "EXPECTING_A_BOOLEAN\\0" + "EXPECTING_A_TIME\\0" + "EXPLICIT_LENGTH_MISMATCH\\0" + "EXPLICIT_TAG_NOT_CONSTRUCTED\\0" + "FIELD_MISSING\\0" + "FIRST_NUM_TOO_LARGE\\0" + "HEADER_TOO_LONG\\0" + "ILLEGAL_BITSTRING_FORMAT\\0" + "ILLEGAL_BOOLEAN\\0" + "ILLEGAL_CHARACTERS\\0" + "ILLEGAL_FORMAT\\0" + "ILLEGAL_HEX\\0" + "ILLEGAL_IMPLICIT_TAG\\0" + "ILLEGAL_INTEGER\\0" + "ILLEGAL_NESTED_TAGGING\\0" + "ILLEGAL_NULL\\0" + "ILLEGAL_NULL_VALUE\\0" + "ILLEGAL_OBJECT\\0" + "ILLEGAL_OPTIONAL_ANY\\0" + "ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE\\0" + "ILLEGAL_TAGGED_ANY\\0" + "ILLEGAL_TIME_VALUE\\0" + "INTEGER_NOT_ASCII_FORMAT\\0" + "INTEGER_TOO_LARGE_FOR_LONG\\0" + "INVALID_BIT_STRING_BITS_LEFT\\0" + "INVALID_BMPSTRING_LENGTH\\0" + "INVALID_DIGIT\\0" + "INVALID_MODIFIER\\0" + "INVALID_NUMBER\\0" + "INVALID_OBJECT_ENCODING\\0" + "INVALID_SEPARATOR\\0" + "INVALID_TIME_FORMAT\\0" + "INVALID_UNIVERSALSTRING_LENGTH\\0" + "INVALID_UTF8STRING\\0" + "LIST_ERROR\\0" + "MISSING_ASN1_EOS\\0" + "MISSING_EOC\\0" + "MISSING_SECOND_NUMBER\\0" + "MISSING_VALUE\\0" + "MSTRING_NOT_UNIVERSAL\\0" + "MSTRING_WRONG_TAG\\0" + "NESTED_ASN1_ERROR\\0" + "NESTED_ASN1_STRING\\0" + "NON_HEX_CHARACTERS\\0" + "NOT_ASCII_FORMAT\\0" + "NOT_ENOUGH_DATA\\0" + "NO_MATCHING_CHOICE_TYPE\\0" + "NULL_IS_WRONG_LENGTH\\0" + "OBJECT_NOT_ASCII_FORMAT\\0" + "ODD_NUMBER_OF_CHARS\\0" + "SECOND_NUMBER_TOO_LARGE\\0" + "SEQUENCE_LENGTH_MISMATCH\\0" + "SEQUENCE_NOT_CONSTRUCTED\\0" + "SEQUENCE_OR_SET_NEEDS_CONFIG\\0" + "SHORT_LINE\\0" + "STREAMING_NOT_SUPPORTED\\0" + "STRING_TOO_LONG\\0" + "STRING_TOO_SHORT\\0" + "TAG_VALUE_TOO_HIGH\\0" + "TIME_NOT_ASCII_FORMAT\\0" + "TOO_LONG\\0" + "TYPE_NOT_CONSTRUCTED\\0" + "TYPE_NOT_PRIMITIVE\\0" + "UNEXPECTED_EOC\\0" + "UNIVERSALSTRING_IS_WRONG_LENGTH\\0" + "UNKNOWN_FORMAT\\0" + "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\\0" + "UNKNOWN_SIGNATURE_ALGORITHM\\0" + "UNKNOWN_TAG\\0" + "UNSUPPORTED_ANY_DEFINED_BY_TYPE\\0" + "UNSUPPORTED_PUBLIC_KEY_TYPE\\0" + "UNSUPPORTED_TYPE\\0" + "WRONG_PUBLIC_KEY_TYPE\\0" + "WRONG_TAG\\0" + "WRONG_TYPE\\0" + "BAD_FOPEN_MODE\\0" + "BROKEN_PIPE\\0" + "CONNECT_ERROR\\0" + "ERROR_SETTING_NBIO\\0" + "INVALID_ARGUMENT\\0" + "IN_USE\\0" + "KEEPALIVE\\0" + "NBIO_CONNECT_ERROR\\0" + "NO_HOSTNAME_SPECIFIED\\0" + "NO_PORT_SPECIFIED\\0" + "NO_SUCH_FILE\\0" + "NULL_PARAMETER\\0" + "SYS_LIB\\0" + "UNABLE_TO_CREATE_SOCKET\\0" + "UNINITIALIZED\\0" + "UNSUPPORTED_METHOD\\0" + "WRITE_TO_READ_ONLY_BIO\\0" + "ARG2_LT_ARG3\\0" + "BAD_ENCODING\\0" + "BAD_RECIPROCAL\\0" + "BIGNUM_TOO_LONG\\0" + "BITS_TOO_SMALL\\0" + "CALLED_WITH_EVEN_MODULUS\\0" + "DIV_BY_ZERO\\0" + "EXPAND_ON_STATIC_BIGNUM_DATA\\0" + "INPUT_NOT_REDUCED\\0" + "INVALID_INPUT\\0" + "INVALID_RANGE\\0" + "NEGATIVE_NUMBER\\0" + "NOT_A_SQUARE\\0" + "NOT_INITIALIZED\\0" + "NO_INVERSE\\0" + "PRIVATE_KEY_TOO_LARGE\\0" + "P_IS_NOT_PRIME\\0" + "TOO_MANY_ITERATIONS\\0" + "TOO_MANY_TEMPORARY_VARIABLES\\0" + "AES_KEY_SETUP_FAILED\\0" + "BAD_DECRYPT\\0" + "BAD_KEY_LENGTH\\0" + "CTRL_NOT_IMPLEMENTED\\0" + "CTRL_OPERATION_NOT_IMPLEMENTED\\0" + "DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH\\0" + "INITIALIZATION_ERROR\\0" + "INPUT_NOT_INITIALIZED\\0" + "INVALID_AD_SIZE\\0" + "INVALID_KEY_LENGTH\\0" + "INVALID_NONCE\\0" + "INVALID_NONCE_SIZE\\0" + "INVALID_OPERATION\\0" + "IV_TOO_LARGE\\0" + "NO_CIPHER_SET\\0" + "NO_DIRECTION_SET\\0" + "OUTPUT_ALIASES_INPUT\\0" + "TAG_TOO_LARGE\\0" + "TOO_LARGE\\0" + "UNSUPPORTED_AD_SIZE\\0" + "UNSUPPORTED_INPUT_SIZE\\0" + "UNSUPPORTED_KEY_SIZE\\0" + "UNSUPPORTED_NONCE_SIZE\\0" + "UNSUPPORTED_TAG_SIZE\\0" + "WRONG_FINAL_BLOCK_LENGTH\\0" + "LIST_CANNOT_BE_NULL\\0" + "MISSING_CLOSE_SQUARE_BRACKET\\0" + "MISSING_EQUAL_SIGN\\0" + "NO_CLOSE_BRACE\\0" + "UNABLE_TO_CREATE_NEW_SECTION\\0" + "VARIABLE_EXPANSION_TOO_LONG\\0" + "VARIABLE_HAS_NO_VALUE\\0" + "BAD_GENERATOR\\0" + "INVALID_PUBKEY\\0" + "MODULUS_TOO_LARGE\\0" + "NO_PRIVATE_VALUE\\0" + "UNKNOWN_HASH\\0" + "BAD_Q_VALUE\\0" + "BAD_VERSION\\0" + "MISSING_PARAMETERS\\0" + "NEED_NEW_SETUP_VALUES\\0" + "BIGNUM_OUT_OF_RANGE\\0" + "COORDINATES_OUT_OF_RANGE\\0" + "D2I_ECPKPARAMETERS_FAILURE\\0" + "EC_GROUP_NEW_BY_NAME_FAILURE\\0" + "GROUP2PKPARAMETERS_FAILURE\\0" + "GROUP_MISMATCH\\0" + "I2D_ECPKPARAMETERS_FAILURE\\0" + "INCOMPATIBLE_OBJECTS\\0" + "INVALID_COFACTOR\\0" + "INVALID_COMPRESSED_POINT\\0" + "INVALID_COMPRESSION_BIT\\0" + "INVALID_ENCODING\\0" + "INVALID_FIELD\\0" + "INVALID_FORM\\0" + "INVALID_GROUP_ORDER\\0" + "INVALID_PRIVATE_KEY\\0" + "MISSING_PRIVATE_KEY\\0" + "NON_NAMED_CURVE\\0" + "PKPARAMETERS2GROUP_FAILURE\\0" + "POINT_AT_INFINITY\\0" + "POINT_IS_NOT_ON_CURVE\\0" + "PUBLIC_KEY_VALIDATION_FAILED\\0" + "SLOT_FULL\\0" + "UNDEFINED_GENERATOR\\0" + "UNKNOWN_GROUP\\0" + "UNKNOWN_ORDER\\0" + "WRONG_CURVE_PARAMETERS\\0" + "WRONG_ORDER\\0" + "KDF_FAILED\\0" + "POINT_ARITHMETIC_FAILURE\\0" + "BAD_SIGNATURE\\0" + "NOT_IMPLEMENTED\\0" + "RANDOM_NUMBER_GENERATION_FAILED\\0" + "OPERATION_NOT_SUPPORTED\\0" + "COMMAND_NOT_SUPPORTED\\0" + "DIFFERENT_KEY_TYPES\\0" + "DIFFERENT_PARAMETERS\\0" + "EXPECTING_AN_EC_KEY_KEY\\0" + "EXPECTING_AN_RSA_KEY\\0" + "EXPECTING_A_DSA_KEY\\0" + "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\\0" + "INVALID_DIGEST_LENGTH\\0" + "INVALID_DIGEST_TYPE\\0" + "INVALID_KEYBITS\\0" + "INVALID_MGF1_MD\\0" + "INVALID_PADDING_MODE\\0" + "INVALID_PARAMETERS\\0" + "INVALID_PSS_SALTLEN\\0" + "INVALID_SIGNATURE\\0" + "KEYS_NOT_SET\\0" + "MEMORY_LIMIT_EXCEEDED\\0" + "NOT_A_PRIVATE_KEY\\0" + "NO_DEFAULT_DIGEST\\0" + "NO_KEY_SET\\0" + "NO_MDC2_SUPPORT\\0" + "NO_NID_FOR_CURVE\\0" + "NO_OPERATION_SET\\0" + "NO_PARAMETERS_SET\\0" + "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\\0" + "OPERATON_NOT_INITIALIZED\\0" + "UNKNOWN_PUBLIC_KEY_TYPE\\0" + "UNSUPPORTED_ALGORITHM\\0" + "OUTPUT_TOO_LARGE\\0" + "UNKNOWN_NID\\0" + "BAD_BASE64_DECODE\\0" + "BAD_END_LINE\\0" + "BAD_IV_CHARS\\0" + "BAD_PASSWORD_READ\\0" + "CIPHER_IS_NULL\\0" + "ERROR_CONVERTING_PRIVATE_KEY\\0" + "NOT_DEK_INFO\\0" + "NOT_ENCRYPTED\\0" + "NOT_PROC_TYPE\\0" + "NO_START_LINE\\0" + "READ_KEY\\0" + "SHORT_HEADER\\0" + "UNSUPPORTED_CIPHER\\0" + "UNSUPPORTED_ENCRYPTION\\0" + "BAD_PKCS7_VERSION\\0" + "NOT_PKCS7_SIGNED_DATA\\0" + "NO_CERTIFICATES_INCLUDED\\0" + "NO_CRLS_INCLUDED\\0" + "BAD_ITERATION_COUNT\\0" + "BAD_PKCS12_DATA\\0" + "BAD_PKCS12_VERSION\\0" + "CIPHER_HAS_NO_OBJECT_IDENTIFIER\\0" + "CRYPT_ERROR\\0" + "ENCRYPT_ERROR\\0" + "ERROR_SETTING_CIPHER_PARAMS\\0" + "INCORRECT_PASSWORD\\0" + "KEYGEN_FAILURE\\0" + "KEY_GEN_ERROR\\0" + "METHOD_NOT_SUPPORTED\\0" + "MISSING_MAC\\0" + "MULTIPLE_PRIVATE_KEYS_IN_PKCS12\\0" + "PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED\\0" + "PKCS12_TOO_DEEPLY_NESTED\\0" + "PRIVATE_KEY_DECODE_ERROR\\0" + "PRIVATE_KEY_ENCODE_ERROR\\0" + "UNKNOWN_ALGORITHM\\0" + "UNKNOWN_CIPHER\\0" + "UNKNOWN_CIPHER_ALGORITHM\\0" + "UNKNOWN_DIGEST\\0" + "UNSUPPORTED_KEYLENGTH\\0" + "UNSUPPORTED_KEY_DERIVATION_FUNCTION\\0" + "UNSUPPORTED_PRF\\0" + "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\\0" + "UNSUPPORTED_SALT_TYPE\\0" + "BAD_E_VALUE\\0" + "BAD_FIXED_HEADER_DECRYPT\\0" + "BAD_PAD_BYTE_COUNT\\0" + "BAD_RSA_PARAMETERS\\0" + "BLOCK_TYPE_IS_NOT_01\\0" + "BN_NOT_INITIALIZED\\0" + "CANNOT_RECOVER_MULTI_PRIME_KEY\\0" + "CRT_PARAMS_ALREADY_GIVEN\\0" + "CRT_VALUES_INCORRECT\\0" + "DATA_LEN_NOT_EQUAL_TO_MOD_LEN\\0" + "DATA_TOO_LARGE\\0" + "DATA_TOO_LARGE_FOR_KEY_SIZE\\0" + "DATA_TOO_LARGE_FOR_MODULUS\\0" + "DATA_TOO_SMALL\\0" + "DATA_TOO_SMALL_FOR_KEY_SIZE\\0" + "DIGEST_TOO_BIG_FOR_RSA_KEY\\0" + "D_E_NOT_CONGRUENT_TO_1\\0" + "EMPTY_PUBLIC_KEY\\0" + "FIRST_OCTET_INVALID\\0" + "INCONSISTENT_SET_OF_CRT_VALUES\\0" + "INTERNAL_ERROR\\0" + "INVALID_MESSAGE_LENGTH\\0" + "KEY_SIZE_TOO_SMALL\\0" + "LAST_OCTET_INVALID\\0" + "MUST_HAVE_AT_LEAST_TWO_PRIMES\\0" + "NO_PUBLIC_EXPONENT\\0" + "NULL_BEFORE_BLOCK_MISSING\\0" + "N_NOT_EQUAL_P_Q\\0" + "OAEP_DECODING_ERROR\\0" + "ONLY_ONE_OF_P_Q_GIVEN\\0" + "OUTPUT_BUFFER_TOO_SMALL\\0" + "PADDING_CHECK_FAILED\\0" + "PKCS_DECODING_ERROR\\0" + "SLEN_CHECK_FAILED\\0" + "SLEN_RECOVERY_FAILED\\0" + "UNKNOWN_ALGORITHM_TYPE\\0" + "UNKNOWN_PADDING_TYPE\\0" + "VALUE_MISSING\\0" + "WRONG_SIGNATURE_LENGTH\\0" + "ALPN_MISMATCH_ON_EARLY_DATA\\0" + "APPLICATION_DATA_INSTEAD_OF_HANDSHAKE\\0" + "APP_DATA_IN_HANDSHAKE\\0" + "ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT\\0" + "BAD_ALERT\\0" + "BAD_CHANGE_CIPHER_SPEC\\0" + "BAD_DATA_RETURNED_BY_CALLBACK\\0" + "BAD_DH_P_LENGTH\\0" + "BAD_DIGEST_LENGTH\\0" + "BAD_ECC_CERT\\0" + "BAD_ECPOINT\\0" + "BAD_HANDSHAKE_RECORD\\0" + "BAD_HELLO_REQUEST\\0" + "BAD_LENGTH\\0" + "BAD_PACKET_LENGTH\\0" + "BAD_RSA_ENCRYPT\\0" + "BAD_SRTP_MKI_VALUE\\0" + "BAD_SRTP_PROTECTION_PROFILE_LIST\\0" + "BAD_SSL_FILETYPE\\0" + "BAD_WRITE_RETRY\\0" + "BIO_NOT_SET\\0" + "BLOCK_CIPHER_PAD_IS_WRONG\\0" + "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\\0" + "CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD\\0" + "CANNOT_PARSE_LEAF_CERT\\0" + "CA_DN_LENGTH_MISMATCH\\0" + "CA_DN_TOO_LONG\\0" + "CCS_RECEIVED_EARLY\\0" + "CERTIFICATE_AND_PRIVATE_KEY_MISMATCH\\0" + "CERTIFICATE_VERIFY_FAILED\\0" + "CERT_CB_ERROR\\0" + "CERT_LENGTH_MISMATCH\\0" + "CHANNEL_ID_NOT_P256\\0" + "CHANNEL_ID_SIGNATURE_INVALID\\0" + "CIPHER_OR_HASH_UNAVAILABLE\\0" + "CLIENTHELLO_PARSE_FAILED\\0" + "CLIENTHELLO_TLSEXT\\0" + "CONNECTION_REJECTED\\0" + "CONNECTION_TYPE_NOT_SET\\0" + "CUSTOM_EXTENSION_ERROR\\0" + "DATA_LENGTH_TOO_LONG\\0" + "DECRYPTION_FAILED\\0" + "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\\0" + "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\\0" + "DH_P_TOO_LONG\\0" + "DIGEST_CHECK_FAILED\\0" + "DOWNGRADE_DETECTED\\0" + "DTLS_MESSAGE_TOO_BIG\\0" + "DUPLICATE_EXTENSION\\0" + "DUPLICATE_KEY_SHARE\\0" + "ECC_CERT_NOT_FOR_SIGNING\\0" + "EMS_STATE_INCONSISTENT\\0" + "ENCRYPTED_LENGTH_TOO_LONG\\0" + "ERROR_ADDING_EXTENSION\\0" + "ERROR_IN_RECEIVED_CIPHER_LIST\\0" + "ERROR_PARSING_EXTENSION\\0" + "EXCESSIVE_MESSAGE_SIZE\\0" + "EXTRA_DATA_IN_MESSAGE\\0" + "FRAGMENT_MISMATCH\\0" + "GOT_NEXT_PROTO_WITHOUT_EXTENSION\\0" + "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\\0" + "HTTPS_PROXY_REQUEST\\0" + "HTTP_REQUEST\\0" + "INAPPROPRIATE_FALLBACK\\0" + "INVALID_ALPN_PROTOCOL\\0" + "INVALID_COMMAND\\0" + "INVALID_COMPRESSION_LIST\\0" + "INVALID_MESSAGE\\0" + "INVALID_OUTER_RECORD_TYPE\\0" + "INVALID_SCT_LIST\\0" + "INVALID_SSL_SESSION\\0" + "INVALID_TICKET_KEYS_LENGTH\\0" + "LENGTH_MISMATCH\\0" + "MISSING_EXTENSION\\0" + "MISSING_KEY_SHARE\\0" + "MISSING_RSA_CERTIFICATE\\0" + "MISSING_TMP_DH_KEY\\0" + "MISSING_TMP_ECDH_KEY\\0" + "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\\0" + "MTU_TOO_SMALL\\0" + "NEGOTIATED_BOTH_NPN_AND_ALPN\\0" + "NESTED_GROUP\\0" + "NO_CERTIFICATES_RETURNED\\0" + "NO_CERTIFICATE_ASSIGNED\\0" + "NO_CERTIFICATE_SET\\0" + "NO_CIPHERS_AVAILABLE\\0" + "NO_CIPHERS_PASSED\\0" + "NO_CIPHERS_SPECIFIED\\0" + "NO_CIPHER_MATCH\\0" + "NO_COMMON_SIGNATURE_ALGORITHMS\\0" + "NO_COMPRESSION_SPECIFIED\\0" + "NO_GROUPS_SPECIFIED\\0" + "NO_METHOD_SPECIFIED\\0" + "NO_P256_SUPPORT\\0" + "NO_PRIVATE_KEY_ASSIGNED\\0" + "NO_RENEGOTIATION\\0" + "NO_REQUIRED_DIGEST\\0" + "NO_SHARED_CIPHER\\0" + "NO_SHARED_GROUP\\0" + "NO_SUPPORTED_VERSIONS_ENABLED\\0" + "NULL_SSL_CTX\\0" + "NULL_SSL_METHOD_PASSED\\0" + "OLD_SESSION_CIPHER_NOT_RETURNED\\0" + "OLD_SESSION_PRF_HASH_MISMATCH\\0" + "OLD_SESSION_VERSION_NOT_RETURNED\\0" + "PARSE_TLSEXT\\0" + "PATH_TOO_LONG\\0" + "PEER_DID_NOT_RETURN_A_CERTIFICATE\\0" + "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\\0" + "PRE_SHARED_KEY_MUST_BE_LAST\\0" + "PROTOCOL_IS_SHUTDOWN\\0" + "PSK_IDENTITY_BINDER_COUNT_MISMATCH\\0" + "PSK_IDENTITY_NOT_FOUND\\0" + "PSK_NO_CLIENT_CB\\0" + "PSK_NO_SERVER_CB\\0" + "READ_TIMEOUT_EXPIRED\\0" + "RECORD_LENGTH_MISMATCH\\0" + "RECORD_TOO_LARGE\\0" + "RENEGOTIATION_EMS_MISMATCH\\0" + "RENEGOTIATION_ENCODING_ERR\\0" + "RENEGOTIATION_MISMATCH\\0" + "REQUIRED_CIPHER_MISSING\\0" + "RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION\\0" + "RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION\\0" + "SCSV_RECEIVED_WHEN_RENEGOTIATING\\0" + "SERVERHELLO_TLSEXT\\0" + "SERVER_CERT_CHANGED\\0" + "SESSION_ID_CONTEXT_UNINITIALIZED\\0" + "SESSION_MAY_NOT_BE_CREATED\\0" + "SHUTDOWN_WHILE_IN_INIT\\0" + "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\\0" + "SRTP_COULD_NOT_ALLOCATE_PROFILES\\0" + "SRTP_UNKNOWN_PROTECTION_PROFILE\\0" + "SSL3_EXT_INVALID_SERVERNAME\\0" + "SSLV3_ALERT_BAD_CERTIFICATE\\0" + "SSLV3_ALERT_BAD_RECORD_MAC\\0" + "SSLV3_ALERT_CERTIFICATE_EXPIRED\\0" + "SSLV3_ALERT_CERTIFICATE_REVOKED\\0" + "SSLV3_ALERT_CERTIFICATE_UNKNOWN\\0" + "SSLV3_ALERT_CLOSE_NOTIFY\\0" + "SSLV3_ALERT_DECOMPRESSION_FAILURE\\0" + "SSLV3_ALERT_HANDSHAKE_FAILURE\\0" + "SSLV3_ALERT_ILLEGAL_PARAMETER\\0" + "SSLV3_ALERT_NO_CERTIFICATE\\0" + "SSLV3_ALERT_UNEXPECTED_MESSAGE\\0" + "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\\0" + "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\\0" + "SSL_HANDSHAKE_FAILURE\\0" + "SSL_SESSION_ID_CONTEXT_TOO_LONG\\0" + "TICKET_ENCRYPTION_FAILED\\0" + "TLSV1_ALERT_ACCESS_DENIED\\0" + "TLSV1_ALERT_DECODE_ERROR\\0" + "TLSV1_ALERT_DECRYPTION_FAILED\\0" + "TLSV1_ALERT_DECRYPT_ERROR\\0" + "TLSV1_ALERT_EXPORT_RESTRICTION\\0" + "TLSV1_ALERT_INAPPROPRIATE_FALLBACK\\0" + "TLSV1_ALERT_INSUFFICIENT_SECURITY\\0" + "TLSV1_ALERT_INTERNAL_ERROR\\0" + "TLSV1_ALERT_NO_RENEGOTIATION\\0" + "TLSV1_ALERT_PROTOCOL_VERSION\\0" + "TLSV1_ALERT_RECORD_OVERFLOW\\0" + "TLSV1_ALERT_UNKNOWN_CA\\0" + "TLSV1_ALERT_USER_CANCELLED\\0" + "TLSV1_BAD_CERTIFICATE_HASH_VALUE\\0" + "TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\\0" + "TLSV1_CERTIFICATE_REQUIRED\\0" + "TLSV1_CERTIFICATE_UNOBTAINABLE\\0" + "TLSV1_UNKNOWN_PSK_IDENTITY\\0" + "TLSV1_UNRECOGNIZED_NAME\\0" + "TLSV1_UNSUPPORTED_EXTENSION\\0" + "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\\0" + "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\\0" + "TOO_MANY_EMPTY_FRAGMENTS\\0" + "TOO_MANY_KEY_UPDATES\\0" + "TOO_MANY_WARNING_ALERTS\\0" + "TOO_MUCH_READ_EARLY_DATA\\0" + "TOO_MUCH_SKIPPED_EARLY_DATA\\0" + "UNABLE_TO_FIND_ECDH_PARAMETERS\\0" + "UNEXPECTED_EXTENSION\\0" + "UNEXPECTED_EXTENSION_ON_EARLY_DATA\\0" + "UNEXPECTED_MESSAGE\\0" + "UNEXPECTED_OPERATOR_IN_GROUP\\0" + "UNEXPECTED_RECORD\\0" + "UNKNOWN_ALERT_TYPE\\0" + "UNKNOWN_CERTIFICATE_TYPE\\0" + "UNKNOWN_CIPHER_RETURNED\\0" + "UNKNOWN_CIPHER_TYPE\\0" + "UNKNOWN_KEY_EXCHANGE_TYPE\\0" + "UNKNOWN_PROTOCOL\\0" + "UNKNOWN_SSL_VERSION\\0" + "UNKNOWN_STATE\\0" + "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\\0" + "UNSUPPORTED_COMPRESSION_ALGORITHM\\0" + "UNSUPPORTED_ELLIPTIC_CURVE\\0" + "UNSUPPORTED_PROTOCOL\\0" + "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\\0" + "WRONG_CERTIFICATE_TYPE\\0" + "WRONG_CIPHER_RETURNED\\0" + "WRONG_CURVE\\0" + "WRONG_MESSAGE_TYPE\\0" + "WRONG_SIGNATURE_TYPE\\0" + "WRONG_SSL_VERSION\\0" + "WRONG_VERSION_NUMBER\\0" + "WRONG_VERSION_ON_EARLY_DATA\\0" + "X509_LIB\\0" + "X509_VERIFICATION_SETUP_PROBLEMS\\0" + "AKID_MISMATCH\\0" + "BAD_X509_FILETYPE\\0" + "BASE64_DECODE_ERROR\\0" + "CANT_CHECK_DH_KEY\\0" + "CERT_ALREADY_IN_HASH_TABLE\\0" + "CRL_ALREADY_DELTA\\0" + "CRL_VERIFY_FAILURE\\0" + "IDP_MISMATCH\\0" + "INVALID_DIRECTORY\\0" + "INVALID_FIELD_NAME\\0" + "INVALID_PARAMETER\\0" + "INVALID_PSS_PARAMETERS\\0" + "INVALID_TRUST\\0" + "ISSUER_MISMATCH\\0" + "KEY_TYPE_MISMATCH\\0" + "KEY_VALUES_MISMATCH\\0" + "LOADING_CERT_DIR\\0" + "LOADING_DEFAULTS\\0" + "NAME_TOO_LONG\\0" + "NEWER_CRL_NOT_NEWER\\0" + "NO_CERT_SET_FOR_US_TO_VERIFY\\0" + "NO_CRL_NUMBER\\0" + "PUBLIC_KEY_DECODE_ERROR\\0" + "PUBLIC_KEY_ENCODE_ERROR\\0" + "SHOULD_RETRY\\0" + "UNKNOWN_KEY_TYPE\\0" + "UNKNOWN_PURPOSE_ID\\0" + "UNKNOWN_TRUST_ID\\0" + "WRONG_LOOKUP_TYPE\\0" + "BAD_IP_ADDRESS\\0" + "BAD_OBJECT\\0" + "BN_DEC2BN_ERROR\\0" + "BN_TO_ASN1_INTEGER_ERROR\\0" + "CANNOT_FIND_FREE_FUNCTION\\0" + "DIRNAME_ERROR\\0" + "DISTPOINT_ALREADY_SET\\0" + "DUPLICATE_ZONE_ID\\0" + "ERROR_CONVERTING_ZONE\\0" + "ERROR_CREATING_EXTENSION\\0" + "ERROR_IN_EXTENSION\\0" + "EXPECTED_A_SECTION_NAME\\0" + "EXTENSION_EXISTS\\0" + "EXTENSION_NAME_ERROR\\0" + "EXTENSION_NOT_FOUND\\0" + "EXTENSION_SETTING_NOT_SUPPORTED\\0" + "EXTENSION_VALUE_ERROR\\0" + "ILLEGAL_EMPTY_EXTENSION\\0" + "ILLEGAL_HEX_DIGIT\\0" + "INCORRECT_POLICY_SYNTAX_TAG\\0" + "INVALID_BOOLEAN_STRING\\0" + "INVALID_EXTENSION_STRING\\0" + "INVALID_MULTIPLE_RDNS\\0" + "INVALID_NAME\\0" + "INVALID_NULL_ARGUMENT\\0" + "INVALID_NULL_NAME\\0" + "INVALID_NULL_VALUE\\0" + "INVALID_NUMBERS\\0" + "INVALID_OBJECT_IDENTIFIER\\0" + "INVALID_OPTION\\0" + "INVALID_POLICY_IDENTIFIER\\0" + "INVALID_PROXY_POLICY_SETTING\\0" + "INVALID_PURPOSE\\0" + "INVALID_SECTION\\0" + "INVALID_SYNTAX\\0" + "ISSUER_DECODE_ERROR\\0" + "NEED_ORGANIZATION_AND_NUMBERS\\0" + "NO_CONFIG_DATABASE\\0" + "NO_ISSUER_CERTIFICATE\\0" + "NO_ISSUER_DETAILS\\0" + "NO_POLICY_IDENTIFIER\\0" + "NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED\\0" + "NO_PUBLIC_KEY\\0" + "NO_SUBJECT_DETAILS\\0" + "ODD_NUMBER_OF_DIGITS\\0" + "OPERATION_NOT_DEFINED\\0" + "OTHERNAME_ERROR\\0" + "POLICY_LANGUAGE_ALREADY_DEFINED\\0" + "POLICY_PATH_LENGTH\\0" + "POLICY_PATH_LENGTH_ALREADY_DEFINED\\0" + "POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY\\0" + "SECTION_NOT_FOUND\\0" + "UNABLE_TO_GET_ISSUER_DETAILS\\0" + "UNABLE_TO_GET_ISSUER_KEYID\\0" + "UNKNOWN_BIT_STRING_ARGUMENT\\0" + "UNKNOWN_EXTENSION\\0" + "UNKNOWN_EXTENSION_NAME\\0" + "UNKNOWN_OPTION\\0" + "UNSUPPORTED_OPTION\\0" + "USER_TOO_LONG\\0" + ""; + EOF + + sed -i'.back' '/^#define \\([A-Za-z0-9_]*\\) \\1/d' include/openssl/ssl.h + sed -i'.back' 'N;/^#define \\([A-Za-z0-9_]*\\) *\\\\\\n *\\1/d' include/openssl/ssl.h + sed -i'.back' 's/#ifndef md5_block_data_order/#ifndef GRPC_SHADOW_md5_block_data_order/g' crypto/fipsmodule/md5/md5.c + find . -type f \\( -path '*.h' -or -path '*.cc' -or -path '*.c' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include Date: Thu, 17 Jan 2019 09:54:26 +0100 Subject: [PATCH 081/814] revert unnecessary using --- src/csharp/Grpc.Core/Internal/CallSafeHandle.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index 7154ddae30b..a3ef3e61ee1 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -18,7 +18,6 @@ using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; -using System.Threading; using Grpc.Core; using Grpc.Core.Utils; using Grpc.Core.Profiling; From e358f567b0edc26ead1db3bd6c5e4d033bf69a7d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 17 Jan 2019 14:16:41 +0100 Subject: [PATCH 082/814] make ServerCallContext an abstract base class --- .../TestServerCallContext.cs | 73 ++++++++- .../Internal/DefaultServerCallContext.cs | 111 ++++++++++++++ .../Internal/ServerCallContextExtraData.cs | 97 ------------ .../Grpc.Core/Internal/ServerCallHandler.cs | 4 +- src/csharp/Grpc.Core/ServerCallContext.cs | 143 +++++------------- 5 files changed, 220 insertions(+), 208 deletions(-) create mode 100644 src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs delete mode 100644 src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs index d72e98e75a2..7a4fb15b4f9 100644 --- a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs +++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs @@ -36,12 +36,73 @@ namespace Grpc.Core.Testing string peer, AuthContext authContext, ContextPropagationToken contextPropagationToken, Func writeHeadersFunc, Func writeOptionsGetter, Action writeOptionsSetter) { - return new ServerCallContext(null, method, host, deadline, requestHeaders, cancellationToken, - (ctx, extraData, headers) => writeHeadersFunc(headers), - (ctx, extraData) => writeOptionsGetter(), - (ctx, extraData, options) => writeOptionsSetter(options), - (ctx, extraData) => peer, (ctx, callHandle) => authContext, - (ctx, callHandle, options) => contextPropagationToken); + return new TestingServerCallContext(method, host, deadline, requestHeaders, cancellationToken, peer, + authContext, contextPropagationToken, writeHeadersFunc, writeOptionsGetter, writeOptionsSetter); + } + + private class TestingServerCallContext : ServerCallContext + { + private readonly string method; + private readonly string host; + private readonly DateTime deadline; + private readonly Metadata requestHeaders; + private readonly CancellationToken cancellationToken; + private readonly Metadata responseTrailers = new Metadata(); + private Status status; + private readonly string peer; + private readonly AuthContext authContext; + private readonly ContextPropagationToken contextPropagationToken; + private readonly Func writeHeadersFunc; + private readonly Func writeOptionsGetter; + private readonly Action writeOptionsSetter; + + public TestingServerCallContext(string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, + string peer, AuthContext authContext, ContextPropagationToken contextPropagationToken, + Func writeHeadersFunc, Func writeOptionsGetter, Action writeOptionsSetter) + { + this.method = method; + this.host = host; + this.deadline = deadline; + this.requestHeaders = requestHeaders; + this.cancellationToken = cancellationToken; + this.responseTrailers = new Metadata(); + this.status = Status.DefaultSuccess; + this.peer = peer; + this.authContext = authContext; + this.contextPropagationToken = contextPropagationToken; + this.writeHeadersFunc = writeHeadersFunc; + this.writeOptionsGetter = writeOptionsGetter; + this.writeOptionsSetter = writeOptionsSetter; + } + + protected override string MethodInternal => method; + + protected override string HostInternal => host; + + protected override string PeerInternal => peer; + + protected override DateTime DeadlineInternal => deadline; + + protected override Metadata RequestHeadersInternal => requestHeaders; + + protected override CancellationToken CancellationTokenInternal => cancellationToken; + + protected override Metadata ResponseTrailersInternal => responseTrailers; + + protected override Status StatusInternal { get => status; set => status = value; } + protected override WriteOptions WriteOptionsInternal { get => writeOptionsGetter(); set => writeOptionsSetter(value); } + + protected override AuthContext AuthContextInternal => authContext; + + protected override ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options) + { + return contextPropagationToken; + } + + protected override Task WriteResponseHeadersInternalAsync(Metadata responseHeaders) + { + return writeHeadersFunc(responseHeaders); + } } } } diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs new file mode 100644 index 00000000000..1e484bdcf2d --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -0,0 +1,111 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Threading; +using System.Threading.Tasks; + +using Grpc.Core.Internal; +using Grpc.Core.Utils; + +namespace Grpc.Core +{ + /// + /// Default implementation of ServerCallContext. + /// + internal class DefaultServerCallContext : ServerCallContext + { + private readonly CallSafeHandle callHandle; + private readonly string method; + private readonly string host; + private readonly DateTime deadline; + private readonly Metadata requestHeaders; + private readonly CancellationToken cancellationToken; + private readonly Metadata responseTrailers; + private Status status; + private readonly IServerResponseStream serverResponseStream; + private readonly Lazy authContext; + + /// + /// Creates a new instance of ServerCallContext. + /// To allow reuse of ServerCallContext API by different gRPC implementations, the implementation of some members is provided externally. + /// To provide state, this ServerCallContext instance and extraData will be passed to the member implementations. + /// + internal DefaultServerCallContext(CallSafeHandle callHandle, string method, string host, DateTime deadline, + Metadata requestHeaders, CancellationToken cancellationToken, IServerResponseStream serverResponseStream) + { + this.callHandle = callHandle; + this.method = method; + this.host = host; + this.deadline = deadline; + this.requestHeaders = requestHeaders; + this.cancellationToken = cancellationToken; + this.responseTrailers = new Metadata(); + this.status = Status.DefaultSuccess; + this.serverResponseStream = serverResponseStream; + // TODO(jtattermusch): avoid unnecessary allocation of factory function and the lazy object + this.authContext = new Lazy(GetAuthContextEager); + } + + protected override ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options) + { + return new ContextPropagationToken(callHandle, deadline, cancellationToken, options); + } + + protected override Task WriteResponseHeadersInternalAsync(Metadata responseHeaders) + { + return serverResponseStream.WriteResponseHeadersAsync(responseHeaders); + } + + protected override string MethodInternal => method; + + protected override string HostInternal => host; + + protected override string PeerInternal => callHandle.GetPeer(); + + protected override DateTime DeadlineInternal => deadline; + + protected override Metadata RequestHeadersInternal => requestHeaders; + + protected override CancellationToken CancellationTokenInternal => cancellationToken; + + protected override Metadata ResponseTrailersInternal => responseTrailers; + + protected override Status StatusInternal + { + get => status; + set => status = value; + } + + protected override WriteOptions WriteOptionsInternal + { + get => serverResponseStream.WriteOptions; + set => serverResponseStream.WriteOptions = value; + } + + protected override AuthContext AuthContextInternal => authContext.Value; + + private AuthContext GetAuthContextEager() + { + using (var authContextNative = callHandle.GetAuthContext()) + { + return authContextNative.ToAuthContext(); + } + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs b/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs deleted file mode 100644 index 97b95e66df9..00000000000 --- a/src/csharp/Grpc.Core/Internal/ServerCallContextExtraData.cs +++ /dev/null @@ -1,97 +0,0 @@ -#region Copyright notice and license - -// Copyright 2019 The gRPC Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#endregion - -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Grpc.Core.Internal -{ - /// - /// Additional state for ServerCallContext. - /// Storing the extra state outside of ServerCallContext allows it to be implementation-agnostic. - /// - internal class ServerCallContextExtraData - { - readonly CallSafeHandle callHandle; - readonly IServerResponseStream serverResponseStream; - readonly Lazy cachedAuthContext; - - public ServerCallContextExtraData(CallSafeHandle callHandle, IServerResponseStream serverResponseStream) - { - this.callHandle = callHandle; - this.serverResponseStream = serverResponseStream; - // TODO(jtattermusch): avoid unnecessary allocation of factory function and the lazy object. - this.cachedAuthContext = new Lazy(GetAuthContextEager); - } - - public ServerCallContext NewServerCallContext(ServerRpcNew newRpc, CancellationToken cancellationToken) - { - DateTime realtimeDeadline = newRpc.Deadline.ToClockType(ClockType.Realtime).ToDateTime(); - - return new ServerCallContext(this, newRpc.Method, newRpc.Host, realtimeDeadline, - newRpc.RequestMetadata, cancellationToken, - ServerCallContext_WriteHeadersFunc, ServerCallContext_WriteOptionsGetter, ServerCallContext_WriteOptionsSetter, - ServerCallContext_PeerGetter, ServerCallContext_AuthContextGetter, ServerCallContext_ContextPropagationTokenFactory); - } - - private AuthContext GetAuthContextEager() - { - using (var authContextNative = callHandle.GetAuthContext()) - { - return authContextNative.ToAuthContext(); - } - } - - // Implementors of ServerCallContext's members are pre-allocated to avoid unneccessary delegate allocations. - readonly static Func ServerCallContext_WriteHeadersFunc = (ctx, extraData, headers) => - { - return ((ServerCallContextExtraData)extraData).serverResponseStream.WriteResponseHeadersAsync(headers); - }; - - readonly static Func ServerCallContext_WriteOptionsGetter = (ctx, extraData) => - { - - return ((ServerCallContextExtraData)extraData).serverResponseStream.WriteOptions; - }; - - readonly static Action ServerCallContext_WriteOptionsSetter = (ctx, extraData, options) => - { - ((ServerCallContextExtraData)extraData).serverResponseStream.WriteOptions = options; - }; - - readonly static Func ServerCallContext_PeerGetter = (ctx, extraData) => - { - // Getting the peer lazily is fine as the native call is guaranteed - // not to be disposed before user-supplied server side handler returns. - // Most users won't need to read this field anyway. - return ((ServerCallContextExtraData)extraData).callHandle.GetPeer(); - }; - - readonly static Func ServerCallContext_AuthContextGetter = (ctx, extraData) => - { - return ((ServerCallContextExtraData)extraData).cachedAuthContext.Value; - }; - - readonly static Func ServerCallContext_ContextPropagationTokenFactory = (ctx, extraData, options) => - { - var callHandle = ((ServerCallContextExtraData)extraData).callHandle; - return new ContextPropagationToken(callHandle, ctx.Deadline, ctx.CancellationToken, options); - }; - } -} diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index ae586f7d1c4..c3859f1de27 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -348,9 +348,7 @@ namespace Grpc.Core.Internal public static ServerCallContext NewContext(ServerRpcNew newRpc, IServerResponseStream serverResponseStream, CancellationToken cancellationToken) { DateTime realtimeDeadline = newRpc.Deadline.ToClockType(ClockType.Realtime).ToDateTime(); - - var contextExtraData = new ServerCallContextExtraData(newRpc.Call, serverResponseStream); - return contextExtraData.NewServerCallContext(newRpc, cancellationToken); + return new DefaultServerCallContext(newRpc.Call, newRpc.Method, newRpc.Host, realtimeDeadline, newRpc.RequestMetadata, cancellationToken, serverResponseStream); } } } diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs index 05c20ca75f8..4a2fdf32c71 100644 --- a/src/csharp/Grpc.Core/ServerCallContext.cs +++ b/src/csharp/Grpc.Core/ServerCallContext.cs @@ -28,51 +28,13 @@ namespace Grpc.Core /// /// Context for a server-side call. /// - public class ServerCallContext + public abstract class ServerCallContext { - private readonly object extraData; - private readonly string method; - private readonly string host; - private readonly DateTime deadline; - private readonly Metadata requestHeaders; - private readonly CancellationToken cancellationToken; - private readonly Metadata responseTrailers = new Metadata(); - private readonly Func writeHeadersFunc; - private readonly Func writeOptionsGetter; - private readonly Action writeOptionsSetter; - - private readonly Func peerGetter; - private readonly Func authContextGetter; - private readonly Func contextPropagationTokenFactory; - - private Status status = Status.DefaultSuccess; - /// /// Creates a new instance of ServerCallContext. - /// To allow reuse of ServerCallContext API by different gRPC implementations, the implementation of some members is provided externally. - /// To provide state, this ServerCallContext instance and extraData will be passed to the member implementations. /// - internal ServerCallContext(object extraData, - string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken, - Func writeHeadersFunc, - Func writeOptionsGetter, - Action writeOptionsSetter, - Func peerGetter, - Func authContextGetter, - Func contextPropagationTokenFactory) + protected ServerCallContext() { - this.extraData = extraData; - this.method = method; - this.host = host; - this.deadline = deadline; - this.requestHeaders = requestHeaders; - this.cancellationToken = cancellationToken; - this.writeHeadersFunc = GrpcPreconditions.CheckNotNull(writeHeadersFunc); - this.writeOptionsGetter = GrpcPreconditions.CheckNotNull(writeOptionsGetter); - this.writeOptionsSetter = GrpcPreconditions.CheckNotNull(writeOptionsSetter); - this.peerGetter = GrpcPreconditions.CheckNotNull(peerGetter); - this.authContextGetter = GrpcPreconditions.CheckNotNull(authContextGetter); - this.contextPropagationTokenFactory = GrpcPreconditions.CheckNotNull(contextPropagationTokenFactory); } /// @@ -84,7 +46,7 @@ namespace Grpc.Core /// The task that finished once response headers have been written. public Task WriteResponseHeadersAsync(Metadata responseHeaders) { - return writeHeadersFunc(this, extraData, responseHeaders); + return WriteResponseHeadersInternalAsync(responseHeaders); } /// @@ -92,83 +54,41 @@ namespace Grpc.Core /// public ContextPropagationToken CreatePropagationToken(ContextPropagationOptions options = null) { - return contextPropagationTokenFactory(this, extraData, options); + return CreatePropagationTokenInternal(options); } /// Name of method called in this RPC. - public string Method - { - get - { - return this.method; - } - } + public string Method => MethodInternal; /// Name of host called in this RPC. - public string Host - { - get - { - return this.host; - } - } + public string Host => HostInternal; /// Address of the remote endpoint in URI format. - public string Peer - { - get - { - return peerGetter(this, extraData); - } - } + public string Peer => PeerInternal; /// Deadline for this RPC. - public DateTime Deadline - { - get - { - return this.deadline; - } - } + public DateTime Deadline => DeadlineInternal; /// Initial metadata sent by client. - public Metadata RequestHeaders - { - get - { - return this.requestHeaders; - } - } + public Metadata RequestHeaders => RequestHeadersInternal; /// Cancellation token signals when call is cancelled. - public CancellationToken CancellationToken - { - get - { - return this.cancellationToken; - } - } + public CancellationToken CancellationToken => CancellationTokenInternal; /// Trailers to send back to client after RPC finishes. - public Metadata ResponseTrailers - { - get - { - return this.responseTrailers; - } - } + public Metadata ResponseTrailers => ResponseTrailersInternal; /// Status to send back to client after RPC finishes. public Status Status { get { - return this.status; + return StatusInternal; } set { - status = value; + StatusInternal = value; } } @@ -181,12 +101,12 @@ namespace Grpc.Core { get { - return writeOptionsGetter(this, extraData); + return WriteOptionsInternal; } set { - writeOptionsSetter(this, extraData, value); + WriteOptionsInternal = value; } } @@ -194,12 +114,31 @@ namespace Grpc.Core /// Gets the AuthContext associated with this call. /// Note: Access to AuthContext is an experimental API that can change without any prior notice. /// - public AuthContext AuthContext - { - get - { - return authContextGetter(this, extraData); - } - } + public AuthContext AuthContext => AuthContextInternal; + + /// Provides implementation of a non-virtual public member. + protected abstract Task WriteResponseHeadersInternalAsync(Metadata responseHeaders); + /// Provides implementation of a non-virtual public member. + protected abstract ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options); + /// Provides implementation of a non-virtual public member. + protected abstract string MethodInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract string HostInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract string PeerInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract DateTime DeadlineInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract Metadata RequestHeadersInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract CancellationToken CancellationTokenInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract Metadata ResponseTrailersInternal { get; } + /// Provides implementation of a non-virtual public member. + protected abstract Status StatusInternal { get; set; } + /// Provides implementation of a non-virtual public member. + protected abstract WriteOptions WriteOptionsInternal { get; set; } + /// Provides implementation of a non-virtual public member. + protected abstract AuthContext AuthContextInternal { get; } } } From 7d6341b627b883d400074bbdd0a70735f5290e84 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 17 Jan 2019 14:51:02 +0100 Subject: [PATCH 083/814] remove unnecessary using --- src/csharp/Grpc.Core.Testing/TestServerCallContext.cs | 1 - src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs | 1 - src/csharp/Grpc.Core/ServerCallContext.cs | 3 --- 3 files changed, 5 deletions(-) diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs index 7a4fb15b4f9..ff4fb66c6c9 100644 --- a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs +++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs @@ -19,7 +19,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Grpc.Core; namespace Grpc.Core.Testing { diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs index 1e484bdcf2d..b6a29af2edb 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -21,7 +21,6 @@ using System.Threading; using System.Threading.Tasks; using Grpc.Core.Internal; -using Grpc.Core.Utils; namespace Grpc.Core { diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs index 4a2fdf32c71..17aa1fe0661 100644 --- a/src/csharp/Grpc.Core/ServerCallContext.cs +++ b/src/csharp/Grpc.Core/ServerCallContext.cs @@ -20,9 +20,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Grpc.Core.Internal; -using Grpc.Core.Utils; - namespace Grpc.Core { /// From e3f1f3c8568314bd777f78883fa56520e0b7aee2 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 17 Jan 2019 09:39:23 -0800 Subject: [PATCH 084/814] Atomically store uuid of lb channel --- .../client_channel/lb_policy/grpclb/grpclb.cc | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 78de8b35659..6d46baa08fe 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -296,9 +296,8 @@ class GrpcLb : public LoadBalancingPolicy { // The channel for communicating with the LB server. grpc_channel* lb_channel_ = nullptr; - // Mutex to protect the channel to the LB server. This is used when - // processing a channelz request. - gpr_mu lb_channel_mu_; + // Uuid of the lb channel. Used for channelz. + gpr_atm lb_channel_uuid_ = 0; grpc_connectivity_state lb_channel_connectivity_; grpc_closure lb_channel_on_connectivity_changed_; // Are we already watching the LB channel's connectivity? @@ -986,7 +985,6 @@ GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args) .set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { // Initialization. - gpr_mu_init(&lb_channel_mu_); GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); @@ -1023,7 +1021,6 @@ GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args) GrpcLb::~GrpcLb() { GPR_ASSERT(pending_picks_ == nullptr); - gpr_mu_destroy(&lb_channel_mu_); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); grpc_connectivity_state_destroy(&state_tracker_); @@ -1049,10 +1046,9 @@ void GrpcLb::ShutdownLocked() { // OnBalancerChannelConnectivityChangedLocked(), and we need to be // alive when that callback is invoked. if (lb_channel_ != nullptr) { - gpr_mu_lock(&lb_channel_mu_); grpc_channel_destroy(lb_channel_); lb_channel_ = nullptr; - gpr_mu_unlock(&lb_channel_mu_); + gpr_atm_no_barrier_store(&lb_channel_uuid_, 0); } grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), "grpclb_shutdown"); @@ -1210,12 +1206,8 @@ void GrpcLb::FillChildRefsForChannelz( if (rr_policy_ != nullptr) { rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); } - if (lb_channel_ != nullptr) { - grpc_core::channelz::ChannelNode* channel_node = - grpc_channel_get_channelz_node(lb_channel_); - if (channel_node != nullptr) { - child_channels->push_back(channel_node->uuid()); - } + if (lb_channel_uuid_ != 0) { + child_channels->push_back(lb_channel_uuid_); } } @@ -1275,12 +1267,15 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { if (lb_channel_ == nullptr) { char* uri_str; gpr_asprintf(&uri_str, "fake:///%s", server_name_); - gpr_mu_lock(&lb_channel_mu_); lb_channel_ = grpc_client_channel_factory_create_channel( client_channel_factory(), uri_str, GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args); - gpr_mu_unlock(&lb_channel_mu_); GPR_ASSERT(lb_channel_ != nullptr); + grpc_core::channelz::ChannelNode* channel_node = + grpc_channel_get_channelz_node(lb_channel_); + if (channel_node != nullptr) { + gpr_atm_no_barrier_store(&lb_channel_uuid_, channel_node->uuid()); + } gpr_free(uri_str); } // Propagate updates to the LB channel (pick_first) through the fake From 79b9707db4469aa48af694689e73157b7cd16864 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 17 Jan 2019 09:51:07 -0800 Subject: [PATCH 085/814] reviewer feedback --- .../ext/filters/client_channel/lb_policy/grpclb/grpclb.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 6d46baa08fe..51b61ecb92c 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1206,8 +1206,9 @@ void GrpcLb::FillChildRefsForChannelz( if (rr_policy_ != nullptr) { rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); } - if (lb_channel_uuid_ != 0) { - child_channels->push_back(lb_channel_uuid_); + gpr_atm uuid = gpr_atm_no_barrier_load(&lb_channel_uuid_); + if (uuid != 0) { + child_channels->push_back(uuid); } } From 47e5771181c305bab79322a85e58a23203703be8 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 17 Jan 2019 10:25:41 -0800 Subject: [PATCH 086/814] Fix grpc_tool_test --- test/cpp/util/grpc_tool_test.cc | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index b96b00f2db2..57cdbeb7b76 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -258,14 +258,6 @@ class GrpcToolTest : public ::testing::Test { void ShutdownServer() { server_->Shutdown(); } - void ExitWhenError(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback) { - int result = GrpcToolMainLib(argc, argv, cred, callback); - if (result) { - exit(result); - } - } - std::unique_ptr server_; TestServiceImpl service_; reflection::ProtoServerReflectionPlugin plugin_; @@ -418,11 +410,9 @@ TEST_F(GrpcToolTest, TypeNotFound) { const char* argv[] = {"grpc_cli", "type", server_address.c_str(), "grpc.testing.DummyRequest"}; - EXPECT_DEATH(ExitWhenError(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1)), - ".*Type grpc.testing.DummyRequest not found.*"); - + EXPECT_TRUE(1 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); ShutdownServer(); } From dde966f8c62f664b637d195983562b75860e4626 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 17 Jan 2019 12:03:14 -0800 Subject: [PATCH 087/814] Reviewer comments --- examples/cpp/keyvaluestore/caching_interceptor.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/cpp/keyvaluestore/caching_interceptor.h b/examples/cpp/keyvaluestore/caching_interceptor.h index 8ecdafaf159..5a31afe0f01 100644 --- a/examples/cpp/keyvaluestore/caching_interceptor.h +++ b/examples/cpp/keyvaluestore/caching_interceptor.h @@ -27,8 +27,9 @@ #endif // This is a naive implementation of a cache. A new cache is for each call. For -// each new key request, the key is first searched in the map and if found, the interceptor feeds in the value. Only -// if the key is not found in the cache do we make a request. +// each new key request, the key is first searched in the map and if found, the +// interceptor fills in the return value without making a request to the server. +// Only if the key is not found in the cache do we make a request. class CachingInterceptor : public grpc::experimental::Interceptor { public: CachingInterceptor(grpc::experimental::ClientRpcInfo* info) {} @@ -101,11 +102,14 @@ class CachingInterceptor : public grpc::experimental::Interceptor { auto* status = methods->GetRecvStatus(); *status = grpc::Status::OK; } + // One of Hijack or Proceed always needs to be called to make progress. if (hijack) { - // Hijack is called only once when PRE_SEND_INITIAL_METADATA is present in the hook points + // Hijack is called only once when PRE_SEND_INITIAL_METADATA is present in + // the hook points methods->Hijack(); } else { - // Proceed is an indicator that the interceptor is done intercepting the batch. + // Proceed is an indicator that the interceptor is done intercepting the + // batch. methods->Proceed(); } } From a5d9c353bf110aab347137e98541f55a50162994 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 17 Jan 2019 13:37:26 -0800 Subject: [PATCH 088/814] fix indent in template --- .../BoringSSL-GRPC.podspec.template | 9040 ++++++++--------- 1 file changed, 4520 insertions(+), 4520 deletions(-) diff --git a/templates/src/objective-c/BoringSSL-GRPC.podspec.template b/templates/src/objective-c/BoringSSL-GRPC.podspec.template index 42e3c7a82ea..8b2a23ae0c5 100644 --- a/templates/src/objective-c/BoringSSL-GRPC.podspec.template +++ b/templates/src/objective-c/BoringSSL-GRPC.podspec.template @@ -5,4531 +5,4531 @@ return ',\n '.join("'#define %s GRPC_SHADOW_%s'" % (symbol, symbol) for symbol in symbol_list) %> -# This file has been automatically generated from a template file. -# Please make modifications to -# `templates/src/objective-c/BoringSSL-GRPC.podspec.template` instead. This -# file can be regenerated from the template by running -# `tools/buildgen/generate_projects.sh`. + # This file has been automatically generated from a template file. + # Please make modifications to + # `templates/src/objective-c/BoringSSL-GRPC.podspec.template` instead. This + # file can be regenerated from the template by running + # `tools/buildgen/generate_projects.sh`. -# BoringSSL CocoaPods podspec + # BoringSSL CocoaPods podspec -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Pod::Spec.new do |s| - s.name = 'BoringSSL-GRPC' - version = '0.0.2' - s.version = version - s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.' - # Adapted from the homepage: - s.description = <<-DESC - BoringSSL is a fork of OpenSSL that is designed to meet Google's needs. - - Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. - We don't recommend that third parties depend upon it. Doing so is likely to be frustrating - because there are no guarantees of API stability. Only the latest version of this pod is - supported, and every new version is a new major version. - - We update Google libraries and programs that use BoringSSL as needed when deciding to make API - changes. This allows us to mostly avoid compromises in the name of compatibility. It works for - us, but it may not work for you. - - As a Cocoapods pod, it has the advantage over OpenSSL's pods that the library doesn't need to - be precompiled. This eliminates the 10 - 20 minutes of wait the first time a user does "pod - install", lets it be used as a dynamic framework (pending solution of Cocoapods' issue #4605), - and works with bitcode automatically. It's also thought to be smaller than OpenSSL (which takes - 1MB - 2MB per ARM architecture), but we don't have specific numbers yet. - - BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built - up a large number of patches that were maintained while tracking upstream OpenSSL. As Google's - product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved - in maintaining all these patches in multiple places was growing steadily. - - Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's not part of the - NDK) and a number of other apps/programs. - DESC - s.homepage = 'https://github.com/google/boringssl' - s.license = { :type => 'Mixed', :file => 'LICENSE' } - # "The name and email addresses of the library maintainers, not the Podspec maintainer." - s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite' - - s.source = { - :git => 'https://github.com/google/boringssl.git', - :commit => "b29b21a81b32ec273f118f589f46d56ad3332420", - } - - s.ios.deployment_target = '5.0' - s.osx.deployment_target = '10.7' - s.tvos.deployment_target = '10.0' - - name = 'openssl_grpc' - - # When creating a dynamic framework, name it openssl.framework instead of BoringSSL.framework. - # This lets users write their includes like `#include ` as opposed to `#include - # `. - s.module_name = name - - # When creating a dynamic framework, copy the headers under `include/openssl/` into the root of - # the `Headers/` directory of the framework (i.e., not under `Headers/include/openssl`). + # Copyright 2015, Google Inc. + # All rights reserved. # - # TODO(jcanizales): Debug why this doesn't work on macOS. - s.header_mappings_dir = 'include/openssl' + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are + # met: + # + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above + # copyright notice, this list of conditions and the following disclaimer + # in the documentation and/or other materials provided with the + # distribution. + # * Neither the name of Google Inc. nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - # The above has an undesired effect when creating a static library: It forces users to write - # includes like `#include `. `s.header_dir` adds a path prefix to that, and - # because Cocoapods lets omit the pod name when including headers of static libraries, the - # following lets users write `#include `. - s.header_dir = name + Pod::Spec.new do |s| + s.name = 'BoringSSL-GRPC' + version = '0.0.2' + s.version = version + s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.' + # Adapted from the homepage: + s.description = <<-DESC + BoringSSL is a fork of OpenSSL that is designed to meet Google's needs. - # The module map and umbrella header created automatically by Cocoapods don't work for C libraries - # like this one. The following file, and a correct umbrella header, are created on the fly by the - # `prepare_command` of this pod. - s.module_map = 'include/openssl/BoringSSL.modulemap' + Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. + We don't recommend that third parties depend upon it. Doing so is likely to be frustrating + because there are no guarantees of API stability. Only the latest version of this pod is + supported, and every new version is a new major version. - # We don't need to inhibit all warnings; only -Wno-shorten-64-to-32. But Cocoapods' linter doesn't - # want that for some reason. - s.compiler_flags = '-DOPENSSL_NO_ASM', '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w' - s.requires_arc = false + We update Google libraries and programs that use BoringSSL as needed when deciding to make API + changes. This allows us to mostly avoid compromises in the name of compatibility. It works for + us, but it may not work for you. - # Like many other C libraries, BoringSSL has its public headers under `include//` and its - # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't - # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in - # practice). Because we need our `header_mappings_dir` to be `include/openssl/` for the reason - # mentioned above, we work around the linter limitation by dividing the pod into two subspecs, one - # for public headers and the other for implementation. Each gets its own `header_mappings_dir`, - # making the linter happy. - s.subspec 'Interface' do |ss| - ss.header_mappings_dir = 'include/openssl' - ss.source_files = 'include/openssl/*.h' + As a Cocoapods pod, it has the advantage over OpenSSL's pods that the library doesn't need to + be precompiled. This eliminates the 10 - 20 minutes of wait the first time a user does "pod + install", lets it be used as a dynamic framework (pending solution of Cocoapods' issue #4605), + and works with bitcode automatically. It's also thought to be smaller than OpenSSL (which takes + 1MB - 2MB per ARM architecture), but we don't have specific numbers yet. + + BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built + up a large number of patches that were maintained while tracking upstream OpenSSL. As Google's + product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved + in maintaining all these patches in multiple places was growing steadily. + + Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's not part of the + NDK) and a number of other apps/programs. + DESC + s.homepage = 'https://github.com/google/boringssl' + s.license = { :type => 'Mixed', :file => 'LICENSE' } + # "The name and email addresses of the library maintainers, not the Podspec maintainer." + s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite' + + s.source = { + :git => 'https://github.com/google/boringssl.git', + :commit => "b29b21a81b32ec273f118f589f46d56ad3332420", + } + + s.ios.deployment_target = '5.0' + s.osx.deployment_target = '10.7' + s.tvos.deployment_target = '10.0' + + name = 'openssl_grpc' + + # When creating a dynamic framework, name it openssl.framework instead of BoringSSL.framework. + # This lets users write their includes like `#include ` as opposed to `#include + # `. + s.module_name = name + + # When creating a dynamic framework, copy the headers under `include/openssl/` into the root of + # the `Headers/` directory of the framework (i.e., not under `Headers/include/openssl`). + # + # TODO(jcanizales): Debug why this doesn't work on macOS. + s.header_mappings_dir = 'include/openssl' + + # The above has an undesired effect when creating a static library: It forces users to write + # includes like `#include `. `s.header_dir` adds a path prefix to that, and + # because Cocoapods lets omit the pod name when including headers of static libraries, the + # following lets users write `#include `. + s.header_dir = name + + # The module map and umbrella header created automatically by Cocoapods don't work for C libraries + # like this one. The following file, and a correct umbrella header, are created on the fly by the + # `prepare_command` of this pod. + s.module_map = 'include/openssl/BoringSSL.modulemap' + + # We don't need to inhibit all warnings; only -Wno-shorten-64-to-32. But Cocoapods' linter doesn't + # want that for some reason. + s.compiler_flags = '-DOPENSSL_NO_ASM', '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w' + s.requires_arc = false + + # Like many other C libraries, BoringSSL has its public headers under `include//` and its + # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't + # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in + # practice). Because we need our `header_mappings_dir` to be `include/openssl/` for the reason + # mentioned above, we work around the linter limitation by dividing the pod into two subspecs, one + # for public headers and the other for implementation. Each gets its own `header_mappings_dir`, + # making the linter happy. + s.subspec 'Interface' do |ss| + ss.header_mappings_dir = 'include/openssl' + ss.source_files = 'include/openssl/*.h' + end + s.subspec 'Implementation' do |ss| + ss.header_mappings_dir = '.' + ss.source_files = 'ssl/*.{h,cc}', + 'ssl/**/*.{h,cc}', + '*.{h,c}', + 'crypto/*.{h,c}', + 'crypto/**/*.{h,c}', + 'third_party/fiat/*.{h,c}' + ss.private_header_files = 'ssl/*.h', + 'ssl/**/*.h', + '*.h', + 'crypto/*.h', + 'crypto/**/*.h' + # bcm.c includes other source files, creating duplicated symbols. Since it is not used, we + # explicitly exclude it from the pod. + # TODO (mxyan): Work with BoringSSL team to remove this hack. + ss.exclude_files = 'crypto/fipsmodule/bcm.c', + '**/*_test.*', + '**/test_*.*', + '**/test/*.*' + + ss.dependency "#{s.name}/Interface", version + end + + s.prepare_command = <<-END_OF_COMMAND + # Add a module map and an umbrella header + cat > include/openssl/umbrella.h < include/openssl/BoringSSL.modulemap < err_data.c < + #include + #include + + + OPENSSL_COMPILE_ASSERT(ERR_LIB_NONE == 1, library_values_changed_1); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SYS == 2, library_values_changed_2); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BN == 3, library_values_changed_3); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RSA == 4, library_values_changed_4); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DH == 5, library_values_changed_5); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EVP == 6, library_values_changed_6); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BUF == 7, library_values_changed_7); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OBJ == 8, library_values_changed_8); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PEM == 9, library_values_changed_9); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DSA == 10, library_values_changed_10); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509 == 11, library_values_changed_11); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ASN1 == 12, library_values_changed_12); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CONF == 13, library_values_changed_13); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CRYPTO == 14, library_values_changed_14); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EC == 15, library_values_changed_15); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SSL == 16, library_values_changed_16); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BIO == 17, library_values_changed_17); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS7 == 18, library_values_changed_18); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS8 == 19, library_values_changed_19); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509V3 == 20, library_values_changed_20); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RAND == 21, library_values_changed_21); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ENGINE == 22, library_values_changed_22); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OCSP == 23, library_values_changed_23); + OPENSSL_COMPILE_ASSERT(ERR_LIB_UI == 24, library_values_changed_24); + OPENSSL_COMPILE_ASSERT(ERR_LIB_COMP == 25, library_values_changed_25); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDSA == 26, library_values_changed_26); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDH == 27, library_values_changed_27); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31); + OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32); + OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num); + + const uint32_t kOpenSSLReasonValues[] = { + 0xc320838, + 0xc328852, + 0xc330861, + 0xc338871, + 0xc340880, + 0xc348899, + 0xc3508a5, + 0xc3588c2, + 0xc3608e2, + 0xc3688f0, + 0xc370900, + 0xc37890d, + 0xc38091d, + 0xc388928, + 0xc39093e, + 0xc39894d, + 0xc3a0961, + 0xc3a8845, + 0xc3b00ea, + 0xc3b88d4, + 0x10320845, + 0x10329513, + 0x1033151f, + 0x10339538, + 0x1034154b, + 0x10348eed, + 0x10350c5e, + 0x1035955e, + 0x10361573, + 0x10369586, + 0x103715a5, + 0x103795be, + 0x103815d3, + 0x103895f1, + 0x10391600, + 0x1039961c, + 0x103a1637, + 0x103a9646, + 0x103b1662, + 0x103b967d, + 0x103c1694, + 0x103c80ea, + 0x103d16a5, + 0x103d96b9, + 0x103e16d8, + 0x103e96e7, + 0x103f16fe, + 0x103f9711, + 0x10400c22, + 0x10409724, + 0x10411742, + 0x10419755, + 0x1042176f, + 0x1042977f, + 0x10431793, + 0x104397a9, + 0x104417c1, + 0x104497d6, + 0x104517ea, + 0x104597fc, + 0x104605fb, + 0x1046894d, + 0x10471811, + 0x10479828, + 0x1048183d, + 0x1048984b, + 0x10490e4f, + 0x14320c05, + 0x14328c13, + 0x14330c22, + 0x14338c34, + 0x143400ac, + 0x143480ea, + 0x18320083, + 0x18328f43, + 0x183300ac, + 0x18338f59, + 0x18340f6d, + 0x183480ea, + 0x18350f82, + 0x18358f9a, + 0x18360faf, + 0x18368fc3, + 0x18370fe7, + 0x18378ffd, + 0x18381011, + 0x18389021, + 0x18390a73, + 0x18399031, + 0x183a1059, + 0x183a907f, + 0x183b0c6a, + 0x183b90b4, + 0x183c10c6, + 0x183c90d1, + 0x183d10e1, + 0x183d90f2, + 0x183e1103, + 0x183e9115, + 0x183f113e, + 0x183f9157, + 0x1840116f, + 0x184086d3, + 0x184110a2, + 0x1841906d, + 0x1842108c, + 0x18429046, + 0x20321196, + 0x243211a2, + 0x24328993, + 0x243311b4, + 0x243391c1, + 0x243411ce, + 0x243491e0, + 0x243511ef, + 0x2435920c, + 0x24361219, + 0x24369227, + 0x24371235, + 0x24379243, + 0x2438124c, + 0x24389259, + 0x2439126c, + 0x28320c52, + 0x28328c6a, + 0x28330c22, + 0x28338c7d, + 0x28340c5e, + 0x283480ac, + 0x283500ea, + 0x2c322c30, + 0x2c329283, + 0x2c332c3e, + 0x2c33ac50, + 0x2c342c64, + 0x2c34ac76, + 0x2c352c91, + 0x2c35aca3, + 0x2c362cb6, + 0x2c36832d, + 0x2c372cc3, + 0x2c37acd5, + 0x2c382cfa, + 0x2c38ad11, + 0x2c392d1f, + 0x2c39ad2f, + 0x2c3a2d41, + 0x2c3aad55, + 0x2c3b2d66, + 0x2c3bad85, + 0x2c3c1295, + 0x2c3c92ab, + 0x2c3d2d99, + 0x2c3d92c4, + 0x2c3e2db6, + 0x2c3eadc4, + 0x2c3f2ddc, + 0x2c3fadf4, + 0x2c402e01, + 0x2c409196, + 0x2c412e12, + 0x2c41ae25, + 0x2c42116f, + 0x2c42ae36, + 0x2c430720, + 0x2c43ad77, + 0x2c442ce8, + 0x30320000, + 0x30328015, + 0x3033001f, + 0x30338038, + 0x3034004a, + 0x30348064, + 0x3035006b, + 0x30358083, + 0x30360094, + 0x303680ac, + 0x303700b9, + 0x303780c8, + 0x303800ea, + 0x303880f7, + 0x3039010a, + 0x30398125, + 0x303a013a, + 0x303a814e, + 0x303b0162, + 0x303b8173, + 0x303c018c, + 0x303c81a9, + 0x303d01b7, + 0x303d81cb, + 0x303e01db, + 0x303e81f4, + 0x303f0204, + 0x303f8217, + 0x30400226, + 0x30408232, + 0x30410247, + 0x30418257, + 0x3042026e, + 0x3042827b, + 0x3043028e, + 0x3043829d, + 0x304402b2, + 0x304482d3, + 0x304502e6, + 0x304582f9, + 0x30460312, + 0x3046832d, + 0x3047034a, + 0x30478363, + 0x30480371, + 0x30488382, + 0x30490391, + 0x304983a9, + 0x304a03bb, + 0x304a83cf, + 0x304b03ee, + 0x304b8401, + 0x304c040c, + 0x304c841d, + 0x304d0429, + 0x304d843f, + 0x304e044d, + 0x304e8463, + 0x304f0475, + 0x304f8487, + 0x3050049a, + 0x305084ad, + 0x305104be, + 0x305184ce, + 0x305204e6, + 0x305284fb, + 0x30530513, + 0x30538527, + 0x3054053f, + 0x30548558, + 0x30550571, + 0x3055858e, + 0x30560599, + 0x305685b1, + 0x305705c1, + 0x305785d2, + 0x305805e5, + 0x305885fb, + 0x30590604, + 0x30598619, + 0x305a062c, + 0x305a863b, + 0x305b065b, + 0x305b866a, + 0x305c068b, + 0x305c86a7, + 0x305d06b3, + 0x305d86d3, + 0x305e06ef, + 0x305e8700, + 0x305f0716, + 0x305f8720, + 0x34320b63, + 0x34328b77, + 0x34330b94, + 0x34338ba7, + 0x34340bb6, + 0x34348bef, + 0x34350bd3, + 0x3c320083, + 0x3c328ca7, + 0x3c330cc0, + 0x3c338cdb, + 0x3c340cf8, + 0x3c348d22, + 0x3c350d3d, + 0x3c358d63, + 0x3c360d7c, + 0x3c368d94, + 0x3c370da5, + 0x3c378db3, + 0x3c380dc0, + 0x3c388dd4, + 0x3c390c6a, + 0x3c398de8, + 0x3c3a0dfc, + 0x3c3a890d, + 0x3c3b0e0c, + 0x3c3b8e27, + 0x3c3c0e39, + 0x3c3c8e6c, + 0x3c3d0e76, + 0x3c3d8e8a, + 0x3c3e0e98, + 0x3c3e8ebd, + 0x3c3f0c93, + 0x3c3f8ea6, + 0x3c4000ac, + 0x3c4080ea, + 0x3c410d13, + 0x3c418d52, + 0x3c420e4f, + 0x403218a4, + 0x403298ba, + 0x403318e8, + 0x403398f2, + 0x40341909, + 0x40349927, + 0x40351937, + 0x40359949, + 0x40361956, + 0x40369962, + 0x40371977, + 0x40379989, + 0x40381994, + 0x403899a6, + 0x40390eed, + 0x403999b6, + 0x403a19c9, + 0x403a99ea, + 0x403b19fb, + 0x403b9a0b, + 0x403c0064, + 0x403c8083, + 0x403d1a8f, + 0x403d9aa5, + 0x403e1ab4, + 0x403e9aec, + 0x403f1b06, + 0x403f9b14, + 0x40401b29, + 0x40409b3d, + 0x40411b5a, + 0x40419b75, + 0x40421b8e, + 0x40429ba1, + 0x40431bb5, + 0x40439bcd, + 0x40441be4, + 0x404480ac, + 0x40451bf9, + 0x40459c0b, + 0x40461c2f, + 0x40469c4f, + 0x40471c5d, + 0x40479c84, + 0x40481cc1, + 0x40489cda, + 0x40491cf1, + 0x40499d0b, + 0x404a1d22, + 0x404a9d40, + 0x404b1d58, + 0x404b9d6f, + 0x404c1d85, + 0x404c9d97, + 0x404d1db8, + 0x404d9dda, + 0x404e1dee, + 0x404e9dfb, + 0x404f1e28, + 0x404f9e51, + 0x40501e8c, + 0x40509ea0, + 0x40511ebb, + 0x40521ecb, + 0x40529eef, + 0x40531f07, + 0x40539f1a, + 0x40541f2f, + 0x40549f52, + 0x40551f60, + 0x40559f7d, + 0x40561f8a, + 0x40569fa3, + 0x40571fbb, + 0x40579fce, + 0x40581fe3, + 0x4058a00a, + 0x40592039, + 0x4059a066, + 0x405a207a, + 0x405aa08a, + 0x405b20a2, + 0x405ba0b3, + 0x405c20c6, + 0x405ca105, + 0x405d2112, + 0x405da129, + 0x405e2167, + 0x405e8ab1, + 0x405f2188, + 0x405fa195, + 0x406021a3, + 0x4060a1c5, + 0x40612209, + 0x4061a241, + 0x40622258, + 0x4062a269, + 0x4063227a, + 0x4063a28f, + 0x406422a6, + 0x4064a2d2, + 0x406522ed, + 0x4065a304, + 0x4066231c, + 0x4066a346, + 0x40672371, + 0x4067a392, + 0x406823b9, + 0x4068a3da, + 0x4069240c, + 0x4069a43a, + 0x406a245b, + 0x406aa47b, + 0x406b2603, + 0x406ba626, + 0x406c263c, + 0x406ca8b7, + 0x406d28e6, + 0x406da90e, + 0x406e293c, + 0x406ea989, + 0x406f29a8, + 0x406fa9e0, + 0x407029f3, + 0x4070aa10, + 0x40710800, + 0x4071aa22, + 0x40722a35, + 0x4072aa4e, + 0x40732a66, + 0x40739482, + 0x40742a7a, + 0x4074aa94, + 0x40752aa5, + 0x4075aab9, + 0x40762ac7, + 0x40769259, + 0x40772aec, + 0x4077ab0e, + 0x40782b29, + 0x4078ab62, + 0x40792b79, + 0x4079ab8f, + 0x407a2b9b, + 0x407aabae, + 0x407b2bc3, + 0x407babd5, + 0x407c2c06, + 0x407cac0f, + 0x407d23f5, + 0x407d9e61, + 0x407e2b3e, + 0x407ea01a, + 0x407f1c71, + 0x407f9a31, + 0x40801e38, + 0x40809c99, + 0x40811edd, + 0x40819e12, + 0x40822927, + 0x40829a17, + 0x40831ff5, + 0x4083a2b7, + 0x40841cad, + 0x4084a052, + 0x408520d7, + 0x4085a1ed, + 0x40862149, + 0x40869e7b, + 0x4087296d, + 0x4087a21e, + 0x40881a78, + 0x4088a3a5, + 0x40891ac7, + 0x40899a54, + 0x408a265c, + 0x408a9862, + 0x408b2bea, + 0x408ba9bd, + 0x408c20e7, + 0x408c987e, + 0x41f4252e, + 0x41f925c0, + 0x41fe24b3, + 0x41fea6a8, + 0x41ff2799, + 0x42032547, + 0x42082569, + 0x4208a5a5, + 0x42092497, + 0x4209a5df, + 0x420a24ee, + 0x420aa4ce, + 0x420b250e, + 0x420ba587, + 0x420c27b5, + 0x420ca675, + 0x420d268f, + 0x420da6c6, + 0x421226e0, + 0x4217277c, + 0x4217a722, + 0x421c2744, + 0x421f26ff, + 0x422127cc, + 0x4226275f, + 0x422b289b, + 0x422ba849, + 0x422c2883, + 0x422ca808, + 0x422d27e7, + 0x422da868, + 0x422e282e, + 0x422ea954, + 0x4432072b, + 0x4432873a, + 0x44330746, + 0x44338754, + 0x44340767, + 0x44348778, + 0x4435077f, + 0x44358789, + 0x4436079c, + 0x443687b2, + 0x443707c4, + 0x443787d1, + 0x443807e0, + 0x443887e8, + 0x44390800, + 0x4439880e, + 0x443a0821, + 0x48321283, + 0x48329295, + 0x483312ab, + 0x483392c4, + 0x4c3212e9, + 0x4c3292f9, + 0x4c33130c, + 0x4c33932c, + 0x4c3400ac, + 0x4c3480ea, + 0x4c351338, + 0x4c359346, + 0x4c361362, + 0x4c369375, + 0x4c371384, + 0x4c379392, + 0x4c3813a7, + 0x4c3893b3, + 0x4c3913d3, + 0x4c3993fd, + 0x4c3a1416, + 0x4c3a942f, + 0x4c3b05fb, + 0x4c3b9448, + 0x4c3c145a, + 0x4c3c9469, + 0x4c3d1482, + 0x4c3d8c45, + 0x4c3e14db, + 0x4c3e9491, + 0x4c3f14fd, + 0x4c3f9259, + 0x4c4014a7, + 0x4c4092d5, + 0x4c4114cb, + 0x50322e48, + 0x5032ae57, + 0x50332e62, + 0x5033ae72, + 0x50342e8b, + 0x5034aea5, + 0x50352eb3, + 0x5035aec9, + 0x50362edb, + 0x5036aef1, + 0x50372f0a, + 0x5037af1d, + 0x50382f35, + 0x5038af46, + 0x50392f5b, + 0x5039af6f, + 0x503a2f8f, + 0x503aafa5, + 0x503b2fbd, + 0x503bafcf, + 0x503c2feb, + 0x503cb002, + 0x503d301b, + 0x503db031, + 0x503e303e, + 0x503eb054, + 0x503f3066, + 0x503f8382, + 0x50403079, + 0x5040b089, + 0x504130a3, + 0x5041b0b2, + 0x504230cc, + 0x5042b0e9, + 0x504330f9, + 0x5043b109, + 0x50443118, + 0x5044843f, + 0x5045312c, + 0x5045b14a, + 0x5046315d, + 0x5046b173, + 0x50473185, + 0x5047b19a, + 0x504831c0, + 0x5048b1ce, + 0x504931e1, + 0x5049b1f6, + 0x504a320c, + 0x504ab21c, + 0x504b323c, + 0x504bb24f, + 0x504c3272, + 0x504cb2a0, + 0x504d32b2, + 0x504db2cf, + 0x504e32ea, + 0x504eb306, + 0x504f3318, + 0x504fb32f, + 0x5050333e, + 0x505086ef, + 0x50513351, + 0x58320f2b, + 0x68320eed, + 0x68328c6a, + 0x68330c7d, + 0x68338efb, + 0x68340f0b, + 0x683480ea, + 0x6c320ec9, + 0x6c328c34, + 0x6c330ed4, + 0x74320a19, + 0x743280ac, + 0x74330c45, + 0x7832097e, + 0x78328993, + 0x7833099f, + 0x78338083, + 0x783409ae, + 0x783489c3, + 0x783509e2, + 0x78358a04, + 0x78360a19, + 0x78368a2f, + 0x78370a3f, + 0x78378a60, + 0x78380a73, + 0x78388a85, + 0x78390a92, + 0x78398ab1, + 0x783a0ac6, + 0x783a8ad4, + 0x783b0ade, + 0x783b8af2, + 0x783c0b09, + 0x783c8b1e, + 0x783d0b35, + 0x783d8b4a, + 0x783e0aa0, + 0x783e8a52, + 0x7c321185, + }; + + const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); + + const char kOpenSSLReasonStringData[] = + "ASN1_LENGTH_MISMATCH\\0" + "AUX_ERROR\\0" + "BAD_GET_ASN1_OBJECT_CALL\\0" + "BAD_OBJECT_HEADER\\0" + "BMPSTRING_IS_WRONG_LENGTH\\0" + "BN_LIB\\0" + "BOOLEAN_IS_WRONG_LENGTH\\0" + "BUFFER_TOO_SMALL\\0" + "CONTEXT_NOT_INITIALISED\\0" + "DECODE_ERROR\\0" + "DEPTH_EXCEEDED\\0" + "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\\0" + "ENCODE_ERROR\\0" + "ERROR_GETTING_TIME\\0" + "EXPECTING_AN_ASN1_SEQUENCE\\0" + "EXPECTING_AN_INTEGER\\0" + "EXPECTING_AN_OBJECT\\0" + "EXPECTING_A_BOOLEAN\\0" + "EXPECTING_A_TIME\\0" + "EXPLICIT_LENGTH_MISMATCH\\0" + "EXPLICIT_TAG_NOT_CONSTRUCTED\\0" + "FIELD_MISSING\\0" + "FIRST_NUM_TOO_LARGE\\0" + "HEADER_TOO_LONG\\0" + "ILLEGAL_BITSTRING_FORMAT\\0" + "ILLEGAL_BOOLEAN\\0" + "ILLEGAL_CHARACTERS\\0" + "ILLEGAL_FORMAT\\0" + "ILLEGAL_HEX\\0" + "ILLEGAL_IMPLICIT_TAG\\0" + "ILLEGAL_INTEGER\\0" + "ILLEGAL_NESTED_TAGGING\\0" + "ILLEGAL_NULL\\0" + "ILLEGAL_NULL_VALUE\\0" + "ILLEGAL_OBJECT\\0" + "ILLEGAL_OPTIONAL_ANY\\0" + "ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE\\0" + "ILLEGAL_TAGGED_ANY\\0" + "ILLEGAL_TIME_VALUE\\0" + "INTEGER_NOT_ASCII_FORMAT\\0" + "INTEGER_TOO_LARGE_FOR_LONG\\0" + "INVALID_BIT_STRING_BITS_LEFT\\0" + "INVALID_BMPSTRING_LENGTH\\0" + "INVALID_DIGIT\\0" + "INVALID_MODIFIER\\0" + "INVALID_NUMBER\\0" + "INVALID_OBJECT_ENCODING\\0" + "INVALID_SEPARATOR\\0" + "INVALID_TIME_FORMAT\\0" + "INVALID_UNIVERSALSTRING_LENGTH\\0" + "INVALID_UTF8STRING\\0" + "LIST_ERROR\\0" + "MISSING_ASN1_EOS\\0" + "MISSING_EOC\\0" + "MISSING_SECOND_NUMBER\\0" + "MISSING_VALUE\\0" + "MSTRING_NOT_UNIVERSAL\\0" + "MSTRING_WRONG_TAG\\0" + "NESTED_ASN1_ERROR\\0" + "NESTED_ASN1_STRING\\0" + "NON_HEX_CHARACTERS\\0" + "NOT_ASCII_FORMAT\\0" + "NOT_ENOUGH_DATA\\0" + "NO_MATCHING_CHOICE_TYPE\\0" + "NULL_IS_WRONG_LENGTH\\0" + "OBJECT_NOT_ASCII_FORMAT\\0" + "ODD_NUMBER_OF_CHARS\\0" + "SECOND_NUMBER_TOO_LARGE\\0" + "SEQUENCE_LENGTH_MISMATCH\\0" + "SEQUENCE_NOT_CONSTRUCTED\\0" + "SEQUENCE_OR_SET_NEEDS_CONFIG\\0" + "SHORT_LINE\\0" + "STREAMING_NOT_SUPPORTED\\0" + "STRING_TOO_LONG\\0" + "STRING_TOO_SHORT\\0" + "TAG_VALUE_TOO_HIGH\\0" + "TIME_NOT_ASCII_FORMAT\\0" + "TOO_LONG\\0" + "TYPE_NOT_CONSTRUCTED\\0" + "TYPE_NOT_PRIMITIVE\\0" + "UNEXPECTED_EOC\\0" + "UNIVERSALSTRING_IS_WRONG_LENGTH\\0" + "UNKNOWN_FORMAT\\0" + "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\\0" + "UNKNOWN_SIGNATURE_ALGORITHM\\0" + "UNKNOWN_TAG\\0" + "UNSUPPORTED_ANY_DEFINED_BY_TYPE\\0" + "UNSUPPORTED_PUBLIC_KEY_TYPE\\0" + "UNSUPPORTED_TYPE\\0" + "WRONG_PUBLIC_KEY_TYPE\\0" + "WRONG_TAG\\0" + "WRONG_TYPE\\0" + "BAD_FOPEN_MODE\\0" + "BROKEN_PIPE\\0" + "CONNECT_ERROR\\0" + "ERROR_SETTING_NBIO\\0" + "INVALID_ARGUMENT\\0" + "IN_USE\\0" + "KEEPALIVE\\0" + "NBIO_CONNECT_ERROR\\0" + "NO_HOSTNAME_SPECIFIED\\0" + "NO_PORT_SPECIFIED\\0" + "NO_SUCH_FILE\\0" + "NULL_PARAMETER\\0" + "SYS_LIB\\0" + "UNABLE_TO_CREATE_SOCKET\\0" + "UNINITIALIZED\\0" + "UNSUPPORTED_METHOD\\0" + "WRITE_TO_READ_ONLY_BIO\\0" + "ARG2_LT_ARG3\\0" + "BAD_ENCODING\\0" + "BAD_RECIPROCAL\\0" + "BIGNUM_TOO_LONG\\0" + "BITS_TOO_SMALL\\0" + "CALLED_WITH_EVEN_MODULUS\\0" + "DIV_BY_ZERO\\0" + "EXPAND_ON_STATIC_BIGNUM_DATA\\0" + "INPUT_NOT_REDUCED\\0" + "INVALID_INPUT\\0" + "INVALID_RANGE\\0" + "NEGATIVE_NUMBER\\0" + "NOT_A_SQUARE\\0" + "NOT_INITIALIZED\\0" + "NO_INVERSE\\0" + "PRIVATE_KEY_TOO_LARGE\\0" + "P_IS_NOT_PRIME\\0" + "TOO_MANY_ITERATIONS\\0" + "TOO_MANY_TEMPORARY_VARIABLES\\0" + "AES_KEY_SETUP_FAILED\\0" + "BAD_DECRYPT\\0" + "BAD_KEY_LENGTH\\0" + "CTRL_NOT_IMPLEMENTED\\0" + "CTRL_OPERATION_NOT_IMPLEMENTED\\0" + "DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH\\0" + "INITIALIZATION_ERROR\\0" + "INPUT_NOT_INITIALIZED\\0" + "INVALID_AD_SIZE\\0" + "INVALID_KEY_LENGTH\\0" + "INVALID_NONCE\\0" + "INVALID_NONCE_SIZE\\0" + "INVALID_OPERATION\\0" + "IV_TOO_LARGE\\0" + "NO_CIPHER_SET\\0" + "NO_DIRECTION_SET\\0" + "OUTPUT_ALIASES_INPUT\\0" + "TAG_TOO_LARGE\\0" + "TOO_LARGE\\0" + "UNSUPPORTED_AD_SIZE\\0" + "UNSUPPORTED_INPUT_SIZE\\0" + "UNSUPPORTED_KEY_SIZE\\0" + "UNSUPPORTED_NONCE_SIZE\\0" + "UNSUPPORTED_TAG_SIZE\\0" + "WRONG_FINAL_BLOCK_LENGTH\\0" + "LIST_CANNOT_BE_NULL\\0" + "MISSING_CLOSE_SQUARE_BRACKET\\0" + "MISSING_EQUAL_SIGN\\0" + "NO_CLOSE_BRACE\\0" + "UNABLE_TO_CREATE_NEW_SECTION\\0" + "VARIABLE_EXPANSION_TOO_LONG\\0" + "VARIABLE_HAS_NO_VALUE\\0" + "BAD_GENERATOR\\0" + "INVALID_PUBKEY\\0" + "MODULUS_TOO_LARGE\\0" + "NO_PRIVATE_VALUE\\0" + "UNKNOWN_HASH\\0" + "BAD_Q_VALUE\\0" + "BAD_VERSION\\0" + "MISSING_PARAMETERS\\0" + "NEED_NEW_SETUP_VALUES\\0" + "BIGNUM_OUT_OF_RANGE\\0" + "COORDINATES_OUT_OF_RANGE\\0" + "D2I_ECPKPARAMETERS_FAILURE\\0" + "EC_GROUP_NEW_BY_NAME_FAILURE\\0" + "GROUP2PKPARAMETERS_FAILURE\\0" + "GROUP_MISMATCH\\0" + "I2D_ECPKPARAMETERS_FAILURE\\0" + "INCOMPATIBLE_OBJECTS\\0" + "INVALID_COFACTOR\\0" + "INVALID_COMPRESSED_POINT\\0" + "INVALID_COMPRESSION_BIT\\0" + "INVALID_ENCODING\\0" + "INVALID_FIELD\\0" + "INVALID_FORM\\0" + "INVALID_GROUP_ORDER\\0" + "INVALID_PRIVATE_KEY\\0" + "MISSING_PRIVATE_KEY\\0" + "NON_NAMED_CURVE\\0" + "PKPARAMETERS2GROUP_FAILURE\\0" + "POINT_AT_INFINITY\\0" + "POINT_IS_NOT_ON_CURVE\\0" + "PUBLIC_KEY_VALIDATION_FAILED\\0" + "SLOT_FULL\\0" + "UNDEFINED_GENERATOR\\0" + "UNKNOWN_GROUP\\0" + "UNKNOWN_ORDER\\0" + "WRONG_CURVE_PARAMETERS\\0" + "WRONG_ORDER\\0" + "KDF_FAILED\\0" + "POINT_ARITHMETIC_FAILURE\\0" + "BAD_SIGNATURE\\0" + "NOT_IMPLEMENTED\\0" + "RANDOM_NUMBER_GENERATION_FAILED\\0" + "OPERATION_NOT_SUPPORTED\\0" + "COMMAND_NOT_SUPPORTED\\0" + "DIFFERENT_KEY_TYPES\\0" + "DIFFERENT_PARAMETERS\\0" + "EXPECTING_AN_EC_KEY_KEY\\0" + "EXPECTING_AN_RSA_KEY\\0" + "EXPECTING_A_DSA_KEY\\0" + "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\\0" + "INVALID_DIGEST_LENGTH\\0" + "INVALID_DIGEST_TYPE\\0" + "INVALID_KEYBITS\\0" + "INVALID_MGF1_MD\\0" + "INVALID_PADDING_MODE\\0" + "INVALID_PARAMETERS\\0" + "INVALID_PSS_SALTLEN\\0" + "INVALID_SIGNATURE\\0" + "KEYS_NOT_SET\\0" + "MEMORY_LIMIT_EXCEEDED\\0" + "NOT_A_PRIVATE_KEY\\0" + "NO_DEFAULT_DIGEST\\0" + "NO_KEY_SET\\0" + "NO_MDC2_SUPPORT\\0" + "NO_NID_FOR_CURVE\\0" + "NO_OPERATION_SET\\0" + "NO_PARAMETERS_SET\\0" + "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\\0" + "OPERATON_NOT_INITIALIZED\\0" + "UNKNOWN_PUBLIC_KEY_TYPE\\0" + "UNSUPPORTED_ALGORITHM\\0" + "OUTPUT_TOO_LARGE\\0" + "UNKNOWN_NID\\0" + "BAD_BASE64_DECODE\\0" + "BAD_END_LINE\\0" + "BAD_IV_CHARS\\0" + "BAD_PASSWORD_READ\\0" + "CIPHER_IS_NULL\\0" + "ERROR_CONVERTING_PRIVATE_KEY\\0" + "NOT_DEK_INFO\\0" + "NOT_ENCRYPTED\\0" + "NOT_PROC_TYPE\\0" + "NO_START_LINE\\0" + "READ_KEY\\0" + "SHORT_HEADER\\0" + "UNSUPPORTED_CIPHER\\0" + "UNSUPPORTED_ENCRYPTION\\0" + "BAD_PKCS7_VERSION\\0" + "NOT_PKCS7_SIGNED_DATA\\0" + "NO_CERTIFICATES_INCLUDED\\0" + "NO_CRLS_INCLUDED\\0" + "BAD_ITERATION_COUNT\\0" + "BAD_PKCS12_DATA\\0" + "BAD_PKCS12_VERSION\\0" + "CIPHER_HAS_NO_OBJECT_IDENTIFIER\\0" + "CRYPT_ERROR\\0" + "ENCRYPT_ERROR\\0" + "ERROR_SETTING_CIPHER_PARAMS\\0" + "INCORRECT_PASSWORD\\0" + "KEYGEN_FAILURE\\0" + "KEY_GEN_ERROR\\0" + "METHOD_NOT_SUPPORTED\\0" + "MISSING_MAC\\0" + "MULTIPLE_PRIVATE_KEYS_IN_PKCS12\\0" + "PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED\\0" + "PKCS12_TOO_DEEPLY_NESTED\\0" + "PRIVATE_KEY_DECODE_ERROR\\0" + "PRIVATE_KEY_ENCODE_ERROR\\0" + "UNKNOWN_ALGORITHM\\0" + "UNKNOWN_CIPHER\\0" + "UNKNOWN_CIPHER_ALGORITHM\\0" + "UNKNOWN_DIGEST\\0" + "UNSUPPORTED_KEYLENGTH\\0" + "UNSUPPORTED_KEY_DERIVATION_FUNCTION\\0" + "UNSUPPORTED_PRF\\0" + "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\\0" + "UNSUPPORTED_SALT_TYPE\\0" + "BAD_E_VALUE\\0" + "BAD_FIXED_HEADER_DECRYPT\\0" + "BAD_PAD_BYTE_COUNT\\0" + "BAD_RSA_PARAMETERS\\0" + "BLOCK_TYPE_IS_NOT_01\\0" + "BN_NOT_INITIALIZED\\0" + "CANNOT_RECOVER_MULTI_PRIME_KEY\\0" + "CRT_PARAMS_ALREADY_GIVEN\\0" + "CRT_VALUES_INCORRECT\\0" + "DATA_LEN_NOT_EQUAL_TO_MOD_LEN\\0" + "DATA_TOO_LARGE\\0" + "DATA_TOO_LARGE_FOR_KEY_SIZE\\0" + "DATA_TOO_LARGE_FOR_MODULUS\\0" + "DATA_TOO_SMALL\\0" + "DATA_TOO_SMALL_FOR_KEY_SIZE\\0" + "DIGEST_TOO_BIG_FOR_RSA_KEY\\0" + "D_E_NOT_CONGRUENT_TO_1\\0" + "EMPTY_PUBLIC_KEY\\0" + "FIRST_OCTET_INVALID\\0" + "INCONSISTENT_SET_OF_CRT_VALUES\\0" + "INTERNAL_ERROR\\0" + "INVALID_MESSAGE_LENGTH\\0" + "KEY_SIZE_TOO_SMALL\\0" + "LAST_OCTET_INVALID\\0" + "MUST_HAVE_AT_LEAST_TWO_PRIMES\\0" + "NO_PUBLIC_EXPONENT\\0" + "NULL_BEFORE_BLOCK_MISSING\\0" + "N_NOT_EQUAL_P_Q\\0" + "OAEP_DECODING_ERROR\\0" + "ONLY_ONE_OF_P_Q_GIVEN\\0" + "OUTPUT_BUFFER_TOO_SMALL\\0" + "PADDING_CHECK_FAILED\\0" + "PKCS_DECODING_ERROR\\0" + "SLEN_CHECK_FAILED\\0" + "SLEN_RECOVERY_FAILED\\0" + "UNKNOWN_ALGORITHM_TYPE\\0" + "UNKNOWN_PADDING_TYPE\\0" + "VALUE_MISSING\\0" + "WRONG_SIGNATURE_LENGTH\\0" + "ALPN_MISMATCH_ON_EARLY_DATA\\0" + "APPLICATION_DATA_INSTEAD_OF_HANDSHAKE\\0" + "APP_DATA_IN_HANDSHAKE\\0" + "ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT\\0" + "BAD_ALERT\\0" + "BAD_CHANGE_CIPHER_SPEC\\0" + "BAD_DATA_RETURNED_BY_CALLBACK\\0" + "BAD_DH_P_LENGTH\\0" + "BAD_DIGEST_LENGTH\\0" + "BAD_ECC_CERT\\0" + "BAD_ECPOINT\\0" + "BAD_HANDSHAKE_RECORD\\0" + "BAD_HELLO_REQUEST\\0" + "BAD_LENGTH\\0" + "BAD_PACKET_LENGTH\\0" + "BAD_RSA_ENCRYPT\\0" + "BAD_SRTP_MKI_VALUE\\0" + "BAD_SRTP_PROTECTION_PROFILE_LIST\\0" + "BAD_SSL_FILETYPE\\0" + "BAD_WRITE_RETRY\\0" + "BIO_NOT_SET\\0" + "BLOCK_CIPHER_PAD_IS_WRONG\\0" + "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\\0" + "CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD\\0" + "CANNOT_PARSE_LEAF_CERT\\0" + "CA_DN_LENGTH_MISMATCH\\0" + "CA_DN_TOO_LONG\\0" + "CCS_RECEIVED_EARLY\\0" + "CERTIFICATE_AND_PRIVATE_KEY_MISMATCH\\0" + "CERTIFICATE_VERIFY_FAILED\\0" + "CERT_CB_ERROR\\0" + "CERT_LENGTH_MISMATCH\\0" + "CHANNEL_ID_NOT_P256\\0" + "CHANNEL_ID_SIGNATURE_INVALID\\0" + "CIPHER_OR_HASH_UNAVAILABLE\\0" + "CLIENTHELLO_PARSE_FAILED\\0" + "CLIENTHELLO_TLSEXT\\0" + "CONNECTION_REJECTED\\0" + "CONNECTION_TYPE_NOT_SET\\0" + "CUSTOM_EXTENSION_ERROR\\0" + "DATA_LENGTH_TOO_LONG\\0" + "DECRYPTION_FAILED\\0" + "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\\0" + "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\\0" + "DH_P_TOO_LONG\\0" + "DIGEST_CHECK_FAILED\\0" + "DOWNGRADE_DETECTED\\0" + "DTLS_MESSAGE_TOO_BIG\\0" + "DUPLICATE_EXTENSION\\0" + "DUPLICATE_KEY_SHARE\\0" + "ECC_CERT_NOT_FOR_SIGNING\\0" + "EMS_STATE_INCONSISTENT\\0" + "ENCRYPTED_LENGTH_TOO_LONG\\0" + "ERROR_ADDING_EXTENSION\\0" + "ERROR_IN_RECEIVED_CIPHER_LIST\\0" + "ERROR_PARSING_EXTENSION\\0" + "EXCESSIVE_MESSAGE_SIZE\\0" + "EXTRA_DATA_IN_MESSAGE\\0" + "FRAGMENT_MISMATCH\\0" + "GOT_NEXT_PROTO_WITHOUT_EXTENSION\\0" + "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\\0" + "HTTPS_PROXY_REQUEST\\0" + "HTTP_REQUEST\\0" + "INAPPROPRIATE_FALLBACK\\0" + "INVALID_ALPN_PROTOCOL\\0" + "INVALID_COMMAND\\0" + "INVALID_COMPRESSION_LIST\\0" + "INVALID_MESSAGE\\0" + "INVALID_OUTER_RECORD_TYPE\\0" + "INVALID_SCT_LIST\\0" + "INVALID_SSL_SESSION\\0" + "INVALID_TICKET_KEYS_LENGTH\\0" + "LENGTH_MISMATCH\\0" + "MISSING_EXTENSION\\0" + "MISSING_KEY_SHARE\\0" + "MISSING_RSA_CERTIFICATE\\0" + "MISSING_TMP_DH_KEY\\0" + "MISSING_TMP_ECDH_KEY\\0" + "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\\0" + "MTU_TOO_SMALL\\0" + "NEGOTIATED_BOTH_NPN_AND_ALPN\\0" + "NESTED_GROUP\\0" + "NO_CERTIFICATES_RETURNED\\0" + "NO_CERTIFICATE_ASSIGNED\\0" + "NO_CERTIFICATE_SET\\0" + "NO_CIPHERS_AVAILABLE\\0" + "NO_CIPHERS_PASSED\\0" + "NO_CIPHERS_SPECIFIED\\0" + "NO_CIPHER_MATCH\\0" + "NO_COMMON_SIGNATURE_ALGORITHMS\\0" + "NO_COMPRESSION_SPECIFIED\\0" + "NO_GROUPS_SPECIFIED\\0" + "NO_METHOD_SPECIFIED\\0" + "NO_P256_SUPPORT\\0" + "NO_PRIVATE_KEY_ASSIGNED\\0" + "NO_RENEGOTIATION\\0" + "NO_REQUIRED_DIGEST\\0" + "NO_SHARED_CIPHER\\0" + "NO_SHARED_GROUP\\0" + "NO_SUPPORTED_VERSIONS_ENABLED\\0" + "NULL_SSL_CTX\\0" + "NULL_SSL_METHOD_PASSED\\0" + "OLD_SESSION_CIPHER_NOT_RETURNED\\0" + "OLD_SESSION_PRF_HASH_MISMATCH\\0" + "OLD_SESSION_VERSION_NOT_RETURNED\\0" + "PARSE_TLSEXT\\0" + "PATH_TOO_LONG\\0" + "PEER_DID_NOT_RETURN_A_CERTIFICATE\\0" + "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\\0" + "PRE_SHARED_KEY_MUST_BE_LAST\\0" + "PROTOCOL_IS_SHUTDOWN\\0" + "PSK_IDENTITY_BINDER_COUNT_MISMATCH\\0" + "PSK_IDENTITY_NOT_FOUND\\0" + "PSK_NO_CLIENT_CB\\0" + "PSK_NO_SERVER_CB\\0" + "READ_TIMEOUT_EXPIRED\\0" + "RECORD_LENGTH_MISMATCH\\0" + "RECORD_TOO_LARGE\\0" + "RENEGOTIATION_EMS_MISMATCH\\0" + "RENEGOTIATION_ENCODING_ERR\\0" + "RENEGOTIATION_MISMATCH\\0" + "REQUIRED_CIPHER_MISSING\\0" + "RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION\\0" + "RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION\\0" + "SCSV_RECEIVED_WHEN_RENEGOTIATING\\0" + "SERVERHELLO_TLSEXT\\0" + "SERVER_CERT_CHANGED\\0" + "SESSION_ID_CONTEXT_UNINITIALIZED\\0" + "SESSION_MAY_NOT_BE_CREATED\\0" + "SHUTDOWN_WHILE_IN_INIT\\0" + "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\\0" + "SRTP_COULD_NOT_ALLOCATE_PROFILES\\0" + "SRTP_UNKNOWN_PROTECTION_PROFILE\\0" + "SSL3_EXT_INVALID_SERVERNAME\\0" + "SSLV3_ALERT_BAD_CERTIFICATE\\0" + "SSLV3_ALERT_BAD_RECORD_MAC\\0" + "SSLV3_ALERT_CERTIFICATE_EXPIRED\\0" + "SSLV3_ALERT_CERTIFICATE_REVOKED\\0" + "SSLV3_ALERT_CERTIFICATE_UNKNOWN\\0" + "SSLV3_ALERT_CLOSE_NOTIFY\\0" + "SSLV3_ALERT_DECOMPRESSION_FAILURE\\0" + "SSLV3_ALERT_HANDSHAKE_FAILURE\\0" + "SSLV3_ALERT_ILLEGAL_PARAMETER\\0" + "SSLV3_ALERT_NO_CERTIFICATE\\0" + "SSLV3_ALERT_UNEXPECTED_MESSAGE\\0" + "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\\0" + "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\\0" + "SSL_HANDSHAKE_FAILURE\\0" + "SSL_SESSION_ID_CONTEXT_TOO_LONG\\0" + "TICKET_ENCRYPTION_FAILED\\0" + "TLSV1_ALERT_ACCESS_DENIED\\0" + "TLSV1_ALERT_DECODE_ERROR\\0" + "TLSV1_ALERT_DECRYPTION_FAILED\\0" + "TLSV1_ALERT_DECRYPT_ERROR\\0" + "TLSV1_ALERT_EXPORT_RESTRICTION\\0" + "TLSV1_ALERT_INAPPROPRIATE_FALLBACK\\0" + "TLSV1_ALERT_INSUFFICIENT_SECURITY\\0" + "TLSV1_ALERT_INTERNAL_ERROR\\0" + "TLSV1_ALERT_NO_RENEGOTIATION\\0" + "TLSV1_ALERT_PROTOCOL_VERSION\\0" + "TLSV1_ALERT_RECORD_OVERFLOW\\0" + "TLSV1_ALERT_UNKNOWN_CA\\0" + "TLSV1_ALERT_USER_CANCELLED\\0" + "TLSV1_BAD_CERTIFICATE_HASH_VALUE\\0" + "TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\\0" + "TLSV1_CERTIFICATE_REQUIRED\\0" + "TLSV1_CERTIFICATE_UNOBTAINABLE\\0" + "TLSV1_UNKNOWN_PSK_IDENTITY\\0" + "TLSV1_UNRECOGNIZED_NAME\\0" + "TLSV1_UNSUPPORTED_EXTENSION\\0" + "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\\0" + "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\\0" + "TOO_MANY_EMPTY_FRAGMENTS\\0" + "TOO_MANY_KEY_UPDATES\\0" + "TOO_MANY_WARNING_ALERTS\\0" + "TOO_MUCH_READ_EARLY_DATA\\0" + "TOO_MUCH_SKIPPED_EARLY_DATA\\0" + "UNABLE_TO_FIND_ECDH_PARAMETERS\\0" + "UNEXPECTED_EXTENSION\\0" + "UNEXPECTED_EXTENSION_ON_EARLY_DATA\\0" + "UNEXPECTED_MESSAGE\\0" + "UNEXPECTED_OPERATOR_IN_GROUP\\0" + "UNEXPECTED_RECORD\\0" + "UNKNOWN_ALERT_TYPE\\0" + "UNKNOWN_CERTIFICATE_TYPE\\0" + "UNKNOWN_CIPHER_RETURNED\\0" + "UNKNOWN_CIPHER_TYPE\\0" + "UNKNOWN_KEY_EXCHANGE_TYPE\\0" + "UNKNOWN_PROTOCOL\\0" + "UNKNOWN_SSL_VERSION\\0" + "UNKNOWN_STATE\\0" + "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\\0" + "UNSUPPORTED_COMPRESSION_ALGORITHM\\0" + "UNSUPPORTED_ELLIPTIC_CURVE\\0" + "UNSUPPORTED_PROTOCOL\\0" + "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\\0" + "WRONG_CERTIFICATE_TYPE\\0" + "WRONG_CIPHER_RETURNED\\0" + "WRONG_CURVE\\0" + "WRONG_MESSAGE_TYPE\\0" + "WRONG_SIGNATURE_TYPE\\0" + "WRONG_SSL_VERSION\\0" + "WRONG_VERSION_NUMBER\\0" + "WRONG_VERSION_ON_EARLY_DATA\\0" + "X509_LIB\\0" + "X509_VERIFICATION_SETUP_PROBLEMS\\0" + "AKID_MISMATCH\\0" + "BAD_X509_FILETYPE\\0" + "BASE64_DECODE_ERROR\\0" + "CANT_CHECK_DH_KEY\\0" + "CERT_ALREADY_IN_HASH_TABLE\\0" + "CRL_ALREADY_DELTA\\0" + "CRL_VERIFY_FAILURE\\0" + "IDP_MISMATCH\\0" + "INVALID_DIRECTORY\\0" + "INVALID_FIELD_NAME\\0" + "INVALID_PARAMETER\\0" + "INVALID_PSS_PARAMETERS\\0" + "INVALID_TRUST\\0" + "ISSUER_MISMATCH\\0" + "KEY_TYPE_MISMATCH\\0" + "KEY_VALUES_MISMATCH\\0" + "LOADING_CERT_DIR\\0" + "LOADING_DEFAULTS\\0" + "NAME_TOO_LONG\\0" + "NEWER_CRL_NOT_NEWER\\0" + "NO_CERT_SET_FOR_US_TO_VERIFY\\0" + "NO_CRL_NUMBER\\0" + "PUBLIC_KEY_DECODE_ERROR\\0" + "PUBLIC_KEY_ENCODE_ERROR\\0" + "SHOULD_RETRY\\0" + "UNKNOWN_KEY_TYPE\\0" + "UNKNOWN_PURPOSE_ID\\0" + "UNKNOWN_TRUST_ID\\0" + "WRONG_LOOKUP_TYPE\\0" + "BAD_IP_ADDRESS\\0" + "BAD_OBJECT\\0" + "BN_DEC2BN_ERROR\\0" + "BN_TO_ASN1_INTEGER_ERROR\\0" + "CANNOT_FIND_FREE_FUNCTION\\0" + "DIRNAME_ERROR\\0" + "DISTPOINT_ALREADY_SET\\0" + "DUPLICATE_ZONE_ID\\0" + "ERROR_CONVERTING_ZONE\\0" + "ERROR_CREATING_EXTENSION\\0" + "ERROR_IN_EXTENSION\\0" + "EXPECTED_A_SECTION_NAME\\0" + "EXTENSION_EXISTS\\0" + "EXTENSION_NAME_ERROR\\0" + "EXTENSION_NOT_FOUND\\0" + "EXTENSION_SETTING_NOT_SUPPORTED\\0" + "EXTENSION_VALUE_ERROR\\0" + "ILLEGAL_EMPTY_EXTENSION\\0" + "ILLEGAL_HEX_DIGIT\\0" + "INCORRECT_POLICY_SYNTAX_TAG\\0" + "INVALID_BOOLEAN_STRING\\0" + "INVALID_EXTENSION_STRING\\0" + "INVALID_MULTIPLE_RDNS\\0" + "INVALID_NAME\\0" + "INVALID_NULL_ARGUMENT\\0" + "INVALID_NULL_NAME\\0" + "INVALID_NULL_VALUE\\0" + "INVALID_NUMBERS\\0" + "INVALID_OBJECT_IDENTIFIER\\0" + "INVALID_OPTION\\0" + "INVALID_POLICY_IDENTIFIER\\0" + "INVALID_PROXY_POLICY_SETTING\\0" + "INVALID_PURPOSE\\0" + "INVALID_SECTION\\0" + "INVALID_SYNTAX\\0" + "ISSUER_DECODE_ERROR\\0" + "NEED_ORGANIZATION_AND_NUMBERS\\0" + "NO_CONFIG_DATABASE\\0" + "NO_ISSUER_CERTIFICATE\\0" + "NO_ISSUER_DETAILS\\0" + "NO_POLICY_IDENTIFIER\\0" + "NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED\\0" + "NO_PUBLIC_KEY\\0" + "NO_SUBJECT_DETAILS\\0" + "ODD_NUMBER_OF_DIGITS\\0" + "OPERATION_NOT_DEFINED\\0" + "OTHERNAME_ERROR\\0" + "POLICY_LANGUAGE_ALREADY_DEFINED\\0" + "POLICY_PATH_LENGTH\\0" + "POLICY_PATH_LENGTH_ALREADY_DEFINED\\0" + "POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY\\0" + "SECTION_NOT_FOUND\\0" + "UNABLE_TO_GET_ISSUER_DETAILS\\0" + "UNABLE_TO_GET_ISSUER_KEYID\\0" + "UNKNOWN_BIT_STRING_ARGUMENT\\0" + "UNKNOWN_EXTENSION\\0" + "UNKNOWN_EXTENSION_NAME\\0" + "UNKNOWN_OPTION\\0" + "UNSUPPORTED_OPTION\\0" + "USER_TOO_LONG\\0" + ""; + EOF + + sed -i'.back' '/^#define \\([A-Za-z0-9_]*\\) \\1/d' include/openssl/ssl.h + sed -i'.back' 'N;/^#define \\([A-Za-z0-9_]*\\) *\\\\\\n *\\1/d' include/openssl/ssl.h + sed -i'.back' 's/#ifndef md5_block_data_order/#ifndef GRPC_SHADOW_md5_block_data_order/g' crypto/fipsmodule/md5/md5.c + find . -type f \\( -path '*.h' -or -path '*.cc' -or -path '*.c' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include include/openssl/umbrella.h < include/openssl/BoringSSL.modulemap < err_data.c < - #include - #include - - - OPENSSL_COMPILE_ASSERT(ERR_LIB_NONE == 1, library_values_changed_1); - OPENSSL_COMPILE_ASSERT(ERR_LIB_SYS == 2, library_values_changed_2); - OPENSSL_COMPILE_ASSERT(ERR_LIB_BN == 3, library_values_changed_3); - OPENSSL_COMPILE_ASSERT(ERR_LIB_RSA == 4, library_values_changed_4); - OPENSSL_COMPILE_ASSERT(ERR_LIB_DH == 5, library_values_changed_5); - OPENSSL_COMPILE_ASSERT(ERR_LIB_EVP == 6, library_values_changed_6); - OPENSSL_COMPILE_ASSERT(ERR_LIB_BUF == 7, library_values_changed_7); - OPENSSL_COMPILE_ASSERT(ERR_LIB_OBJ == 8, library_values_changed_8); - OPENSSL_COMPILE_ASSERT(ERR_LIB_PEM == 9, library_values_changed_9); - OPENSSL_COMPILE_ASSERT(ERR_LIB_DSA == 10, library_values_changed_10); - OPENSSL_COMPILE_ASSERT(ERR_LIB_X509 == 11, library_values_changed_11); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ASN1 == 12, library_values_changed_12); - OPENSSL_COMPILE_ASSERT(ERR_LIB_CONF == 13, library_values_changed_13); - OPENSSL_COMPILE_ASSERT(ERR_LIB_CRYPTO == 14, library_values_changed_14); - OPENSSL_COMPILE_ASSERT(ERR_LIB_EC == 15, library_values_changed_15); - OPENSSL_COMPILE_ASSERT(ERR_LIB_SSL == 16, library_values_changed_16); - OPENSSL_COMPILE_ASSERT(ERR_LIB_BIO == 17, library_values_changed_17); - OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS7 == 18, library_values_changed_18); - OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS8 == 19, library_values_changed_19); - OPENSSL_COMPILE_ASSERT(ERR_LIB_X509V3 == 20, library_values_changed_20); - OPENSSL_COMPILE_ASSERT(ERR_LIB_RAND == 21, library_values_changed_21); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ENGINE == 22, library_values_changed_22); - OPENSSL_COMPILE_ASSERT(ERR_LIB_OCSP == 23, library_values_changed_23); - OPENSSL_COMPILE_ASSERT(ERR_LIB_UI == 24, library_values_changed_24); - OPENSSL_COMPILE_ASSERT(ERR_LIB_COMP == 25, library_values_changed_25); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDSA == 26, library_values_changed_26); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDH == 27, library_values_changed_27); - OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28); - OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29); - OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30); - OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31); - OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32); - OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num); - - const uint32_t kOpenSSLReasonValues[] = { - 0xc320838, - 0xc328852, - 0xc330861, - 0xc338871, - 0xc340880, - 0xc348899, - 0xc3508a5, - 0xc3588c2, - 0xc3608e2, - 0xc3688f0, - 0xc370900, - 0xc37890d, - 0xc38091d, - 0xc388928, - 0xc39093e, - 0xc39894d, - 0xc3a0961, - 0xc3a8845, - 0xc3b00ea, - 0xc3b88d4, - 0x10320845, - 0x10329513, - 0x1033151f, - 0x10339538, - 0x1034154b, - 0x10348eed, - 0x10350c5e, - 0x1035955e, - 0x10361573, - 0x10369586, - 0x103715a5, - 0x103795be, - 0x103815d3, - 0x103895f1, - 0x10391600, - 0x1039961c, - 0x103a1637, - 0x103a9646, - 0x103b1662, - 0x103b967d, - 0x103c1694, - 0x103c80ea, - 0x103d16a5, - 0x103d96b9, - 0x103e16d8, - 0x103e96e7, - 0x103f16fe, - 0x103f9711, - 0x10400c22, - 0x10409724, - 0x10411742, - 0x10419755, - 0x1042176f, - 0x1042977f, - 0x10431793, - 0x104397a9, - 0x104417c1, - 0x104497d6, - 0x104517ea, - 0x104597fc, - 0x104605fb, - 0x1046894d, - 0x10471811, - 0x10479828, - 0x1048183d, - 0x1048984b, - 0x10490e4f, - 0x14320c05, - 0x14328c13, - 0x14330c22, - 0x14338c34, - 0x143400ac, - 0x143480ea, - 0x18320083, - 0x18328f43, - 0x183300ac, - 0x18338f59, - 0x18340f6d, - 0x183480ea, - 0x18350f82, - 0x18358f9a, - 0x18360faf, - 0x18368fc3, - 0x18370fe7, - 0x18378ffd, - 0x18381011, - 0x18389021, - 0x18390a73, - 0x18399031, - 0x183a1059, - 0x183a907f, - 0x183b0c6a, - 0x183b90b4, - 0x183c10c6, - 0x183c90d1, - 0x183d10e1, - 0x183d90f2, - 0x183e1103, - 0x183e9115, - 0x183f113e, - 0x183f9157, - 0x1840116f, - 0x184086d3, - 0x184110a2, - 0x1841906d, - 0x1842108c, - 0x18429046, - 0x20321196, - 0x243211a2, - 0x24328993, - 0x243311b4, - 0x243391c1, - 0x243411ce, - 0x243491e0, - 0x243511ef, - 0x2435920c, - 0x24361219, - 0x24369227, - 0x24371235, - 0x24379243, - 0x2438124c, - 0x24389259, - 0x2439126c, - 0x28320c52, - 0x28328c6a, - 0x28330c22, - 0x28338c7d, - 0x28340c5e, - 0x283480ac, - 0x283500ea, - 0x2c322c30, - 0x2c329283, - 0x2c332c3e, - 0x2c33ac50, - 0x2c342c64, - 0x2c34ac76, - 0x2c352c91, - 0x2c35aca3, - 0x2c362cb6, - 0x2c36832d, - 0x2c372cc3, - 0x2c37acd5, - 0x2c382cfa, - 0x2c38ad11, - 0x2c392d1f, - 0x2c39ad2f, - 0x2c3a2d41, - 0x2c3aad55, - 0x2c3b2d66, - 0x2c3bad85, - 0x2c3c1295, - 0x2c3c92ab, - 0x2c3d2d99, - 0x2c3d92c4, - 0x2c3e2db6, - 0x2c3eadc4, - 0x2c3f2ddc, - 0x2c3fadf4, - 0x2c402e01, - 0x2c409196, - 0x2c412e12, - 0x2c41ae25, - 0x2c42116f, - 0x2c42ae36, - 0x2c430720, - 0x2c43ad77, - 0x2c442ce8, - 0x30320000, - 0x30328015, - 0x3033001f, - 0x30338038, - 0x3034004a, - 0x30348064, - 0x3035006b, - 0x30358083, - 0x30360094, - 0x303680ac, - 0x303700b9, - 0x303780c8, - 0x303800ea, - 0x303880f7, - 0x3039010a, - 0x30398125, - 0x303a013a, - 0x303a814e, - 0x303b0162, - 0x303b8173, - 0x303c018c, - 0x303c81a9, - 0x303d01b7, - 0x303d81cb, - 0x303e01db, - 0x303e81f4, - 0x303f0204, - 0x303f8217, - 0x30400226, - 0x30408232, - 0x30410247, - 0x30418257, - 0x3042026e, - 0x3042827b, - 0x3043028e, - 0x3043829d, - 0x304402b2, - 0x304482d3, - 0x304502e6, - 0x304582f9, - 0x30460312, - 0x3046832d, - 0x3047034a, - 0x30478363, - 0x30480371, - 0x30488382, - 0x30490391, - 0x304983a9, - 0x304a03bb, - 0x304a83cf, - 0x304b03ee, - 0x304b8401, - 0x304c040c, - 0x304c841d, - 0x304d0429, - 0x304d843f, - 0x304e044d, - 0x304e8463, - 0x304f0475, - 0x304f8487, - 0x3050049a, - 0x305084ad, - 0x305104be, - 0x305184ce, - 0x305204e6, - 0x305284fb, - 0x30530513, - 0x30538527, - 0x3054053f, - 0x30548558, - 0x30550571, - 0x3055858e, - 0x30560599, - 0x305685b1, - 0x305705c1, - 0x305785d2, - 0x305805e5, - 0x305885fb, - 0x30590604, - 0x30598619, - 0x305a062c, - 0x305a863b, - 0x305b065b, - 0x305b866a, - 0x305c068b, - 0x305c86a7, - 0x305d06b3, - 0x305d86d3, - 0x305e06ef, - 0x305e8700, - 0x305f0716, - 0x305f8720, - 0x34320b63, - 0x34328b77, - 0x34330b94, - 0x34338ba7, - 0x34340bb6, - 0x34348bef, - 0x34350bd3, - 0x3c320083, - 0x3c328ca7, - 0x3c330cc0, - 0x3c338cdb, - 0x3c340cf8, - 0x3c348d22, - 0x3c350d3d, - 0x3c358d63, - 0x3c360d7c, - 0x3c368d94, - 0x3c370da5, - 0x3c378db3, - 0x3c380dc0, - 0x3c388dd4, - 0x3c390c6a, - 0x3c398de8, - 0x3c3a0dfc, - 0x3c3a890d, - 0x3c3b0e0c, - 0x3c3b8e27, - 0x3c3c0e39, - 0x3c3c8e6c, - 0x3c3d0e76, - 0x3c3d8e8a, - 0x3c3e0e98, - 0x3c3e8ebd, - 0x3c3f0c93, - 0x3c3f8ea6, - 0x3c4000ac, - 0x3c4080ea, - 0x3c410d13, - 0x3c418d52, - 0x3c420e4f, - 0x403218a4, - 0x403298ba, - 0x403318e8, - 0x403398f2, - 0x40341909, - 0x40349927, - 0x40351937, - 0x40359949, - 0x40361956, - 0x40369962, - 0x40371977, - 0x40379989, - 0x40381994, - 0x403899a6, - 0x40390eed, - 0x403999b6, - 0x403a19c9, - 0x403a99ea, - 0x403b19fb, - 0x403b9a0b, - 0x403c0064, - 0x403c8083, - 0x403d1a8f, - 0x403d9aa5, - 0x403e1ab4, - 0x403e9aec, - 0x403f1b06, - 0x403f9b14, - 0x40401b29, - 0x40409b3d, - 0x40411b5a, - 0x40419b75, - 0x40421b8e, - 0x40429ba1, - 0x40431bb5, - 0x40439bcd, - 0x40441be4, - 0x404480ac, - 0x40451bf9, - 0x40459c0b, - 0x40461c2f, - 0x40469c4f, - 0x40471c5d, - 0x40479c84, - 0x40481cc1, - 0x40489cda, - 0x40491cf1, - 0x40499d0b, - 0x404a1d22, - 0x404a9d40, - 0x404b1d58, - 0x404b9d6f, - 0x404c1d85, - 0x404c9d97, - 0x404d1db8, - 0x404d9dda, - 0x404e1dee, - 0x404e9dfb, - 0x404f1e28, - 0x404f9e51, - 0x40501e8c, - 0x40509ea0, - 0x40511ebb, - 0x40521ecb, - 0x40529eef, - 0x40531f07, - 0x40539f1a, - 0x40541f2f, - 0x40549f52, - 0x40551f60, - 0x40559f7d, - 0x40561f8a, - 0x40569fa3, - 0x40571fbb, - 0x40579fce, - 0x40581fe3, - 0x4058a00a, - 0x40592039, - 0x4059a066, - 0x405a207a, - 0x405aa08a, - 0x405b20a2, - 0x405ba0b3, - 0x405c20c6, - 0x405ca105, - 0x405d2112, - 0x405da129, - 0x405e2167, - 0x405e8ab1, - 0x405f2188, - 0x405fa195, - 0x406021a3, - 0x4060a1c5, - 0x40612209, - 0x4061a241, - 0x40622258, - 0x4062a269, - 0x4063227a, - 0x4063a28f, - 0x406422a6, - 0x4064a2d2, - 0x406522ed, - 0x4065a304, - 0x4066231c, - 0x4066a346, - 0x40672371, - 0x4067a392, - 0x406823b9, - 0x4068a3da, - 0x4069240c, - 0x4069a43a, - 0x406a245b, - 0x406aa47b, - 0x406b2603, - 0x406ba626, - 0x406c263c, - 0x406ca8b7, - 0x406d28e6, - 0x406da90e, - 0x406e293c, - 0x406ea989, - 0x406f29a8, - 0x406fa9e0, - 0x407029f3, - 0x4070aa10, - 0x40710800, - 0x4071aa22, - 0x40722a35, - 0x4072aa4e, - 0x40732a66, - 0x40739482, - 0x40742a7a, - 0x4074aa94, - 0x40752aa5, - 0x4075aab9, - 0x40762ac7, - 0x40769259, - 0x40772aec, - 0x4077ab0e, - 0x40782b29, - 0x4078ab62, - 0x40792b79, - 0x4079ab8f, - 0x407a2b9b, - 0x407aabae, - 0x407b2bc3, - 0x407babd5, - 0x407c2c06, - 0x407cac0f, - 0x407d23f5, - 0x407d9e61, - 0x407e2b3e, - 0x407ea01a, - 0x407f1c71, - 0x407f9a31, - 0x40801e38, - 0x40809c99, - 0x40811edd, - 0x40819e12, - 0x40822927, - 0x40829a17, - 0x40831ff5, - 0x4083a2b7, - 0x40841cad, - 0x4084a052, - 0x408520d7, - 0x4085a1ed, - 0x40862149, - 0x40869e7b, - 0x4087296d, - 0x4087a21e, - 0x40881a78, - 0x4088a3a5, - 0x40891ac7, - 0x40899a54, - 0x408a265c, - 0x408a9862, - 0x408b2bea, - 0x408ba9bd, - 0x408c20e7, - 0x408c987e, - 0x41f4252e, - 0x41f925c0, - 0x41fe24b3, - 0x41fea6a8, - 0x41ff2799, - 0x42032547, - 0x42082569, - 0x4208a5a5, - 0x42092497, - 0x4209a5df, - 0x420a24ee, - 0x420aa4ce, - 0x420b250e, - 0x420ba587, - 0x420c27b5, - 0x420ca675, - 0x420d268f, - 0x420da6c6, - 0x421226e0, - 0x4217277c, - 0x4217a722, - 0x421c2744, - 0x421f26ff, - 0x422127cc, - 0x4226275f, - 0x422b289b, - 0x422ba849, - 0x422c2883, - 0x422ca808, - 0x422d27e7, - 0x422da868, - 0x422e282e, - 0x422ea954, - 0x4432072b, - 0x4432873a, - 0x44330746, - 0x44338754, - 0x44340767, - 0x44348778, - 0x4435077f, - 0x44358789, - 0x4436079c, - 0x443687b2, - 0x443707c4, - 0x443787d1, - 0x443807e0, - 0x443887e8, - 0x44390800, - 0x4439880e, - 0x443a0821, - 0x48321283, - 0x48329295, - 0x483312ab, - 0x483392c4, - 0x4c3212e9, - 0x4c3292f9, - 0x4c33130c, - 0x4c33932c, - 0x4c3400ac, - 0x4c3480ea, - 0x4c351338, - 0x4c359346, - 0x4c361362, - 0x4c369375, - 0x4c371384, - 0x4c379392, - 0x4c3813a7, - 0x4c3893b3, - 0x4c3913d3, - 0x4c3993fd, - 0x4c3a1416, - 0x4c3a942f, - 0x4c3b05fb, - 0x4c3b9448, - 0x4c3c145a, - 0x4c3c9469, - 0x4c3d1482, - 0x4c3d8c45, - 0x4c3e14db, - 0x4c3e9491, - 0x4c3f14fd, - 0x4c3f9259, - 0x4c4014a7, - 0x4c4092d5, - 0x4c4114cb, - 0x50322e48, - 0x5032ae57, - 0x50332e62, - 0x5033ae72, - 0x50342e8b, - 0x5034aea5, - 0x50352eb3, - 0x5035aec9, - 0x50362edb, - 0x5036aef1, - 0x50372f0a, - 0x5037af1d, - 0x50382f35, - 0x5038af46, - 0x50392f5b, - 0x5039af6f, - 0x503a2f8f, - 0x503aafa5, - 0x503b2fbd, - 0x503bafcf, - 0x503c2feb, - 0x503cb002, - 0x503d301b, - 0x503db031, - 0x503e303e, - 0x503eb054, - 0x503f3066, - 0x503f8382, - 0x50403079, - 0x5040b089, - 0x504130a3, - 0x5041b0b2, - 0x504230cc, - 0x5042b0e9, - 0x504330f9, - 0x5043b109, - 0x50443118, - 0x5044843f, - 0x5045312c, - 0x5045b14a, - 0x5046315d, - 0x5046b173, - 0x50473185, - 0x5047b19a, - 0x504831c0, - 0x5048b1ce, - 0x504931e1, - 0x5049b1f6, - 0x504a320c, - 0x504ab21c, - 0x504b323c, - 0x504bb24f, - 0x504c3272, - 0x504cb2a0, - 0x504d32b2, - 0x504db2cf, - 0x504e32ea, - 0x504eb306, - 0x504f3318, - 0x504fb32f, - 0x5050333e, - 0x505086ef, - 0x50513351, - 0x58320f2b, - 0x68320eed, - 0x68328c6a, - 0x68330c7d, - 0x68338efb, - 0x68340f0b, - 0x683480ea, - 0x6c320ec9, - 0x6c328c34, - 0x6c330ed4, - 0x74320a19, - 0x743280ac, - 0x74330c45, - 0x7832097e, - 0x78328993, - 0x7833099f, - 0x78338083, - 0x783409ae, - 0x783489c3, - 0x783509e2, - 0x78358a04, - 0x78360a19, - 0x78368a2f, - 0x78370a3f, - 0x78378a60, - 0x78380a73, - 0x78388a85, - 0x78390a92, - 0x78398ab1, - 0x783a0ac6, - 0x783a8ad4, - 0x783b0ade, - 0x783b8af2, - 0x783c0b09, - 0x783c8b1e, - 0x783d0b35, - 0x783d8b4a, - 0x783e0aa0, - 0x783e8a52, - 0x7c321185, - }; - - const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); - - const char kOpenSSLReasonStringData[] = - "ASN1_LENGTH_MISMATCH\\0" - "AUX_ERROR\\0" - "BAD_GET_ASN1_OBJECT_CALL\\0" - "BAD_OBJECT_HEADER\\0" - "BMPSTRING_IS_WRONG_LENGTH\\0" - "BN_LIB\\0" - "BOOLEAN_IS_WRONG_LENGTH\\0" - "BUFFER_TOO_SMALL\\0" - "CONTEXT_NOT_INITIALISED\\0" - "DECODE_ERROR\\0" - "DEPTH_EXCEEDED\\0" - "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\\0" - "ENCODE_ERROR\\0" - "ERROR_GETTING_TIME\\0" - "EXPECTING_AN_ASN1_SEQUENCE\\0" - "EXPECTING_AN_INTEGER\\0" - "EXPECTING_AN_OBJECT\\0" - "EXPECTING_A_BOOLEAN\\0" - "EXPECTING_A_TIME\\0" - "EXPLICIT_LENGTH_MISMATCH\\0" - "EXPLICIT_TAG_NOT_CONSTRUCTED\\0" - "FIELD_MISSING\\0" - "FIRST_NUM_TOO_LARGE\\0" - "HEADER_TOO_LONG\\0" - "ILLEGAL_BITSTRING_FORMAT\\0" - "ILLEGAL_BOOLEAN\\0" - "ILLEGAL_CHARACTERS\\0" - "ILLEGAL_FORMAT\\0" - "ILLEGAL_HEX\\0" - "ILLEGAL_IMPLICIT_TAG\\0" - "ILLEGAL_INTEGER\\0" - "ILLEGAL_NESTED_TAGGING\\0" - "ILLEGAL_NULL\\0" - "ILLEGAL_NULL_VALUE\\0" - "ILLEGAL_OBJECT\\0" - "ILLEGAL_OPTIONAL_ANY\\0" - "ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE\\0" - "ILLEGAL_TAGGED_ANY\\0" - "ILLEGAL_TIME_VALUE\\0" - "INTEGER_NOT_ASCII_FORMAT\\0" - "INTEGER_TOO_LARGE_FOR_LONG\\0" - "INVALID_BIT_STRING_BITS_LEFT\\0" - "INVALID_BMPSTRING_LENGTH\\0" - "INVALID_DIGIT\\0" - "INVALID_MODIFIER\\0" - "INVALID_NUMBER\\0" - "INVALID_OBJECT_ENCODING\\0" - "INVALID_SEPARATOR\\0" - "INVALID_TIME_FORMAT\\0" - "INVALID_UNIVERSALSTRING_LENGTH\\0" - "INVALID_UTF8STRING\\0" - "LIST_ERROR\\0" - "MISSING_ASN1_EOS\\0" - "MISSING_EOC\\0" - "MISSING_SECOND_NUMBER\\0" - "MISSING_VALUE\\0" - "MSTRING_NOT_UNIVERSAL\\0" - "MSTRING_WRONG_TAG\\0" - "NESTED_ASN1_ERROR\\0" - "NESTED_ASN1_STRING\\0" - "NON_HEX_CHARACTERS\\0" - "NOT_ASCII_FORMAT\\0" - "NOT_ENOUGH_DATA\\0" - "NO_MATCHING_CHOICE_TYPE\\0" - "NULL_IS_WRONG_LENGTH\\0" - "OBJECT_NOT_ASCII_FORMAT\\0" - "ODD_NUMBER_OF_CHARS\\0" - "SECOND_NUMBER_TOO_LARGE\\0" - "SEQUENCE_LENGTH_MISMATCH\\0" - "SEQUENCE_NOT_CONSTRUCTED\\0" - "SEQUENCE_OR_SET_NEEDS_CONFIG\\0" - "SHORT_LINE\\0" - "STREAMING_NOT_SUPPORTED\\0" - "STRING_TOO_LONG\\0" - "STRING_TOO_SHORT\\0" - "TAG_VALUE_TOO_HIGH\\0" - "TIME_NOT_ASCII_FORMAT\\0" - "TOO_LONG\\0" - "TYPE_NOT_CONSTRUCTED\\0" - "TYPE_NOT_PRIMITIVE\\0" - "UNEXPECTED_EOC\\0" - "UNIVERSALSTRING_IS_WRONG_LENGTH\\0" - "UNKNOWN_FORMAT\\0" - "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\\0" - "UNKNOWN_SIGNATURE_ALGORITHM\\0" - "UNKNOWN_TAG\\0" - "UNSUPPORTED_ANY_DEFINED_BY_TYPE\\0" - "UNSUPPORTED_PUBLIC_KEY_TYPE\\0" - "UNSUPPORTED_TYPE\\0" - "WRONG_PUBLIC_KEY_TYPE\\0" - "WRONG_TAG\\0" - "WRONG_TYPE\\0" - "BAD_FOPEN_MODE\\0" - "BROKEN_PIPE\\0" - "CONNECT_ERROR\\0" - "ERROR_SETTING_NBIO\\0" - "INVALID_ARGUMENT\\0" - "IN_USE\\0" - "KEEPALIVE\\0" - "NBIO_CONNECT_ERROR\\0" - "NO_HOSTNAME_SPECIFIED\\0" - "NO_PORT_SPECIFIED\\0" - "NO_SUCH_FILE\\0" - "NULL_PARAMETER\\0" - "SYS_LIB\\0" - "UNABLE_TO_CREATE_SOCKET\\0" - "UNINITIALIZED\\0" - "UNSUPPORTED_METHOD\\0" - "WRITE_TO_READ_ONLY_BIO\\0" - "ARG2_LT_ARG3\\0" - "BAD_ENCODING\\0" - "BAD_RECIPROCAL\\0" - "BIGNUM_TOO_LONG\\0" - "BITS_TOO_SMALL\\0" - "CALLED_WITH_EVEN_MODULUS\\0" - "DIV_BY_ZERO\\0" - "EXPAND_ON_STATIC_BIGNUM_DATA\\0" - "INPUT_NOT_REDUCED\\0" - "INVALID_INPUT\\0" - "INVALID_RANGE\\0" - "NEGATIVE_NUMBER\\0" - "NOT_A_SQUARE\\0" - "NOT_INITIALIZED\\0" - "NO_INVERSE\\0" - "PRIVATE_KEY_TOO_LARGE\\0" - "P_IS_NOT_PRIME\\0" - "TOO_MANY_ITERATIONS\\0" - "TOO_MANY_TEMPORARY_VARIABLES\\0" - "AES_KEY_SETUP_FAILED\\0" - "BAD_DECRYPT\\0" - "BAD_KEY_LENGTH\\0" - "CTRL_NOT_IMPLEMENTED\\0" - "CTRL_OPERATION_NOT_IMPLEMENTED\\0" - "DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH\\0" - "INITIALIZATION_ERROR\\0" - "INPUT_NOT_INITIALIZED\\0" - "INVALID_AD_SIZE\\0" - "INVALID_KEY_LENGTH\\0" - "INVALID_NONCE\\0" - "INVALID_NONCE_SIZE\\0" - "INVALID_OPERATION\\0" - "IV_TOO_LARGE\\0" - "NO_CIPHER_SET\\0" - "NO_DIRECTION_SET\\0" - "OUTPUT_ALIASES_INPUT\\0" - "TAG_TOO_LARGE\\0" - "TOO_LARGE\\0" - "UNSUPPORTED_AD_SIZE\\0" - "UNSUPPORTED_INPUT_SIZE\\0" - "UNSUPPORTED_KEY_SIZE\\0" - "UNSUPPORTED_NONCE_SIZE\\0" - "UNSUPPORTED_TAG_SIZE\\0" - "WRONG_FINAL_BLOCK_LENGTH\\0" - "LIST_CANNOT_BE_NULL\\0" - "MISSING_CLOSE_SQUARE_BRACKET\\0" - "MISSING_EQUAL_SIGN\\0" - "NO_CLOSE_BRACE\\0" - "UNABLE_TO_CREATE_NEW_SECTION\\0" - "VARIABLE_EXPANSION_TOO_LONG\\0" - "VARIABLE_HAS_NO_VALUE\\0" - "BAD_GENERATOR\\0" - "INVALID_PUBKEY\\0" - "MODULUS_TOO_LARGE\\0" - "NO_PRIVATE_VALUE\\0" - "UNKNOWN_HASH\\0" - "BAD_Q_VALUE\\0" - "BAD_VERSION\\0" - "MISSING_PARAMETERS\\0" - "NEED_NEW_SETUP_VALUES\\0" - "BIGNUM_OUT_OF_RANGE\\0" - "COORDINATES_OUT_OF_RANGE\\0" - "D2I_ECPKPARAMETERS_FAILURE\\0" - "EC_GROUP_NEW_BY_NAME_FAILURE\\0" - "GROUP2PKPARAMETERS_FAILURE\\0" - "GROUP_MISMATCH\\0" - "I2D_ECPKPARAMETERS_FAILURE\\0" - "INCOMPATIBLE_OBJECTS\\0" - "INVALID_COFACTOR\\0" - "INVALID_COMPRESSED_POINT\\0" - "INVALID_COMPRESSION_BIT\\0" - "INVALID_ENCODING\\0" - "INVALID_FIELD\\0" - "INVALID_FORM\\0" - "INVALID_GROUP_ORDER\\0" - "INVALID_PRIVATE_KEY\\0" - "MISSING_PRIVATE_KEY\\0" - "NON_NAMED_CURVE\\0" - "PKPARAMETERS2GROUP_FAILURE\\0" - "POINT_AT_INFINITY\\0" - "POINT_IS_NOT_ON_CURVE\\0" - "PUBLIC_KEY_VALIDATION_FAILED\\0" - "SLOT_FULL\\0" - "UNDEFINED_GENERATOR\\0" - "UNKNOWN_GROUP\\0" - "UNKNOWN_ORDER\\0" - "WRONG_CURVE_PARAMETERS\\0" - "WRONG_ORDER\\0" - "KDF_FAILED\\0" - "POINT_ARITHMETIC_FAILURE\\0" - "BAD_SIGNATURE\\0" - "NOT_IMPLEMENTED\\0" - "RANDOM_NUMBER_GENERATION_FAILED\\0" - "OPERATION_NOT_SUPPORTED\\0" - "COMMAND_NOT_SUPPORTED\\0" - "DIFFERENT_KEY_TYPES\\0" - "DIFFERENT_PARAMETERS\\0" - "EXPECTING_AN_EC_KEY_KEY\\0" - "EXPECTING_AN_RSA_KEY\\0" - "EXPECTING_A_DSA_KEY\\0" - "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\\0" - "INVALID_DIGEST_LENGTH\\0" - "INVALID_DIGEST_TYPE\\0" - "INVALID_KEYBITS\\0" - "INVALID_MGF1_MD\\0" - "INVALID_PADDING_MODE\\0" - "INVALID_PARAMETERS\\0" - "INVALID_PSS_SALTLEN\\0" - "INVALID_SIGNATURE\\0" - "KEYS_NOT_SET\\0" - "MEMORY_LIMIT_EXCEEDED\\0" - "NOT_A_PRIVATE_KEY\\0" - "NO_DEFAULT_DIGEST\\0" - "NO_KEY_SET\\0" - "NO_MDC2_SUPPORT\\0" - "NO_NID_FOR_CURVE\\0" - "NO_OPERATION_SET\\0" - "NO_PARAMETERS_SET\\0" - "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\\0" - "OPERATON_NOT_INITIALIZED\\0" - "UNKNOWN_PUBLIC_KEY_TYPE\\0" - "UNSUPPORTED_ALGORITHM\\0" - "OUTPUT_TOO_LARGE\\0" - "UNKNOWN_NID\\0" - "BAD_BASE64_DECODE\\0" - "BAD_END_LINE\\0" - "BAD_IV_CHARS\\0" - "BAD_PASSWORD_READ\\0" - "CIPHER_IS_NULL\\0" - "ERROR_CONVERTING_PRIVATE_KEY\\0" - "NOT_DEK_INFO\\0" - "NOT_ENCRYPTED\\0" - "NOT_PROC_TYPE\\0" - "NO_START_LINE\\0" - "READ_KEY\\0" - "SHORT_HEADER\\0" - "UNSUPPORTED_CIPHER\\0" - "UNSUPPORTED_ENCRYPTION\\0" - "BAD_PKCS7_VERSION\\0" - "NOT_PKCS7_SIGNED_DATA\\0" - "NO_CERTIFICATES_INCLUDED\\0" - "NO_CRLS_INCLUDED\\0" - "BAD_ITERATION_COUNT\\0" - "BAD_PKCS12_DATA\\0" - "BAD_PKCS12_VERSION\\0" - "CIPHER_HAS_NO_OBJECT_IDENTIFIER\\0" - "CRYPT_ERROR\\0" - "ENCRYPT_ERROR\\0" - "ERROR_SETTING_CIPHER_PARAMS\\0" - "INCORRECT_PASSWORD\\0" - "KEYGEN_FAILURE\\0" - "KEY_GEN_ERROR\\0" - "METHOD_NOT_SUPPORTED\\0" - "MISSING_MAC\\0" - "MULTIPLE_PRIVATE_KEYS_IN_PKCS12\\0" - "PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED\\0" - "PKCS12_TOO_DEEPLY_NESTED\\0" - "PRIVATE_KEY_DECODE_ERROR\\0" - "PRIVATE_KEY_ENCODE_ERROR\\0" - "UNKNOWN_ALGORITHM\\0" - "UNKNOWN_CIPHER\\0" - "UNKNOWN_CIPHER_ALGORITHM\\0" - "UNKNOWN_DIGEST\\0" - "UNSUPPORTED_KEYLENGTH\\0" - "UNSUPPORTED_KEY_DERIVATION_FUNCTION\\0" - "UNSUPPORTED_PRF\\0" - "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\\0" - "UNSUPPORTED_SALT_TYPE\\0" - "BAD_E_VALUE\\0" - "BAD_FIXED_HEADER_DECRYPT\\0" - "BAD_PAD_BYTE_COUNT\\0" - "BAD_RSA_PARAMETERS\\0" - "BLOCK_TYPE_IS_NOT_01\\0" - "BN_NOT_INITIALIZED\\0" - "CANNOT_RECOVER_MULTI_PRIME_KEY\\0" - "CRT_PARAMS_ALREADY_GIVEN\\0" - "CRT_VALUES_INCORRECT\\0" - "DATA_LEN_NOT_EQUAL_TO_MOD_LEN\\0" - "DATA_TOO_LARGE\\0" - "DATA_TOO_LARGE_FOR_KEY_SIZE\\0" - "DATA_TOO_LARGE_FOR_MODULUS\\0" - "DATA_TOO_SMALL\\0" - "DATA_TOO_SMALL_FOR_KEY_SIZE\\0" - "DIGEST_TOO_BIG_FOR_RSA_KEY\\0" - "D_E_NOT_CONGRUENT_TO_1\\0" - "EMPTY_PUBLIC_KEY\\0" - "FIRST_OCTET_INVALID\\0" - "INCONSISTENT_SET_OF_CRT_VALUES\\0" - "INTERNAL_ERROR\\0" - "INVALID_MESSAGE_LENGTH\\0" - "KEY_SIZE_TOO_SMALL\\0" - "LAST_OCTET_INVALID\\0" - "MUST_HAVE_AT_LEAST_TWO_PRIMES\\0" - "NO_PUBLIC_EXPONENT\\0" - "NULL_BEFORE_BLOCK_MISSING\\0" - "N_NOT_EQUAL_P_Q\\0" - "OAEP_DECODING_ERROR\\0" - "ONLY_ONE_OF_P_Q_GIVEN\\0" - "OUTPUT_BUFFER_TOO_SMALL\\0" - "PADDING_CHECK_FAILED\\0" - "PKCS_DECODING_ERROR\\0" - "SLEN_CHECK_FAILED\\0" - "SLEN_RECOVERY_FAILED\\0" - "UNKNOWN_ALGORITHM_TYPE\\0" - "UNKNOWN_PADDING_TYPE\\0" - "VALUE_MISSING\\0" - "WRONG_SIGNATURE_LENGTH\\0" - "ALPN_MISMATCH_ON_EARLY_DATA\\0" - "APPLICATION_DATA_INSTEAD_OF_HANDSHAKE\\0" - "APP_DATA_IN_HANDSHAKE\\0" - "ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT\\0" - "BAD_ALERT\\0" - "BAD_CHANGE_CIPHER_SPEC\\0" - "BAD_DATA_RETURNED_BY_CALLBACK\\0" - "BAD_DH_P_LENGTH\\0" - "BAD_DIGEST_LENGTH\\0" - "BAD_ECC_CERT\\0" - "BAD_ECPOINT\\0" - "BAD_HANDSHAKE_RECORD\\0" - "BAD_HELLO_REQUEST\\0" - "BAD_LENGTH\\0" - "BAD_PACKET_LENGTH\\0" - "BAD_RSA_ENCRYPT\\0" - "BAD_SRTP_MKI_VALUE\\0" - "BAD_SRTP_PROTECTION_PROFILE_LIST\\0" - "BAD_SSL_FILETYPE\\0" - "BAD_WRITE_RETRY\\0" - "BIO_NOT_SET\\0" - "BLOCK_CIPHER_PAD_IS_WRONG\\0" - "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\\0" - "CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD\\0" - "CANNOT_PARSE_LEAF_CERT\\0" - "CA_DN_LENGTH_MISMATCH\\0" - "CA_DN_TOO_LONG\\0" - "CCS_RECEIVED_EARLY\\0" - "CERTIFICATE_AND_PRIVATE_KEY_MISMATCH\\0" - "CERTIFICATE_VERIFY_FAILED\\0" - "CERT_CB_ERROR\\0" - "CERT_LENGTH_MISMATCH\\0" - "CHANNEL_ID_NOT_P256\\0" - "CHANNEL_ID_SIGNATURE_INVALID\\0" - "CIPHER_OR_HASH_UNAVAILABLE\\0" - "CLIENTHELLO_PARSE_FAILED\\0" - "CLIENTHELLO_TLSEXT\\0" - "CONNECTION_REJECTED\\0" - "CONNECTION_TYPE_NOT_SET\\0" - "CUSTOM_EXTENSION_ERROR\\0" - "DATA_LENGTH_TOO_LONG\\0" - "DECRYPTION_FAILED\\0" - "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\\0" - "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\\0" - "DH_P_TOO_LONG\\0" - "DIGEST_CHECK_FAILED\\0" - "DOWNGRADE_DETECTED\\0" - "DTLS_MESSAGE_TOO_BIG\\0" - "DUPLICATE_EXTENSION\\0" - "DUPLICATE_KEY_SHARE\\0" - "ECC_CERT_NOT_FOR_SIGNING\\0" - "EMS_STATE_INCONSISTENT\\0" - "ENCRYPTED_LENGTH_TOO_LONG\\0" - "ERROR_ADDING_EXTENSION\\0" - "ERROR_IN_RECEIVED_CIPHER_LIST\\0" - "ERROR_PARSING_EXTENSION\\0" - "EXCESSIVE_MESSAGE_SIZE\\0" - "EXTRA_DATA_IN_MESSAGE\\0" - "FRAGMENT_MISMATCH\\0" - "GOT_NEXT_PROTO_WITHOUT_EXTENSION\\0" - "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\\0" - "HTTPS_PROXY_REQUEST\\0" - "HTTP_REQUEST\\0" - "INAPPROPRIATE_FALLBACK\\0" - "INVALID_ALPN_PROTOCOL\\0" - "INVALID_COMMAND\\0" - "INVALID_COMPRESSION_LIST\\0" - "INVALID_MESSAGE\\0" - "INVALID_OUTER_RECORD_TYPE\\0" - "INVALID_SCT_LIST\\0" - "INVALID_SSL_SESSION\\0" - "INVALID_TICKET_KEYS_LENGTH\\0" - "LENGTH_MISMATCH\\0" - "MISSING_EXTENSION\\0" - "MISSING_KEY_SHARE\\0" - "MISSING_RSA_CERTIFICATE\\0" - "MISSING_TMP_DH_KEY\\0" - "MISSING_TMP_ECDH_KEY\\0" - "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\\0" - "MTU_TOO_SMALL\\0" - "NEGOTIATED_BOTH_NPN_AND_ALPN\\0" - "NESTED_GROUP\\0" - "NO_CERTIFICATES_RETURNED\\0" - "NO_CERTIFICATE_ASSIGNED\\0" - "NO_CERTIFICATE_SET\\0" - "NO_CIPHERS_AVAILABLE\\0" - "NO_CIPHERS_PASSED\\0" - "NO_CIPHERS_SPECIFIED\\0" - "NO_CIPHER_MATCH\\0" - "NO_COMMON_SIGNATURE_ALGORITHMS\\0" - "NO_COMPRESSION_SPECIFIED\\0" - "NO_GROUPS_SPECIFIED\\0" - "NO_METHOD_SPECIFIED\\0" - "NO_P256_SUPPORT\\0" - "NO_PRIVATE_KEY_ASSIGNED\\0" - "NO_RENEGOTIATION\\0" - "NO_REQUIRED_DIGEST\\0" - "NO_SHARED_CIPHER\\0" - "NO_SHARED_GROUP\\0" - "NO_SUPPORTED_VERSIONS_ENABLED\\0" - "NULL_SSL_CTX\\0" - "NULL_SSL_METHOD_PASSED\\0" - "OLD_SESSION_CIPHER_NOT_RETURNED\\0" - "OLD_SESSION_PRF_HASH_MISMATCH\\0" - "OLD_SESSION_VERSION_NOT_RETURNED\\0" - "PARSE_TLSEXT\\0" - "PATH_TOO_LONG\\0" - "PEER_DID_NOT_RETURN_A_CERTIFICATE\\0" - "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\\0" - "PRE_SHARED_KEY_MUST_BE_LAST\\0" - "PROTOCOL_IS_SHUTDOWN\\0" - "PSK_IDENTITY_BINDER_COUNT_MISMATCH\\0" - "PSK_IDENTITY_NOT_FOUND\\0" - "PSK_NO_CLIENT_CB\\0" - "PSK_NO_SERVER_CB\\0" - "READ_TIMEOUT_EXPIRED\\0" - "RECORD_LENGTH_MISMATCH\\0" - "RECORD_TOO_LARGE\\0" - "RENEGOTIATION_EMS_MISMATCH\\0" - "RENEGOTIATION_ENCODING_ERR\\0" - "RENEGOTIATION_MISMATCH\\0" - "REQUIRED_CIPHER_MISSING\\0" - "RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION\\0" - "RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION\\0" - "SCSV_RECEIVED_WHEN_RENEGOTIATING\\0" - "SERVERHELLO_TLSEXT\\0" - "SERVER_CERT_CHANGED\\0" - "SESSION_ID_CONTEXT_UNINITIALIZED\\0" - "SESSION_MAY_NOT_BE_CREATED\\0" - "SHUTDOWN_WHILE_IN_INIT\\0" - "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\\0" - "SRTP_COULD_NOT_ALLOCATE_PROFILES\\0" - "SRTP_UNKNOWN_PROTECTION_PROFILE\\0" - "SSL3_EXT_INVALID_SERVERNAME\\0" - "SSLV3_ALERT_BAD_CERTIFICATE\\0" - "SSLV3_ALERT_BAD_RECORD_MAC\\0" - "SSLV3_ALERT_CERTIFICATE_EXPIRED\\0" - "SSLV3_ALERT_CERTIFICATE_REVOKED\\0" - "SSLV3_ALERT_CERTIFICATE_UNKNOWN\\0" - "SSLV3_ALERT_CLOSE_NOTIFY\\0" - "SSLV3_ALERT_DECOMPRESSION_FAILURE\\0" - "SSLV3_ALERT_HANDSHAKE_FAILURE\\0" - "SSLV3_ALERT_ILLEGAL_PARAMETER\\0" - "SSLV3_ALERT_NO_CERTIFICATE\\0" - "SSLV3_ALERT_UNEXPECTED_MESSAGE\\0" - "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\\0" - "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\\0" - "SSL_HANDSHAKE_FAILURE\\0" - "SSL_SESSION_ID_CONTEXT_TOO_LONG\\0" - "TICKET_ENCRYPTION_FAILED\\0" - "TLSV1_ALERT_ACCESS_DENIED\\0" - "TLSV1_ALERT_DECODE_ERROR\\0" - "TLSV1_ALERT_DECRYPTION_FAILED\\0" - "TLSV1_ALERT_DECRYPT_ERROR\\0" - "TLSV1_ALERT_EXPORT_RESTRICTION\\0" - "TLSV1_ALERT_INAPPROPRIATE_FALLBACK\\0" - "TLSV1_ALERT_INSUFFICIENT_SECURITY\\0" - "TLSV1_ALERT_INTERNAL_ERROR\\0" - "TLSV1_ALERT_NO_RENEGOTIATION\\0" - "TLSV1_ALERT_PROTOCOL_VERSION\\0" - "TLSV1_ALERT_RECORD_OVERFLOW\\0" - "TLSV1_ALERT_UNKNOWN_CA\\0" - "TLSV1_ALERT_USER_CANCELLED\\0" - "TLSV1_BAD_CERTIFICATE_HASH_VALUE\\0" - "TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\\0" - "TLSV1_CERTIFICATE_REQUIRED\\0" - "TLSV1_CERTIFICATE_UNOBTAINABLE\\0" - "TLSV1_UNKNOWN_PSK_IDENTITY\\0" - "TLSV1_UNRECOGNIZED_NAME\\0" - "TLSV1_UNSUPPORTED_EXTENSION\\0" - "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\\0" - "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\\0" - "TOO_MANY_EMPTY_FRAGMENTS\\0" - "TOO_MANY_KEY_UPDATES\\0" - "TOO_MANY_WARNING_ALERTS\\0" - "TOO_MUCH_READ_EARLY_DATA\\0" - "TOO_MUCH_SKIPPED_EARLY_DATA\\0" - "UNABLE_TO_FIND_ECDH_PARAMETERS\\0" - "UNEXPECTED_EXTENSION\\0" - "UNEXPECTED_EXTENSION_ON_EARLY_DATA\\0" - "UNEXPECTED_MESSAGE\\0" - "UNEXPECTED_OPERATOR_IN_GROUP\\0" - "UNEXPECTED_RECORD\\0" - "UNKNOWN_ALERT_TYPE\\0" - "UNKNOWN_CERTIFICATE_TYPE\\0" - "UNKNOWN_CIPHER_RETURNED\\0" - "UNKNOWN_CIPHER_TYPE\\0" - "UNKNOWN_KEY_EXCHANGE_TYPE\\0" - "UNKNOWN_PROTOCOL\\0" - "UNKNOWN_SSL_VERSION\\0" - "UNKNOWN_STATE\\0" - "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\\0" - "UNSUPPORTED_COMPRESSION_ALGORITHM\\0" - "UNSUPPORTED_ELLIPTIC_CURVE\\0" - "UNSUPPORTED_PROTOCOL\\0" - "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\\0" - "WRONG_CERTIFICATE_TYPE\\0" - "WRONG_CIPHER_RETURNED\\0" - "WRONG_CURVE\\0" - "WRONG_MESSAGE_TYPE\\0" - "WRONG_SIGNATURE_TYPE\\0" - "WRONG_SSL_VERSION\\0" - "WRONG_VERSION_NUMBER\\0" - "WRONG_VERSION_ON_EARLY_DATA\\0" - "X509_LIB\\0" - "X509_VERIFICATION_SETUP_PROBLEMS\\0" - "AKID_MISMATCH\\0" - "BAD_X509_FILETYPE\\0" - "BASE64_DECODE_ERROR\\0" - "CANT_CHECK_DH_KEY\\0" - "CERT_ALREADY_IN_HASH_TABLE\\0" - "CRL_ALREADY_DELTA\\0" - "CRL_VERIFY_FAILURE\\0" - "IDP_MISMATCH\\0" - "INVALID_DIRECTORY\\0" - "INVALID_FIELD_NAME\\0" - "INVALID_PARAMETER\\0" - "INVALID_PSS_PARAMETERS\\0" - "INVALID_TRUST\\0" - "ISSUER_MISMATCH\\0" - "KEY_TYPE_MISMATCH\\0" - "KEY_VALUES_MISMATCH\\0" - "LOADING_CERT_DIR\\0" - "LOADING_DEFAULTS\\0" - "NAME_TOO_LONG\\0" - "NEWER_CRL_NOT_NEWER\\0" - "NO_CERT_SET_FOR_US_TO_VERIFY\\0" - "NO_CRL_NUMBER\\0" - "PUBLIC_KEY_DECODE_ERROR\\0" - "PUBLIC_KEY_ENCODE_ERROR\\0" - "SHOULD_RETRY\\0" - "UNKNOWN_KEY_TYPE\\0" - "UNKNOWN_PURPOSE_ID\\0" - "UNKNOWN_TRUST_ID\\0" - "WRONG_LOOKUP_TYPE\\0" - "BAD_IP_ADDRESS\\0" - "BAD_OBJECT\\0" - "BN_DEC2BN_ERROR\\0" - "BN_TO_ASN1_INTEGER_ERROR\\0" - "CANNOT_FIND_FREE_FUNCTION\\0" - "DIRNAME_ERROR\\0" - "DISTPOINT_ALREADY_SET\\0" - "DUPLICATE_ZONE_ID\\0" - "ERROR_CONVERTING_ZONE\\0" - "ERROR_CREATING_EXTENSION\\0" - "ERROR_IN_EXTENSION\\0" - "EXPECTED_A_SECTION_NAME\\0" - "EXTENSION_EXISTS\\0" - "EXTENSION_NAME_ERROR\\0" - "EXTENSION_NOT_FOUND\\0" - "EXTENSION_SETTING_NOT_SUPPORTED\\0" - "EXTENSION_VALUE_ERROR\\0" - "ILLEGAL_EMPTY_EXTENSION\\0" - "ILLEGAL_HEX_DIGIT\\0" - "INCORRECT_POLICY_SYNTAX_TAG\\0" - "INVALID_BOOLEAN_STRING\\0" - "INVALID_EXTENSION_STRING\\0" - "INVALID_MULTIPLE_RDNS\\0" - "INVALID_NAME\\0" - "INVALID_NULL_ARGUMENT\\0" - "INVALID_NULL_NAME\\0" - "INVALID_NULL_VALUE\\0" - "INVALID_NUMBERS\\0" - "INVALID_OBJECT_IDENTIFIER\\0" - "INVALID_OPTION\\0" - "INVALID_POLICY_IDENTIFIER\\0" - "INVALID_PROXY_POLICY_SETTING\\0" - "INVALID_PURPOSE\\0" - "INVALID_SECTION\\0" - "INVALID_SYNTAX\\0" - "ISSUER_DECODE_ERROR\\0" - "NEED_ORGANIZATION_AND_NUMBERS\\0" - "NO_CONFIG_DATABASE\\0" - "NO_ISSUER_CERTIFICATE\\0" - "NO_ISSUER_DETAILS\\0" - "NO_POLICY_IDENTIFIER\\0" - "NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED\\0" - "NO_PUBLIC_KEY\\0" - "NO_SUBJECT_DETAILS\\0" - "ODD_NUMBER_OF_DIGITS\\0" - "OPERATION_NOT_DEFINED\\0" - "OTHERNAME_ERROR\\0" - "POLICY_LANGUAGE_ALREADY_DEFINED\\0" - "POLICY_PATH_LENGTH\\0" - "POLICY_PATH_LENGTH_ALREADY_DEFINED\\0" - "POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY\\0" - "SECTION_NOT_FOUND\\0" - "UNABLE_TO_GET_ISSUER_DETAILS\\0" - "UNABLE_TO_GET_ISSUER_KEYID\\0" - "UNKNOWN_BIT_STRING_ARGUMENT\\0" - "UNKNOWN_EXTENSION\\0" - "UNKNOWN_EXTENSION_NAME\\0" - "UNKNOWN_OPTION\\0" - "UNSUPPORTED_OPTION\\0" - "USER_TOO_LONG\\0" - ""; - EOF - - sed -i'.back' '/^#define \\([A-Za-z0-9_]*\\) \\1/d' include/openssl/ssl.h - sed -i'.back' 'N;/^#define \\([A-Za-z0-9_]*\\) *\\\\\\n *\\1/d' include/openssl/ssl.h - sed -i'.back' 's/#ifndef md5_block_data_order/#ifndef GRPC_SHADOW_md5_block_data_order/g' crypto/fipsmodule/md5/md5.c - find . -type f \\( -path '*.h' -or -path '*.cc' -or -path '*.c' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include Date: Thu, 17 Jan 2019 13:37:33 -0800 Subject: [PATCH 089/814] generate projects --- gRPC-C++.podspec | 1 + gRPC-Core.podspec | 1 + gRPC.podspec | 1 + src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 1 + src/objective-c/BoringSSL-GRPC.podspec | 1 + 5 files changed, 5 insertions(+) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 9935ec40e3f..4c30e568a1b 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -41,6 +41,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' s.tvos.deployment_target = '10.0' + s.requires_arc = false name = 'grpcpp' diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 8eabd00e6f0..6f687ca3fb5 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -41,6 +41,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' s.tvos.deployment_target = '10.0' + s.requires_arc = false name = 'grpc' diff --git a/gRPC.podspec b/gRPC.podspec index 940a1ac6217..8577c9d2a33 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -34,6 +34,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' name = 'GRPCClient' s.module_name = name diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 55ca6048bc3..50f2bc4eb29 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -105,6 +105,7 @@ Pod::Spec.new do |s| # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' # Restrict the gRPC runtime version to the one supported by this plugin. s.dependency 'gRPC-ProtoRPC', v diff --git a/src/objective-c/BoringSSL-GRPC.podspec b/src/objective-c/BoringSSL-GRPC.podspec index 3f02268b4fe..6ec3747faef 100644 --- a/src/objective-c/BoringSSL-GRPC.podspec +++ b/src/objective-c/BoringSSL-GRPC.podspec @@ -1,4 +1,5 @@ + # This file has been automatically generated from a template file. # Please make modifications to # `templates/src/objective-c/BoringSSL-GRPC.podspec.template` instead. This From e5453b18649c1f1da51a9af5a57a86eecded8c68 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 17 Jan 2019 14:33:33 -0800 Subject: [PATCH 090/814] Fix authorizer bug --- src/objective-c/GRPCClient/GRPCCall.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 16c01d01ce7..74a1b47ba6c 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -889,14 +889,18 @@ const char *kCFStreamVarName = "grpc_cfstream"; [tokenProvider getTokenWithHandler:^(NSString *token) { __strong typeof(self) strongSelf = weakSelf; if (strongSelf) { + BOOL startCall = NO; @synchronized(strongSelf) { - if (strongSelf->_state == GRXWriterStateNotStarted) { + if (strongSelf->_state != GRXWriterStateFinished) { + startCall = YES; if (token) { strongSelf->_fetchedOauth2AccessToken = [token copy]; } } } - [strongSelf startCallWithWriteable:writeable]; + if (startCall) { + [strongSelf startCallWithWriteable:writeable]; + } } }]; } else { From 4351ca35ee059ae3301dd8033d7d262daa416799 Mon Sep 17 00:00:00 2001 From: Jerry Date: Thu, 17 Jan 2019 14:36:15 -0800 Subject: [PATCH 091/814] memory leak test for php --- src/php/bin/run_tests.sh | 10 + .../tests/MemoryLeakTest/MemoryLeakTest.php | 2310 +++++++++++++++++ src/php/tests/unit_tests/CallTest.php | 20 + 3 files changed, 2340 insertions(+) create mode 100644 src/php/tests/MemoryLeakTest/MemoryLeakTest.php diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh index 295bcb2430c..cfe16ee3e85 100755 --- a/src/php/bin/run_tests.sh +++ b/src/php/bin/run_tests.sh @@ -22,9 +22,19 @@ cd src/php/bin source ./determine_extension_dir.sh # in some jenkins macos machine, somehow the PHP build script can't find libgrpc.dylib export DYLD_LIBRARY_PATH=$root/libs/$CONFIG + php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ --exclude-group persistent_list_bound_tests ../tests/unit_tests php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ ../tests/unit_tests/PersistentChannelTests +export ZEND_DONT_UNLOAD_MODULES=1 +export USE_ZEND_ALLOC=0 +# Detect whether valgrind is executable +if ! [ -x "$(command -v valgrind)" ]; then + echo 'Error: valgrind is not installed and is not executable' >&2 + exit 1 +fi +valgrind --error-exitcode=10 --leak-check=yes php $extension_dir -d max_execution_time=300 \ + ../tests/MemoryLeakTest/MemoryLeakTest.php diff --git a/src/php/tests/MemoryLeakTest/MemoryLeakTest.php b/src/php/tests/MemoryLeakTest/MemoryLeakTest.php new file mode 100644 index 00000000000..6b5fcb1ec78 --- /dev/null +++ b/src/php/tests/MemoryLeakTest/MemoryLeakTest.php @@ -0,0 +1,2310 @@ + "v1"]; +} + +function assertConnecting($state) +{ + assert(($state == GRPC\CHANNEL_CONNECTING || $state == GRPC\CHANNEL_TRANSIENT_FAILURE) == true); +} + +function waitUntilNotIdle($channel) { + for ($i = 0; $i < 10; $i++) { + $now = Grpc\Timeval::now(); + $deadline = $now->add(new Grpc\Timeval(10000)); + if ($channel->watchConnectivityState(GRPC\CHANNEL_IDLE, + $deadline)) { + return true; + } + } + assert(true == false); +} + +// Set up +$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + +// Test InsecureCredentials +assert('Grpc\Channel' == get_class($channel)); + +// Test ConnectivityState +$state = $channel->getConnectivityState(); +assert(0 == $state); + +// Test GetConnectivityStateWithInt +$state = $channel->getConnectivityState(123); +assert(0 == $state); + +// Test GetConnectivityStateWithString +$state = $channel->getConnectivityState('hello'); +assert(0 == $state); + +// Test GetConnectivityStateWithBool +$state = $channel->getConnectivityState(true); +assert(0 == $state); + +$channel->close(); + +// Test GetTarget +$channel = new Grpc\Channel('localhost:8888', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); +$target = $channel->getTarget(); +assert(is_string($target) == true); +$channel->close(); + +// Test WatchConnectivityState +$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); +$now = Grpc\Timeval::now(); +$deadline = $now->add(new Grpc\Timeval(100*1000)); + +$state = $channel->watchConnectivityState(1, $deadline); +assert($state == true); + +unset($now); +unset($deadline); + +$channel->close(); + +// Test InvalidConstructorWithNull +try { + $channel = new Grpc\Channel(); + assert($channel == NULL); +} +catch (\Exception $e) { +} + +// Test InvalidConstructorWith +try { + $channel = new Grpc\Channel('localhost:0', 'invalid'); + assert($channel == NULL); +} +catch (\Exception $e) { +} + +// Test InvalideCredentials +try { + $channel = new Grpc\Channel('localhost:0', ['credentials' => new Grpc\Timeval(100)]); +} +catch (\Exception $e) { +} + +// Test InvalidOptionsArrray +try { + $channel = new Grpc\Channel('localhost:0', ['abc' => []]); +} +catch (\Exception $e) { +} + +// Test InvalidGetConnectivityStateWithArray +$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); +try { + $channel->getConnectivityState([]); +} +catch (\Exception $e) { +} + +// Test InvalidWatchConnectivityState +try { + $channel->watchConnectivityState([]); +} +catch (\Exception $e) { +} + +// Test InvalidWatchConnectivityState2 +try { + $channel->watchConnectivityState(1, 'hi'); +} +catch (\Exception $e) { +} + +$channel->close(); + +// Test PersistentChannelSameHost +$channel1 = new Grpc\Channel('localhost:1', []); +$channel2 = new Grpc\Channel('localhost:1', []); +$state = $channel1->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelDifferentHost +$channel1 = new Grpc\Channel('localhost:1', ["grpc_target_persist_bound" => 3,]); +$channel2 = new Grpc\Channel('localhost:2', []); +$state = $channel1->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelSameArgs +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 3, + "abc" => "def", + ]); +$channel2 = new Grpc\Channel('localhost:1', ["abc" => "def"]); +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelDifferentArgs +$channel1 = new Grpc\Channel('localhost:1', []); +$channel2 = new Grpc\Channel('localhost:1', ["abc" => "def"]); +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelSameChannelCredentials +$creds1 = Grpc\ChannelCredentials::createSsl(); +$creds2 = Grpc\ChannelCredentials::createSsl(); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => $creds1, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => $creds2]); + +$state = $channel1->getConnectivityState(true); +print "state: ".$state."......................"; +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelDifferentChannelCredentials +$creds1 = Grpc\ChannelCredentials::createSsl(); +$creds2 = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => $creds1, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => $creds2]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + + +// Test PersistentChannelSameChannelCredentialsRootCerts +$creds1 = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); +$creds2 = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => $creds1, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => $creds2]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelDifferentSecureChannelCredentials +$creds1 = Grpc\ChannelCredentials::createSsl(); +$creds2 = Grpc\ChannelCredentials::createInsecure(); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => $creds1, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => $creds2]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelSharedChannelClose1 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 3, +]); +$channel2 = new Grpc\Channel('localhost:1', []); + +$channel1->close(); + +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$channel2->close(); + +// Test PersistentChannelSharedChannelClose2 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 3, +]); +$channel2 = new Grpc\Channel('localhost:1', []); + +$channel1->close(); + +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +try{ + $state = $channel1->getConnectivityState(); +} +catch(\Exception $e){ +} + +$channel2->close(); + +//Test PersistentChannelCreateAfterClose +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 3, +]); + +$channel1->close(); + +$channel2 = new Grpc\Channel('localhost:1', []); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel2->close(); + +//Test PersistentChannelSharedMoreThanTwo +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 3, +]); +$channel2 = new Grpc\Channel('localhost:1', []); +$channel3 = new Grpc\Channel('localhost:1', []); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); +$state = $channel3->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); + +//Test PersistentChannelWithCallCredentials +$creds = Grpc\ChannelCredentials::createSsl(); +$callCreds = Grpc\CallCredentials::createFromPlugin( + 'callbackFunc'); +$credsWithCallCreds = Grpc\ChannelCredentials::createComposite( + $creds, $callCreds); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => + $credsWithCallCreds, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => + $credsWithCallCreds]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelWithDifferentCallCredentials +$callCreds1 = Grpc\CallCredentials::createFromPlugin('callbackFunc'); +$callCreds2 = Grpc\CallCredentials::createFromPlugin('callbackFunc2'); + +$creds1 = Grpc\ChannelCredentials::createSsl(); +$creds2 = Grpc\ChannelCredentials::createComposite( + $creds1, $callCreds1); +$creds3 = Grpc\ChannelCredentials::createComposite( + $creds1, $callCreds2); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => $creds1, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => $creds2]); +$channel3 = new Grpc\Channel('localhost:1', + ["credentials" => $creds3]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$state = $channel3->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); +$channel3->close(); + +// Test PersistentChannelForceNew +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', + ["force_new" => true]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelForceNewOldChannelIdle1 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', + ["force_new" => true]); +$channel3 = new Grpc\Channel('localhost:1', []); + +$state = $channel2->getConnectivityState(true); +waitUntilNotIdle($channel2); +$state = $channel1->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); +$state = $channel3->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelForceNewOldChannelIdle2 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', []); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel2); +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelForceNewOldChannelClose1 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', + ["force_new" => true]); +$channel3 = new Grpc\Channel('localhost:1', []); + +$channel1->close(); + +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$state = $channel3->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel2->close(); +$channel3->close(); + +// Test PersistentChannelForceNewOldChannelClose2 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', + ["force_new" => true]); +// channel3 shares with channel1 +$channel3 = new Grpc\Channel('localhost:1', []); + +$channel1->close(); + +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +// channel3 is still usable +$state = $channel3->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +// channel 1 is closed +try{ + $channel1->getConnectivityState(); +} +catch(\Exception $e){ +} + +$channel2->close(); +$channel3->close(); + +// Test PersistentChannelForceNewNewChannelClose +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', + ["force_new" => true]); +$channel3 = new Grpc\Channel('localhost:1', []); + +$channel2->close(); + +$state = $channel1->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +// can still connect on channel1 +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); + +//============== Call Test ==================== +$server = new Grpc\Server([]); +$port = $server->addHttp2Port('0.0.0.0:53000'); +$channel = new Grpc\Channel('localhost:'.$port, []); +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); + +// Test AddEmptyMetadata +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => [], +]; +$result = $call->startBatch($batch); +assert($result->send_metadata == true); + +// Test testAddSingleMetadata +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value']], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +$result = $call->startBatch($batch); +assert($result->send_metadata == true); + +// Test AddMultiValue +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value1', 'value2']], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +$result = $call->startBatch($batch); +assert($result->send_metadata == true); + +// Test AddSingleAndMultiValueMetadata +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], + 'key2' => ['value2', + 'value3', ], ], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +$result = $call->startBatch($batch); +assert($result->send_metadata == true); + +// Test AddMultiAndMultiValueMetadata +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], + 'key2' => ['value2', + 'value3', ], ], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +$result = $call->startBatch($batch); +assert($result->send_metadata == true); + +// Test GetPeer +assert(is_string($call->getPeer()) == true); + +// Test Cancel +assert($call->cancel == NULL); + +// Test InvalidStartBatchKey +$batch = [ + 'invalid' => ['key1' => 'value1'], +]; +try{ + $result = $call->startBatch($batch); +} +catch(\Exception $e){ +} + +// Test InvalideMetadataStrKey +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['Key' => ['value1', 'value2']], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +try{ + $result = $call->startBatch($batch); +} +catch(\Exception $e){ +} + +// Test InvalidMetadataIntKey +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => [1 => ['value1', 'value2']], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +try{ + $result = $call->startBatch($batch); +} +catch(\Exception $e){ +} + +// Test InvalidMetadataInnerValue +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key1' => 'value1'], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +try{ + $result = $call->startBatch($batch); +} +catch(\Exception $e){ +} + +// Test InvalidConstuctor +try { + $call = new Grpc\Call(); +} catch (\Exception $e) {} + +// Test InvalidConstuctor2 +try { + $call = new Grpc\Call('hi', 'hi', 'hi'); +} catch (\Exception $e) {} + +// Test InvalidSetCredentials +try{ + $call->setCredentials('hi'); +} +catch(\Exception $e){ +} + +// Test InvalidSetCredentials2 +try { + $call->setCredentials([]); +} catch (\Exception $e) {} + + +//============== CallCredentials Test 2 ==================== +// Set Up +$credentials = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); +$server_credentials = Grpc\ServerCredentials::createSsl( + null, + file_get_contents(dirname(__FILE__).'/../data/server1.key'), + file_get_contents(dirname(__FILE__).'/../data/server1.pem')); +$server = new Grpc\Server(); +$port = $server->addSecureHttp2Port('0.0.0.0:0', + $server_credentials); +$server->start(); +$host_override = 'foo.test.google.fr'; +$channel = new Grpc\Channel( + 'localhost:'.$port, + [ + 'grpc.ssl_target_name_override' => $host_override, + 'grpc.default_authority' => $host_override, + 'credentials' => $credentials, + ] +); +function callCredscallbackFunc($context) +{ + is_string($context->service_url); + is_string($context->method_name); + return ['k1' => ['v1'], 'k2' => ['v2']]; +} + +// Test CreateFromPlugin +$deadline = Grpc\Timeval::infFuture(); +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + '/abc/dummy_method', + $deadline, + $host_override); + $call_credentials = Grpc\CallCredentials::createFromPlugin( + 'callCredscallbackFunc'); +$call->setCredentials($call_credentials); + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); + +$event = $server->requestCall(); +assert(is_array($event->metadata) == true); + +$metadata = $event->metadata; +assert(array_key_exists('k1', $metadata) == true); +assert(array_key_exists('k2', $metadata) == true); +assert($metadata['k1'] == ['v1']); +assert($metadata['k2'] == ['v2']); +assert('/abc/dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert($event->send_metadata == true); +assert($event->send_status == true); +assert($event->cancelled == false); + +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert([] == $event->metadata); + +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +function invalidKeyCallbackFunc($context) +{ + is_string($context->service_url); + is_string($context->method_name); + return ['K1' => ['v1']]; +} + +// Test CallbackWithInvalidKey +$deadline = Grpc\Timeval::infFuture(); +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + '/abc/dummy_method', + $deadline, + $host_override); + $call_credentials = Grpc\CallCredentials::createFromPlugin( + 'invalidKeyCallbackFunc'); +$call->setCredentials($call_credentials); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); +assert(($event->status->code == Grpc\STATUS_UNAVAILABLE) == true); + +function invalidReturnCallbackFunc($context) +{ + is_string($context->service_url); + is_string($context->method_name); + return 'a string'; +} + +// Test CallbackWithInvalidReturnValue +$deadline = Grpc\Timeval::infFuture(); +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + '/abc/dummy_method', + $deadline, + $host_override); + $call_credentials = Grpc\CallCredentials::createFromPlugin( + 'invalidReturnCallbackFunc'); +$call->setCredentials($call_credentials); + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); + +assert($event->send_metadata == true); +assert($event->send_close == true); +assert(($event->status->code == Grpc\STATUS_UNAVAILABLE) == true); + +unset($channel); +unset($server); + +//============== CallCredentials Test ==================== +//Set Up +$credentials = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); +$call_credentials = Grpc\CallCredentials::createFromPlugin('callbackFunc'); +$credentials = Grpc\ChannelCredentials::createComposite( + $credentials, + $call_credentials +); +$server_credentials = Grpc\ServerCredentials::createSsl( + null, + file_get_contents(dirname(__FILE__).'/../data/server1.key'), + file_get_contents(dirname(__FILE__).'/../data/server1.pem')); +$server = new Grpc\Server(); +$port = $server->addSecureHttp2Port('0.0.0.0:0', + $server_credentials); +$server->start(); +$host_override = 'foo.test.google.fr'; +$channel = new Grpc\Channel( + 'localhost:'.$port, + [ + 'grpc.ssl_target_name_override' => $host_override, + 'grpc.default_authority' => $host_override, + 'credentials' => $credentials, + ] +); + +// Test CreateComposite +$call_credentials2 = Grpc\CallCredentials::createFromPlugin('callbackFunc'); +$call_credentials3 = Grpc\CallCredentials::createComposite( + $call_credentials, + $call_credentials2 +); +assert('Grpc\CallCredentials' == get_class($call_credentials3)); + +// Test CreateFromPluginInvalidParam +try{ + $call_credentials = Grpc\CallCredentials::createFromPlugin( + 'callbackFunc' + ); +} +catch(\Exception $e){} + +// Test CreateCompositeInvalidParam +try{ + $call_credentials3 = Grpc\CallCredentials::createComposite( + $call_credentials, + $credentials + ); +} +catch(\Exception $e){} + +unset($channel); +unset($server); + + +//============== EndToEnd Test ==================== +// Set Up +$server = new Grpc\Server([]); +$port = $server->addHttp2Port('0.0.0.0:0'); +$channel = new Grpc\Channel('localhost:'.$port, []); +$server->start(); + +// Test SimpleRequestBody +$deadline = Grpc\Timeval::infFuture(); +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert($event->send_metadata == true); +assert($event->send_status == true); +assert($event->cancelled == false) +; + $event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +// Test MessageWriteFlags +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'message_write_flags_test'; +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $req_text, + 'flags' => Grpc\WRITE_NO_COMPRESS, ], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], +]); +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +$status = $event->status; + +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +// Test ClientServerFullRequestResponse +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +assert($event->send_metadata == true); +assert($event->send_close == true); +assert($event->send_message == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); +$server_call = $event->call; + +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert($event->send_metadata == true); +assert($event->send_status == true); +assert($event->send_message == true); +assert($event->cancelled == false); +assert($req_text == $event->message); + +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert([] == $event->metadata); +assert($reply_text == $event->message); +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +// Test InvalidClientMessageArray +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +try { + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => 'invalid', + ]); +} catch (\Exception $e) {} + +// Test InvalidClientMessageString +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +try{ + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => 0], + ]); +} catch (\Exception $e) {} + +// Test InvalidClientMessageFlags +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +try{ + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => 'abc', + 'flags' => 'invalid', + ], + ]); +} catch (\Exception $e) {} + +// Test InvalidServerStatusMetadata +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +assert($event->send_metadata == true); +assert($event->send_close == true); +assert($event->send_message == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); +$server_call = $event->call; +try { + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => 'invalid', + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); +} catch (\Exception $e) {} + +// Test InvalidServerStatusCode +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +assert($event->send_metadata == true); +assert($event->send_close == true); +assert($event->send_message == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); +$server_call = $event->call; +try { + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => 'invalid', + 'details' => $status_text, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); +} catch (\Exception $e) {} + +// Test MissingServerStatusCode +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +$event = $server->requestCall(); +$server_call = $event->call; +try { + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'details' => $status_text, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); +} catch (\Exception $e) {} + +// Test InvalidServerStatusDetails +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +$event = $server->requestCall(); +$server_call = $event->call; +try { + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => 0, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); +} catch (\Exception $e) {} + +// Test MissingServerStatusDetails +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +$event = $server->requestCall(); +$server_call = $event->call; +try { + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); +} catch (\Exception $e) {} + +// Test InvalidStartBatchKey +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +try { + $event = $call->startBatch([ + 9999999 => [], + ]); +} catch (\Exception $e) {} + +// Test InvalidStartBatch +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +try { + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => 'abc', + ], + ]); +} catch (\Exception $e) {} + +// Test GetTarget +assert(is_string($channel->getTarget()) == true); + +// Test GetConnectivityState +assert(($channel->getConnectivityState() == + Grpc\CHANNEL_IDLE) == true); + +// Test WatchConnectivityStateFailed +$idle_state = $channel->getConnectivityState(); +assert(($idle_state == Grpc\CHANNEL_IDLE) == true); + +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(50000); // should timeout +$deadline = $now->add($delta); +assert($channel->watchConnectivityState( + $idle_state, $deadline) == false); + +// Test WatchConnectivityStateSuccess() +$idle_state = $channel->getConnectivityState(true); +assert(($idle_state == Grpc\CHANNEL_IDLE) == true); + +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(3000000); // should finish well before +$deadline = $now->add($delta); +$new_state = $channel->getConnectivityState(); +assert($new_state != $idle_state); + +// Test WatchConnectivityStateDoNothing +$idle_state = $channel->getConnectivityState(); +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(50000); +$deadline = $now->add($delta); +assert(!$channel->watchConnectivityState( + $idle_state, $deadline)); + +$new_state = $channel->getConnectivityState(); +assert($new_state == Grpc\CHANNEL_IDLE); + +// Test GetConnectivityStateInvalidParam +try { + $channel->getConnectivityState(new Grpc\Timeval()); +} catch (\Exception $e) {} +// Test WatchConnectivityStateInvalidParam +try { + $channel->watchConnectivityState(0, 1000); +} catch (\Exception $e) {} +// Test ChannelConstructorInvalidParam +try { + $channel = new Grpc\Channel('localhost:'.$port, null); +} catch (\Exception $e) {} +// testClose() +$channel->close(); + + +//============== SecureEndToEnd Test ==================== +// Set Up + +$credentials = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); +$server_credentials = Grpc\ServerCredentials::createSsl( + null, + file_get_contents(dirname(__FILE__).'/../data/server1.key'), + file_get_contents(dirname(__FILE__).'/../data/server1.pem')); +$server = new Grpc\Server(); +$port = $server->addSecureHttp2Port('0.0.0.0:0', + $server_credentials); +$server->start(); +$host_override = 'foo.test.google.fr'; +$channel = new Grpc\Channel( + 'localhost:'.$port, + [ + 'grpc.ssl_target_name_override' => $host_override, + 'grpc.default_authority' => $host_override, + 'credentials' => $credentials, + ] +); + +// Test SimpleRequestBody +$deadline = Grpc\Timeval::infFuture(); +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline, + $host_override); + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert($event->send_metadata == true); +assert($event->send_status == true); +assert($event->cancelled == false); + +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert([] == $event->metadata); +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +// Test MessageWriteFlags +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'message_write_flags_test'; +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline, + $host_override); + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $req_text, + 'flags' => Grpc\WRITE_NO_COMPRESS, ], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], +]); +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert([] == $event->metadata); +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details);unset($call); + +unset($call); +unset($server_call); + +// Test ClientServerFullRequestResponse +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline, + $host_override); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +assert($event->send_metadata == true); +assert($event->send_close == true); +assert($event->send_message == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert($event->send_metadata); +assert($event->send_status); +assert($event->send_message); +assert(!$event->cancelled); +assert($req_text == $event->message); + +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert([] == $event->metadata); +assert($reply_text == $event->message); +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +$channel->close(); + + +//============== Timeval Test ==================== +// Test ConstructorWithInt +$time = new Grpc\Timeval(1234); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test ConstructorWithNegative +$time = new Grpc\Timeval(-123); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test ConstructorWithZero +$time = new Grpc\Timeval(0); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test ConstructorWithOct +$time = new Grpc\Timeval(0123); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test ConstructorWithHex +$time = new Grpc\Timeval(0x1A); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test ConstructorWithFloat +$time = new Grpc\Timeval(123.456); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test CompareSame +$zero = Grpc\Timeval::zero(); +assert(0 == Grpc\Timeval::compare($zero, $zero)); + +// Test PastIsLessThanZero +$zero = Grpc\Timeval::zero(); +$past = Grpc\Timeval::infPast(); +assert(0 > Grpc\Timeval::compare($past, $zero)); +assert(0 < Grpc\Timeval::compare($zero, $past)); + +// Test FutureIsGreaterThanZero +$zero = Grpc\Timeval::zero(); +$future = Grpc\Timeval::infFuture(); +assert(0 > Grpc\Timeval::compare($zero, $future)); +assert(0 < Grpc\Timeval::compare($future, $zero)); + +// Test NowIsBetweenZeroAndFuture +$zero = Grpc\Timeval::zero(); +$future = Grpc\Timeval::infFuture(); +$now = Grpc\Timeval::now(); +assert(0 > Grpc\Timeval::compare($zero, $now)); +assert(0 > Grpc\Timeval::compare($now, $future)); + +// Test NowAndAdd +$now = Grpc\Timeval::now(); +assert($now != NULL); +$delta = new Grpc\Timeval(1000); +$deadline = $now->add($delta); +assert(0 < Grpc\Timeval::compare($deadline, $now)); + +// Test NowAndSubtract +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(1000); +$deadline = $now->subtract($delta); +assert(0 > Grpc\Timeval::compare($deadline, $now)); + +// Test AddAndSubtract +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(1000); +$deadline = $now->add($delta); +$back_to_now = $deadline->subtract($delta); +assert(0 == Grpc\Timeval::compare($back_to_now, $now)); + +// Test Similar +$a = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(1000); +$b = $a->add($delta); +$thresh = new Grpc\Timeval(1100); +assert(Grpc\Timeval::similar($a, $b, $thresh)); +$thresh = new Grpc\Timeval(900); +assert(!Grpc\Timeval::similar($a, $b, $thresh)); + +// Test SleepUntil +$curr_microtime = microtime(true); +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(1000); +$deadline = $now->add($delta); +$deadline->sleepUntil(); +$done_microtime = microtime(true); +assert(($done_microtime - $curr_microtime) > 0.0009); + +// Test ConstructorInvalidParam +try { + $delta = new Grpc\Timeval('abc'); +} catch (\Exception $e) {} +// Test AddInvalidParam +$a = Grpc\Timeval::now(); +try { + $a->add(1000); +} catch (\Exception $e) {} +// Test SubtractInvalidParam +$a = Grpc\Timeval::now(); +try { + $a->subtract(1000); +} catch (\Exception $e) {} +// Test CompareInvalidParam +try { + $a = Grpc\Timeval::compare(1000, 1100); +} catch (\Exception $e) {} +// Test SimilarInvalidParam +try { + $a = Grpc\Timeval::similar(1000, 1100, 1200); +} catch (\Exception $e) {} + unset($time); + + //============== Server Test ==================== + //Set Up + $server = NULL; + + // Test ConstructorWithNull +$server = new Grpc\Server(); +assert($server != NULL); + +// Test ConstructorWithNullArray +$server = new Grpc\Server([]); +assert($server != NULL); + +// Test ConstructorWithArray +$server = new Grpc\Server(['ip' => '127.0.0.1', + 'port' => '8080', ]); +assert($server != NULL); + +// Test RequestCall +$server = new Grpc\Server(); +$port = $server->addHttp2Port('0.0.0.0:0'); +$server->start(); +$channel = new Grpc\Channel('localhost:'.$port, + [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure() + ]); + +$deadline = Grpc\Timeval::infFuture(); +$call = new Grpc\Call($channel, 'dummy_method', $deadline); + +$event = $call->startBatch([Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + ]); + +$c = $server->requestCall(); +assert('dummy_method' == $c->method); +assert(is_string($c->host)); + +unset($call); +unset($channel); + +// Test InvalidConstructorWithNumKeyOfArray +try{ + $server = new Grpc\Server([10 => '127.0.0.1', + 20 => '8080', ]); +} +catch(\Exception $e){} + +// Test Invalid ArgumentException +try{ + $server = new Grpc\Server(['127.0.0.1', '8080']); +} +catch(\Exception $e){} + +// Test InvalidAddHttp2Port +$server = new Grpc\Server([]); +try{ + $port = $server->addHttp2Port(['0.0.0.0:0']); +} +catch(\Exception $e){} + +// Test InvalidAddSecureHttp2Port +$server = new Grpc\Server([]); +try{ + $port = $server->addSecureHttp2Port(['0.0.0.0:0']); +} +catch(\Exception $e){} + +// Test InvalidAddSecureHttp2Port2 +$server = new Grpc\Server(); +try{ + $port = $server->addSecureHttp2Port('0.0.0.0:0'); +} +catch(\Exception $e){} + +// Test InvalidAddSecureHttp2Port3 +$server = new Grpc\Server(); +try{ + $port = $server->addSecureHttp2Port('0.0.0.0:0', 'invalid'); +} +catch(\Exception $e){} +unset($server); + + +//============== ChannelCredential Test ==================== +// Test CreateSslWith3Null +$channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, + null); +assert($channel_credentials != NULL); + +// Test CreateSslWith3NullString +$channel_credentials = Grpc\ChannelCredentials::createSsl('', '', ''); +assert($channel_credentials != NULL); + +// Test CreateInsecure +$channel_credentials = Grpc\ChannelCredentials::createInsecure(); +assert($channel_credentials == NULL); + +// Test InvalidCreateSsl() +try { + $channel_credentials = Grpc\ChannelCredentials::createSsl([]); +} +catch (\Exception $e) { +} +try { + $channel_credentials = Grpc\ChannelCredentials::createComposite( + 'something', 'something'); +} +catch (\Exception $e) { +} + +//============== Interceptor Test ==================== +require_once(dirname(__FILE__).'/../../lib/Grpc/BaseStub.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/AbstractCall.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/CallInvoker.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/DefaultCallInvoker.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php'); + +class SimpleRequest +{ + private $data; + public function __construct($data) + { + $this->data = $data; + } + public function setData($data) + { + $this->data = $data; + } + public function serializeToString() + { + return $this->data; + } +} + +class InterceptorClient extends Grpc\BaseStub +{ + + /** + * @param string $hostname hostname + * @param array $opts channel options + * @param Channel|InterceptorChannel $channel (optional) re-use channel object + */ + public function __construct($hostname, $opts, $channel = null) + { + parent::__construct($hostname, $opts, $channel); + } + + /** + * A simple RPC. + * @param SimpleRequest $argument input argument + * @param array $metadata metadata + * @param array $options call options + */ + public function UnaryCall( + SimpleRequest $argument, + $metadata = [], + $options = [] + ) { + return $this->_simpleRequest( + '/dummy_method', + $argument, + [], + $metadata, + $options + ); + } + + /** + * A client-to-server streaming RPC. + * @param array $metadata metadata + * @param array $options call options + */ + public function StreamCall( + $metadata = [], + $options = [] + ) { + return $this->_clientStreamRequest('/dummy_method', [], $metadata, $options); + } +} + +class ChangeMetadataInterceptor extends Grpc\Interceptor +{ + public function interceptUnaryUnary($method, + $argument, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) + { + $metadata["foo"] = array('interceptor_from_unary_request'); + return $continuation($method, $argument, $deserialize, $metadata, $options); + } + public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) + { + $metadata["foo"] = array('interceptor_from_stream_request'); + return $continuation($method, $deserialize, $metadata, $options); + } +} + +class ChangeMetadataInterceptor2 extends Grpc\Interceptor +{ + public function interceptUnaryUnary($method, + $argument, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) + { + if (array_key_exists('foo', $metadata)) { + $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first'); + } else { + $metadata["bar"] = array('interceptor_from_unary_request'); + } + return $continuation($method, $argument, $deserialize, $metadata, $options); + } + public function interceptStreamUnary($method, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) + { + if (array_key_exists('foo', $metadata)) { + $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first'); + } else { + $metadata["bar"] = array('interceptor_from_stream_request'); + } + return $continuation($method, $deserialize, $metadata, $options); + } +} + +class ChangeRequestCall +{ + private $call; + + public function __construct($call) + { + $this->call = $call; + } + public function getCall() + { + return $this->call; + } + + public function write($request) + { + $request->setData('intercepted_stream_request'); + $this->getCall()->write($request); + } + + public function wait() + { + return $this->getCall()->wait(); + } +} + +class ChangeRequestInterceptor extends Grpc\Interceptor +{ + public function interceptUnaryUnary($method, + $argument, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) + { + $argument->setData('intercepted_unary_request'); + return $continuation($method, $argument, $deserialize, $metadata, $options); + } + public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) + { + return new ChangeRequestCall( + $continuation($method, $deserialize, $metadata, $options) + ); + } +} + +class StopCallInterceptor extends Grpc\Interceptor +{ + public function interceptUnaryUnary($method, + $argument, + array $metadata = [], + array $options = [], + $continuation) + { + $metadata["foo"] = array('interceptor_from_request_response'); + } + public function interceptStreamUnary($method, + array $metadata = [], + array $options = [], + $continuation) + { + $metadata["foo"] = array('interceptor_from_request_response'); + } +} + +// Set Up +$server = new Grpc\Server([]); +$port = $server->addHttp2Port('0.0.0.0:0'); +$channel = new Grpc\Channel('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure()]); +$server->start(); + +// Test ClientChangeMetadataOneInterceptor +$req_text = 'client_request'; +$channel_matadata_interceptor = new ChangeMetadataInterceptor(); +$intercept_channel = Grpc\Interceptor::intercept($channel, $channel_matadata_interceptor); +$client = new InterceptorClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), +], $intercept_channel); +$req = new SimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_unary_request'] == $event->metadata['foo']); + +$stream_call = $client->StreamCall(); +$stream_call->write($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_stream_request'] == $event->metadata['foo']); + +unset($unary_call); +unset($stream_call); +unset($server_call); + +// Test ClientChangeMetadataTwoInterceptor +$req_text = 'client_request'; +$channel_matadata_interceptor = new ChangeMetadataInterceptor(); +$channel_matadata_intercepto2 = new ChangeMetadataInterceptor2(); +// test intercept separately. +$intercept_channel1 = Grpc\Interceptor::intercept($channel, $channel_matadata_interceptor); +$intercept_channel2 = Grpc\Interceptor::intercept($intercept_channel1, $channel_matadata_intercepto2); +$client = new InterceptorClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), +], $intercept_channel2); + +$req = new SimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_unary_request'] == $event->metadata['foo']); +assert(['interceptor_from_unary_request'] == $event->metadata['bar']); + +$stream_call = $client->StreamCall(); +$stream_call->write($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_stream_request'] == $event->metadata['foo']); +assert(['interceptor_from_stream_request'] == $event->metadata['bar']); + +unset($unary_call); +unset($stream_call); +unset($server_call); + +// test intercept by array. +$intercept_channel3 = Grpc\Interceptor::intercept($channel, + [$channel_matadata_intercepto2, $channel_matadata_interceptor]); +$client = new InterceptorClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), +], $intercept_channel3); + +$req = new SimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_unary_request'] == $event->metadata['foo']); +assert(['interceptor_from_unary_request'] == $event->metadata['bar']); + +$stream_call = $client->StreamCall(); +$stream_call->write($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_stream_request'] == $event->metadata['foo']); +assert(['interceptor_from_stream_request'] == $event->metadata['bar']); + +unset($unary_call); +unset($stream_call); +unset($server_call); + + +// Test ClientChangeRequestInterceptor +$req_text = 'client_request'; +$change_request_interceptor = new ChangeRequestInterceptor(); +$intercept_channel = Grpc\Interceptor::intercept($channel, + $change_request_interceptor); +$client = new InterceptorClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), +], $intercept_channel); + +$req = new SimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); + +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => '', + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert('intercepted_unary_request' == $event->message); + +$stream_call = $client->StreamCall(); +$stream_call->write($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => '', + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert('intercepted_stream_request' == $event->message); + +unset($unary_call); +unset($stream_call); +unset($server_call); + +// Test ClientChangeStopCallInterceptor +$req_text = 'client_request'; +$channel_request_interceptor = new StopCallInterceptor(); +$intercept_channel = Grpc\Interceptor::intercept($channel, + $channel_request_interceptor); +$client = new InterceptorClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), +], $intercept_channel); + +$req = new SimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); +assert($unary_call == NULL); + + +$stream_call = $client->StreamCall(); +assert($stream_call == NULL); + +unset($unary_call); +unset($stream_call); +unset($server_call); + +// Test GetInterceptorChannelConnectivityState +$channel = new Grpc\Channel( + 'localhost:0', + [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure() + ] +); +$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); +$state = $interceptor_channel->getConnectivityState(); +assert(0 == $state); +$channel->close(); + +// Test InterceptorChannelWatchConnectivityState +$channel = new Grpc\Channel( + 'localhost:0', + [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure() + ] +); +$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); +$now = Grpc\Timeval::now(); +$deadline = $now->add(new Grpc\Timeval(100*1000)); +$state = $interceptor_channel->watchConnectivityState(1, $deadline); +assert($state); +unset($time); +unset($deadline); +$channel->close(); + +// Test InterceptorChannelClose +$channel = new Grpc\Channel( + 'localhost:0', + [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure() + ] +); +$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); +assert($interceptor_channel != NULL); +$channel->close(); + +// Test InterceptorChannelGetTarget +$channel = new Grpc\Channel( + 'localhost:8888', + [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure() + ] +); +$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); +$target = $interceptor_channel->getTarget(); +assert(is_string($target)); + +$channel->close(); +unset($server); + + +//============== CallInvoker Test ==================== +class CallInvokerSimpleRequest +{ + private $data; + public function __construct($data) + { + $this->data = $data; + } + public function setData($data) + { + $this->data = $data; + } + public function serializeToString() + { + return $this->data; + } +} + +class CallInvokerClient extends Grpc\BaseStub +{ + + /** + * @param string $hostname hostname + * @param array $opts channel options + * @param Channel|InterceptorChannel $channel (optional) re-use channel object + */ + public function __construct($hostname, $opts, $channel = null) + { + parent::__construct($hostname, $opts, $channel); + } + + /** + * A simple RPC. + * @param SimpleRequest $argument input argument + * @param array $metadata metadata + * @param array $options call options + */ + public function UnaryCall( + CallInvokerSimpleRequest $argument, + $metadata = [], + $options = [] + ) { + return $this->_simpleRequest( + '/dummy_method', + $argument, + [], + $metadata, + $options + ); + } +} + +class CallInvokerUpdateChannel implements \Grpc\CallInvoker +{ + private $channel; + + public function getChannel() { + return $this->channel; + } + + public function createChannelFactory($hostname, $opts) { + $this->channel = new \Grpc\Channel('localhost:50050', $opts); + return $this->channel; + } + + public function UnaryCall($channel, $method, $deserialize, $options) { + return new UnaryCall($channel, $method, $deserialize, $options); + } + + public function ClientStreamingCall($channel, $method, $deserialize, $options) { + return new ClientStreamingCall($channel, $method, $deserialize, $options); + } + + public function ServerStreamingCall($channel, $method, $deserialize, $options) { + return new ServerStreamingCall($channel, $method, $deserialize, $options); + } + + public function BidiStreamingCall($channel, $method, $deserialize, $options) { + return new BidiStreamingCall($channel, $method, $deserialize, $options); + } +} + +class CallInvokerChangeRequest implements \Grpc\CallInvoker +{ + private $channel; + + public function getChannel() { + return $this->channel; + } + public function createChannelFactory($hostname, $opts) { + $this->channel = new \Grpc\Channel($hostname, $opts); + return $this->channel; + } + + public function UnaryCall($channel, $method, $deserialize, $options) { + return new CallInvokerChangeRequestCall($channel, $method, $deserialize, $options); + } + + public function ClientStreamingCall($channel, $method, $deserialize, $options) { + return new ClientStreamingCall($channel, $method, $deserialize, $options); + } + + public function ServerStreamingCall($channel, $method, $deserialize, $options) { + return new ServerStreamingCall($channel, $method, $deserialize, $options); + } + + public function BidiStreamingCall($channel, $method, $deserialize, $options) { + return new BidiStreamingCall($channel, $method, $deserialize, $options); + } +} + +class CallInvokerChangeRequestCall +{ + private $call; + + public function __construct($channel, $method, $deserialize, $options) + { + $this->call = new \Grpc\UnaryCall($channel, $method, $deserialize, $options); + } + + public function start($argument, $metadata, $options) { + $argument->setData('intercepted_unary_request'); + $this->call->start($argument, $metadata, $options); + } + + public function wait() + { + return $this->call->wait(); + } +} + +// Set Up +$server = new Grpc\Server([]); +$port = $server->addHttp2Port('0.0.0.0:0'); +$server->start(); + +// Test CreateDefaultCallInvoker +$call_invoker = new \Grpc\DefaultCallInvoker(); + +// Test CreateCallInvoker +$call_invoker = new CallInvokerUpdateChannel(); + +// Test CallInvokerAccessChannel +$call_invoker = new CallInvokerUpdateChannel(); +$stub = new \Grpc\BaseStub('localhost:50051', + ['credentials' => \Grpc\ChannelCredentials::createInsecure(), + 'grpc_call_invoker' => $call_invoker]); +assert($call_invoker->getChannel()->getTarget() == 'localhost:50050'); +$call_invoker->getChannel()->close(); + +// Test ClientChangeRequestCallInvoker +$req_text = 'client_request'; +$call_invoker = new CallInvokerChangeRequest(); +$client = new CallInvokerClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), + 'grpc_call_invoker' => $call_invoker, +]); + +$req = new CallInvokerSimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); + +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => '', + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert('intercepted_unary_request' == $event->message); +$call_invoker->getChannel()->close(); +unset($unary_call); +unset($server_call); + +unset($server); + +<<<<<<< HEAD +<<<<<<< HEAD +echo "Went Through All Unit Tests..............\r\n"; +======= +echo "Went Through All Unit Tests.............."; +>>>>>>> add MemoryLeakTest +======= +echo "Went Through All Unit Tests..............\r\n"; +>>>>>>> complete memory leak test + + diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php index be1d77fe7ad..20c35299cb0 100644 --- a/src/php/tests/unit_tests/CallTest.php +++ b/src/php/tests/unit_tests/CallTest.php @@ -86,6 +86,26 @@ class CallTest extends PHPUnit_Framework_TestCase $this->assertTrue($result->send_metadata); } + public function testAddMultiAndMultiValueMetadata() + { + $batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1', 'value2'], + 'key2' => ['value3', 'value4'],], + ]; + $result = $this->call->startBatch($batch); + $this->assertTrue($result->send_metadata); + } + + public function testAddMultiAndMultiValueMetadata() + { + $batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1', 'value2'], + 'key2' => ['value3', 'value4'],], + ]; + $result = $this->call->startBatch($batch); + $this->assertTrue($result->send_metadata); + } + public function testGetPeer() { $this->assertTrue(is_string($this->call->getPeer())); From 189313d1ddf1358fc23e3924a2cf4785916a61b8 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Thu, 17 Jan 2019 01:31:11 +0000 Subject: [PATCH 092/814] Get the ruby interop client buildable for 1.18.0 back compatiblity matrix --- tools/interop_matrix/client_matrix.py | 4 ++++ .../interop_matrix/patches/ruby_v1.18.0/git_repo.patch | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 tools/interop_matrix/patches/ruby_v1.18.0/git_repo.patch diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index cd542b0f4c5..9b533867836 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -201,6 +201,10 @@ LANG_RELEASE_MATRIX = { ('v1.15.0', ReleaseInfo()), ('v1.16.0', ReleaseInfo()), ('v1.17.1', ReleaseInfo()), + ('v1.18.0', + ReleaseInfo(patch=[ + 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', + ])), ]), 'php': OrderedDict([ diff --git a/tools/interop_matrix/patches/ruby_v1.18.0/git_repo.patch b/tools/interop_matrix/patches/ruby_v1.18.0/git_repo.patch new file mode 100644 index 00000000000..dfa3cfc031a --- /dev/null +++ b/tools/interop_matrix/patches/ruby_v1.18.0/git_repo.patch @@ -0,0 +1,10 @@ +diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh +index 67f66090ae..e71ad91499 100755 +--- a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh ++++ b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh +@@ -30,4 +30,4 @@ cd /var/local/git/grpc + rvm --default use ruby-2.5 + + # build Ruby interop client and server +-(cd src/ruby && gem update bundler && bundle && rake compile) ++(cd src/ruby && gem install bundler -v 1.17.3 && bundle && rake compile) From 8609f42e152796249762e5a8768e8e16d586fe2b Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 17 Jan 2019 15:16:37 -0800 Subject: [PATCH 093/814] Stop copying LICENSE files --- src/python/grpcio_channelz/LICENSE | 1 + .../grpcio_channelz/channelz_commands.py | 3 -- src/python/grpcio_health_checking/LICENSE | 1 + .../grpcio_health_checking/health_commands.py | 3 -- src/python/grpcio_reflection/LICENSE | 1 + .../grpcio_reflection/reflection_commands.py | 3 -- src/python/grpcio_status/LICENSE | 1 + src/python/grpcio_status/setup.py | 19 +++------ src/python/grpcio_status/status_commands.py | 39 ------------------- src/python/grpcio_testing/LICENSE | 1 + src/python/grpcio_testing/setup.py | 16 ++------ src/python/grpcio_testing/testing_commands.py | 39 ------------------- 12 files changed, 14 insertions(+), 113 deletions(-) create mode 120000 src/python/grpcio_channelz/LICENSE create mode 120000 src/python/grpcio_health_checking/LICENSE create mode 120000 src/python/grpcio_reflection/LICENSE create mode 120000 src/python/grpcio_status/LICENSE delete mode 100644 src/python/grpcio_status/status_commands.py create mode 120000 src/python/grpcio_testing/LICENSE delete mode 100644 src/python/grpcio_testing/testing_commands.py diff --git a/src/python/grpcio_channelz/LICENSE b/src/python/grpcio_channelz/LICENSE new file mode 120000 index 00000000000..5853aaea53b --- /dev/null +++ b/src/python/grpcio_channelz/LICENSE @@ -0,0 +1 @@ +../../../LICENSE \ No newline at end of file diff --git a/src/python/grpcio_channelz/channelz_commands.py b/src/python/grpcio_channelz/channelz_commands.py index 7f158c2a4bf..0137959e9d4 100644 --- a/src/python/grpcio_channelz/channelz_commands.py +++ b/src/python/grpcio_channelz/channelz_commands.py @@ -21,7 +21,6 @@ import setuptools ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) CHANNELZ_PROTO = os.path.join(ROOT_DIR, '../../proto/grpc/channelz/channelz.proto') -LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') class Preprocess(setuptools.Command): @@ -42,8 +41,6 @@ class Preprocess(setuptools.Command): shutil.copyfile(CHANNELZ_PROTO, os.path.join(ROOT_DIR, 'grpc_channelz/v1/channelz.proto')) - if os.path.isfile(LICENSE): - shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) class BuildPackageProtos(setuptools.Command): diff --git a/src/python/grpcio_health_checking/LICENSE b/src/python/grpcio_health_checking/LICENSE new file mode 120000 index 00000000000..5853aaea53b --- /dev/null +++ b/src/python/grpcio_health_checking/LICENSE @@ -0,0 +1 @@ +../../../LICENSE \ No newline at end of file diff --git a/src/python/grpcio_health_checking/health_commands.py b/src/python/grpcio_health_checking/health_commands.py index 3820ef0bbad..d1bf03f7a9c 100644 --- a/src/python/grpcio_health_checking/health_commands.py +++ b/src/python/grpcio_health_checking/health_commands.py @@ -20,7 +20,6 @@ import setuptools ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) HEALTH_PROTO = os.path.join(ROOT_DIR, '../../proto/grpc/health/v1/health.proto') -LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') class Preprocess(setuptools.Command): @@ -41,8 +40,6 @@ class Preprocess(setuptools.Command): shutil.copyfile(HEALTH_PROTO, os.path.join(ROOT_DIR, 'grpc_health/v1/health.proto')) - if os.path.isfile(LICENSE): - shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) class BuildPackageProtos(setuptools.Command): diff --git a/src/python/grpcio_reflection/LICENSE b/src/python/grpcio_reflection/LICENSE new file mode 120000 index 00000000000..5853aaea53b --- /dev/null +++ b/src/python/grpcio_reflection/LICENSE @@ -0,0 +1 @@ +../../../LICENSE \ No newline at end of file diff --git a/src/python/grpcio_reflection/reflection_commands.py b/src/python/grpcio_reflection/reflection_commands.py index 311ca4c4dba..ac235576ae0 100644 --- a/src/python/grpcio_reflection/reflection_commands.py +++ b/src/python/grpcio_reflection/reflection_commands.py @@ -21,7 +21,6 @@ import setuptools ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) REFLECTION_PROTO = os.path.join( ROOT_DIR, '../../proto/grpc/reflection/v1alpha/reflection.proto') -LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') class Preprocess(setuptools.Command): @@ -43,8 +42,6 @@ class Preprocess(setuptools.Command): REFLECTION_PROTO, os.path.join(ROOT_DIR, 'grpc_reflection/v1alpha/reflection.proto')) - if os.path.isfile(LICENSE): - shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) class BuildPackageProtos(setuptools.Command): diff --git a/src/python/grpcio_status/LICENSE b/src/python/grpcio_status/LICENSE new file mode 120000 index 00000000000..5853aaea53b --- /dev/null +++ b/src/python/grpcio_status/LICENSE @@ -0,0 +1 @@ +../../../LICENSE \ No newline at end of file diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py index 983d3ea430b..2a39af721d9 100644 --- a/src/python/grpcio_status/setup.py +++ b/src/python/grpcio_status/setup.py @@ -63,20 +63,11 @@ INSTALL_REQUIRES = ( 'googleapis-common-protos>=1.5.5', ) -try: - import status_commands as _status_commands - # we are in the build environment, otherwise the above import fails - COMMAND_CLASS = { - # Run preprocess from the repository *before* doing any packaging! - 'preprocess': _status_commands.Preprocess, - 'build_package_protos': _NoOpCommand, - } -except ImportError: - COMMAND_CLASS = { - # wire up commands to no-op not to break the external dependencies - 'preprocess': _NoOpCommand, - 'build_package_protos': _NoOpCommand, - } +COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + 'build_package_protos': _NoOpCommand, +} setuptools.setup( name='grpcio-status', diff --git a/src/python/grpcio_status/status_commands.py b/src/python/grpcio_status/status_commands.py deleted file mode 100644 index 78cd497f622..00000000000 --- a/src/python/grpcio_status/status_commands.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2018 The gRPC Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Provides distutils command classes for the GRPC Python setup process.""" - -import os -import shutil - -import setuptools - -ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) -LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') - - -class Preprocess(setuptools.Command): - """Command to copy LICENSE from root directory.""" - - description = '' - user_options = [] - - def initialize_options(self): - pass - - def finalize_options(self): - pass - - def run(self): - if os.path.isfile(LICENSE): - shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) diff --git a/src/python/grpcio_testing/LICENSE b/src/python/grpcio_testing/LICENSE new file mode 120000 index 00000000000..5853aaea53b --- /dev/null +++ b/src/python/grpcio_testing/LICENSE @@ -0,0 +1 @@ +../../../LICENSE \ No newline at end of file diff --git a/src/python/grpcio_testing/setup.py b/src/python/grpcio_testing/setup.py index 18db71e0f09..b0df0915347 100644 --- a/src/python/grpcio_testing/setup.py +++ b/src/python/grpcio_testing/setup.py @@ -50,18 +50,10 @@ INSTALL_REQUIRES = ( 'grpcio>={version}'.format(version=grpc_version.VERSION), ) -try: - import testing_commands as _testing_commands - # we are in the build environment, otherwise the above import fails - COMMAND_CLASS = { - # Run preprocess from the repository *before* doing any packaging! - 'preprocess': _testing_commands.Preprocess, - } -except ImportError: - COMMAND_CLASS = { - # wire up commands to no-op not to break the external dependencies - 'preprocess': _NoOpCommand, - } +COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, +} setuptools.setup( name='grpcio-testing', diff --git a/src/python/grpcio_testing/testing_commands.py b/src/python/grpcio_testing/testing_commands.py deleted file mode 100644 index fb40d37efb6..00000000000 --- a/src/python/grpcio_testing/testing_commands.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2018 gRPC Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Provides distutils command classes for the GRPC Python setup process.""" - -import os -import shutil - -import setuptools - -ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) -LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') - - -class Preprocess(setuptools.Command): - """Command to copy LICENSE from root directory.""" - - description = '' - user_options = [] - - def initialize_options(self): - pass - - def finalize_options(self): - pass - - def run(self): - if os.path.isfile(LICENSE): - shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) From 3bd12ee2a8ec39cc186bd11abb7f0afa23633072 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Thu, 17 Jan 2019 16:15:44 -0700 Subject: [PATCH 094/814] grpc: init compression_algorithm_ in ClientContext ctor `compression_algorithm_` could be a random value because not initialized in ctor. --- src/cpp/client/client_context.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index c9ea3e5f83b..efb59c71a8c 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -57,6 +57,7 @@ ClientContext::ClientContext() deadline_(gpr_inf_future(GPR_CLOCK_REALTIME)), census_context_(nullptr), propagate_from_call_(nullptr), + compression_algorithm_(GRPC_COMPRESS_NONE), initial_metadata_corked_(false) { g_client_callbacks->DefaultConstructor(this); } From 22fb5ce2fbd4d69d9952d82954139e29f1fad7bd Mon Sep 17 00:00:00 2001 From: Maxim Bunkov Date: Fri, 18 Jan 2019 05:24:00 +0500 Subject: [PATCH 095/814] Change back to script --- .../BoringSSL-GRPC.podspec.template | 2975 +---------------- 1 file changed, 2 insertions(+), 2973 deletions(-) diff --git a/templates/src/objective-c/BoringSSL-GRPC.podspec.template b/templates/src/objective-c/BoringSSL-GRPC.podspec.template index 8b2a23ae0c5..6804f75f1b0 100644 --- a/templates/src/objective-c/BoringSSL-GRPC.podspec.template +++ b/templates/src/objective-c/BoringSSL-GRPC.podspec.template @@ -1560,2976 +1560,5 @@ # symbols are src/objective-c/grpc_shadow_boringssl_symbol_list. # This is the last part of this file. s.prefix_header_contents = - '#define BIO_f_ssl GRPC_SHADOW_BIO_f_ssl', - '#define BIO_set_ssl GRPC_SHADOW_BIO_set_ssl', - '#define SSL_CTX_add_client_custom_ext GRPC_SHADOW_SSL_CTX_add_client_custom_ext', - '#define SSL_CTX_add_server_custom_ext GRPC_SHADOW_SSL_CTX_add_server_custom_ext', - '#define DTLSv1_get_timeout GRPC_SHADOW_DTLSv1_get_timeout', - '#define DTLSv1_handle_timeout GRPC_SHADOW_DTLSv1_handle_timeout', - '#define DTLSv1_set_initial_timeout_duration GRPC_SHADOW_DTLSv1_set_initial_timeout_duration', - '#define SSL_CTX_set_srtp_profiles GRPC_SHADOW_SSL_CTX_set_srtp_profiles', - '#define SSL_CTX_set_tlsext_use_srtp GRPC_SHADOW_SSL_CTX_set_tlsext_use_srtp', - '#define SSL_get_selected_srtp_profile GRPC_SHADOW_SSL_get_selected_srtp_profile', - '#define SSL_get_srtp_profiles GRPC_SHADOW_SSL_get_srtp_profiles', - '#define SSL_set_srtp_profiles GRPC_SHADOW_SSL_set_srtp_profiles', - '#define SSL_set_tlsext_use_srtp GRPC_SHADOW_SSL_set_tlsext_use_srtp', - '#define DTLS_client_method GRPC_SHADOW_DTLS_client_method', - '#define DTLS_method GRPC_SHADOW_DTLS_method', - '#define DTLS_server_method GRPC_SHADOW_DTLS_server_method', - '#define DTLS_with_buffers_method GRPC_SHADOW_DTLS_with_buffers_method', - '#define DTLSv1_2_client_method GRPC_SHADOW_DTLSv1_2_client_method', - '#define DTLSv1_2_method GRPC_SHADOW_DTLSv1_2_method', - '#define DTLSv1_2_server_method GRPC_SHADOW_DTLSv1_2_server_method', - '#define DTLSv1_client_method GRPC_SHADOW_DTLSv1_client_method', - '#define DTLSv1_method GRPC_SHADOW_DTLSv1_method', - '#define DTLSv1_server_method GRPC_SHADOW_DTLSv1_server_method', - '#define SSL_SESSION_from_bytes GRPC_SHADOW_SSL_SESSION_from_bytes', - '#define SSL_SESSION_to_bytes GRPC_SHADOW_SSL_SESSION_to_bytes', - '#define SSL_SESSION_to_bytes_for_ticket GRPC_SHADOW_SSL_SESSION_to_bytes_for_ticket', - '#define i2d_SSL_SESSION GRPC_SHADOW_i2d_SSL_SESSION', - '#define SSL_CTX_set0_client_CAs GRPC_SHADOW_SSL_CTX_set0_client_CAs', - '#define SSL_CTX_set_cert_cb GRPC_SHADOW_SSL_CTX_set_cert_cb', - '#define SSL_CTX_set_chain_and_key GRPC_SHADOW_SSL_CTX_set_chain_and_key', - '#define SSL_CTX_set_ocsp_response GRPC_SHADOW_SSL_CTX_set_ocsp_response', - '#define SSL_CTX_set_signed_cert_timestamp_list GRPC_SHADOW_SSL_CTX_set_signed_cert_timestamp_list', - '#define SSL_CTX_use_certificate_ASN1 GRPC_SHADOW_SSL_CTX_use_certificate_ASN1', - '#define SSL_get0_peer_certificates GRPC_SHADOW_SSL_get0_peer_certificates', - '#define SSL_get0_server_requested_CAs GRPC_SHADOW_SSL_get0_server_requested_CAs', - '#define SSL_set0_client_CAs GRPC_SHADOW_SSL_set0_client_CAs', - '#define SSL_set_cert_cb GRPC_SHADOW_SSL_set_cert_cb', - '#define SSL_set_chain_and_key GRPC_SHADOW_SSL_set_chain_and_key', - '#define SSL_set_ocsp_response GRPC_SHADOW_SSL_set_ocsp_response', - '#define SSL_set_signed_cert_timestamp_list GRPC_SHADOW_SSL_set_signed_cert_timestamp_list', - '#define SSL_use_certificate_ASN1 GRPC_SHADOW_SSL_use_certificate_ASN1', - '#define SSL_CIPHER_description GRPC_SHADOW_SSL_CIPHER_description', - '#define SSL_CIPHER_get_auth_nid GRPC_SHADOW_SSL_CIPHER_get_auth_nid', - '#define SSL_CIPHER_get_bits GRPC_SHADOW_SSL_CIPHER_get_bits', - '#define SSL_CIPHER_get_cipher_nid GRPC_SHADOW_SSL_CIPHER_get_cipher_nid', - '#define SSL_CIPHER_get_digest_nid GRPC_SHADOW_SSL_CIPHER_get_digest_nid', - '#define SSL_CIPHER_get_id GRPC_SHADOW_SSL_CIPHER_get_id', - '#define SSL_CIPHER_get_kx_name GRPC_SHADOW_SSL_CIPHER_get_kx_name', - '#define SSL_CIPHER_get_kx_nid GRPC_SHADOW_SSL_CIPHER_get_kx_nid', - '#define SSL_CIPHER_get_max_version GRPC_SHADOW_SSL_CIPHER_get_max_version', - '#define SSL_CIPHER_get_min_version GRPC_SHADOW_SSL_CIPHER_get_min_version', - '#define SSL_CIPHER_get_name GRPC_SHADOW_SSL_CIPHER_get_name', - '#define SSL_CIPHER_get_prf_nid GRPC_SHADOW_SSL_CIPHER_get_prf_nid', - '#define SSL_CIPHER_get_rfc_name GRPC_SHADOW_SSL_CIPHER_get_rfc_name', - '#define SSL_CIPHER_get_version GRPC_SHADOW_SSL_CIPHER_get_version', - '#define SSL_CIPHER_is_aead GRPC_SHADOW_SSL_CIPHER_is_aead', - '#define SSL_CIPHER_is_block_cipher GRPC_SHADOW_SSL_CIPHER_is_block_cipher', - '#define SSL_CIPHER_standard_name GRPC_SHADOW_SSL_CIPHER_standard_name', - '#define SSL_COMP_add_compression_method GRPC_SHADOW_SSL_COMP_add_compression_method', - '#define SSL_COMP_free_compression_methods GRPC_SHADOW_SSL_COMP_free_compression_methods', - '#define SSL_COMP_get0_name GRPC_SHADOW_SSL_COMP_get0_name', - '#define SSL_COMP_get_compression_methods GRPC_SHADOW_SSL_COMP_get_compression_methods', - '#define SSL_COMP_get_id GRPC_SHADOW_SSL_COMP_get_id', - '#define SSL_COMP_get_name GRPC_SHADOW_SSL_COMP_get_name', - '#define SSL_get_cipher_by_value GRPC_SHADOW_SSL_get_cipher_by_value', - '#define SSL_CTX_get_default_passwd_cb GRPC_SHADOW_SSL_CTX_get_default_passwd_cb', - '#define SSL_CTX_get_default_passwd_cb_userdata GRPC_SHADOW_SSL_CTX_get_default_passwd_cb_userdata', - '#define SSL_CTX_set_default_passwd_cb GRPC_SHADOW_SSL_CTX_set_default_passwd_cb', - '#define SSL_CTX_set_default_passwd_cb_userdata GRPC_SHADOW_SSL_CTX_set_default_passwd_cb_userdata', - '#define SSL_CTX_use_PrivateKey_file GRPC_SHADOW_SSL_CTX_use_PrivateKey_file', - '#define SSL_CTX_use_RSAPrivateKey_file GRPC_SHADOW_SSL_CTX_use_RSAPrivateKey_file', - '#define SSL_CTX_use_certificate_chain_file GRPC_SHADOW_SSL_CTX_use_certificate_chain_file', - '#define SSL_CTX_use_certificate_file GRPC_SHADOW_SSL_CTX_use_certificate_file', - '#define SSL_add_file_cert_subjects_to_stack GRPC_SHADOW_SSL_add_file_cert_subjects_to_stack', - '#define SSL_load_client_CA_file GRPC_SHADOW_SSL_load_client_CA_file', - '#define SSL_use_PrivateKey_file GRPC_SHADOW_SSL_use_PrivateKey_file', - '#define SSL_use_RSAPrivateKey_file GRPC_SHADOW_SSL_use_RSAPrivateKey_file', - '#define SSL_use_certificate_file GRPC_SHADOW_SSL_use_certificate_file', - '#define SSL_get_curve_name GRPC_SHADOW_SSL_get_curve_name', - '#define ERR_load_SSL_strings GRPC_SHADOW_ERR_load_SSL_strings', - '#define OPENSSL_init_ssl GRPC_SHADOW_OPENSSL_init_ssl', - '#define SSL_CTX_check_private_key GRPC_SHADOW_SSL_CTX_check_private_key', - '#define SSL_CTX_cipher_in_group GRPC_SHADOW_SSL_CTX_cipher_in_group', - '#define SSL_CTX_clear_mode GRPC_SHADOW_SSL_CTX_clear_mode', - '#define SSL_CTX_clear_options GRPC_SHADOW_SSL_CTX_clear_options', - '#define SSL_CTX_enable_ocsp_stapling GRPC_SHADOW_SSL_CTX_enable_ocsp_stapling', - '#define SSL_CTX_enable_signed_cert_timestamps GRPC_SHADOW_SSL_CTX_enable_signed_cert_timestamps', - '#define SSL_CTX_enable_tls_channel_id GRPC_SHADOW_SSL_CTX_enable_tls_channel_id', - '#define SSL_CTX_free GRPC_SHADOW_SSL_CTX_free', - '#define SSL_CTX_get0_privatekey GRPC_SHADOW_SSL_CTX_get0_privatekey', - '#define SSL_CTX_get_ciphers GRPC_SHADOW_SSL_CTX_get_ciphers', - '#define SSL_CTX_get_ex_data GRPC_SHADOW_SSL_CTX_get_ex_data', - '#define SSL_CTX_get_ex_new_index GRPC_SHADOW_SSL_CTX_get_ex_new_index', - '#define SSL_CTX_get_keylog_callback GRPC_SHADOW_SSL_CTX_get_keylog_callback', - '#define SSL_CTX_get_max_cert_list GRPC_SHADOW_SSL_CTX_get_max_cert_list', - '#define SSL_CTX_get_mode GRPC_SHADOW_SSL_CTX_get_mode', - '#define SSL_CTX_get_options GRPC_SHADOW_SSL_CTX_get_options', - '#define SSL_CTX_get_quiet_shutdown GRPC_SHADOW_SSL_CTX_get_quiet_shutdown', - '#define SSL_CTX_get_read_ahead GRPC_SHADOW_SSL_CTX_get_read_ahead', - '#define SSL_CTX_get_session_cache_mode GRPC_SHADOW_SSL_CTX_get_session_cache_mode', - '#define SSL_CTX_get_tlsext_ticket_keys GRPC_SHADOW_SSL_CTX_get_tlsext_ticket_keys', - '#define SSL_CTX_need_tmp_RSA GRPC_SHADOW_SSL_CTX_need_tmp_RSA', - '#define SSL_CTX_new GRPC_SHADOW_SSL_CTX_new', - '#define SSL_CTX_sess_accept GRPC_SHADOW_SSL_CTX_sess_accept', - '#define SSL_CTX_sess_accept_good GRPC_SHADOW_SSL_CTX_sess_accept_good', - '#define SSL_CTX_sess_accept_renegotiate GRPC_SHADOW_SSL_CTX_sess_accept_renegotiate', - '#define SSL_CTX_sess_cache_full GRPC_SHADOW_SSL_CTX_sess_cache_full', - '#define SSL_CTX_sess_cb_hits GRPC_SHADOW_SSL_CTX_sess_cb_hits', - '#define SSL_CTX_sess_connect GRPC_SHADOW_SSL_CTX_sess_connect', - '#define SSL_CTX_sess_connect_good GRPC_SHADOW_SSL_CTX_sess_connect_good', - '#define SSL_CTX_sess_connect_renegotiate GRPC_SHADOW_SSL_CTX_sess_connect_renegotiate', - '#define SSL_CTX_sess_get_cache_size GRPC_SHADOW_SSL_CTX_sess_get_cache_size', - '#define SSL_CTX_sess_hits GRPC_SHADOW_SSL_CTX_sess_hits', - '#define SSL_CTX_sess_misses GRPC_SHADOW_SSL_CTX_sess_misses', - '#define SSL_CTX_sess_number GRPC_SHADOW_SSL_CTX_sess_number', - '#define SSL_CTX_sess_set_cache_size GRPC_SHADOW_SSL_CTX_sess_set_cache_size', - '#define SSL_CTX_sess_timeouts GRPC_SHADOW_SSL_CTX_sess_timeouts', - '#define SSL_CTX_set0_buffer_pool GRPC_SHADOW_SSL_CTX_set0_buffer_pool', - '#define SSL_CTX_set1_curves GRPC_SHADOW_SSL_CTX_set1_curves', - '#define SSL_CTX_set1_curves_list GRPC_SHADOW_SSL_CTX_set1_curves_list', - '#define SSL_CTX_set1_tls_channel_id GRPC_SHADOW_SSL_CTX_set1_tls_channel_id', - '#define SSL_CTX_set_allow_unknown_alpn_protos GRPC_SHADOW_SSL_CTX_set_allow_unknown_alpn_protos', - '#define SSL_CTX_set_alpn_protos GRPC_SHADOW_SSL_CTX_set_alpn_protos', - '#define SSL_CTX_set_alpn_select_cb GRPC_SHADOW_SSL_CTX_set_alpn_select_cb', - '#define SSL_CTX_set_cipher_list GRPC_SHADOW_SSL_CTX_set_cipher_list', - '#define SSL_CTX_set_current_time_cb GRPC_SHADOW_SSL_CTX_set_current_time_cb', - '#define SSL_CTX_set_custom_verify GRPC_SHADOW_SSL_CTX_set_custom_verify', - '#define SSL_CTX_set_dos_protection_cb GRPC_SHADOW_SSL_CTX_set_dos_protection_cb', - '#define SSL_CTX_set_early_data_enabled GRPC_SHADOW_SSL_CTX_set_early_data_enabled', - '#define SSL_CTX_set_ex_data GRPC_SHADOW_SSL_CTX_set_ex_data', - '#define SSL_CTX_set_false_start_allowed_without_alpn GRPC_SHADOW_SSL_CTX_set_false_start_allowed_without_alpn', - '#define SSL_CTX_set_grease_enabled GRPC_SHADOW_SSL_CTX_set_grease_enabled', - '#define SSL_CTX_set_keylog_callback GRPC_SHADOW_SSL_CTX_set_keylog_callback', - '#define SSL_CTX_set_max_cert_list GRPC_SHADOW_SSL_CTX_set_max_cert_list', - '#define SSL_CTX_set_max_send_fragment GRPC_SHADOW_SSL_CTX_set_max_send_fragment', - '#define SSL_CTX_set_mode GRPC_SHADOW_SSL_CTX_set_mode', - '#define SSL_CTX_set_msg_callback GRPC_SHADOW_SSL_CTX_set_msg_callback', - '#define SSL_CTX_set_msg_callback_arg GRPC_SHADOW_SSL_CTX_set_msg_callback_arg', - '#define SSL_CTX_set_next_proto_select_cb GRPC_SHADOW_SSL_CTX_set_next_proto_select_cb', - '#define SSL_CTX_set_next_protos_advertised_cb GRPC_SHADOW_SSL_CTX_set_next_protos_advertised_cb', - '#define SSL_CTX_set_options GRPC_SHADOW_SSL_CTX_set_options', - '#define SSL_CTX_set_psk_client_callback GRPC_SHADOW_SSL_CTX_set_psk_client_callback', - '#define SSL_CTX_set_psk_server_callback GRPC_SHADOW_SSL_CTX_set_psk_server_callback', - '#define SSL_CTX_set_quiet_shutdown GRPC_SHADOW_SSL_CTX_set_quiet_shutdown', - '#define SSL_CTX_set_read_ahead GRPC_SHADOW_SSL_CTX_set_read_ahead', - '#define SSL_CTX_set_retain_only_sha256_of_client_certs GRPC_SHADOW_SSL_CTX_set_retain_only_sha256_of_client_certs', - '#define SSL_CTX_set_select_certificate_cb GRPC_SHADOW_SSL_CTX_set_select_certificate_cb', - '#define SSL_CTX_set_session_cache_mode GRPC_SHADOW_SSL_CTX_set_session_cache_mode', - '#define SSL_CTX_set_session_id_context GRPC_SHADOW_SSL_CTX_set_session_id_context', - '#define SSL_CTX_set_strict_cipher_list GRPC_SHADOW_SSL_CTX_set_strict_cipher_list', - '#define SSL_CTX_set_ticket_aead_method GRPC_SHADOW_SSL_CTX_set_ticket_aead_method', - '#define SSL_CTX_set_tls13_variant GRPC_SHADOW_SSL_CTX_set_tls13_variant', - '#define SSL_CTX_set_tls_channel_id_enabled GRPC_SHADOW_SSL_CTX_set_tls_channel_id_enabled', - '#define SSL_CTX_set_tlsext_servername_arg GRPC_SHADOW_SSL_CTX_set_tlsext_servername_arg', - '#define SSL_CTX_set_tlsext_servername_callback GRPC_SHADOW_SSL_CTX_set_tlsext_servername_callback', - '#define SSL_CTX_set_tlsext_ticket_key_cb GRPC_SHADOW_SSL_CTX_set_tlsext_ticket_key_cb', - '#define SSL_CTX_set_tlsext_ticket_keys GRPC_SHADOW_SSL_CTX_set_tlsext_ticket_keys', - '#define SSL_CTX_set_tmp_dh GRPC_SHADOW_SSL_CTX_set_tmp_dh', - '#define SSL_CTX_set_tmp_dh_callback GRPC_SHADOW_SSL_CTX_set_tmp_dh_callback', - '#define SSL_CTX_set_tmp_ecdh GRPC_SHADOW_SSL_CTX_set_tmp_ecdh', - '#define SSL_CTX_set_tmp_rsa GRPC_SHADOW_SSL_CTX_set_tmp_rsa', - '#define SSL_CTX_set_tmp_rsa_callback GRPC_SHADOW_SSL_CTX_set_tmp_rsa_callback', - '#define SSL_CTX_up_ref GRPC_SHADOW_SSL_CTX_up_ref', - '#define SSL_CTX_use_psk_identity_hint GRPC_SHADOW_SSL_CTX_use_psk_identity_hint', - '#define SSL_accept GRPC_SHADOW_SSL_accept', - '#define SSL_cache_hit GRPC_SHADOW_SSL_cache_hit', - '#define SSL_certs_clear GRPC_SHADOW_SSL_certs_clear', - '#define SSL_check_private_key GRPC_SHADOW_SSL_check_private_key', - '#define SSL_clear GRPC_SHADOW_SSL_clear', - '#define SSL_clear_mode GRPC_SHADOW_SSL_clear_mode', - '#define SSL_clear_options GRPC_SHADOW_SSL_clear_options', - '#define SSL_connect GRPC_SHADOW_SSL_connect', - '#define SSL_cutthrough_complete GRPC_SHADOW_SSL_cutthrough_complete', - '#define SSL_do_handshake GRPC_SHADOW_SSL_do_handshake', - '#define SSL_dummy_pq_padding_used GRPC_SHADOW_SSL_dummy_pq_padding_used', - '#define SSL_early_data_accepted GRPC_SHADOW_SSL_early_data_accepted', - '#define SSL_enable_ocsp_stapling GRPC_SHADOW_SSL_enable_ocsp_stapling', - '#define SSL_enable_signed_cert_timestamps GRPC_SHADOW_SSL_enable_signed_cert_timestamps', - '#define SSL_enable_tls_channel_id GRPC_SHADOW_SSL_enable_tls_channel_id', - '#define SSL_free GRPC_SHADOW_SSL_free', - '#define SSL_get0_alpn_selected GRPC_SHADOW_SSL_get0_alpn_selected', - '#define SSL_get0_certificate_types GRPC_SHADOW_SSL_get0_certificate_types', - '#define SSL_get0_next_proto_negotiated GRPC_SHADOW_SSL_get0_next_proto_negotiated', - '#define SSL_get0_ocsp_response GRPC_SHADOW_SSL_get0_ocsp_response', - '#define SSL_get0_session_id_context GRPC_SHADOW_SSL_get0_session_id_context', - '#define SSL_get0_signed_cert_timestamp_list GRPC_SHADOW_SSL_get0_signed_cert_timestamp_list', - '#define SSL_get_SSL_CTX GRPC_SHADOW_SSL_get_SSL_CTX', - '#define SSL_get_cipher_list GRPC_SHADOW_SSL_get_cipher_list', - '#define SSL_get_ciphers GRPC_SHADOW_SSL_get_ciphers', - '#define SSL_get_client_random GRPC_SHADOW_SSL_get_client_random', - '#define SSL_get_current_cipher GRPC_SHADOW_SSL_get_current_cipher', - '#define SSL_get_current_compression GRPC_SHADOW_SSL_get_current_compression', - '#define SSL_get_current_expansion GRPC_SHADOW_SSL_get_current_expansion', - '#define SSL_get_curve_id GRPC_SHADOW_SSL_get_curve_id', - '#define SSL_get_default_timeout GRPC_SHADOW_SSL_get_default_timeout', - '#define SSL_get_error GRPC_SHADOW_SSL_get_error', - '#define SSL_get_ex_data GRPC_SHADOW_SSL_get_ex_data', - '#define SSL_get_ex_new_index GRPC_SHADOW_SSL_get_ex_new_index', - '#define SSL_get_extms_support GRPC_SHADOW_SSL_get_extms_support', - '#define SSL_get_fd GRPC_SHADOW_SSL_get_fd', - '#define SSL_get_finished GRPC_SHADOW_SSL_get_finished', - '#define SSL_get_info_callback GRPC_SHADOW_SSL_get_info_callback', - '#define SSL_get_ivs GRPC_SHADOW_SSL_get_ivs', - '#define SSL_get_max_cert_list GRPC_SHADOW_SSL_get_max_cert_list', - '#define SSL_get_mode GRPC_SHADOW_SSL_get_mode', - '#define SSL_get_negotiated_token_binding_param GRPC_SHADOW_SSL_get_negotiated_token_binding_param', - '#define SSL_get_options GRPC_SHADOW_SSL_get_options', - '#define SSL_get_peer_finished GRPC_SHADOW_SSL_get_peer_finished', - '#define SSL_get_peer_quic_transport_params GRPC_SHADOW_SSL_get_peer_quic_transport_params', - '#define SSL_get_peer_signature_algorithm GRPC_SHADOW_SSL_get_peer_signature_algorithm', - '#define SSL_get_pending_cipher GRPC_SHADOW_SSL_get_pending_cipher', - '#define SSL_get_privatekey GRPC_SHADOW_SSL_get_privatekey', - '#define SSL_get_psk_identity GRPC_SHADOW_SSL_get_psk_identity', - '#define SSL_get_psk_identity_hint GRPC_SHADOW_SSL_get_psk_identity_hint', - '#define SSL_get_quiet_shutdown GRPC_SHADOW_SSL_get_quiet_shutdown', - '#define SSL_get_rbio GRPC_SHADOW_SSL_get_rbio', - '#define SSL_get_read_ahead GRPC_SHADOW_SSL_get_read_ahead', - '#define SSL_get_read_sequence GRPC_SHADOW_SSL_get_read_sequence', - '#define SSL_get_rfd GRPC_SHADOW_SSL_get_rfd', - '#define SSL_get_secure_renegotiation_support GRPC_SHADOW_SSL_get_secure_renegotiation_support', - '#define SSL_get_server_random GRPC_SHADOW_SSL_get_server_random', - '#define SSL_get_server_tmp_key GRPC_SHADOW_SSL_get_server_tmp_key', - '#define SSL_get_servername GRPC_SHADOW_SSL_get_servername', - '#define SSL_get_servername_type GRPC_SHADOW_SSL_get_servername_type', - '#define SSL_get_shared_ciphers GRPC_SHADOW_SSL_get_shared_ciphers', - '#define SSL_get_shutdown GRPC_SHADOW_SSL_get_shutdown', - '#define SSL_get_structure_sizes GRPC_SHADOW_SSL_get_structure_sizes', - '#define SSL_get_ticket_age_skew GRPC_SHADOW_SSL_get_ticket_age_skew', - '#define SSL_get_tls_channel_id GRPC_SHADOW_SSL_get_tls_channel_id', - '#define SSL_get_tls_unique GRPC_SHADOW_SSL_get_tls_unique', - '#define SSL_get_verify_mode GRPC_SHADOW_SSL_get_verify_mode', - '#define SSL_get_wbio GRPC_SHADOW_SSL_get_wbio', - '#define SSL_get_wfd GRPC_SHADOW_SSL_get_wfd', - '#define SSL_get_write_sequence GRPC_SHADOW_SSL_get_write_sequence', - '#define SSL_in_early_data GRPC_SHADOW_SSL_in_early_data', - '#define SSL_in_false_start GRPC_SHADOW_SSL_in_false_start', - '#define SSL_in_init GRPC_SHADOW_SSL_in_init', - '#define SSL_is_draft_downgrade GRPC_SHADOW_SSL_is_draft_downgrade', - '#define SSL_is_dtls GRPC_SHADOW_SSL_is_dtls', - '#define SSL_is_init_finished GRPC_SHADOW_SSL_is_init_finished', - '#define SSL_is_server GRPC_SHADOW_SSL_is_server', - '#define SSL_is_token_binding_negotiated GRPC_SHADOW_SSL_is_token_binding_negotiated', - '#define SSL_library_init GRPC_SHADOW_SSL_library_init', - '#define SSL_load_error_strings GRPC_SHADOW_SSL_load_error_strings', - '#define SSL_need_tmp_RSA GRPC_SHADOW_SSL_need_tmp_RSA', - '#define SSL_new GRPC_SHADOW_SSL_new', - '#define SSL_num_renegotiations GRPC_SHADOW_SSL_num_renegotiations', - '#define SSL_peek GRPC_SHADOW_SSL_peek', - '#define SSL_pending GRPC_SHADOW_SSL_pending', - '#define SSL_read GRPC_SHADOW_SSL_read', - '#define SSL_renegotiate GRPC_SHADOW_SSL_renegotiate', - '#define SSL_renegotiate_pending GRPC_SHADOW_SSL_renegotiate_pending', - '#define SSL_reset_early_data_reject GRPC_SHADOW_SSL_reset_early_data_reject', - '#define SSL_select_next_proto GRPC_SHADOW_SSL_select_next_proto', - '#define SSL_send_fatal_alert GRPC_SHADOW_SSL_send_fatal_alert', - '#define SSL_session_reused GRPC_SHADOW_SSL_session_reused', - '#define SSL_set0_rbio GRPC_SHADOW_SSL_set0_rbio', - '#define SSL_set0_wbio GRPC_SHADOW_SSL_set0_wbio', - '#define SSL_set1_curves GRPC_SHADOW_SSL_set1_curves', - '#define SSL_set1_curves_list GRPC_SHADOW_SSL_set1_curves_list', - '#define SSL_set1_tls_channel_id GRPC_SHADOW_SSL_set1_tls_channel_id', - '#define SSL_set_SSL_CTX GRPC_SHADOW_SSL_set_SSL_CTX', - '#define SSL_set_accept_state GRPC_SHADOW_SSL_set_accept_state', - '#define SSL_set_alpn_protos GRPC_SHADOW_SSL_set_alpn_protos', - '#define SSL_set_bio GRPC_SHADOW_SSL_set_bio', - '#define SSL_set_cipher_list GRPC_SHADOW_SSL_set_cipher_list', - '#define SSL_set_connect_state GRPC_SHADOW_SSL_set_connect_state', - '#define SSL_set_custom_verify GRPC_SHADOW_SSL_set_custom_verify', - '#define SSL_set_dummy_pq_padding_size GRPC_SHADOW_SSL_set_dummy_pq_padding_size', - '#define SSL_set_early_data_enabled GRPC_SHADOW_SSL_set_early_data_enabled', - '#define SSL_set_ex_data GRPC_SHADOW_SSL_set_ex_data', - '#define SSL_set_fd GRPC_SHADOW_SSL_set_fd', - '#define SSL_set_info_callback GRPC_SHADOW_SSL_set_info_callback', - '#define SSL_set_max_cert_list GRPC_SHADOW_SSL_set_max_cert_list', - '#define SSL_set_max_send_fragment GRPC_SHADOW_SSL_set_max_send_fragment', - '#define SSL_set_mode GRPC_SHADOW_SSL_set_mode', - '#define SSL_set_msg_callback GRPC_SHADOW_SSL_set_msg_callback', - '#define SSL_set_msg_callback_arg GRPC_SHADOW_SSL_set_msg_callback_arg', - '#define SSL_set_mtu GRPC_SHADOW_SSL_set_mtu', - '#define SSL_set_options GRPC_SHADOW_SSL_set_options', - '#define SSL_set_psk_client_callback GRPC_SHADOW_SSL_set_psk_client_callback', - '#define SSL_set_psk_server_callback GRPC_SHADOW_SSL_set_psk_server_callback', - '#define SSL_set_quic_transport_params GRPC_SHADOW_SSL_set_quic_transport_params', - '#define SSL_set_quiet_shutdown GRPC_SHADOW_SSL_set_quiet_shutdown', - '#define SSL_set_read_ahead GRPC_SHADOW_SSL_set_read_ahead', - '#define SSL_set_renegotiate_mode GRPC_SHADOW_SSL_set_renegotiate_mode', - '#define SSL_set_retain_only_sha256_of_client_certs GRPC_SHADOW_SSL_set_retain_only_sha256_of_client_certs', - '#define SSL_set_rfd GRPC_SHADOW_SSL_set_rfd', - '#define SSL_set_session_id_context GRPC_SHADOW_SSL_set_session_id_context', - '#define SSL_set_shutdown GRPC_SHADOW_SSL_set_shutdown', - '#define SSL_set_state GRPC_SHADOW_SSL_set_state', - '#define SSL_set_strict_cipher_list GRPC_SHADOW_SSL_set_strict_cipher_list', - '#define SSL_set_tls13_variant GRPC_SHADOW_SSL_set_tls13_variant', - '#define SSL_set_tls_channel_id_enabled GRPC_SHADOW_SSL_set_tls_channel_id_enabled', - '#define SSL_set_tlsext_host_name GRPC_SHADOW_SSL_set_tlsext_host_name', - '#define SSL_set_tmp_dh GRPC_SHADOW_SSL_set_tmp_dh', - '#define SSL_set_tmp_dh_callback GRPC_SHADOW_SSL_set_tmp_dh_callback', - '#define SSL_set_tmp_ecdh GRPC_SHADOW_SSL_set_tmp_ecdh', - '#define SSL_set_tmp_rsa GRPC_SHADOW_SSL_set_tmp_rsa', - '#define SSL_set_tmp_rsa_callback GRPC_SHADOW_SSL_set_tmp_rsa_callback', - '#define SSL_set_token_binding_params GRPC_SHADOW_SSL_set_token_binding_params', - '#define SSL_set_wfd GRPC_SHADOW_SSL_set_wfd', - '#define SSL_shutdown GRPC_SHADOW_SSL_shutdown', - '#define SSL_state GRPC_SHADOW_SSL_state', - '#define SSL_total_renegotiations GRPC_SHADOW_SSL_total_renegotiations', - '#define SSL_use_psk_identity_hint GRPC_SHADOW_SSL_use_psk_identity_hint', - '#define SSL_want GRPC_SHADOW_SSL_want', - '#define SSL_write GRPC_SHADOW_SSL_write', - '#define SSL_CTX_set_private_key_method GRPC_SHADOW_SSL_CTX_set_private_key_method', - '#define SSL_CTX_set_signing_algorithm_prefs GRPC_SHADOW_SSL_CTX_set_signing_algorithm_prefs', - '#define SSL_CTX_set_verify_algorithm_prefs GRPC_SHADOW_SSL_CTX_set_verify_algorithm_prefs', - '#define SSL_CTX_use_PrivateKey GRPC_SHADOW_SSL_CTX_use_PrivateKey', - '#define SSL_CTX_use_PrivateKey_ASN1 GRPC_SHADOW_SSL_CTX_use_PrivateKey_ASN1', - '#define SSL_CTX_use_RSAPrivateKey GRPC_SHADOW_SSL_CTX_use_RSAPrivateKey', - '#define SSL_CTX_use_RSAPrivateKey_ASN1 GRPC_SHADOW_SSL_CTX_use_RSAPrivateKey_ASN1', - '#define SSL_get_signature_algorithm_digest GRPC_SHADOW_SSL_get_signature_algorithm_digest', - '#define SSL_get_signature_algorithm_key_type GRPC_SHADOW_SSL_get_signature_algorithm_key_type', - '#define SSL_get_signature_algorithm_name GRPC_SHADOW_SSL_get_signature_algorithm_name', - '#define SSL_is_signature_algorithm_rsa_pss GRPC_SHADOW_SSL_is_signature_algorithm_rsa_pss', - '#define SSL_set_private_key_method GRPC_SHADOW_SSL_set_private_key_method', - '#define SSL_set_signing_algorithm_prefs GRPC_SHADOW_SSL_set_signing_algorithm_prefs', - '#define SSL_use_PrivateKey GRPC_SHADOW_SSL_use_PrivateKey', - '#define SSL_use_PrivateKey_ASN1 GRPC_SHADOW_SSL_use_PrivateKey_ASN1', - '#define SSL_use_RSAPrivateKey GRPC_SHADOW_SSL_use_RSAPrivateKey', - '#define SSL_use_RSAPrivateKey_ASN1 GRPC_SHADOW_SSL_use_RSAPrivateKey_ASN1', - '#define SSL_CTX_add_session GRPC_SHADOW_SSL_CTX_add_session', - '#define SSL_CTX_flush_sessions GRPC_SHADOW_SSL_CTX_flush_sessions', - '#define SSL_CTX_get_channel_id_cb GRPC_SHADOW_SSL_CTX_get_channel_id_cb', - '#define SSL_CTX_get_info_callback GRPC_SHADOW_SSL_CTX_get_info_callback', - '#define SSL_CTX_get_timeout GRPC_SHADOW_SSL_CTX_get_timeout', - '#define SSL_CTX_remove_session GRPC_SHADOW_SSL_CTX_remove_session', - '#define SSL_CTX_sess_get_get_cb GRPC_SHADOW_SSL_CTX_sess_get_get_cb', - '#define SSL_CTX_sess_get_new_cb GRPC_SHADOW_SSL_CTX_sess_get_new_cb', - '#define SSL_CTX_sess_get_remove_cb GRPC_SHADOW_SSL_CTX_sess_get_remove_cb', - '#define SSL_CTX_sess_set_get_cb GRPC_SHADOW_SSL_CTX_sess_set_get_cb', - '#define SSL_CTX_sess_set_new_cb GRPC_SHADOW_SSL_CTX_sess_set_new_cb', - '#define SSL_CTX_sess_set_remove_cb GRPC_SHADOW_SSL_CTX_sess_set_remove_cb', - '#define SSL_CTX_set_channel_id_cb GRPC_SHADOW_SSL_CTX_set_channel_id_cb', - '#define SSL_CTX_set_info_callback GRPC_SHADOW_SSL_CTX_set_info_callback', - '#define SSL_CTX_set_session_psk_dhe_timeout GRPC_SHADOW_SSL_CTX_set_session_psk_dhe_timeout', - '#define SSL_CTX_set_timeout GRPC_SHADOW_SSL_CTX_set_timeout', - '#define SSL_SESSION_free GRPC_SHADOW_SSL_SESSION_free', - '#define SSL_SESSION_get0_peer GRPC_SHADOW_SSL_SESSION_get0_peer', - '#define SSL_SESSION_get0_ticket GRPC_SHADOW_SSL_SESSION_get0_ticket', - '#define SSL_SESSION_get_ex_data GRPC_SHADOW_SSL_SESSION_get_ex_data', - '#define SSL_SESSION_get_ex_new_index GRPC_SHADOW_SSL_SESSION_get_ex_new_index', - '#define SSL_SESSION_get_id GRPC_SHADOW_SSL_SESSION_get_id', - '#define SSL_SESSION_get_master_key GRPC_SHADOW_SSL_SESSION_get_master_key', - '#define SSL_SESSION_get_ticket_lifetime_hint GRPC_SHADOW_SSL_SESSION_get_ticket_lifetime_hint', - '#define SSL_SESSION_get_time GRPC_SHADOW_SSL_SESSION_get_time', - '#define SSL_SESSION_get_timeout GRPC_SHADOW_SSL_SESSION_get_timeout', - '#define SSL_SESSION_has_ticket GRPC_SHADOW_SSL_SESSION_has_ticket', - '#define SSL_SESSION_is_resumable GRPC_SHADOW_SSL_SESSION_is_resumable', - '#define SSL_SESSION_new GRPC_SHADOW_SSL_SESSION_new', - '#define SSL_SESSION_set1_id_context GRPC_SHADOW_SSL_SESSION_set1_id_context', - '#define SSL_SESSION_set_ex_data GRPC_SHADOW_SSL_SESSION_set_ex_data', - '#define SSL_SESSION_set_time GRPC_SHADOW_SSL_SESSION_set_time', - '#define SSL_SESSION_set_timeout GRPC_SHADOW_SSL_SESSION_set_timeout', - '#define SSL_SESSION_should_be_single_use GRPC_SHADOW_SSL_SESSION_should_be_single_use', - '#define SSL_SESSION_up_ref GRPC_SHADOW_SSL_SESSION_up_ref', - '#define SSL_get1_session GRPC_SHADOW_SSL_get1_session', - '#define SSL_get_session GRPC_SHADOW_SSL_get_session', - '#define SSL_magic_pending_session_ptr GRPC_SHADOW_SSL_magic_pending_session_ptr', - '#define SSL_set_session GRPC_SHADOW_SSL_set_session', - '#define SSL_alert_desc_string GRPC_SHADOW_SSL_alert_desc_string', - '#define SSL_alert_desc_string_long GRPC_SHADOW_SSL_alert_desc_string_long', - '#define SSL_alert_type_string GRPC_SHADOW_SSL_alert_type_string', - '#define SSL_alert_type_string_long GRPC_SHADOW_SSL_alert_type_string_long', - '#define SSL_state_string GRPC_SHADOW_SSL_state_string', - '#define SSL_state_string_long GRPC_SHADOW_SSL_state_string_long', - '#define SSL_CTX_set_max_proto_version GRPC_SHADOW_SSL_CTX_set_max_proto_version', - '#define SSL_CTX_set_min_proto_version GRPC_SHADOW_SSL_CTX_set_min_proto_version', - '#define SSL_SESSION_get_protocol_version GRPC_SHADOW_SSL_SESSION_get_protocol_version', - '#define SSL_SESSION_get_version GRPC_SHADOW_SSL_SESSION_get_version', - '#define SSL_SESSION_set_protocol_version GRPC_SHADOW_SSL_SESSION_set_protocol_version', - '#define SSL_get_version GRPC_SHADOW_SSL_get_version', - '#define SSL_set_max_proto_version GRPC_SHADOW_SSL_set_max_proto_version', - '#define SSL_set_min_proto_version GRPC_SHADOW_SSL_set_min_proto_version', - '#define SSL_version GRPC_SHADOW_SSL_version', - '#define PEM_read_SSL_SESSION GRPC_SHADOW_PEM_read_SSL_SESSION', - '#define PEM_read_bio_SSL_SESSION GRPC_SHADOW_PEM_read_bio_SSL_SESSION', - '#define PEM_write_SSL_SESSION GRPC_SHADOW_PEM_write_SSL_SESSION', - '#define PEM_write_bio_SSL_SESSION GRPC_SHADOW_PEM_write_bio_SSL_SESSION', - '#define SSL_CTX_add0_chain_cert GRPC_SHADOW_SSL_CTX_add0_chain_cert', - '#define SSL_CTX_add1_chain_cert GRPC_SHADOW_SSL_CTX_add1_chain_cert', - '#define SSL_CTX_add_client_CA GRPC_SHADOW_SSL_CTX_add_client_CA', - '#define SSL_CTX_add_extra_chain_cert GRPC_SHADOW_SSL_CTX_add_extra_chain_cert', - '#define SSL_CTX_clear_chain_certs GRPC_SHADOW_SSL_CTX_clear_chain_certs', - '#define SSL_CTX_clear_extra_chain_certs GRPC_SHADOW_SSL_CTX_clear_extra_chain_certs', - '#define SSL_CTX_get0_certificate GRPC_SHADOW_SSL_CTX_get0_certificate', - '#define SSL_CTX_get0_chain_certs GRPC_SHADOW_SSL_CTX_get0_chain_certs', - '#define SSL_CTX_get0_param GRPC_SHADOW_SSL_CTX_get0_param', - '#define SSL_CTX_get_cert_store GRPC_SHADOW_SSL_CTX_get_cert_store', - '#define SSL_CTX_get_client_CA_list GRPC_SHADOW_SSL_CTX_get_client_CA_list', - '#define SSL_CTX_get_extra_chain_certs GRPC_SHADOW_SSL_CTX_get_extra_chain_certs', - '#define SSL_CTX_get_verify_callback GRPC_SHADOW_SSL_CTX_get_verify_callback', - '#define SSL_CTX_get_verify_depth GRPC_SHADOW_SSL_CTX_get_verify_depth', - '#define SSL_CTX_get_verify_mode GRPC_SHADOW_SSL_CTX_get_verify_mode', - '#define SSL_CTX_load_verify_locations GRPC_SHADOW_SSL_CTX_load_verify_locations', - '#define SSL_CTX_set0_chain GRPC_SHADOW_SSL_CTX_set0_chain', - '#define SSL_CTX_set0_verify_cert_store GRPC_SHADOW_SSL_CTX_set0_verify_cert_store', - '#define SSL_CTX_set1_chain GRPC_SHADOW_SSL_CTX_set1_chain', - '#define SSL_CTX_set1_param GRPC_SHADOW_SSL_CTX_set1_param', - '#define SSL_CTX_set1_verify_cert_store GRPC_SHADOW_SSL_CTX_set1_verify_cert_store', - '#define SSL_CTX_set_cert_store GRPC_SHADOW_SSL_CTX_set_cert_store', - '#define SSL_CTX_set_cert_verify_callback GRPC_SHADOW_SSL_CTX_set_cert_verify_callback', - '#define SSL_CTX_set_client_CA_list GRPC_SHADOW_SSL_CTX_set_client_CA_list', - '#define SSL_CTX_set_client_cert_cb GRPC_SHADOW_SSL_CTX_set_client_cert_cb', - '#define SSL_CTX_set_default_verify_paths GRPC_SHADOW_SSL_CTX_set_default_verify_paths', - '#define SSL_CTX_set_purpose GRPC_SHADOW_SSL_CTX_set_purpose', - '#define SSL_CTX_set_trust GRPC_SHADOW_SSL_CTX_set_trust', - '#define SSL_CTX_set_verify GRPC_SHADOW_SSL_CTX_set_verify', - '#define SSL_CTX_set_verify_depth GRPC_SHADOW_SSL_CTX_set_verify_depth', - '#define SSL_CTX_use_certificate GRPC_SHADOW_SSL_CTX_use_certificate', - '#define SSL_add0_chain_cert GRPC_SHADOW_SSL_add0_chain_cert', - '#define SSL_add1_chain_cert GRPC_SHADOW_SSL_add1_chain_cert', - '#define SSL_add_client_CA GRPC_SHADOW_SSL_add_client_CA', - '#define SSL_alert_from_verify_result GRPC_SHADOW_SSL_alert_from_verify_result', - '#define SSL_clear_chain_certs GRPC_SHADOW_SSL_clear_chain_certs', - '#define SSL_dup_CA_list GRPC_SHADOW_SSL_dup_CA_list', - '#define SSL_get0_chain_certs GRPC_SHADOW_SSL_get0_chain_certs', - '#define SSL_get0_param GRPC_SHADOW_SSL_get0_param', - '#define SSL_get_certificate GRPC_SHADOW_SSL_get_certificate', - '#define SSL_get_client_CA_list GRPC_SHADOW_SSL_get_client_CA_list', - '#define SSL_get_ex_data_X509_STORE_CTX_idx GRPC_SHADOW_SSL_get_ex_data_X509_STORE_CTX_idx', - '#define SSL_get_peer_cert_chain GRPC_SHADOW_SSL_get_peer_cert_chain', - '#define SSL_get_peer_certificate GRPC_SHADOW_SSL_get_peer_certificate', - '#define SSL_get_peer_full_cert_chain GRPC_SHADOW_SSL_get_peer_full_cert_chain', - '#define SSL_get_verify_callback GRPC_SHADOW_SSL_get_verify_callback', - '#define SSL_get_verify_depth GRPC_SHADOW_SSL_get_verify_depth', - '#define SSL_get_verify_result GRPC_SHADOW_SSL_get_verify_result', - '#define SSL_set0_chain GRPC_SHADOW_SSL_set0_chain', - '#define SSL_set0_verify_cert_store GRPC_SHADOW_SSL_set0_verify_cert_store', - '#define SSL_set1_chain GRPC_SHADOW_SSL_set1_chain', - '#define SSL_set1_param GRPC_SHADOW_SSL_set1_param', - '#define SSL_set1_verify_cert_store GRPC_SHADOW_SSL_set1_verify_cert_store', - '#define SSL_set_client_CA_list GRPC_SHADOW_SSL_set_client_CA_list', - '#define SSL_set_purpose GRPC_SHADOW_SSL_set_purpose', - '#define SSL_set_trust GRPC_SHADOW_SSL_set_trust', - '#define SSL_set_verify GRPC_SHADOW_SSL_set_verify', - '#define SSL_set_verify_depth GRPC_SHADOW_SSL_set_verify_depth', - '#define SSL_set_verify_result GRPC_SHADOW_SSL_set_verify_result', - '#define SSL_use_certificate GRPC_SHADOW_SSL_use_certificate', - '#define d2i_SSL_SESSION GRPC_SHADOW_d2i_SSL_SESSION', - '#define d2i_SSL_SESSION_bio GRPC_SHADOW_d2i_SSL_SESSION_bio', - '#define i2d_SSL_SESSION_bio GRPC_SHADOW_i2d_SSL_SESSION_bio', - '#define SSL_export_early_keying_material GRPC_SHADOW_SSL_export_early_keying_material', - '#define SSL_export_keying_material GRPC_SHADOW_SSL_export_keying_material', - '#define SSL_generate_key_block GRPC_SHADOW_SSL_generate_key_block', - '#define SSL_get_key_block_len GRPC_SHADOW_SSL_get_key_block_len', - '#define SSL_CTX_set_ed25519_enabled GRPC_SHADOW_SSL_CTX_set_ed25519_enabled', - '#define SSL_early_callback_ctx_extension_get GRPC_SHADOW_SSL_early_callback_ctx_extension_get', - '#define SSL_extension_supported GRPC_SHADOW_SSL_extension_supported', - '#define SSLv23_client_method GRPC_SHADOW_SSLv23_client_method', - '#define SSLv23_method GRPC_SHADOW_SSLv23_method', - '#define SSLv23_server_method GRPC_SHADOW_SSLv23_server_method', - '#define TLS_client_method GRPC_SHADOW_TLS_client_method', - '#define TLS_method GRPC_SHADOW_TLS_method', - '#define TLS_server_method GRPC_SHADOW_TLS_server_method', - '#define TLS_with_buffers_method GRPC_SHADOW_TLS_with_buffers_method', - '#define TLSv1_1_client_method GRPC_SHADOW_TLSv1_1_client_method', - '#define TLSv1_1_method GRPC_SHADOW_TLSv1_1_method', - '#define TLSv1_1_server_method GRPC_SHADOW_TLSv1_1_server_method', - '#define TLSv1_2_client_method GRPC_SHADOW_TLSv1_2_client_method', - '#define TLSv1_2_method GRPC_SHADOW_TLSv1_2_method', - '#define TLSv1_2_server_method GRPC_SHADOW_TLSv1_2_server_method', - '#define TLSv1_client_method GRPC_SHADOW_TLSv1_client_method', - '#define TLSv1_method GRPC_SHADOW_TLSv1_method', - '#define TLSv1_server_method GRPC_SHADOW_TLSv1_server_method', - '#define SSL_max_seal_overhead GRPC_SHADOW_SSL_max_seal_overhead', - '#define OPENSSL_cpuid_setup GRPC_SHADOW_OPENSSL_cpuid_setup', - '#define CRYPTO_has_asm GRPC_SHADOW_CRYPTO_has_asm', - '#define CRYPTO_is_confidential_build GRPC_SHADOW_CRYPTO_is_confidential_build', - '#define CRYPTO_library_init GRPC_SHADOW_CRYPTO_library_init', - '#define CRYPTO_malloc_init GRPC_SHADOW_CRYPTO_malloc_init', - '#define ENGINE_load_builtin_engines GRPC_SHADOW_ENGINE_load_builtin_engines', - '#define ENGINE_register_all_complete GRPC_SHADOW_ENGINE_register_all_complete', - '#define OPENSSL_ia32cap_P GRPC_SHADOW_OPENSSL_ia32cap_P', - '#define OPENSSL_init_crypto GRPC_SHADOW_OPENSSL_init_crypto', - '#define OPENSSL_load_builtin_modules GRPC_SHADOW_OPENSSL_load_builtin_modules', - '#define OpenSSL_version GRPC_SHADOW_OpenSSL_version', - '#define OpenSSL_version_num GRPC_SHADOW_OpenSSL_version_num', - '#define SSLeay GRPC_SHADOW_SSLeay', - '#define SSLeay_version GRPC_SHADOW_SSLeay_version', - '#define CRYPTO_cleanup_all_ex_data GRPC_SHADOW_CRYPTO_cleanup_all_ex_data', - '#define CRYPTO_free_ex_data GRPC_SHADOW_CRYPTO_free_ex_data', - '#define CRYPTO_get_ex_data GRPC_SHADOW_CRYPTO_get_ex_data', - '#define CRYPTO_get_ex_new_index GRPC_SHADOW_CRYPTO_get_ex_new_index', - '#define CRYPTO_new_ex_data GRPC_SHADOW_CRYPTO_new_ex_data', - '#define CRYPTO_set_ex_data GRPC_SHADOW_CRYPTO_set_ex_data', - '#define BIO_snprintf GRPC_SHADOW_BIO_snprintf', - '#define BIO_vsnprintf GRPC_SHADOW_BIO_vsnprintf', - '#define CRYPTO_memcmp GRPC_SHADOW_CRYPTO_memcmp', - '#define OPENSSL_cleanse GRPC_SHADOW_OPENSSL_cleanse', - '#define OPENSSL_free GRPC_SHADOW_OPENSSL_free', - '#define OPENSSL_hash32 GRPC_SHADOW_OPENSSL_hash32', - '#define OPENSSL_malloc GRPC_SHADOW_OPENSSL_malloc', - '#define OPENSSL_realloc GRPC_SHADOW_OPENSSL_realloc', - '#define OPENSSL_strcasecmp GRPC_SHADOW_OPENSSL_strcasecmp', - '#define OPENSSL_strdup GRPC_SHADOW_OPENSSL_strdup', - '#define OPENSSL_strncasecmp GRPC_SHADOW_OPENSSL_strncasecmp', - '#define OPENSSL_strnlen GRPC_SHADOW_OPENSSL_strnlen', - '#define OPENSSL_tolower GRPC_SHADOW_OPENSSL_tolower', - '#define CRYPTO_refcount_dec_and_test_zero GRPC_SHADOW_CRYPTO_refcount_dec_and_test_zero', - '#define CRYPTO_refcount_inc GRPC_SHADOW_CRYPTO_refcount_inc', - '#define CRYPTO_THREADID_current GRPC_SHADOW_CRYPTO_THREADID_current', - '#define CRYPTO_THREADID_set_callback GRPC_SHADOW_CRYPTO_THREADID_set_callback', - '#define CRYPTO_THREADID_set_numeric GRPC_SHADOW_CRYPTO_THREADID_set_numeric', - '#define CRYPTO_THREADID_set_pointer GRPC_SHADOW_CRYPTO_THREADID_set_pointer', - '#define CRYPTO_get_dynlock_create_callback GRPC_SHADOW_CRYPTO_get_dynlock_create_callback', - '#define CRYPTO_get_dynlock_destroy_callback GRPC_SHADOW_CRYPTO_get_dynlock_destroy_callback', - '#define CRYPTO_get_dynlock_lock_callback GRPC_SHADOW_CRYPTO_get_dynlock_lock_callback', - '#define CRYPTO_get_lock_name GRPC_SHADOW_CRYPTO_get_lock_name', - '#define CRYPTO_get_locking_callback GRPC_SHADOW_CRYPTO_get_locking_callback', - '#define CRYPTO_num_locks GRPC_SHADOW_CRYPTO_num_locks', - '#define CRYPTO_set_add_lock_callback GRPC_SHADOW_CRYPTO_set_add_lock_callback', - '#define CRYPTO_set_dynlock_create_callback GRPC_SHADOW_CRYPTO_set_dynlock_create_callback', - '#define CRYPTO_set_dynlock_destroy_callback GRPC_SHADOW_CRYPTO_set_dynlock_destroy_callback', - '#define CRYPTO_set_dynlock_lock_callback GRPC_SHADOW_CRYPTO_set_dynlock_lock_callback', - '#define CRYPTO_set_id_callback GRPC_SHADOW_CRYPTO_set_id_callback', - '#define CRYPTO_set_locking_callback GRPC_SHADOW_CRYPTO_set_locking_callback', - '#define CRYPTO_MUTEX_cleanup GRPC_SHADOW_CRYPTO_MUTEX_cleanup', - '#define CRYPTO_MUTEX_init GRPC_SHADOW_CRYPTO_MUTEX_init', - '#define CRYPTO_MUTEX_lock_read GRPC_SHADOW_CRYPTO_MUTEX_lock_read', - '#define CRYPTO_MUTEX_lock_write GRPC_SHADOW_CRYPTO_MUTEX_lock_write', - '#define CRYPTO_MUTEX_unlock_read GRPC_SHADOW_CRYPTO_MUTEX_unlock_read', - '#define CRYPTO_MUTEX_unlock_write GRPC_SHADOW_CRYPTO_MUTEX_unlock_write', - '#define CRYPTO_STATIC_MUTEX_lock_read GRPC_SHADOW_CRYPTO_STATIC_MUTEX_lock_read', - '#define CRYPTO_STATIC_MUTEX_lock_write GRPC_SHADOW_CRYPTO_STATIC_MUTEX_lock_write', - '#define CRYPTO_STATIC_MUTEX_unlock_read GRPC_SHADOW_CRYPTO_STATIC_MUTEX_unlock_read', - '#define CRYPTO_STATIC_MUTEX_unlock_write GRPC_SHADOW_CRYPTO_STATIC_MUTEX_unlock_write', - '#define CRYPTO_get_thread_local GRPC_SHADOW_CRYPTO_get_thread_local', - '#define CRYPTO_once GRPC_SHADOW_CRYPTO_once', - '#define CRYPTO_set_thread_local GRPC_SHADOW_CRYPTO_set_thread_local', - '#define sk_deep_copy GRPC_SHADOW_sk_deep_copy', - '#define sk_delete GRPC_SHADOW_sk_delete', - '#define sk_delete_ptr GRPC_SHADOW_sk_delete_ptr', - '#define sk_dup GRPC_SHADOW_sk_dup', - '#define sk_find GRPC_SHADOW_sk_find', - '#define sk_free GRPC_SHADOW_sk_free', - '#define sk_insert GRPC_SHADOW_sk_insert', - '#define sk_is_sorted GRPC_SHADOW_sk_is_sorted', - '#define sk_new GRPC_SHADOW_sk_new', - '#define sk_new_null GRPC_SHADOW_sk_new_null', - '#define sk_num GRPC_SHADOW_sk_num', - '#define sk_pop GRPC_SHADOW_sk_pop', - '#define sk_pop_free GRPC_SHADOW_sk_pop_free', - '#define sk_push GRPC_SHADOW_sk_push', - '#define sk_set GRPC_SHADOW_sk_set', - '#define sk_set_cmp_func GRPC_SHADOW_sk_set_cmp_func', - '#define sk_shift GRPC_SHADOW_sk_shift', - '#define sk_sort GRPC_SHADOW_sk_sort', - '#define sk_value GRPC_SHADOW_sk_value', - '#define sk_zero GRPC_SHADOW_sk_zero', - '#define lh_delete GRPC_SHADOW_lh_delete', - '#define lh_doall GRPC_SHADOW_lh_doall', - '#define lh_doall_arg GRPC_SHADOW_lh_doall_arg', - '#define lh_free GRPC_SHADOW_lh_free', - '#define lh_insert GRPC_SHADOW_lh_insert', - '#define lh_new GRPC_SHADOW_lh_new', - '#define lh_num_items GRPC_SHADOW_lh_num_items', - '#define lh_retrieve GRPC_SHADOW_lh_retrieve', - '#define lh_strhash GRPC_SHADOW_lh_strhash', - '#define ERR_SAVE_STATE_free GRPC_SHADOW_ERR_SAVE_STATE_free', - '#define ERR_add_error_data GRPC_SHADOW_ERR_add_error_data', - '#define ERR_add_error_dataf GRPC_SHADOW_ERR_add_error_dataf', - '#define ERR_clear_error GRPC_SHADOW_ERR_clear_error', - '#define ERR_clear_system_error GRPC_SHADOW_ERR_clear_system_error', - '#define ERR_error_string GRPC_SHADOW_ERR_error_string', - '#define ERR_error_string_n GRPC_SHADOW_ERR_error_string_n', - '#define ERR_free_strings GRPC_SHADOW_ERR_free_strings', - '#define ERR_func_error_string GRPC_SHADOW_ERR_func_error_string', - '#define ERR_get_error GRPC_SHADOW_ERR_get_error', - '#define ERR_get_error_line GRPC_SHADOW_ERR_get_error_line', - '#define ERR_get_error_line_data GRPC_SHADOW_ERR_get_error_line_data', - '#define ERR_get_next_error_library GRPC_SHADOW_ERR_get_next_error_library', - '#define ERR_lib_error_string GRPC_SHADOW_ERR_lib_error_string', - '#define ERR_load_BIO_strings GRPC_SHADOW_ERR_load_BIO_strings', - '#define ERR_load_ERR_strings GRPC_SHADOW_ERR_load_ERR_strings', - '#define ERR_load_crypto_strings GRPC_SHADOW_ERR_load_crypto_strings', - '#define ERR_peek_error GRPC_SHADOW_ERR_peek_error', - '#define ERR_peek_error_line GRPC_SHADOW_ERR_peek_error_line', - '#define ERR_peek_error_line_data GRPC_SHADOW_ERR_peek_error_line_data', - '#define ERR_peek_last_error GRPC_SHADOW_ERR_peek_last_error', - '#define ERR_peek_last_error_line GRPC_SHADOW_ERR_peek_last_error_line', - '#define ERR_peek_last_error_line_data GRPC_SHADOW_ERR_peek_last_error_line_data', - '#define ERR_pop_to_mark GRPC_SHADOW_ERR_pop_to_mark', - '#define ERR_print_errors_cb GRPC_SHADOW_ERR_print_errors_cb', - '#define ERR_print_errors_fp GRPC_SHADOW_ERR_print_errors_fp', - '#define ERR_put_error GRPC_SHADOW_ERR_put_error', - '#define ERR_reason_error_string GRPC_SHADOW_ERR_reason_error_string', - '#define ERR_remove_state GRPC_SHADOW_ERR_remove_state', - '#define ERR_remove_thread_state GRPC_SHADOW_ERR_remove_thread_state', - '#define ERR_restore_state GRPC_SHADOW_ERR_restore_state', - '#define ERR_save_state GRPC_SHADOW_ERR_save_state', - '#define ERR_set_mark GRPC_SHADOW_ERR_set_mark', - '#define kOpenSSLReasonStringData GRPC_SHADOW_kOpenSSLReasonStringData', - '#define kOpenSSLReasonValues GRPC_SHADOW_kOpenSSLReasonValues', - '#define kOpenSSLReasonValuesLen GRPC_SHADOW_kOpenSSLReasonValuesLen', - '#define EVP_DecodeBase64 GRPC_SHADOW_EVP_DecodeBase64', - '#define EVP_DecodeBlock GRPC_SHADOW_EVP_DecodeBlock', - '#define EVP_DecodeFinal GRPC_SHADOW_EVP_DecodeFinal', - '#define EVP_DecodeInit GRPC_SHADOW_EVP_DecodeInit', - '#define EVP_DecodeUpdate GRPC_SHADOW_EVP_DecodeUpdate', - '#define EVP_DecodedLength GRPC_SHADOW_EVP_DecodedLength', - '#define EVP_EncodeBlock GRPC_SHADOW_EVP_EncodeBlock', - '#define EVP_EncodeFinal GRPC_SHADOW_EVP_EncodeFinal', - '#define EVP_EncodeInit GRPC_SHADOW_EVP_EncodeInit', - '#define EVP_EncodeUpdate GRPC_SHADOW_EVP_EncodeUpdate', - '#define EVP_EncodedLength GRPC_SHADOW_EVP_EncodedLength', - '#define CBB_finish_i2d GRPC_SHADOW_CBB_finish_i2d', - '#define CBS_asn1_ber_to_der GRPC_SHADOW_CBS_asn1_ber_to_der', - '#define CBS_get_asn1_implicit_string GRPC_SHADOW_CBS_get_asn1_implicit_string', - '#define CBS_asn1_bitstring_has_bit GRPC_SHADOW_CBS_asn1_bitstring_has_bit', - '#define CBS_asn1_oid_to_text GRPC_SHADOW_CBS_asn1_oid_to_text', - '#define CBS_contains_zero_byte GRPC_SHADOW_CBS_contains_zero_byte', - '#define CBS_copy_bytes GRPC_SHADOW_CBS_copy_bytes', - '#define CBS_data GRPC_SHADOW_CBS_data', - '#define CBS_get_any_asn1 GRPC_SHADOW_CBS_get_any_asn1', - '#define CBS_get_any_asn1_element GRPC_SHADOW_CBS_get_any_asn1_element', - '#define CBS_get_any_ber_asn1_element GRPC_SHADOW_CBS_get_any_ber_asn1_element', - '#define CBS_get_asn1 GRPC_SHADOW_CBS_get_asn1', - '#define CBS_get_asn1_bool GRPC_SHADOW_CBS_get_asn1_bool', - '#define CBS_get_asn1_element GRPC_SHADOW_CBS_get_asn1_element', - '#define CBS_get_asn1_uint64 GRPC_SHADOW_CBS_get_asn1_uint64', - '#define CBS_get_bytes GRPC_SHADOW_CBS_get_bytes', - '#define CBS_get_last_u8 GRPC_SHADOW_CBS_get_last_u8', - '#define CBS_get_optional_asn1 GRPC_SHADOW_CBS_get_optional_asn1', - '#define CBS_get_optional_asn1_bool GRPC_SHADOW_CBS_get_optional_asn1_bool', - '#define CBS_get_optional_asn1_octet_string GRPC_SHADOW_CBS_get_optional_asn1_octet_string', - '#define CBS_get_optional_asn1_uint64 GRPC_SHADOW_CBS_get_optional_asn1_uint64', - '#define CBS_get_u16 GRPC_SHADOW_CBS_get_u16', - '#define CBS_get_u16_length_prefixed GRPC_SHADOW_CBS_get_u16_length_prefixed', - '#define CBS_get_u24 GRPC_SHADOW_CBS_get_u24', - '#define CBS_get_u24_length_prefixed GRPC_SHADOW_CBS_get_u24_length_prefixed', - '#define CBS_get_u32 GRPC_SHADOW_CBS_get_u32', - '#define CBS_get_u8 GRPC_SHADOW_CBS_get_u8', - '#define CBS_get_u8_length_prefixed GRPC_SHADOW_CBS_get_u8_length_prefixed', - '#define CBS_init GRPC_SHADOW_CBS_init', - '#define CBS_is_valid_asn1_bitstring GRPC_SHADOW_CBS_is_valid_asn1_bitstring', - '#define CBS_len GRPC_SHADOW_CBS_len', - '#define CBS_mem_equal GRPC_SHADOW_CBS_mem_equal', - '#define CBS_peek_asn1_tag GRPC_SHADOW_CBS_peek_asn1_tag', - '#define CBS_skip GRPC_SHADOW_CBS_skip', - '#define CBS_stow GRPC_SHADOW_CBS_stow', - '#define CBS_strdup GRPC_SHADOW_CBS_strdup', - '#define CBB_add_asn1 GRPC_SHADOW_CBB_add_asn1', - '#define CBB_add_asn1_bool GRPC_SHADOW_CBB_add_asn1_bool', - '#define CBB_add_asn1_octet_string GRPC_SHADOW_CBB_add_asn1_octet_string', - '#define CBB_add_asn1_oid_from_text GRPC_SHADOW_CBB_add_asn1_oid_from_text', - '#define CBB_add_asn1_uint64 GRPC_SHADOW_CBB_add_asn1_uint64', - '#define CBB_add_bytes GRPC_SHADOW_CBB_add_bytes', - '#define CBB_add_space GRPC_SHADOW_CBB_add_space', - '#define CBB_add_u16 GRPC_SHADOW_CBB_add_u16', - '#define CBB_add_u16_length_prefixed GRPC_SHADOW_CBB_add_u16_length_prefixed', - '#define CBB_add_u24 GRPC_SHADOW_CBB_add_u24', - '#define CBB_add_u24_length_prefixed GRPC_SHADOW_CBB_add_u24_length_prefixed', - '#define CBB_add_u32 GRPC_SHADOW_CBB_add_u32', - '#define CBB_add_u8 GRPC_SHADOW_CBB_add_u8', - '#define CBB_add_u8_length_prefixed GRPC_SHADOW_CBB_add_u8_length_prefixed', - '#define CBB_cleanup GRPC_SHADOW_CBB_cleanup', - '#define CBB_data GRPC_SHADOW_CBB_data', - '#define CBB_did_write GRPC_SHADOW_CBB_did_write', - '#define CBB_discard_child GRPC_SHADOW_CBB_discard_child', - '#define CBB_finish GRPC_SHADOW_CBB_finish', - '#define CBB_flush GRPC_SHADOW_CBB_flush', - '#define CBB_flush_asn1_set_of GRPC_SHADOW_CBB_flush_asn1_set_of', - '#define CBB_init GRPC_SHADOW_CBB_init', - '#define CBB_init_fixed GRPC_SHADOW_CBB_init_fixed', - '#define CBB_len GRPC_SHADOW_CBB_len', - '#define CBB_reserve GRPC_SHADOW_CBB_reserve', - '#define CBB_zero GRPC_SHADOW_CBB_zero', - '#define CRYPTO_BUFFER_POOL_free GRPC_SHADOW_CRYPTO_BUFFER_POOL_free', - '#define CRYPTO_BUFFER_POOL_new GRPC_SHADOW_CRYPTO_BUFFER_POOL_new', - '#define CRYPTO_BUFFER_data GRPC_SHADOW_CRYPTO_BUFFER_data', - '#define CRYPTO_BUFFER_free GRPC_SHADOW_CRYPTO_BUFFER_free', - '#define CRYPTO_BUFFER_init_CBS GRPC_SHADOW_CRYPTO_BUFFER_init_CBS', - '#define CRYPTO_BUFFER_len GRPC_SHADOW_CRYPTO_BUFFER_len', - '#define CRYPTO_BUFFER_new GRPC_SHADOW_CRYPTO_BUFFER_new', - '#define CRYPTO_BUFFER_new_from_CBS GRPC_SHADOW_CRYPTO_BUFFER_new_from_CBS', - '#define CRYPTO_BUFFER_up_ref GRPC_SHADOW_CRYPTO_BUFFER_up_ref', - '#define AES_cbc_encrypt GRPC_SHADOW_AES_cbc_encrypt', - '#define AES_cfb128_encrypt GRPC_SHADOW_AES_cfb128_encrypt', - '#define AES_ctr128_encrypt GRPC_SHADOW_AES_ctr128_encrypt', - '#define AES_decrypt GRPC_SHADOW_AES_decrypt', - '#define AES_ecb_encrypt GRPC_SHADOW_AES_ecb_encrypt', - '#define AES_encrypt GRPC_SHADOW_AES_encrypt', - '#define AES_ofb128_encrypt GRPC_SHADOW_AES_ofb128_encrypt', - '#define AES_set_decrypt_key GRPC_SHADOW_AES_set_decrypt_key', - '#define AES_set_encrypt_key GRPC_SHADOW_AES_set_encrypt_key', - '#define AES_unwrap_key GRPC_SHADOW_AES_unwrap_key', - '#define AES_wrap_key GRPC_SHADOW_AES_wrap_key', - '#define BN_BLINDING_convert GRPC_SHADOW_BN_BLINDING_convert', - '#define BN_BLINDING_free GRPC_SHADOW_BN_BLINDING_free', - '#define BN_BLINDING_invert GRPC_SHADOW_BN_BLINDING_invert', - '#define BN_BLINDING_new GRPC_SHADOW_BN_BLINDING_new', - '#define BN_CTX_end GRPC_SHADOW_BN_CTX_end', - '#define BN_CTX_free GRPC_SHADOW_BN_CTX_free', - '#define BN_CTX_get GRPC_SHADOW_BN_CTX_get', - '#define BN_CTX_new GRPC_SHADOW_BN_CTX_new', - '#define BN_CTX_start GRPC_SHADOW_BN_CTX_start', - '#define BN_GENCB_call GRPC_SHADOW_BN_GENCB_call', - '#define BN_GENCB_set GRPC_SHADOW_BN_GENCB_set', - '#define BN_MONT_CTX_copy GRPC_SHADOW_BN_MONT_CTX_copy', - '#define BN_MONT_CTX_free GRPC_SHADOW_BN_MONT_CTX_free', - '#define BN_MONT_CTX_new GRPC_SHADOW_BN_MONT_CTX_new', - '#define BN_MONT_CTX_new_for_modulus GRPC_SHADOW_BN_MONT_CTX_new_for_modulus', - '#define BN_MONT_CTX_set GRPC_SHADOW_BN_MONT_CTX_set', - '#define BN_MONT_CTX_set_locked GRPC_SHADOW_BN_MONT_CTX_set_locked', - '#define BN_abs_is_word GRPC_SHADOW_BN_abs_is_word', - '#define BN_add GRPC_SHADOW_BN_add', - '#define BN_add_word GRPC_SHADOW_BN_add_word', - '#define BN_bin2bn GRPC_SHADOW_BN_bin2bn', - '#define BN_bn2bin GRPC_SHADOW_BN_bn2bin', - '#define BN_bn2bin_padded GRPC_SHADOW_BN_bn2bin_padded', - '#define BN_bn2le_padded GRPC_SHADOW_BN_bn2le_padded', - '#define BN_clear GRPC_SHADOW_BN_clear', - '#define BN_clear_bit GRPC_SHADOW_BN_clear_bit', - '#define BN_clear_free GRPC_SHADOW_BN_clear_free', - '#define BN_cmp GRPC_SHADOW_BN_cmp', - '#define BN_cmp_word GRPC_SHADOW_BN_cmp_word', - '#define BN_copy GRPC_SHADOW_BN_copy', - '#define BN_count_low_zero_bits GRPC_SHADOW_BN_count_low_zero_bits', - '#define BN_div GRPC_SHADOW_BN_div', - '#define BN_div_word GRPC_SHADOW_BN_div_word', - '#define BN_dup GRPC_SHADOW_BN_dup', - '#define BN_enhanced_miller_rabin_primality_test GRPC_SHADOW_BN_enhanced_miller_rabin_primality_test', - '#define BN_equal_consttime GRPC_SHADOW_BN_equal_consttime', - '#define BN_exp GRPC_SHADOW_BN_exp', - '#define BN_free GRPC_SHADOW_BN_free', - '#define BN_from_montgomery GRPC_SHADOW_BN_from_montgomery', - '#define BN_gcd GRPC_SHADOW_BN_gcd', - '#define BN_generate_prime_ex GRPC_SHADOW_BN_generate_prime_ex', - '#define BN_get_u64 GRPC_SHADOW_BN_get_u64', - '#define BN_get_word GRPC_SHADOW_BN_get_word', - '#define BN_init GRPC_SHADOW_BN_init', - '#define BN_is_bit_set GRPC_SHADOW_BN_is_bit_set', - '#define BN_is_negative GRPC_SHADOW_BN_is_negative', - '#define BN_is_odd GRPC_SHADOW_BN_is_odd', - '#define BN_is_one GRPC_SHADOW_BN_is_one', - '#define BN_is_pow2 GRPC_SHADOW_BN_is_pow2', - '#define BN_is_prime_ex GRPC_SHADOW_BN_is_prime_ex', - '#define BN_is_prime_fasttest_ex GRPC_SHADOW_BN_is_prime_fasttest_ex', - '#define BN_is_word GRPC_SHADOW_BN_is_word', - '#define BN_is_zero GRPC_SHADOW_BN_is_zero', - '#define BN_le2bn GRPC_SHADOW_BN_le2bn', - '#define BN_lshift GRPC_SHADOW_BN_lshift', - '#define BN_lshift1 GRPC_SHADOW_BN_lshift1', - '#define BN_mask_bits GRPC_SHADOW_BN_mask_bits', - '#define BN_mod_add GRPC_SHADOW_BN_mod_add', - '#define BN_mod_add_quick GRPC_SHADOW_BN_mod_add_quick', - '#define BN_mod_exp GRPC_SHADOW_BN_mod_exp', - '#define BN_mod_exp2_mont GRPC_SHADOW_BN_mod_exp2_mont', - '#define BN_mod_exp_mont GRPC_SHADOW_BN_mod_exp_mont', - '#define BN_mod_exp_mont_consttime GRPC_SHADOW_BN_mod_exp_mont_consttime', - '#define BN_mod_exp_mont_word GRPC_SHADOW_BN_mod_exp_mont_word', - '#define BN_mod_inverse GRPC_SHADOW_BN_mod_inverse', - '#define BN_mod_inverse_blinded GRPC_SHADOW_BN_mod_inverse_blinded', - '#define BN_mod_inverse_odd GRPC_SHADOW_BN_mod_inverse_odd', - '#define BN_mod_lshift GRPC_SHADOW_BN_mod_lshift', - '#define BN_mod_lshift1 GRPC_SHADOW_BN_mod_lshift1', - '#define BN_mod_lshift1_quick GRPC_SHADOW_BN_mod_lshift1_quick', - '#define BN_mod_lshift_quick GRPC_SHADOW_BN_mod_lshift_quick', - '#define BN_mod_mul GRPC_SHADOW_BN_mod_mul', - '#define BN_mod_mul_montgomery GRPC_SHADOW_BN_mod_mul_montgomery', - '#define BN_mod_pow2 GRPC_SHADOW_BN_mod_pow2', - '#define BN_mod_sqr GRPC_SHADOW_BN_mod_sqr', - '#define BN_mod_sqrt GRPC_SHADOW_BN_mod_sqrt', - '#define BN_mod_sub GRPC_SHADOW_BN_mod_sub', - '#define BN_mod_sub_quick GRPC_SHADOW_BN_mod_sub_quick', - '#define BN_mod_word GRPC_SHADOW_BN_mod_word', - '#define BN_mul GRPC_SHADOW_BN_mul', - '#define BN_mul_word GRPC_SHADOW_BN_mul_word', - '#define BN_new GRPC_SHADOW_BN_new', - '#define BN_nnmod GRPC_SHADOW_BN_nnmod', - '#define BN_nnmod_pow2 GRPC_SHADOW_BN_nnmod_pow2', - '#define BN_num_bits GRPC_SHADOW_BN_num_bits', - '#define BN_num_bits_word GRPC_SHADOW_BN_num_bits_word', - '#define BN_num_bytes GRPC_SHADOW_BN_num_bytes', - '#define BN_one GRPC_SHADOW_BN_one', - '#define BN_primality_test GRPC_SHADOW_BN_primality_test', - '#define BN_pseudo_rand GRPC_SHADOW_BN_pseudo_rand', - '#define BN_pseudo_rand_range GRPC_SHADOW_BN_pseudo_rand_range', - '#define BN_rand GRPC_SHADOW_BN_rand', - '#define BN_rand_range GRPC_SHADOW_BN_rand_range', - '#define BN_rand_range_ex GRPC_SHADOW_BN_rand_range_ex', - '#define BN_rshift GRPC_SHADOW_BN_rshift', - '#define BN_rshift1 GRPC_SHADOW_BN_rshift1', - '#define BN_set_bit GRPC_SHADOW_BN_set_bit', - '#define BN_set_negative GRPC_SHADOW_BN_set_negative', - '#define BN_set_u64 GRPC_SHADOW_BN_set_u64', - '#define BN_set_word GRPC_SHADOW_BN_set_word', - '#define BN_sqr GRPC_SHADOW_BN_sqr', - '#define BN_sqrt GRPC_SHADOW_BN_sqrt', - '#define BN_sub GRPC_SHADOW_BN_sub', - '#define BN_sub_word GRPC_SHADOW_BN_sub_word', - '#define BN_to_montgomery GRPC_SHADOW_BN_to_montgomery', - '#define BN_uadd GRPC_SHADOW_BN_uadd', - '#define BN_ucmp GRPC_SHADOW_BN_ucmp', - '#define BN_usub GRPC_SHADOW_BN_usub', - '#define BN_value_one GRPC_SHADOW_BN_value_one', - '#define BN_zero GRPC_SHADOW_BN_zero', - '#define BORINGSSL_self_test GRPC_SHADOW_BORINGSSL_self_test', - '#define CRYPTO_POLYVAL_finish GRPC_SHADOW_CRYPTO_POLYVAL_finish', - '#define CRYPTO_POLYVAL_init GRPC_SHADOW_CRYPTO_POLYVAL_init', - '#define CRYPTO_POLYVAL_update_blocks GRPC_SHADOW_CRYPTO_POLYVAL_update_blocks', - '#define CRYPTO_cbc128_decrypt GRPC_SHADOW_CRYPTO_cbc128_decrypt', - '#define CRYPTO_cbc128_encrypt GRPC_SHADOW_CRYPTO_cbc128_encrypt', - '#define CRYPTO_ccm128_decrypt GRPC_SHADOW_CRYPTO_ccm128_decrypt', - '#define CRYPTO_ccm128_encrypt GRPC_SHADOW_CRYPTO_ccm128_encrypt', - '#define CRYPTO_ccm128_init GRPC_SHADOW_CRYPTO_ccm128_init', - '#define CRYPTO_ccm128_max_input GRPC_SHADOW_CRYPTO_ccm128_max_input', - '#define CRYPTO_cfb128_1_encrypt GRPC_SHADOW_CRYPTO_cfb128_1_encrypt', - '#define CRYPTO_cfb128_8_encrypt GRPC_SHADOW_CRYPTO_cfb128_8_encrypt', - '#define CRYPTO_cfb128_encrypt GRPC_SHADOW_CRYPTO_cfb128_encrypt', - '#define CRYPTO_ctr128_encrypt GRPC_SHADOW_CRYPTO_ctr128_encrypt', - '#define CRYPTO_ctr128_encrypt_ctr32 GRPC_SHADOW_CRYPTO_ctr128_encrypt_ctr32', - '#define CRYPTO_gcm128_aad GRPC_SHADOW_CRYPTO_gcm128_aad', - '#define CRYPTO_gcm128_decrypt GRPC_SHADOW_CRYPTO_gcm128_decrypt', - '#define CRYPTO_gcm128_decrypt_ctr32 GRPC_SHADOW_CRYPTO_gcm128_decrypt_ctr32', - '#define CRYPTO_gcm128_encrypt GRPC_SHADOW_CRYPTO_gcm128_encrypt', - '#define CRYPTO_gcm128_encrypt_ctr32 GRPC_SHADOW_CRYPTO_gcm128_encrypt_ctr32', - '#define CRYPTO_gcm128_finish GRPC_SHADOW_CRYPTO_gcm128_finish', - '#define CRYPTO_gcm128_init GRPC_SHADOW_CRYPTO_gcm128_init', - '#define CRYPTO_gcm128_setiv GRPC_SHADOW_CRYPTO_gcm128_setiv', - '#define CRYPTO_gcm128_tag GRPC_SHADOW_CRYPTO_gcm128_tag', - '#define CRYPTO_ghash_init GRPC_SHADOW_CRYPTO_ghash_init', - '#define CRYPTO_ofb128_encrypt GRPC_SHADOW_CRYPTO_ofb128_encrypt', - '#define CRYPTO_sysrand GRPC_SHADOW_CRYPTO_sysrand', - '#define CRYPTO_tls1_prf GRPC_SHADOW_CRYPTO_tls1_prf', - '#define CTR_DRBG_clear GRPC_SHADOW_CTR_DRBG_clear', - '#define CTR_DRBG_generate GRPC_SHADOW_CTR_DRBG_generate', - '#define CTR_DRBG_init GRPC_SHADOW_CTR_DRBG_init', - '#define CTR_DRBG_reseed GRPC_SHADOW_CTR_DRBG_reseed', - '#define DES_decrypt3 GRPC_SHADOW_DES_decrypt3', - '#define DES_ecb3_encrypt GRPC_SHADOW_DES_ecb3_encrypt', - '#define DES_ecb_encrypt GRPC_SHADOW_DES_ecb_encrypt', - '#define DES_ede2_cbc_encrypt GRPC_SHADOW_DES_ede2_cbc_encrypt', - '#define DES_ede3_cbc_encrypt GRPC_SHADOW_DES_ede3_cbc_encrypt', - '#define DES_encrypt3 GRPC_SHADOW_DES_encrypt3', - '#define DES_ncbc_encrypt GRPC_SHADOW_DES_ncbc_encrypt', - '#define DES_set_key GRPC_SHADOW_DES_set_key', - '#define DES_set_key_unchecked GRPC_SHADOW_DES_set_key_unchecked', - '#define DES_set_odd_parity GRPC_SHADOW_DES_set_odd_parity', - '#define ECDSA_SIG_free GRPC_SHADOW_ECDSA_SIG_free', - '#define ECDSA_SIG_get0 GRPC_SHADOW_ECDSA_SIG_get0', - '#define ECDSA_SIG_new GRPC_SHADOW_ECDSA_SIG_new', - '#define ECDSA_SIG_set0 GRPC_SHADOW_ECDSA_SIG_set0', - '#define ECDSA_do_sign GRPC_SHADOW_ECDSA_do_sign', - '#define ECDSA_do_verify GRPC_SHADOW_ECDSA_do_verify', - '#define EC_GFp_mont_method GRPC_SHADOW_EC_GFp_mont_method', - '#define EC_GFp_nistp224_method GRPC_SHADOW_EC_GFp_nistp224_method', - '#define EC_GFp_nistp256_method GRPC_SHADOW_EC_GFp_nistp256_method', - '#define EC_GFp_nistz256_method GRPC_SHADOW_EC_GFp_nistz256_method', - '#define EC_GROUP_cmp GRPC_SHADOW_EC_GROUP_cmp', - '#define EC_GROUP_dup GRPC_SHADOW_EC_GROUP_dup', - '#define EC_GROUP_free GRPC_SHADOW_EC_GROUP_free', - '#define EC_GROUP_get0_generator GRPC_SHADOW_EC_GROUP_get0_generator', - '#define EC_GROUP_get0_order GRPC_SHADOW_EC_GROUP_get0_order', - '#define EC_GROUP_get_cofactor GRPC_SHADOW_EC_GROUP_get_cofactor', - '#define EC_GROUP_get_curve_GFp GRPC_SHADOW_EC_GROUP_get_curve_GFp', - '#define EC_GROUP_get_curve_name GRPC_SHADOW_EC_GROUP_get_curve_name', - '#define EC_GROUP_get_degree GRPC_SHADOW_EC_GROUP_get_degree', - '#define EC_GROUP_get_order GRPC_SHADOW_EC_GROUP_get_order', - '#define EC_GROUP_method_of GRPC_SHADOW_EC_GROUP_method_of', - '#define EC_GROUP_new_by_curve_name GRPC_SHADOW_EC_GROUP_new_by_curve_name', - '#define EC_GROUP_new_curve_GFp GRPC_SHADOW_EC_GROUP_new_curve_GFp', - '#define EC_GROUP_set_asn1_flag GRPC_SHADOW_EC_GROUP_set_asn1_flag', - '#define EC_GROUP_set_generator GRPC_SHADOW_EC_GROUP_set_generator', - '#define EC_GROUP_set_point_conversion_form GRPC_SHADOW_EC_GROUP_set_point_conversion_form', - '#define EC_KEY_check_fips GRPC_SHADOW_EC_KEY_check_fips', - '#define EC_KEY_check_key GRPC_SHADOW_EC_KEY_check_key', - '#define EC_KEY_dup GRPC_SHADOW_EC_KEY_dup', - '#define EC_KEY_free GRPC_SHADOW_EC_KEY_free', - '#define EC_KEY_generate_key GRPC_SHADOW_EC_KEY_generate_key', - '#define EC_KEY_generate_key_fips GRPC_SHADOW_EC_KEY_generate_key_fips', - '#define EC_KEY_get0_group GRPC_SHADOW_EC_KEY_get0_group', - '#define EC_KEY_get0_private_key GRPC_SHADOW_EC_KEY_get0_private_key', - '#define EC_KEY_get0_public_key GRPC_SHADOW_EC_KEY_get0_public_key', - '#define EC_KEY_get_conv_form GRPC_SHADOW_EC_KEY_get_conv_form', - '#define EC_KEY_get_enc_flags GRPC_SHADOW_EC_KEY_get_enc_flags', - '#define EC_KEY_get_ex_data GRPC_SHADOW_EC_KEY_get_ex_data', - '#define EC_KEY_get_ex_new_index GRPC_SHADOW_EC_KEY_get_ex_new_index', - '#define EC_KEY_is_opaque GRPC_SHADOW_EC_KEY_is_opaque', - '#define EC_KEY_new GRPC_SHADOW_EC_KEY_new', - '#define EC_KEY_new_by_curve_name GRPC_SHADOW_EC_KEY_new_by_curve_name', - '#define EC_KEY_new_method GRPC_SHADOW_EC_KEY_new_method', - '#define EC_KEY_set_asn1_flag GRPC_SHADOW_EC_KEY_set_asn1_flag', - '#define EC_KEY_set_conv_form GRPC_SHADOW_EC_KEY_set_conv_form', - '#define EC_KEY_set_enc_flags GRPC_SHADOW_EC_KEY_set_enc_flags', - '#define EC_KEY_set_ex_data GRPC_SHADOW_EC_KEY_set_ex_data', - '#define EC_KEY_set_group GRPC_SHADOW_EC_KEY_set_group', - '#define EC_KEY_set_private_key GRPC_SHADOW_EC_KEY_set_private_key', - '#define EC_KEY_set_public_key GRPC_SHADOW_EC_KEY_set_public_key', - '#define EC_KEY_set_public_key_affine_coordinates GRPC_SHADOW_EC_KEY_set_public_key_affine_coordinates', - '#define EC_KEY_up_ref GRPC_SHADOW_EC_KEY_up_ref', - '#define EC_METHOD_get_field_type GRPC_SHADOW_EC_METHOD_get_field_type', - '#define EC_POINT_add GRPC_SHADOW_EC_POINT_add', - '#define EC_POINT_clear_free GRPC_SHADOW_EC_POINT_clear_free', - '#define EC_POINT_cmp GRPC_SHADOW_EC_POINT_cmp', - '#define EC_POINT_copy GRPC_SHADOW_EC_POINT_copy', - '#define EC_POINT_dbl GRPC_SHADOW_EC_POINT_dbl', - '#define EC_POINT_dup GRPC_SHADOW_EC_POINT_dup', - '#define EC_POINT_free GRPC_SHADOW_EC_POINT_free', - '#define EC_POINT_get_affine_coordinates_GFp GRPC_SHADOW_EC_POINT_get_affine_coordinates_GFp', - '#define EC_POINT_invert GRPC_SHADOW_EC_POINT_invert', - '#define EC_POINT_is_at_infinity GRPC_SHADOW_EC_POINT_is_at_infinity', - '#define EC_POINT_is_on_curve GRPC_SHADOW_EC_POINT_is_on_curve', - '#define EC_POINT_make_affine GRPC_SHADOW_EC_POINT_make_affine', - '#define EC_POINT_mul GRPC_SHADOW_EC_POINT_mul', - '#define EC_POINT_new GRPC_SHADOW_EC_POINT_new', - '#define EC_POINT_oct2point GRPC_SHADOW_EC_POINT_oct2point', - '#define EC_POINT_point2oct GRPC_SHADOW_EC_POINT_point2oct', - '#define EC_POINT_set_affine_coordinates_GFp GRPC_SHADOW_EC_POINT_set_affine_coordinates_GFp', - '#define EC_POINT_set_compressed_coordinates_GFp GRPC_SHADOW_EC_POINT_set_compressed_coordinates_GFp', - '#define EC_POINT_set_to_infinity GRPC_SHADOW_EC_POINT_set_to_infinity', - '#define EC_POINTs_make_affine GRPC_SHADOW_EC_POINTs_make_affine', - '#define EC_get_builtin_curves GRPC_SHADOW_EC_get_builtin_curves', - '#define EVP_AEAD_CTX_aead GRPC_SHADOW_EVP_AEAD_CTX_aead', - '#define EVP_AEAD_CTX_cleanup GRPC_SHADOW_EVP_AEAD_CTX_cleanup', - '#define EVP_AEAD_CTX_free GRPC_SHADOW_EVP_AEAD_CTX_free', - '#define EVP_AEAD_CTX_get_iv GRPC_SHADOW_EVP_AEAD_CTX_get_iv', - '#define EVP_AEAD_CTX_init GRPC_SHADOW_EVP_AEAD_CTX_init', - '#define EVP_AEAD_CTX_init_with_direction GRPC_SHADOW_EVP_AEAD_CTX_init_with_direction', - '#define EVP_AEAD_CTX_new GRPC_SHADOW_EVP_AEAD_CTX_new', - '#define EVP_AEAD_CTX_open GRPC_SHADOW_EVP_AEAD_CTX_open', - '#define EVP_AEAD_CTX_open_gather GRPC_SHADOW_EVP_AEAD_CTX_open_gather', - '#define EVP_AEAD_CTX_seal GRPC_SHADOW_EVP_AEAD_CTX_seal', - '#define EVP_AEAD_CTX_seal_scatter GRPC_SHADOW_EVP_AEAD_CTX_seal_scatter', - '#define EVP_AEAD_CTX_tag_len GRPC_SHADOW_EVP_AEAD_CTX_tag_len', - '#define EVP_AEAD_CTX_zero GRPC_SHADOW_EVP_AEAD_CTX_zero', - '#define EVP_AEAD_key_length GRPC_SHADOW_EVP_AEAD_key_length', - '#define EVP_AEAD_max_overhead GRPC_SHADOW_EVP_AEAD_max_overhead', - '#define EVP_AEAD_max_tag_len GRPC_SHADOW_EVP_AEAD_max_tag_len', - '#define EVP_AEAD_nonce_length GRPC_SHADOW_EVP_AEAD_nonce_length', - '#define EVP_CIPHER_CTX_block_size GRPC_SHADOW_EVP_CIPHER_CTX_block_size', - '#define EVP_CIPHER_CTX_cipher GRPC_SHADOW_EVP_CIPHER_CTX_cipher', - '#define EVP_CIPHER_CTX_cleanup GRPC_SHADOW_EVP_CIPHER_CTX_cleanup', - '#define EVP_CIPHER_CTX_copy GRPC_SHADOW_EVP_CIPHER_CTX_copy', - '#define EVP_CIPHER_CTX_ctrl GRPC_SHADOW_EVP_CIPHER_CTX_ctrl', - '#define EVP_CIPHER_CTX_flags GRPC_SHADOW_EVP_CIPHER_CTX_flags', - '#define EVP_CIPHER_CTX_free GRPC_SHADOW_EVP_CIPHER_CTX_free', - '#define EVP_CIPHER_CTX_get_app_data GRPC_SHADOW_EVP_CIPHER_CTX_get_app_data', - '#define EVP_CIPHER_CTX_init GRPC_SHADOW_EVP_CIPHER_CTX_init', - '#define EVP_CIPHER_CTX_iv_length GRPC_SHADOW_EVP_CIPHER_CTX_iv_length', - '#define EVP_CIPHER_CTX_key_length GRPC_SHADOW_EVP_CIPHER_CTX_key_length', - '#define EVP_CIPHER_CTX_mode GRPC_SHADOW_EVP_CIPHER_CTX_mode', - '#define EVP_CIPHER_CTX_new GRPC_SHADOW_EVP_CIPHER_CTX_new', - '#define EVP_CIPHER_CTX_nid GRPC_SHADOW_EVP_CIPHER_CTX_nid', - '#define EVP_CIPHER_CTX_reset GRPC_SHADOW_EVP_CIPHER_CTX_reset', - '#define EVP_CIPHER_CTX_set_app_data GRPC_SHADOW_EVP_CIPHER_CTX_set_app_data', - '#define EVP_CIPHER_CTX_set_flags GRPC_SHADOW_EVP_CIPHER_CTX_set_flags', - '#define EVP_CIPHER_CTX_set_key_length GRPC_SHADOW_EVP_CIPHER_CTX_set_key_length', - '#define EVP_CIPHER_CTX_set_padding GRPC_SHADOW_EVP_CIPHER_CTX_set_padding', - '#define EVP_CIPHER_block_size GRPC_SHADOW_EVP_CIPHER_block_size', - '#define EVP_CIPHER_flags GRPC_SHADOW_EVP_CIPHER_flags', - '#define EVP_CIPHER_iv_length GRPC_SHADOW_EVP_CIPHER_iv_length', - '#define EVP_CIPHER_key_length GRPC_SHADOW_EVP_CIPHER_key_length', - '#define EVP_CIPHER_mode GRPC_SHADOW_EVP_CIPHER_mode', - '#define EVP_CIPHER_nid GRPC_SHADOW_EVP_CIPHER_nid', - '#define EVP_Cipher GRPC_SHADOW_EVP_Cipher', - '#define EVP_CipherFinal_ex GRPC_SHADOW_EVP_CipherFinal_ex', - '#define EVP_CipherInit GRPC_SHADOW_EVP_CipherInit', - '#define EVP_CipherInit_ex GRPC_SHADOW_EVP_CipherInit_ex', - '#define EVP_CipherUpdate GRPC_SHADOW_EVP_CipherUpdate', - '#define EVP_DecryptFinal_ex GRPC_SHADOW_EVP_DecryptFinal_ex', - '#define EVP_DecryptInit GRPC_SHADOW_EVP_DecryptInit', - '#define EVP_DecryptInit_ex GRPC_SHADOW_EVP_DecryptInit_ex', - '#define EVP_DecryptUpdate GRPC_SHADOW_EVP_DecryptUpdate', - '#define EVP_Digest GRPC_SHADOW_EVP_Digest', - '#define EVP_DigestFinal GRPC_SHADOW_EVP_DigestFinal', - '#define EVP_DigestFinal_ex GRPC_SHADOW_EVP_DigestFinal_ex', - '#define EVP_DigestInit GRPC_SHADOW_EVP_DigestInit', - '#define EVP_DigestInit_ex GRPC_SHADOW_EVP_DigestInit_ex', - '#define EVP_DigestUpdate GRPC_SHADOW_EVP_DigestUpdate', - '#define EVP_EncryptFinal_ex GRPC_SHADOW_EVP_EncryptFinal_ex', - '#define EVP_EncryptInit GRPC_SHADOW_EVP_EncryptInit', - '#define EVP_EncryptInit_ex GRPC_SHADOW_EVP_EncryptInit_ex', - '#define EVP_EncryptUpdate GRPC_SHADOW_EVP_EncryptUpdate', - '#define EVP_MD_CTX_block_size GRPC_SHADOW_EVP_MD_CTX_block_size', - '#define EVP_MD_CTX_cleanup GRPC_SHADOW_EVP_MD_CTX_cleanup', - '#define EVP_MD_CTX_copy GRPC_SHADOW_EVP_MD_CTX_copy', - '#define EVP_MD_CTX_copy_ex GRPC_SHADOW_EVP_MD_CTX_copy_ex', - '#define EVP_MD_CTX_create GRPC_SHADOW_EVP_MD_CTX_create', - '#define EVP_MD_CTX_destroy GRPC_SHADOW_EVP_MD_CTX_destroy', - '#define EVP_MD_CTX_free GRPC_SHADOW_EVP_MD_CTX_free', - '#define EVP_MD_CTX_init GRPC_SHADOW_EVP_MD_CTX_init', - '#define EVP_MD_CTX_md GRPC_SHADOW_EVP_MD_CTX_md', - '#define EVP_MD_CTX_new GRPC_SHADOW_EVP_MD_CTX_new', - '#define EVP_MD_CTX_reset GRPC_SHADOW_EVP_MD_CTX_reset', - '#define EVP_MD_CTX_size GRPC_SHADOW_EVP_MD_CTX_size', - '#define EVP_MD_CTX_type GRPC_SHADOW_EVP_MD_CTX_type', - '#define EVP_MD_block_size GRPC_SHADOW_EVP_MD_block_size', - '#define EVP_MD_flags GRPC_SHADOW_EVP_MD_flags', - '#define EVP_MD_size GRPC_SHADOW_EVP_MD_size', - '#define EVP_MD_type GRPC_SHADOW_EVP_MD_type', - '#define EVP_add_cipher_alias GRPC_SHADOW_EVP_add_cipher_alias', - '#define EVP_add_digest GRPC_SHADOW_EVP_add_digest', - '#define EVP_aead_aes_128_gcm GRPC_SHADOW_EVP_aead_aes_128_gcm', - '#define EVP_aead_aes_128_gcm_tls12 GRPC_SHADOW_EVP_aead_aes_128_gcm_tls12', - '#define EVP_aead_aes_256_gcm GRPC_SHADOW_EVP_aead_aes_256_gcm', - '#define EVP_aead_aes_256_gcm_tls12 GRPC_SHADOW_EVP_aead_aes_256_gcm_tls12', - '#define EVP_aes_128_cbc GRPC_SHADOW_EVP_aes_128_cbc', - '#define EVP_aes_128_ctr GRPC_SHADOW_EVP_aes_128_ctr', - '#define EVP_aes_128_ecb GRPC_SHADOW_EVP_aes_128_ecb', - '#define EVP_aes_128_gcm GRPC_SHADOW_EVP_aes_128_gcm', - '#define EVP_aes_128_ofb GRPC_SHADOW_EVP_aes_128_ofb', - '#define EVP_aes_192_cbc GRPC_SHADOW_EVP_aes_192_cbc', - '#define EVP_aes_192_ctr GRPC_SHADOW_EVP_aes_192_ctr', - '#define EVP_aes_192_ecb GRPC_SHADOW_EVP_aes_192_ecb', - '#define EVP_aes_192_gcm GRPC_SHADOW_EVP_aes_192_gcm', - '#define EVP_aes_256_cbc GRPC_SHADOW_EVP_aes_256_cbc', - '#define EVP_aes_256_ctr GRPC_SHADOW_EVP_aes_256_ctr', - '#define EVP_aes_256_ecb GRPC_SHADOW_EVP_aes_256_ecb', - '#define EVP_aes_256_gcm GRPC_SHADOW_EVP_aes_256_gcm', - '#define EVP_aes_256_ofb GRPC_SHADOW_EVP_aes_256_ofb', - '#define EVP_des_cbc GRPC_SHADOW_EVP_des_cbc', - '#define EVP_des_ecb GRPC_SHADOW_EVP_des_ecb', - '#define EVP_des_ede GRPC_SHADOW_EVP_des_ede', - '#define EVP_des_ede3 GRPC_SHADOW_EVP_des_ede3', - '#define EVP_des_ede3_cbc GRPC_SHADOW_EVP_des_ede3_cbc', - '#define EVP_des_ede_cbc GRPC_SHADOW_EVP_des_ede_cbc', - '#define EVP_has_aes_hardware GRPC_SHADOW_EVP_has_aes_hardware', - '#define EVP_md4 GRPC_SHADOW_EVP_md4', - '#define EVP_md5 GRPC_SHADOW_EVP_md5', - '#define EVP_md5_sha1 GRPC_SHADOW_EVP_md5_sha1', - '#define EVP_sha1 GRPC_SHADOW_EVP_sha1', - '#define EVP_sha224 GRPC_SHADOW_EVP_sha224', - '#define EVP_sha256 GRPC_SHADOW_EVP_sha256', - '#define EVP_sha384 GRPC_SHADOW_EVP_sha384', - '#define EVP_sha512 GRPC_SHADOW_EVP_sha512', - '#define HMAC GRPC_SHADOW_HMAC', - '#define HMAC_CTX_cleanup GRPC_SHADOW_HMAC_CTX_cleanup', - '#define HMAC_CTX_copy GRPC_SHADOW_HMAC_CTX_copy', - '#define HMAC_CTX_copy_ex GRPC_SHADOW_HMAC_CTX_copy_ex', - '#define HMAC_CTX_free GRPC_SHADOW_HMAC_CTX_free', - '#define HMAC_CTX_init GRPC_SHADOW_HMAC_CTX_init', - '#define HMAC_CTX_new GRPC_SHADOW_HMAC_CTX_new', - '#define HMAC_CTX_reset GRPC_SHADOW_HMAC_CTX_reset', - '#define HMAC_Final GRPC_SHADOW_HMAC_Final', - '#define HMAC_Init GRPC_SHADOW_HMAC_Init', - '#define HMAC_Init_ex GRPC_SHADOW_HMAC_Init_ex', - '#define HMAC_Update GRPC_SHADOW_HMAC_Update', - '#define HMAC_size GRPC_SHADOW_HMAC_size', - '#define MD4 GRPC_SHADOW_MD4', - '#define MD4_Final GRPC_SHADOW_MD4_Final', - '#define MD4_Init GRPC_SHADOW_MD4_Init', - '#define MD4_Transform GRPC_SHADOW_MD4_Transform', - '#define MD4_Update GRPC_SHADOW_MD4_Update', - '#define MD5 GRPC_SHADOW_MD5', - '#define MD5_Final GRPC_SHADOW_MD5_Final', - '#define MD5_Init GRPC_SHADOW_MD5_Init', - '#define MD5_Transform GRPC_SHADOW_MD5_Transform', - '#define MD5_Update GRPC_SHADOW_MD5_Update', - '#define OPENSSL_built_in_curves GRPC_SHADOW_OPENSSL_built_in_curves', - '#define RAND_bytes GRPC_SHADOW_RAND_bytes', - '#define RAND_bytes_with_additional_data GRPC_SHADOW_RAND_bytes_with_additional_data', - '#define RAND_pseudo_bytes GRPC_SHADOW_RAND_pseudo_bytes', - '#define RAND_set_urandom_fd GRPC_SHADOW_RAND_set_urandom_fd', - '#define RSAZ_1024_mod_exp_avx2 GRPC_SHADOW_RSAZ_1024_mod_exp_avx2', - '#define RSA_add_pkcs1_prefix GRPC_SHADOW_RSA_add_pkcs1_prefix', - '#define RSA_bits GRPC_SHADOW_RSA_bits', - '#define RSA_blinding_on GRPC_SHADOW_RSA_blinding_on', - '#define RSA_check_fips GRPC_SHADOW_RSA_check_fips', - '#define RSA_check_key GRPC_SHADOW_RSA_check_key', - '#define RSA_decrypt GRPC_SHADOW_RSA_decrypt', - '#define RSA_default_method GRPC_SHADOW_RSA_default_method', - '#define RSA_encrypt GRPC_SHADOW_RSA_encrypt', - '#define RSA_flags GRPC_SHADOW_RSA_flags', - '#define RSA_free GRPC_SHADOW_RSA_free', - '#define RSA_generate_key_ex GRPC_SHADOW_RSA_generate_key_ex', - '#define RSA_generate_key_fips GRPC_SHADOW_RSA_generate_key_fips', - '#define RSA_get0_crt_params GRPC_SHADOW_RSA_get0_crt_params', - '#define RSA_get0_factors GRPC_SHADOW_RSA_get0_factors', - '#define RSA_get0_key GRPC_SHADOW_RSA_get0_key', - '#define RSA_get_ex_data GRPC_SHADOW_RSA_get_ex_data', - '#define RSA_get_ex_new_index GRPC_SHADOW_RSA_get_ex_new_index', - '#define RSA_is_opaque GRPC_SHADOW_RSA_is_opaque', - '#define RSA_new GRPC_SHADOW_RSA_new', - '#define RSA_new_method GRPC_SHADOW_RSA_new_method', - '#define RSA_padding_add_PKCS1_OAEP_mgf1 GRPC_SHADOW_RSA_padding_add_PKCS1_OAEP_mgf1', - '#define RSA_padding_add_PKCS1_PSS_mgf1 GRPC_SHADOW_RSA_padding_add_PKCS1_PSS_mgf1', - '#define RSA_padding_add_PKCS1_type_1 GRPC_SHADOW_RSA_padding_add_PKCS1_type_1', - '#define RSA_padding_add_PKCS1_type_2 GRPC_SHADOW_RSA_padding_add_PKCS1_type_2', - '#define RSA_padding_add_none GRPC_SHADOW_RSA_padding_add_none', - '#define RSA_padding_check_PKCS1_OAEP_mgf1 GRPC_SHADOW_RSA_padding_check_PKCS1_OAEP_mgf1', - '#define RSA_padding_check_PKCS1_type_1 GRPC_SHADOW_RSA_padding_check_PKCS1_type_1', - '#define RSA_padding_check_PKCS1_type_2 GRPC_SHADOW_RSA_padding_check_PKCS1_type_2', - '#define RSA_private_decrypt GRPC_SHADOW_RSA_private_decrypt', - '#define RSA_private_encrypt GRPC_SHADOW_RSA_private_encrypt', - '#define RSA_private_transform GRPC_SHADOW_RSA_private_transform', - '#define RSA_public_decrypt GRPC_SHADOW_RSA_public_decrypt', - '#define RSA_public_encrypt GRPC_SHADOW_RSA_public_encrypt', - '#define RSA_set0_crt_params GRPC_SHADOW_RSA_set0_crt_params', - '#define RSA_set0_factors GRPC_SHADOW_RSA_set0_factors', - '#define RSA_set0_key GRPC_SHADOW_RSA_set0_key', - '#define RSA_set_ex_data GRPC_SHADOW_RSA_set_ex_data', - '#define RSA_sign GRPC_SHADOW_RSA_sign', - '#define RSA_sign_pss_mgf1 GRPC_SHADOW_RSA_sign_pss_mgf1', - '#define RSA_sign_raw GRPC_SHADOW_RSA_sign_raw', - '#define RSA_size GRPC_SHADOW_RSA_size', - '#define RSA_up_ref GRPC_SHADOW_RSA_up_ref', - '#define RSA_verify GRPC_SHADOW_RSA_verify', - '#define RSA_verify_PKCS1_PSS_mgf1 GRPC_SHADOW_RSA_verify_PKCS1_PSS_mgf1', - '#define RSA_verify_pss_mgf1 GRPC_SHADOW_RSA_verify_pss_mgf1', - '#define RSA_verify_raw GRPC_SHADOW_RSA_verify_raw', - '#define SHA1 GRPC_SHADOW_SHA1', - '#define SHA1_Final GRPC_SHADOW_SHA1_Final', - '#define SHA1_Init GRPC_SHADOW_SHA1_Init', - '#define SHA1_Transform GRPC_SHADOW_SHA1_Transform', - '#define SHA1_Update GRPC_SHADOW_SHA1_Update', - '#define SHA224 GRPC_SHADOW_SHA224', - '#define SHA224_Final GRPC_SHADOW_SHA224_Final', - '#define SHA224_Init GRPC_SHADOW_SHA224_Init', - '#define SHA224_Update GRPC_SHADOW_SHA224_Update', - '#define SHA256 GRPC_SHADOW_SHA256', - '#define SHA256_Final GRPC_SHADOW_SHA256_Final', - '#define SHA256_Init GRPC_SHADOW_SHA256_Init', - '#define SHA256_Transform GRPC_SHADOW_SHA256_Transform', - '#define SHA256_Update GRPC_SHADOW_SHA256_Update', - '#define SHA384 GRPC_SHADOW_SHA384', - '#define SHA384_Final GRPC_SHADOW_SHA384_Final', - '#define SHA384_Init GRPC_SHADOW_SHA384_Init', - '#define SHA384_Update GRPC_SHADOW_SHA384_Update', - '#define SHA512 GRPC_SHADOW_SHA512', - '#define SHA512_Final GRPC_SHADOW_SHA512_Final', - '#define SHA512_Init GRPC_SHADOW_SHA512_Init', - '#define SHA512_Transform GRPC_SHADOW_SHA512_Transform', - '#define SHA512_Update GRPC_SHADOW_SHA512_Update', - '#define aes_ctr_set_key GRPC_SHADOW_aes_ctr_set_key', - '#define bn_abs_sub_consttime GRPC_SHADOW_bn_abs_sub_consttime', - '#define bn_add_words GRPC_SHADOW_bn_add_words', - '#define bn_copy_words GRPC_SHADOW_bn_copy_words', - '#define bn_div_consttime GRPC_SHADOW_bn_div_consttime', - '#define bn_expand GRPC_SHADOW_bn_expand', - '#define bn_fits_in_words GRPC_SHADOW_bn_fits_in_words', - '#define bn_from_montgomery_small GRPC_SHADOW_bn_from_montgomery_small', - '#define bn_in_range_words GRPC_SHADOW_bn_in_range_words', - '#define bn_is_bit_set_words GRPC_SHADOW_bn_is_bit_set_words', - '#define bn_is_relatively_prime GRPC_SHADOW_bn_is_relatively_prime', - '#define bn_jacobi GRPC_SHADOW_bn_jacobi', - '#define bn_lcm_consttime GRPC_SHADOW_bn_lcm_consttime', - '#define bn_less_than_montgomery_R GRPC_SHADOW_bn_less_than_montgomery_R', - '#define bn_less_than_words GRPC_SHADOW_bn_less_than_words', - '#define bn_minimal_width GRPC_SHADOW_bn_minimal_width', - '#define bn_mod_add_consttime GRPC_SHADOW_bn_mod_add_consttime', - '#define bn_mod_exp_base_2_consttime GRPC_SHADOW_bn_mod_exp_base_2_consttime', - '#define bn_mod_exp_mont_small GRPC_SHADOW_bn_mod_exp_mont_small', - '#define bn_mod_inverse_consttime GRPC_SHADOW_bn_mod_inverse_consttime', - '#define bn_mod_inverse_prime GRPC_SHADOW_bn_mod_inverse_prime', - '#define bn_mod_inverse_prime_mont_small GRPC_SHADOW_bn_mod_inverse_prime_mont_small', - '#define bn_mod_inverse_secret_prime GRPC_SHADOW_bn_mod_inverse_secret_prime', - '#define bn_mod_lshift1_consttime GRPC_SHADOW_bn_mod_lshift1_consttime', - '#define bn_mod_lshift_consttime GRPC_SHADOW_bn_mod_lshift_consttime', - '#define bn_mod_mul_montgomery_small GRPC_SHADOW_bn_mod_mul_montgomery_small', - '#define bn_mod_sub_consttime GRPC_SHADOW_bn_mod_sub_consttime', - '#define bn_mod_u16_consttime GRPC_SHADOW_bn_mod_u16_consttime', - '#define bn_mont_n0 GRPC_SHADOW_bn_mont_n0', - '#define bn_mul_add_words GRPC_SHADOW_bn_mul_add_words', - '#define bn_mul_comba4 GRPC_SHADOW_bn_mul_comba4', - '#define bn_mul_comba8 GRPC_SHADOW_bn_mul_comba8', - '#define bn_mul_consttime GRPC_SHADOW_bn_mul_consttime', - '#define bn_mul_small GRPC_SHADOW_bn_mul_small', - '#define bn_mul_words GRPC_SHADOW_bn_mul_words', - '#define bn_odd_number_is_obviously_composite GRPC_SHADOW_bn_odd_number_is_obviously_composite', - '#define bn_one_to_montgomery GRPC_SHADOW_bn_one_to_montgomery', - '#define bn_one_to_montgomery_small GRPC_SHADOW_bn_one_to_montgomery_small', - '#define bn_rand_range_words GRPC_SHADOW_bn_rand_range_words', - '#define bn_rand_secret_range GRPC_SHADOW_bn_rand_secret_range', - '#define bn_resize_words GRPC_SHADOW_bn_resize_words', - '#define bn_rshift1_words GRPC_SHADOW_bn_rshift1_words', - '#define bn_rshift_secret_shift GRPC_SHADOW_bn_rshift_secret_shift', - '#define bn_select_words GRPC_SHADOW_bn_select_words', - '#define bn_set_minimal_width GRPC_SHADOW_bn_set_minimal_width', - '#define bn_set_words GRPC_SHADOW_bn_set_words', - '#define bn_sqr_comba4 GRPC_SHADOW_bn_sqr_comba4', - '#define bn_sqr_comba8 GRPC_SHADOW_bn_sqr_comba8', - '#define bn_sqr_consttime GRPC_SHADOW_bn_sqr_consttime', - '#define bn_sqr_small GRPC_SHADOW_bn_sqr_small', - '#define bn_sqr_words GRPC_SHADOW_bn_sqr_words', - '#define bn_sub_words GRPC_SHADOW_bn_sub_words', - '#define bn_to_montgomery_small GRPC_SHADOW_bn_to_montgomery_small', - '#define bn_uadd_consttime GRPC_SHADOW_bn_uadd_consttime', - '#define bn_usub_consttime GRPC_SHADOW_bn_usub_consttime', - '#define bn_wexpand GRPC_SHADOW_bn_wexpand', - '#define crypto_gcm_clmul_enabled GRPC_SHADOW_crypto_gcm_clmul_enabled', - '#define ec_GFp_mont_field_decode GRPC_SHADOW_ec_GFp_mont_field_decode', - '#define ec_GFp_mont_field_encode GRPC_SHADOW_ec_GFp_mont_field_encode', - '#define ec_GFp_mont_field_mul GRPC_SHADOW_ec_GFp_mont_field_mul', - '#define ec_GFp_mont_field_sqr GRPC_SHADOW_ec_GFp_mont_field_sqr', - '#define ec_GFp_mont_group_finish GRPC_SHADOW_ec_GFp_mont_group_finish', - '#define ec_GFp_mont_group_init GRPC_SHADOW_ec_GFp_mont_group_init', - '#define ec_GFp_mont_group_set_curve GRPC_SHADOW_ec_GFp_mont_group_set_curve', - '#define ec_GFp_nistp_recode_scalar_bits GRPC_SHADOW_ec_GFp_nistp_recode_scalar_bits', - '#define ec_GFp_simple_add GRPC_SHADOW_ec_GFp_simple_add', - '#define ec_GFp_simple_cmp GRPC_SHADOW_ec_GFp_simple_cmp', - '#define ec_GFp_simple_dbl GRPC_SHADOW_ec_GFp_simple_dbl', - '#define ec_GFp_simple_field_mul GRPC_SHADOW_ec_GFp_simple_field_mul', - '#define ec_GFp_simple_field_sqr GRPC_SHADOW_ec_GFp_simple_field_sqr', - '#define ec_GFp_simple_group_finish GRPC_SHADOW_ec_GFp_simple_group_finish', - '#define ec_GFp_simple_group_get_curve GRPC_SHADOW_ec_GFp_simple_group_get_curve', - '#define ec_GFp_simple_group_get_degree GRPC_SHADOW_ec_GFp_simple_group_get_degree', - '#define ec_GFp_simple_group_init GRPC_SHADOW_ec_GFp_simple_group_init', - '#define ec_GFp_simple_group_set_curve GRPC_SHADOW_ec_GFp_simple_group_set_curve', - '#define ec_GFp_simple_invert GRPC_SHADOW_ec_GFp_simple_invert', - '#define ec_GFp_simple_is_at_infinity GRPC_SHADOW_ec_GFp_simple_is_at_infinity', - '#define ec_GFp_simple_is_on_curve GRPC_SHADOW_ec_GFp_simple_is_on_curve', - '#define ec_GFp_simple_make_affine GRPC_SHADOW_ec_GFp_simple_make_affine', - '#define ec_GFp_simple_point_copy GRPC_SHADOW_ec_GFp_simple_point_copy', - '#define ec_GFp_simple_point_finish GRPC_SHADOW_ec_GFp_simple_point_finish', - '#define ec_GFp_simple_point_init GRPC_SHADOW_ec_GFp_simple_point_init', - '#define ec_GFp_simple_point_set_affine_coordinates GRPC_SHADOW_ec_GFp_simple_point_set_affine_coordinates', - '#define ec_GFp_simple_point_set_to_infinity GRPC_SHADOW_ec_GFp_simple_point_set_to_infinity', - '#define ec_GFp_simple_points_make_affine GRPC_SHADOW_ec_GFp_simple_points_make_affine', - '#define ec_bignum_to_scalar GRPC_SHADOW_ec_bignum_to_scalar', - '#define ec_bignum_to_scalar_unchecked GRPC_SHADOW_ec_bignum_to_scalar_unchecked', - '#define ec_compute_wNAF GRPC_SHADOW_ec_compute_wNAF', - '#define ec_group_new GRPC_SHADOW_ec_group_new', - '#define ec_point_mul_scalar GRPC_SHADOW_ec_point_mul_scalar', - '#define ec_point_mul_scalar_public GRPC_SHADOW_ec_point_mul_scalar_public', - '#define ec_random_nonzero_scalar GRPC_SHADOW_ec_random_nonzero_scalar', - '#define ec_wNAF_mul GRPC_SHADOW_ec_wNAF_mul', - '#define kBoringSSLRSASqrtTwo GRPC_SHADOW_kBoringSSLRSASqrtTwo', - '#define kBoringSSLRSASqrtTwoLen GRPC_SHADOW_kBoringSSLRSASqrtTwoLen', - '#define md4_block_data_order GRPC_SHADOW_md4_block_data_order', - '#define rsa_default_decrypt GRPC_SHADOW_rsa_default_decrypt', - '#define rsa_default_private_transform GRPC_SHADOW_rsa_default_private_transform', - '#define rsa_default_sign_raw GRPC_SHADOW_rsa_default_sign_raw', - '#define rsa_default_size GRPC_SHADOW_rsa_default_size', - '#define FIPS_mode GRPC_SHADOW_FIPS_mode', - '#define aesni_gcm_decrypt GRPC_SHADOW_aesni_gcm_decrypt', - '#define aesni_gcm_encrypt GRPC_SHADOW_aesni_gcm_encrypt', - '#define aesni_cbc_encrypt GRPC_SHADOW_aesni_cbc_encrypt', - '#define aesni_ccm64_decrypt_blocks GRPC_SHADOW_aesni_ccm64_decrypt_blocks', - '#define aesni_ccm64_encrypt_blocks GRPC_SHADOW_aesni_ccm64_encrypt_blocks', - '#define aesni_ctr32_encrypt_blocks GRPC_SHADOW_aesni_ctr32_encrypt_blocks', - '#define aesni_decrypt GRPC_SHADOW_aesni_decrypt', - '#define aesni_ecb_encrypt GRPC_SHADOW_aesni_ecb_encrypt', - '#define aesni_encrypt GRPC_SHADOW_aesni_encrypt', - '#define aesni_ocb_decrypt GRPC_SHADOW_aesni_ocb_decrypt', - '#define aesni_ocb_encrypt GRPC_SHADOW_aesni_ocb_encrypt', - '#define aesni_set_decrypt_key GRPC_SHADOW_aesni_set_decrypt_key', - '#define aesni_set_encrypt_key GRPC_SHADOW_aesni_set_encrypt_key', - '#define aesni_xts_decrypt GRPC_SHADOW_aesni_xts_decrypt', - '#define aesni_xts_encrypt GRPC_SHADOW_aesni_xts_encrypt', - '#define asm_AES_cbc_encrypt GRPC_SHADOW_asm_AES_cbc_encrypt', - '#define asm_AES_decrypt GRPC_SHADOW_asm_AES_decrypt', - '#define asm_AES_encrypt GRPC_SHADOW_asm_AES_encrypt', - '#define asm_AES_set_decrypt_key GRPC_SHADOW_asm_AES_set_decrypt_key', - '#define asm_AES_set_encrypt_key GRPC_SHADOW_asm_AES_set_encrypt_key', - '#define bsaes_cbc_encrypt GRPC_SHADOW_bsaes_cbc_encrypt', - '#define bsaes_ctr32_encrypt_blocks GRPC_SHADOW_bsaes_ctr32_encrypt_blocks', - '#define bsaes_xts_decrypt GRPC_SHADOW_bsaes_xts_decrypt', - '#define bsaes_xts_encrypt GRPC_SHADOW_bsaes_xts_encrypt', - '#define gcm_ghash_4bit GRPC_SHADOW_gcm_ghash_4bit', - '#define gcm_ghash_avx GRPC_SHADOW_gcm_ghash_avx', - '#define gcm_ghash_clmul GRPC_SHADOW_gcm_ghash_clmul', - '#define gcm_gmult_4bit GRPC_SHADOW_gcm_gmult_4bit', - '#define gcm_gmult_avx GRPC_SHADOW_gcm_gmult_avx', - '#define gcm_gmult_clmul GRPC_SHADOW_gcm_gmult_clmul', - '#define gcm_init_avx GRPC_SHADOW_gcm_init_avx', - '#define gcm_init_clmul GRPC_SHADOW_gcm_init_clmul', - '#define md5_block_asm_data_order GRPC_SHADOW_md5_block_asm_data_order', - '#define ecp_nistz256_avx2_select_w7 GRPC_SHADOW_ecp_nistz256_avx2_select_w7', - '#define ecp_nistz256_mul_mont GRPC_SHADOW_ecp_nistz256_mul_mont', - '#define ecp_nistz256_neg GRPC_SHADOW_ecp_nistz256_neg', - '#define ecp_nistz256_point_add GRPC_SHADOW_ecp_nistz256_point_add', - '#define ecp_nistz256_point_add_affine GRPC_SHADOW_ecp_nistz256_point_add_affine', - '#define ecp_nistz256_point_double GRPC_SHADOW_ecp_nistz256_point_double', - '#define ecp_nistz256_select_w5 GRPC_SHADOW_ecp_nistz256_select_w5', - '#define ecp_nistz256_select_w7 GRPC_SHADOW_ecp_nistz256_select_w7', - '#define ecp_nistz256_sqr_mont GRPC_SHADOW_ecp_nistz256_sqr_mont', - '#define CRYPTO_rdrand GRPC_SHADOW_CRYPTO_rdrand', - '#define CRYPTO_rdrand_multiple8_buf GRPC_SHADOW_CRYPTO_rdrand_multiple8_buf', - '#define rsaz_1024_gather5_avx2 GRPC_SHADOW_rsaz_1024_gather5_avx2', - '#define rsaz_1024_mul_avx2 GRPC_SHADOW_rsaz_1024_mul_avx2', - '#define rsaz_1024_norm2red_avx2 GRPC_SHADOW_rsaz_1024_norm2red_avx2', - '#define rsaz_1024_red2norm_avx2 GRPC_SHADOW_rsaz_1024_red2norm_avx2', - '#define rsaz_1024_scatter5_avx2 GRPC_SHADOW_rsaz_1024_scatter5_avx2', - '#define rsaz_1024_sqr_avx2 GRPC_SHADOW_rsaz_1024_sqr_avx2', - '#define rsaz_avx2_eligible GRPC_SHADOW_rsaz_avx2_eligible', - '#define sha1_block_data_order GRPC_SHADOW_sha1_block_data_order', - '#define sha256_block_data_order GRPC_SHADOW_sha256_block_data_order', - '#define sha512_block_data_order GRPC_SHADOW_sha512_block_data_order', - '#define vpaes_cbc_encrypt GRPC_SHADOW_vpaes_cbc_encrypt', - '#define vpaes_decrypt GRPC_SHADOW_vpaes_decrypt', - '#define vpaes_encrypt GRPC_SHADOW_vpaes_encrypt', - '#define vpaes_set_decrypt_key GRPC_SHADOW_vpaes_set_decrypt_key', - '#define vpaes_set_encrypt_key GRPC_SHADOW_vpaes_set_encrypt_key', - '#define bn_from_montgomery GRPC_SHADOW_bn_from_montgomery', - '#define bn_gather5 GRPC_SHADOW_bn_gather5', - '#define bn_mul_mont_gather5 GRPC_SHADOW_bn_mul_mont_gather5', - '#define bn_power5 GRPC_SHADOW_bn_power5', - '#define bn_scatter5 GRPC_SHADOW_bn_scatter5', - '#define bn_sqr8x_internal GRPC_SHADOW_bn_sqr8x_internal', - '#define bn_mul_mont GRPC_SHADOW_bn_mul_mont', - '#define EVP_get_digestbyname GRPC_SHADOW_EVP_get_digestbyname', - '#define EVP_get_digestbynid GRPC_SHADOW_EVP_get_digestbynid', - '#define EVP_get_digestbyobj GRPC_SHADOW_EVP_get_digestbyobj', - '#define EVP_marshal_digest_algorithm GRPC_SHADOW_EVP_marshal_digest_algorithm', - '#define EVP_parse_digest_algorithm GRPC_SHADOW_EVP_parse_digest_algorithm', - '#define EVP_get_cipherbyname GRPC_SHADOW_EVP_get_cipherbyname', - '#define EVP_get_cipherbynid GRPC_SHADOW_EVP_get_cipherbynid', - '#define EVP_BytesToKey GRPC_SHADOW_EVP_BytesToKey', - '#define EVP_enc_null GRPC_SHADOW_EVP_enc_null', - '#define EVP_rc2_40_cbc GRPC_SHADOW_EVP_rc2_40_cbc', - '#define EVP_rc2_cbc GRPC_SHADOW_EVP_rc2_cbc', - '#define EVP_rc4 GRPC_SHADOW_EVP_rc4', - '#define EVP_aead_aes_128_gcm_siv GRPC_SHADOW_EVP_aead_aes_128_gcm_siv', - '#define EVP_aead_aes_256_gcm_siv GRPC_SHADOW_EVP_aead_aes_256_gcm_siv', - '#define EVP_aead_aes_128_ctr_hmac_sha256 GRPC_SHADOW_EVP_aead_aes_128_ctr_hmac_sha256', - '#define EVP_aead_aes_256_ctr_hmac_sha256 GRPC_SHADOW_EVP_aead_aes_256_ctr_hmac_sha256', - '#define EVP_aead_aes_128_ccm_bluetooth GRPC_SHADOW_EVP_aead_aes_128_ccm_bluetooth', - '#define EVP_aead_aes_128_ccm_bluetooth_8 GRPC_SHADOW_EVP_aead_aes_128_ccm_bluetooth_8', - '#define EVP_aead_chacha20_poly1305 GRPC_SHADOW_EVP_aead_chacha20_poly1305', - '#define EVP_tls_cbc_copy_mac GRPC_SHADOW_EVP_tls_cbc_copy_mac', - '#define EVP_tls_cbc_digest_record GRPC_SHADOW_EVP_tls_cbc_digest_record', - '#define EVP_tls_cbc_record_digest_supported GRPC_SHADOW_EVP_tls_cbc_record_digest_supported', - '#define EVP_tls_cbc_remove_padding GRPC_SHADOW_EVP_tls_cbc_remove_padding', - '#define EVP_aead_aes_128_cbc_sha1_tls GRPC_SHADOW_EVP_aead_aes_128_cbc_sha1_tls', - '#define EVP_aead_aes_128_cbc_sha1_tls_implicit_iv GRPC_SHADOW_EVP_aead_aes_128_cbc_sha1_tls_implicit_iv', - '#define EVP_aead_aes_128_cbc_sha256_tls GRPC_SHADOW_EVP_aead_aes_128_cbc_sha256_tls', - '#define EVP_aead_aes_256_cbc_sha1_tls GRPC_SHADOW_EVP_aead_aes_256_cbc_sha1_tls', - '#define EVP_aead_aes_256_cbc_sha1_tls_implicit_iv GRPC_SHADOW_EVP_aead_aes_256_cbc_sha1_tls_implicit_iv', - '#define EVP_aead_aes_256_cbc_sha256_tls GRPC_SHADOW_EVP_aead_aes_256_cbc_sha256_tls', - '#define EVP_aead_aes_256_cbc_sha384_tls GRPC_SHADOW_EVP_aead_aes_256_cbc_sha384_tls', - '#define EVP_aead_des_ede3_cbc_sha1_tls GRPC_SHADOW_EVP_aead_des_ede3_cbc_sha1_tls', - '#define EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv GRPC_SHADOW_EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv', - '#define EVP_aead_null_sha1_tls GRPC_SHADOW_EVP_aead_null_sha1_tls', - '#define EVP_aead_aes_128_cbc_sha1_ssl3 GRPC_SHADOW_EVP_aead_aes_128_cbc_sha1_ssl3', - '#define EVP_aead_aes_256_cbc_sha1_ssl3 GRPC_SHADOW_EVP_aead_aes_256_cbc_sha1_ssl3', - '#define EVP_aead_des_ede3_cbc_sha1_ssl3 GRPC_SHADOW_EVP_aead_des_ede3_cbc_sha1_ssl3', - '#define EVP_aead_null_sha1_ssl3 GRPC_SHADOW_EVP_aead_null_sha1_ssl3', - '#define aes128gcmsiv_aes_ks GRPC_SHADOW_aes128gcmsiv_aes_ks', - '#define aes128gcmsiv_aes_ks_enc_x1 GRPC_SHADOW_aes128gcmsiv_aes_ks_enc_x1', - '#define aes128gcmsiv_dec GRPC_SHADOW_aes128gcmsiv_dec', - '#define aes128gcmsiv_ecb_enc_block GRPC_SHADOW_aes128gcmsiv_ecb_enc_block', - '#define aes128gcmsiv_enc_msg_x4 GRPC_SHADOW_aes128gcmsiv_enc_msg_x4', - '#define aes128gcmsiv_enc_msg_x8 GRPC_SHADOW_aes128gcmsiv_enc_msg_x8', - '#define aes128gcmsiv_kdf GRPC_SHADOW_aes128gcmsiv_kdf', - '#define aes256gcmsiv_aes_ks GRPC_SHADOW_aes256gcmsiv_aes_ks', - '#define aes256gcmsiv_aes_ks_enc_x1 GRPC_SHADOW_aes256gcmsiv_aes_ks_enc_x1', - '#define aes256gcmsiv_dec GRPC_SHADOW_aes256gcmsiv_dec', - '#define aes256gcmsiv_ecb_enc_block GRPC_SHADOW_aes256gcmsiv_ecb_enc_block', - '#define aes256gcmsiv_enc_msg_x4 GRPC_SHADOW_aes256gcmsiv_enc_msg_x4', - '#define aes256gcmsiv_enc_msg_x8 GRPC_SHADOW_aes256gcmsiv_enc_msg_x8', - '#define aes256gcmsiv_kdf GRPC_SHADOW_aes256gcmsiv_kdf', - '#define aesgcmsiv_htable6_init GRPC_SHADOW_aesgcmsiv_htable6_init', - '#define aesgcmsiv_htable_init GRPC_SHADOW_aesgcmsiv_htable_init', - '#define aesgcmsiv_htable_polyval GRPC_SHADOW_aesgcmsiv_htable_polyval', - '#define aesgcmsiv_polyval_horner GRPC_SHADOW_aesgcmsiv_polyval_horner', - '#define chacha20_poly1305_open GRPC_SHADOW_chacha20_poly1305_open', - '#define chacha20_poly1305_seal GRPC_SHADOW_chacha20_poly1305_seal', - '#define RC4 GRPC_SHADOW_RC4', - '#define RC4_set_key GRPC_SHADOW_RC4_set_key', - '#define CONF_VALUE_new GRPC_SHADOW_CONF_VALUE_new', - '#define CONF_modules_free GRPC_SHADOW_CONF_modules_free', - '#define CONF_modules_load_file GRPC_SHADOW_CONF_modules_load_file', - '#define CONF_parse_list GRPC_SHADOW_CONF_parse_list', - '#define NCONF_free GRPC_SHADOW_NCONF_free', - '#define NCONF_get_section GRPC_SHADOW_NCONF_get_section', - '#define NCONF_get_string GRPC_SHADOW_NCONF_get_string', - '#define NCONF_load GRPC_SHADOW_NCONF_load', - '#define NCONF_load_bio GRPC_SHADOW_NCONF_load_bio', - '#define NCONF_new GRPC_SHADOW_NCONF_new', - '#define OPENSSL_config GRPC_SHADOW_OPENSSL_config', - '#define OPENSSL_no_config GRPC_SHADOW_OPENSSL_no_config', - '#define CRYPTO_chacha_20 GRPC_SHADOW_CRYPTO_chacha_20', - '#define ChaCha20_ctr32 GRPC_SHADOW_ChaCha20_ctr32', - '#define CRYPTO_poly1305_finish GRPC_SHADOW_CRYPTO_poly1305_finish', - '#define CRYPTO_poly1305_init GRPC_SHADOW_CRYPTO_poly1305_init', - '#define CRYPTO_poly1305_update GRPC_SHADOW_CRYPTO_poly1305_update', - '#define SPAKE2_CTX_free GRPC_SHADOW_SPAKE2_CTX_free', - '#define SPAKE2_CTX_new GRPC_SHADOW_SPAKE2_CTX_new', - '#define SPAKE2_generate_msg GRPC_SHADOW_SPAKE2_generate_msg', - '#define SPAKE2_process_msg GRPC_SHADOW_SPAKE2_process_msg', - '#define ED25519_keypair GRPC_SHADOW_ED25519_keypair', - '#define ED25519_keypair_from_seed GRPC_SHADOW_ED25519_keypair_from_seed', - '#define ED25519_sign GRPC_SHADOW_ED25519_sign', - '#define ED25519_verify GRPC_SHADOW_ED25519_verify', - '#define X25519 GRPC_SHADOW_X25519', - '#define X25519_keypair GRPC_SHADOW_X25519_keypair', - '#define X25519_public_from_private GRPC_SHADOW_X25519_public_from_private', - '#define x25519_ge_add GRPC_SHADOW_x25519_ge_add', - '#define x25519_ge_frombytes_vartime GRPC_SHADOW_x25519_ge_frombytes_vartime', - '#define x25519_ge_p1p1_to_p2 GRPC_SHADOW_x25519_ge_p1p1_to_p2', - '#define x25519_ge_p1p1_to_p3 GRPC_SHADOW_x25519_ge_p1p1_to_p3', - '#define x25519_ge_p3_to_cached GRPC_SHADOW_x25519_ge_p3_to_cached', - '#define x25519_ge_scalarmult GRPC_SHADOW_x25519_ge_scalarmult', - '#define x25519_ge_scalarmult_base GRPC_SHADOW_x25519_ge_scalarmult_base', - '#define x25519_ge_scalarmult_small_precomp GRPC_SHADOW_x25519_ge_scalarmult_small_precomp', - '#define x25519_ge_sub GRPC_SHADOW_x25519_ge_sub', - '#define x25519_ge_tobytes GRPC_SHADOW_x25519_ge_tobytes', - '#define x25519_sc_reduce GRPC_SHADOW_x25519_sc_reduce', - '#define BUF_MEM_append GRPC_SHADOW_BUF_MEM_append', - '#define BUF_MEM_free GRPC_SHADOW_BUF_MEM_free', - '#define BUF_MEM_grow GRPC_SHADOW_BUF_MEM_grow', - '#define BUF_MEM_grow_clean GRPC_SHADOW_BUF_MEM_grow_clean', - '#define BUF_MEM_new GRPC_SHADOW_BUF_MEM_new', - '#define BUF_MEM_reserve GRPC_SHADOW_BUF_MEM_reserve', - '#define BUF_memdup GRPC_SHADOW_BUF_memdup', - '#define BUF_strdup GRPC_SHADOW_BUF_strdup', - '#define BUF_strlcat GRPC_SHADOW_BUF_strlcat', - '#define BUF_strlcpy GRPC_SHADOW_BUF_strlcpy', - '#define BUF_strndup GRPC_SHADOW_BUF_strndup', - '#define BUF_strnlen GRPC_SHADOW_BUF_strnlen', - '#define BN_marshal_asn1 GRPC_SHADOW_BN_marshal_asn1', - '#define BN_parse_asn1_unsigned GRPC_SHADOW_BN_parse_asn1_unsigned', - '#define BN_asc2bn GRPC_SHADOW_BN_asc2bn', - '#define BN_bn2cbb_padded GRPC_SHADOW_BN_bn2cbb_padded', - '#define BN_bn2dec GRPC_SHADOW_BN_bn2dec', - '#define BN_bn2hex GRPC_SHADOW_BN_bn2hex', - '#define BN_bn2mpi GRPC_SHADOW_BN_bn2mpi', - '#define BN_dec2bn GRPC_SHADOW_BN_dec2bn', - '#define BN_hex2bn GRPC_SHADOW_BN_hex2bn', - '#define BN_mpi2bn GRPC_SHADOW_BN_mpi2bn', - '#define BN_print GRPC_SHADOW_BN_print', - '#define BN_print_fp GRPC_SHADOW_BN_print_fp', - '#define BIO_callback_ctrl GRPC_SHADOW_BIO_callback_ctrl', - '#define BIO_clear_flags GRPC_SHADOW_BIO_clear_flags', - '#define BIO_clear_retry_flags GRPC_SHADOW_BIO_clear_retry_flags', - '#define BIO_copy_next_retry GRPC_SHADOW_BIO_copy_next_retry', - '#define BIO_ctrl GRPC_SHADOW_BIO_ctrl', - '#define BIO_ctrl_pending GRPC_SHADOW_BIO_ctrl_pending', - '#define BIO_eof GRPC_SHADOW_BIO_eof', - '#define BIO_find_type GRPC_SHADOW_BIO_find_type', - '#define BIO_flush GRPC_SHADOW_BIO_flush', - '#define BIO_free GRPC_SHADOW_BIO_free', - '#define BIO_free_all GRPC_SHADOW_BIO_free_all', - '#define BIO_get_data GRPC_SHADOW_BIO_get_data', - '#define BIO_get_init GRPC_SHADOW_BIO_get_init', - '#define BIO_get_new_index GRPC_SHADOW_BIO_get_new_index', - '#define BIO_get_retry_flags GRPC_SHADOW_BIO_get_retry_flags', - '#define BIO_get_retry_reason GRPC_SHADOW_BIO_get_retry_reason', - '#define BIO_get_shutdown GRPC_SHADOW_BIO_get_shutdown', - '#define BIO_gets GRPC_SHADOW_BIO_gets', - '#define BIO_indent GRPC_SHADOW_BIO_indent', - '#define BIO_int_ctrl GRPC_SHADOW_BIO_int_ctrl', - '#define BIO_meth_free GRPC_SHADOW_BIO_meth_free', - '#define BIO_meth_new GRPC_SHADOW_BIO_meth_new', - '#define BIO_meth_set_create GRPC_SHADOW_BIO_meth_set_create', - '#define BIO_meth_set_ctrl GRPC_SHADOW_BIO_meth_set_ctrl', - '#define BIO_meth_set_destroy GRPC_SHADOW_BIO_meth_set_destroy', - '#define BIO_meth_set_gets GRPC_SHADOW_BIO_meth_set_gets', - '#define BIO_meth_set_puts GRPC_SHADOW_BIO_meth_set_puts', - '#define BIO_meth_set_read GRPC_SHADOW_BIO_meth_set_read', - '#define BIO_meth_set_write GRPC_SHADOW_BIO_meth_set_write', - '#define BIO_method_type GRPC_SHADOW_BIO_method_type', - '#define BIO_new GRPC_SHADOW_BIO_new', - '#define BIO_next GRPC_SHADOW_BIO_next', - '#define BIO_number_read GRPC_SHADOW_BIO_number_read', - '#define BIO_number_written GRPC_SHADOW_BIO_number_written', - '#define BIO_pending GRPC_SHADOW_BIO_pending', - '#define BIO_pop GRPC_SHADOW_BIO_pop', - '#define BIO_ptr_ctrl GRPC_SHADOW_BIO_ptr_ctrl', - '#define BIO_push GRPC_SHADOW_BIO_push', - '#define BIO_puts GRPC_SHADOW_BIO_puts', - '#define BIO_read GRPC_SHADOW_BIO_read', - '#define BIO_read_asn1 GRPC_SHADOW_BIO_read_asn1', - '#define BIO_reset GRPC_SHADOW_BIO_reset', - '#define BIO_set_close GRPC_SHADOW_BIO_set_close', - '#define BIO_set_data GRPC_SHADOW_BIO_set_data', - '#define BIO_set_flags GRPC_SHADOW_BIO_set_flags', - '#define BIO_set_init GRPC_SHADOW_BIO_set_init', - '#define BIO_set_retry_read GRPC_SHADOW_BIO_set_retry_read', - '#define BIO_set_retry_special GRPC_SHADOW_BIO_set_retry_special', - '#define BIO_set_retry_write GRPC_SHADOW_BIO_set_retry_write', - '#define BIO_set_shutdown GRPC_SHADOW_BIO_set_shutdown', - '#define BIO_set_write_buffer_size GRPC_SHADOW_BIO_set_write_buffer_size', - '#define BIO_should_io_special GRPC_SHADOW_BIO_should_io_special', - '#define BIO_should_read GRPC_SHADOW_BIO_should_read', - '#define BIO_should_retry GRPC_SHADOW_BIO_should_retry', - '#define BIO_should_write GRPC_SHADOW_BIO_should_write', - '#define BIO_test_flags GRPC_SHADOW_BIO_test_flags', - '#define BIO_up_ref GRPC_SHADOW_BIO_up_ref', - '#define BIO_vfree GRPC_SHADOW_BIO_vfree', - '#define BIO_wpending GRPC_SHADOW_BIO_wpending', - '#define BIO_write GRPC_SHADOW_BIO_write', - '#define ERR_print_errors GRPC_SHADOW_ERR_print_errors', - '#define BIO_get_mem_data GRPC_SHADOW_BIO_get_mem_data', - '#define BIO_get_mem_ptr GRPC_SHADOW_BIO_get_mem_ptr', - '#define BIO_mem_contents GRPC_SHADOW_BIO_mem_contents', - '#define BIO_new_mem_buf GRPC_SHADOW_BIO_new_mem_buf', - '#define BIO_s_mem GRPC_SHADOW_BIO_s_mem', - '#define BIO_set_mem_buf GRPC_SHADOW_BIO_set_mem_buf', - '#define BIO_set_mem_eof_return GRPC_SHADOW_BIO_set_mem_eof_return', - '#define BIO_do_connect GRPC_SHADOW_BIO_do_connect', - '#define BIO_new_connect GRPC_SHADOW_BIO_new_connect', - '#define BIO_s_connect GRPC_SHADOW_BIO_s_connect', - '#define BIO_set_conn_hostname GRPC_SHADOW_BIO_set_conn_hostname', - '#define BIO_set_conn_int_port GRPC_SHADOW_BIO_set_conn_int_port', - '#define BIO_set_conn_port GRPC_SHADOW_BIO_set_conn_port', - '#define BIO_set_nbio GRPC_SHADOW_BIO_set_nbio', - '#define BIO_get_fd GRPC_SHADOW_BIO_get_fd', - '#define BIO_new_fd GRPC_SHADOW_BIO_new_fd', - '#define BIO_s_fd GRPC_SHADOW_BIO_s_fd', - '#define BIO_set_fd GRPC_SHADOW_BIO_set_fd', - '#define bio_fd_should_retry GRPC_SHADOW_bio_fd_should_retry', - '#define BIO_append_filename GRPC_SHADOW_BIO_append_filename', - '#define BIO_get_fp GRPC_SHADOW_BIO_get_fp', - '#define BIO_new_file GRPC_SHADOW_BIO_new_file', - '#define BIO_new_fp GRPC_SHADOW_BIO_new_fp', - '#define BIO_read_filename GRPC_SHADOW_BIO_read_filename', - '#define BIO_rw_filename GRPC_SHADOW_BIO_rw_filename', - '#define BIO_s_file GRPC_SHADOW_BIO_s_file', - '#define BIO_set_fp GRPC_SHADOW_BIO_set_fp', - '#define BIO_write_filename GRPC_SHADOW_BIO_write_filename', - '#define BIO_hexdump GRPC_SHADOW_BIO_hexdump', - '#define BIO_ctrl_get_read_request GRPC_SHADOW_BIO_ctrl_get_read_request', - '#define BIO_ctrl_get_write_guarantee GRPC_SHADOW_BIO_ctrl_get_write_guarantee', - '#define BIO_new_bio_pair GRPC_SHADOW_BIO_new_bio_pair', - '#define BIO_shutdown_wr GRPC_SHADOW_BIO_shutdown_wr', - '#define BIO_printf GRPC_SHADOW_BIO_printf', - '#define BIO_new_socket GRPC_SHADOW_BIO_new_socket', - '#define BIO_s_socket GRPC_SHADOW_BIO_s_socket', - '#define bio_clear_socket_error GRPC_SHADOW_bio_clear_socket_error', - '#define bio_ip_and_port_to_socket_and_addr GRPC_SHADOW_bio_ip_and_port_to_socket_and_addr', - '#define bio_sock_error GRPC_SHADOW_bio_sock_error', - '#define bio_socket_nbio GRPC_SHADOW_bio_socket_nbio', - '#define RAND_enable_fork_unsafe_buffering GRPC_SHADOW_RAND_enable_fork_unsafe_buffering', - '#define rand_fork_unsafe_buffering_enabled GRPC_SHADOW_rand_fork_unsafe_buffering_enabled', - '#define RAND_SSLeay GRPC_SHADOW_RAND_SSLeay', - '#define RAND_add GRPC_SHADOW_RAND_add', - '#define RAND_cleanup GRPC_SHADOW_RAND_cleanup', - '#define RAND_egd GRPC_SHADOW_RAND_egd', - '#define RAND_file_name GRPC_SHADOW_RAND_file_name', - '#define RAND_get_rand_method GRPC_SHADOW_RAND_get_rand_method', - '#define RAND_load_file GRPC_SHADOW_RAND_load_file', - '#define RAND_poll GRPC_SHADOW_RAND_poll', - '#define RAND_seed GRPC_SHADOW_RAND_seed', - '#define RAND_set_rand_method GRPC_SHADOW_RAND_set_rand_method', - '#define RAND_status GRPC_SHADOW_RAND_status', - '#define OBJ_cbs2nid GRPC_SHADOW_OBJ_cbs2nid', - '#define OBJ_cmp GRPC_SHADOW_OBJ_cmp', - '#define OBJ_create GRPC_SHADOW_OBJ_create', - '#define OBJ_dup GRPC_SHADOW_OBJ_dup', - '#define OBJ_get0_data GRPC_SHADOW_OBJ_get0_data', - '#define OBJ_length GRPC_SHADOW_OBJ_length', - '#define OBJ_ln2nid GRPC_SHADOW_OBJ_ln2nid', - '#define OBJ_nid2cbb GRPC_SHADOW_OBJ_nid2cbb', - '#define OBJ_nid2ln GRPC_SHADOW_OBJ_nid2ln', - '#define OBJ_nid2obj GRPC_SHADOW_OBJ_nid2obj', - '#define OBJ_nid2sn GRPC_SHADOW_OBJ_nid2sn', - '#define OBJ_obj2nid GRPC_SHADOW_OBJ_obj2nid', - '#define OBJ_obj2txt GRPC_SHADOW_OBJ_obj2txt', - '#define OBJ_sn2nid GRPC_SHADOW_OBJ_sn2nid', - '#define OBJ_txt2nid GRPC_SHADOW_OBJ_txt2nid', - '#define OBJ_txt2obj GRPC_SHADOW_OBJ_txt2obj', - '#define OBJ_find_sigid_algs GRPC_SHADOW_OBJ_find_sigid_algs', - '#define OBJ_find_sigid_by_algs GRPC_SHADOW_OBJ_find_sigid_by_algs', - '#define ASN1_BIT_STRING_check GRPC_SHADOW_ASN1_BIT_STRING_check', - '#define ASN1_BIT_STRING_get_bit GRPC_SHADOW_ASN1_BIT_STRING_get_bit', - '#define ASN1_BIT_STRING_set GRPC_SHADOW_ASN1_BIT_STRING_set', - '#define ASN1_BIT_STRING_set_bit GRPC_SHADOW_ASN1_BIT_STRING_set_bit', - '#define c2i_ASN1_BIT_STRING GRPC_SHADOW_c2i_ASN1_BIT_STRING', - '#define i2c_ASN1_BIT_STRING GRPC_SHADOW_i2c_ASN1_BIT_STRING', - '#define d2i_ASN1_BOOLEAN GRPC_SHADOW_d2i_ASN1_BOOLEAN', - '#define i2d_ASN1_BOOLEAN GRPC_SHADOW_i2d_ASN1_BOOLEAN', - '#define ASN1_d2i_bio GRPC_SHADOW_ASN1_d2i_bio', - '#define ASN1_d2i_fp GRPC_SHADOW_ASN1_d2i_fp', - '#define ASN1_item_d2i_bio GRPC_SHADOW_ASN1_item_d2i_bio', - '#define ASN1_item_d2i_fp GRPC_SHADOW_ASN1_item_d2i_fp', - '#define ASN1_dup GRPC_SHADOW_ASN1_dup', - '#define ASN1_item_dup GRPC_SHADOW_ASN1_item_dup', - '#define ASN1_ENUMERATED_get GRPC_SHADOW_ASN1_ENUMERATED_get', - '#define ASN1_ENUMERATED_set GRPC_SHADOW_ASN1_ENUMERATED_set', - '#define ASN1_ENUMERATED_to_BN GRPC_SHADOW_ASN1_ENUMERATED_to_BN', - '#define BN_to_ASN1_ENUMERATED GRPC_SHADOW_BN_to_ASN1_ENUMERATED', - '#define ASN1_GENERALIZEDTIME_adj GRPC_SHADOW_ASN1_GENERALIZEDTIME_adj', - '#define ASN1_GENERALIZEDTIME_check GRPC_SHADOW_ASN1_GENERALIZEDTIME_check', - '#define ASN1_GENERALIZEDTIME_set GRPC_SHADOW_ASN1_GENERALIZEDTIME_set', - '#define ASN1_GENERALIZEDTIME_set_string GRPC_SHADOW_ASN1_GENERALIZEDTIME_set_string', - '#define asn1_generalizedtime_to_tm GRPC_SHADOW_asn1_generalizedtime_to_tm', - '#define ASN1_i2d_bio GRPC_SHADOW_ASN1_i2d_bio', - '#define ASN1_i2d_fp GRPC_SHADOW_ASN1_i2d_fp', - '#define ASN1_item_i2d_bio GRPC_SHADOW_ASN1_item_i2d_bio', - '#define ASN1_item_i2d_fp GRPC_SHADOW_ASN1_item_i2d_fp', - '#define ASN1_INTEGER_cmp GRPC_SHADOW_ASN1_INTEGER_cmp', - '#define ASN1_INTEGER_dup GRPC_SHADOW_ASN1_INTEGER_dup', - '#define ASN1_INTEGER_get GRPC_SHADOW_ASN1_INTEGER_get', - '#define ASN1_INTEGER_set GRPC_SHADOW_ASN1_INTEGER_set', - '#define ASN1_INTEGER_set_uint64 GRPC_SHADOW_ASN1_INTEGER_set_uint64', - '#define ASN1_INTEGER_to_BN GRPC_SHADOW_ASN1_INTEGER_to_BN', - '#define BN_to_ASN1_INTEGER GRPC_SHADOW_BN_to_ASN1_INTEGER', - '#define c2i_ASN1_INTEGER GRPC_SHADOW_c2i_ASN1_INTEGER', - '#define d2i_ASN1_UINTEGER GRPC_SHADOW_d2i_ASN1_UINTEGER', - '#define i2c_ASN1_INTEGER GRPC_SHADOW_i2c_ASN1_INTEGER', - '#define ASN1_mbstring_copy GRPC_SHADOW_ASN1_mbstring_copy', - '#define ASN1_mbstring_ncopy GRPC_SHADOW_ASN1_mbstring_ncopy', - '#define ASN1_OBJECT_create GRPC_SHADOW_ASN1_OBJECT_create', - '#define ASN1_OBJECT_free GRPC_SHADOW_ASN1_OBJECT_free', - '#define ASN1_OBJECT_new GRPC_SHADOW_ASN1_OBJECT_new', - '#define c2i_ASN1_OBJECT GRPC_SHADOW_c2i_ASN1_OBJECT', - '#define d2i_ASN1_OBJECT GRPC_SHADOW_d2i_ASN1_OBJECT', - '#define i2a_ASN1_OBJECT GRPC_SHADOW_i2a_ASN1_OBJECT', - '#define i2d_ASN1_OBJECT GRPC_SHADOW_i2d_ASN1_OBJECT', - '#define i2t_ASN1_OBJECT GRPC_SHADOW_i2t_ASN1_OBJECT', - '#define ASN1_OCTET_STRING_cmp GRPC_SHADOW_ASN1_OCTET_STRING_cmp', - '#define ASN1_OCTET_STRING_dup GRPC_SHADOW_ASN1_OCTET_STRING_dup', - '#define ASN1_OCTET_STRING_set GRPC_SHADOW_ASN1_OCTET_STRING_set', - '#define ASN1_PRINTABLE_type GRPC_SHADOW_ASN1_PRINTABLE_type', - '#define ASN1_STRING_TABLE_add GRPC_SHADOW_ASN1_STRING_TABLE_add', - '#define ASN1_STRING_TABLE_cleanup GRPC_SHADOW_ASN1_STRING_TABLE_cleanup', - '#define ASN1_STRING_TABLE_get GRPC_SHADOW_ASN1_STRING_TABLE_get', - '#define ASN1_STRING_get_default_mask GRPC_SHADOW_ASN1_STRING_get_default_mask', - '#define ASN1_STRING_set_by_NID GRPC_SHADOW_ASN1_STRING_set_by_NID', - '#define ASN1_STRING_set_default_mask GRPC_SHADOW_ASN1_STRING_set_default_mask', - '#define ASN1_STRING_set_default_mask_asc GRPC_SHADOW_ASN1_STRING_set_default_mask_asc', - '#define ASN1_TIME_adj GRPC_SHADOW_ASN1_TIME_adj', - '#define ASN1_TIME_check GRPC_SHADOW_ASN1_TIME_check', - '#define ASN1_TIME_diff GRPC_SHADOW_ASN1_TIME_diff', - '#define ASN1_TIME_free GRPC_SHADOW_ASN1_TIME_free', - '#define ASN1_TIME_it GRPC_SHADOW_ASN1_TIME_it', - '#define ASN1_TIME_new GRPC_SHADOW_ASN1_TIME_new', - '#define ASN1_TIME_set GRPC_SHADOW_ASN1_TIME_set', - '#define ASN1_TIME_set_string GRPC_SHADOW_ASN1_TIME_set_string', - '#define ASN1_TIME_to_generalizedtime GRPC_SHADOW_ASN1_TIME_to_generalizedtime', - '#define d2i_ASN1_TIME GRPC_SHADOW_d2i_ASN1_TIME', - '#define i2d_ASN1_TIME GRPC_SHADOW_i2d_ASN1_TIME', - '#define ASN1_TYPE_cmp GRPC_SHADOW_ASN1_TYPE_cmp', - '#define ASN1_TYPE_get GRPC_SHADOW_ASN1_TYPE_get', - '#define ASN1_TYPE_set GRPC_SHADOW_ASN1_TYPE_set', - '#define ASN1_TYPE_set1 GRPC_SHADOW_ASN1_TYPE_set1', - '#define ASN1_UTCTIME_adj GRPC_SHADOW_ASN1_UTCTIME_adj', - '#define ASN1_UTCTIME_check GRPC_SHADOW_ASN1_UTCTIME_check', - '#define ASN1_UTCTIME_cmp_time_t GRPC_SHADOW_ASN1_UTCTIME_cmp_time_t', - '#define ASN1_UTCTIME_set GRPC_SHADOW_ASN1_UTCTIME_set', - '#define ASN1_UTCTIME_set_string GRPC_SHADOW_ASN1_UTCTIME_set_string', - '#define asn1_utctime_to_tm GRPC_SHADOW_asn1_utctime_to_tm', - '#define UTF8_getc GRPC_SHADOW_UTF8_getc', - '#define UTF8_putc GRPC_SHADOW_UTF8_putc', - '#define ASN1_STRING_cmp GRPC_SHADOW_ASN1_STRING_cmp', - '#define ASN1_STRING_copy GRPC_SHADOW_ASN1_STRING_copy', - '#define ASN1_STRING_data GRPC_SHADOW_ASN1_STRING_data', - '#define ASN1_STRING_dup GRPC_SHADOW_ASN1_STRING_dup', - '#define ASN1_STRING_free GRPC_SHADOW_ASN1_STRING_free', - '#define ASN1_STRING_get0_data GRPC_SHADOW_ASN1_STRING_get0_data', - '#define ASN1_STRING_length GRPC_SHADOW_ASN1_STRING_length', - '#define ASN1_STRING_length_set GRPC_SHADOW_ASN1_STRING_length_set', - '#define ASN1_STRING_new GRPC_SHADOW_ASN1_STRING_new', - '#define ASN1_STRING_set GRPC_SHADOW_ASN1_STRING_set', - '#define ASN1_STRING_set0 GRPC_SHADOW_ASN1_STRING_set0', - '#define ASN1_STRING_type GRPC_SHADOW_ASN1_STRING_type', - '#define ASN1_STRING_type_new GRPC_SHADOW_ASN1_STRING_type_new', - '#define ASN1_get_object GRPC_SHADOW_ASN1_get_object', - '#define ASN1_object_size GRPC_SHADOW_ASN1_object_size', - '#define ASN1_put_eoc GRPC_SHADOW_ASN1_put_eoc', - '#define ASN1_put_object GRPC_SHADOW_ASN1_put_object', - '#define ASN1_tag2str GRPC_SHADOW_ASN1_tag2str', - '#define ASN1_item_pack GRPC_SHADOW_ASN1_item_pack', - '#define ASN1_item_unpack GRPC_SHADOW_ASN1_item_unpack', - '#define i2a_ASN1_ENUMERATED GRPC_SHADOW_i2a_ASN1_ENUMERATED', - '#define i2a_ASN1_INTEGER GRPC_SHADOW_i2a_ASN1_INTEGER', - '#define i2a_ASN1_STRING GRPC_SHADOW_i2a_ASN1_STRING', - '#define ASN1_item_d2i GRPC_SHADOW_ASN1_item_d2i', - '#define ASN1_item_ex_d2i GRPC_SHADOW_ASN1_item_ex_d2i', - '#define ASN1_tag2bit GRPC_SHADOW_ASN1_tag2bit', - '#define asn1_ex_c2i GRPC_SHADOW_asn1_ex_c2i', - '#define ASN1_item_ex_i2d GRPC_SHADOW_ASN1_item_ex_i2d', - '#define ASN1_item_i2d GRPC_SHADOW_ASN1_item_i2d', - '#define ASN1_item_ndef_i2d GRPC_SHADOW_ASN1_item_ndef_i2d', - '#define asn1_ex_i2c GRPC_SHADOW_asn1_ex_i2c', - '#define ASN1_item_ex_free GRPC_SHADOW_ASN1_item_ex_free', - '#define ASN1_item_free GRPC_SHADOW_ASN1_item_free', - '#define ASN1_primitive_free GRPC_SHADOW_ASN1_primitive_free', - '#define ASN1_template_free GRPC_SHADOW_ASN1_template_free', - '#define asn1_item_combine_free GRPC_SHADOW_asn1_item_combine_free', - '#define ASN1_item_ex_new GRPC_SHADOW_ASN1_item_ex_new', - '#define ASN1_item_new GRPC_SHADOW_ASN1_item_new', - '#define ASN1_primitive_new GRPC_SHADOW_ASN1_primitive_new', - '#define ASN1_template_new GRPC_SHADOW_ASN1_template_new', - '#define ASN1_ANY_it GRPC_SHADOW_ASN1_ANY_it', - '#define ASN1_BIT_STRING_free GRPC_SHADOW_ASN1_BIT_STRING_free', - '#define ASN1_BIT_STRING_it GRPC_SHADOW_ASN1_BIT_STRING_it', - '#define ASN1_BIT_STRING_new GRPC_SHADOW_ASN1_BIT_STRING_new', - '#define ASN1_BMPSTRING_free GRPC_SHADOW_ASN1_BMPSTRING_free', - '#define ASN1_BMPSTRING_it GRPC_SHADOW_ASN1_BMPSTRING_it', - '#define ASN1_BMPSTRING_new GRPC_SHADOW_ASN1_BMPSTRING_new', - '#define ASN1_BOOLEAN_it GRPC_SHADOW_ASN1_BOOLEAN_it', - '#define ASN1_ENUMERATED_free GRPC_SHADOW_ASN1_ENUMERATED_free', - '#define ASN1_ENUMERATED_it GRPC_SHADOW_ASN1_ENUMERATED_it', - '#define ASN1_ENUMERATED_new GRPC_SHADOW_ASN1_ENUMERATED_new', - '#define ASN1_FBOOLEAN_it GRPC_SHADOW_ASN1_FBOOLEAN_it', - '#define ASN1_GENERALIZEDTIME_free GRPC_SHADOW_ASN1_GENERALIZEDTIME_free', - '#define ASN1_GENERALIZEDTIME_it GRPC_SHADOW_ASN1_GENERALIZEDTIME_it', - '#define ASN1_GENERALIZEDTIME_new GRPC_SHADOW_ASN1_GENERALIZEDTIME_new', - '#define ASN1_GENERALSTRING_free GRPC_SHADOW_ASN1_GENERALSTRING_free', - '#define ASN1_GENERALSTRING_it GRPC_SHADOW_ASN1_GENERALSTRING_it', - '#define ASN1_GENERALSTRING_new GRPC_SHADOW_ASN1_GENERALSTRING_new', - '#define ASN1_IA5STRING_free GRPC_SHADOW_ASN1_IA5STRING_free', - '#define ASN1_IA5STRING_it GRPC_SHADOW_ASN1_IA5STRING_it', - '#define ASN1_IA5STRING_new GRPC_SHADOW_ASN1_IA5STRING_new', - '#define ASN1_INTEGER_free GRPC_SHADOW_ASN1_INTEGER_free', - '#define ASN1_INTEGER_it GRPC_SHADOW_ASN1_INTEGER_it', - '#define ASN1_INTEGER_new GRPC_SHADOW_ASN1_INTEGER_new', - '#define ASN1_NULL_free GRPC_SHADOW_ASN1_NULL_free', - '#define ASN1_NULL_it GRPC_SHADOW_ASN1_NULL_it', - '#define ASN1_NULL_new GRPC_SHADOW_ASN1_NULL_new', - '#define ASN1_OBJECT_it GRPC_SHADOW_ASN1_OBJECT_it', - '#define ASN1_OCTET_STRING_NDEF_it GRPC_SHADOW_ASN1_OCTET_STRING_NDEF_it', - '#define ASN1_OCTET_STRING_free GRPC_SHADOW_ASN1_OCTET_STRING_free', - '#define ASN1_OCTET_STRING_it GRPC_SHADOW_ASN1_OCTET_STRING_it', - '#define ASN1_OCTET_STRING_new GRPC_SHADOW_ASN1_OCTET_STRING_new', - '#define ASN1_PRINTABLESTRING_free GRPC_SHADOW_ASN1_PRINTABLESTRING_free', - '#define ASN1_PRINTABLESTRING_it GRPC_SHADOW_ASN1_PRINTABLESTRING_it', - '#define ASN1_PRINTABLESTRING_new GRPC_SHADOW_ASN1_PRINTABLESTRING_new', - '#define ASN1_PRINTABLE_free GRPC_SHADOW_ASN1_PRINTABLE_free', - '#define ASN1_PRINTABLE_it GRPC_SHADOW_ASN1_PRINTABLE_it', - '#define ASN1_PRINTABLE_new GRPC_SHADOW_ASN1_PRINTABLE_new', - '#define ASN1_SEQUENCE_ANY_it GRPC_SHADOW_ASN1_SEQUENCE_ANY_it', - '#define ASN1_SEQUENCE_it GRPC_SHADOW_ASN1_SEQUENCE_it', - '#define ASN1_SET_ANY_it GRPC_SHADOW_ASN1_SET_ANY_it', - '#define ASN1_T61STRING_free GRPC_SHADOW_ASN1_T61STRING_free', - '#define ASN1_T61STRING_it GRPC_SHADOW_ASN1_T61STRING_it', - '#define ASN1_T61STRING_new GRPC_SHADOW_ASN1_T61STRING_new', - '#define ASN1_TBOOLEAN_it GRPC_SHADOW_ASN1_TBOOLEAN_it', - '#define ASN1_TYPE_free GRPC_SHADOW_ASN1_TYPE_free', - '#define ASN1_TYPE_new GRPC_SHADOW_ASN1_TYPE_new', - '#define ASN1_UNIVERSALSTRING_free GRPC_SHADOW_ASN1_UNIVERSALSTRING_free', - '#define ASN1_UNIVERSALSTRING_it GRPC_SHADOW_ASN1_UNIVERSALSTRING_it', - '#define ASN1_UNIVERSALSTRING_new GRPC_SHADOW_ASN1_UNIVERSALSTRING_new', - '#define ASN1_UTCTIME_free GRPC_SHADOW_ASN1_UTCTIME_free', - '#define ASN1_UTCTIME_it GRPC_SHADOW_ASN1_UTCTIME_it', - '#define ASN1_UTCTIME_new GRPC_SHADOW_ASN1_UTCTIME_new', - '#define ASN1_UTF8STRING_free GRPC_SHADOW_ASN1_UTF8STRING_free', - '#define ASN1_UTF8STRING_it GRPC_SHADOW_ASN1_UTF8STRING_it', - '#define ASN1_UTF8STRING_new GRPC_SHADOW_ASN1_UTF8STRING_new', - '#define ASN1_VISIBLESTRING_free GRPC_SHADOW_ASN1_VISIBLESTRING_free', - '#define ASN1_VISIBLESTRING_it GRPC_SHADOW_ASN1_VISIBLESTRING_it', - '#define ASN1_VISIBLESTRING_new GRPC_SHADOW_ASN1_VISIBLESTRING_new', - '#define DIRECTORYSTRING_free GRPC_SHADOW_DIRECTORYSTRING_free', - '#define DIRECTORYSTRING_it GRPC_SHADOW_DIRECTORYSTRING_it', - '#define DIRECTORYSTRING_new GRPC_SHADOW_DIRECTORYSTRING_new', - '#define DISPLAYTEXT_free GRPC_SHADOW_DISPLAYTEXT_free', - '#define DISPLAYTEXT_it GRPC_SHADOW_DISPLAYTEXT_it', - '#define DISPLAYTEXT_new GRPC_SHADOW_DISPLAYTEXT_new', - '#define d2i_ASN1_BIT_STRING GRPC_SHADOW_d2i_ASN1_BIT_STRING', - '#define d2i_ASN1_BMPSTRING GRPC_SHADOW_d2i_ASN1_BMPSTRING', - '#define d2i_ASN1_ENUMERATED GRPC_SHADOW_d2i_ASN1_ENUMERATED', - '#define d2i_ASN1_GENERALIZEDTIME GRPC_SHADOW_d2i_ASN1_GENERALIZEDTIME', - '#define d2i_ASN1_GENERALSTRING GRPC_SHADOW_d2i_ASN1_GENERALSTRING', - '#define d2i_ASN1_IA5STRING GRPC_SHADOW_d2i_ASN1_IA5STRING', - '#define d2i_ASN1_INTEGER GRPC_SHADOW_d2i_ASN1_INTEGER', - '#define d2i_ASN1_NULL GRPC_SHADOW_d2i_ASN1_NULL', - '#define d2i_ASN1_OCTET_STRING GRPC_SHADOW_d2i_ASN1_OCTET_STRING', - '#define d2i_ASN1_PRINTABLE GRPC_SHADOW_d2i_ASN1_PRINTABLE', - '#define d2i_ASN1_PRINTABLESTRING GRPC_SHADOW_d2i_ASN1_PRINTABLESTRING', - '#define d2i_ASN1_SEQUENCE_ANY GRPC_SHADOW_d2i_ASN1_SEQUENCE_ANY', - '#define d2i_ASN1_SET_ANY GRPC_SHADOW_d2i_ASN1_SET_ANY', - '#define d2i_ASN1_T61STRING GRPC_SHADOW_d2i_ASN1_T61STRING', - '#define d2i_ASN1_TYPE GRPC_SHADOW_d2i_ASN1_TYPE', - '#define d2i_ASN1_UNIVERSALSTRING GRPC_SHADOW_d2i_ASN1_UNIVERSALSTRING', - '#define d2i_ASN1_UTCTIME GRPC_SHADOW_d2i_ASN1_UTCTIME', - '#define d2i_ASN1_UTF8STRING GRPC_SHADOW_d2i_ASN1_UTF8STRING', - '#define d2i_ASN1_VISIBLESTRING GRPC_SHADOW_d2i_ASN1_VISIBLESTRING', - '#define d2i_DIRECTORYSTRING GRPC_SHADOW_d2i_DIRECTORYSTRING', - '#define d2i_DISPLAYTEXT GRPC_SHADOW_d2i_DISPLAYTEXT', - '#define i2d_ASN1_BIT_STRING GRPC_SHADOW_i2d_ASN1_BIT_STRING', - '#define i2d_ASN1_BMPSTRING GRPC_SHADOW_i2d_ASN1_BMPSTRING', - '#define i2d_ASN1_ENUMERATED GRPC_SHADOW_i2d_ASN1_ENUMERATED', - '#define i2d_ASN1_GENERALIZEDTIME GRPC_SHADOW_i2d_ASN1_GENERALIZEDTIME', - '#define i2d_ASN1_GENERALSTRING GRPC_SHADOW_i2d_ASN1_GENERALSTRING', - '#define i2d_ASN1_IA5STRING GRPC_SHADOW_i2d_ASN1_IA5STRING', - '#define i2d_ASN1_INTEGER GRPC_SHADOW_i2d_ASN1_INTEGER', - '#define i2d_ASN1_NULL GRPC_SHADOW_i2d_ASN1_NULL', - '#define i2d_ASN1_OCTET_STRING GRPC_SHADOW_i2d_ASN1_OCTET_STRING', - '#define i2d_ASN1_PRINTABLE GRPC_SHADOW_i2d_ASN1_PRINTABLE', - '#define i2d_ASN1_PRINTABLESTRING GRPC_SHADOW_i2d_ASN1_PRINTABLESTRING', - '#define i2d_ASN1_SEQUENCE_ANY GRPC_SHADOW_i2d_ASN1_SEQUENCE_ANY', - '#define i2d_ASN1_SET_ANY GRPC_SHADOW_i2d_ASN1_SET_ANY', - '#define i2d_ASN1_T61STRING GRPC_SHADOW_i2d_ASN1_T61STRING', - '#define i2d_ASN1_TYPE GRPC_SHADOW_i2d_ASN1_TYPE', - '#define i2d_ASN1_UNIVERSALSTRING GRPC_SHADOW_i2d_ASN1_UNIVERSALSTRING', - '#define i2d_ASN1_UTCTIME GRPC_SHADOW_i2d_ASN1_UTCTIME', - '#define i2d_ASN1_UTF8STRING GRPC_SHADOW_i2d_ASN1_UTF8STRING', - '#define i2d_ASN1_VISIBLESTRING GRPC_SHADOW_i2d_ASN1_VISIBLESTRING', - '#define i2d_DIRECTORYSTRING GRPC_SHADOW_i2d_DIRECTORYSTRING', - '#define i2d_DISPLAYTEXT GRPC_SHADOW_i2d_DISPLAYTEXT', - '#define asn1_do_adb GRPC_SHADOW_asn1_do_adb', - '#define asn1_enc_free GRPC_SHADOW_asn1_enc_free', - '#define asn1_enc_init GRPC_SHADOW_asn1_enc_init', - '#define asn1_enc_restore GRPC_SHADOW_asn1_enc_restore', - '#define asn1_enc_save GRPC_SHADOW_asn1_enc_save', - '#define asn1_get_choice_selector GRPC_SHADOW_asn1_get_choice_selector', - '#define asn1_get_field_ptr GRPC_SHADOW_asn1_get_field_ptr', - '#define asn1_refcount_dec_and_test_zero GRPC_SHADOW_asn1_refcount_dec_and_test_zero', - '#define asn1_refcount_set_one GRPC_SHADOW_asn1_refcount_set_one', - '#define asn1_set_choice_selector GRPC_SHADOW_asn1_set_choice_selector', - '#define OPENSSL_gmtime GRPC_SHADOW_OPENSSL_gmtime', - '#define OPENSSL_gmtime_adj GRPC_SHADOW_OPENSSL_gmtime_adj', - '#define OPENSSL_gmtime_diff GRPC_SHADOW_OPENSSL_gmtime_diff', - '#define ENGINE_free GRPC_SHADOW_ENGINE_free', - '#define ENGINE_get_ECDSA_method GRPC_SHADOW_ENGINE_get_ECDSA_method', - '#define ENGINE_get_RSA_method GRPC_SHADOW_ENGINE_get_RSA_method', - '#define ENGINE_new GRPC_SHADOW_ENGINE_new', - '#define ENGINE_set_ECDSA_method GRPC_SHADOW_ENGINE_set_ECDSA_method', - '#define ENGINE_set_RSA_method GRPC_SHADOW_ENGINE_set_RSA_method', - '#define METHOD_ref GRPC_SHADOW_METHOD_ref', - '#define METHOD_unref GRPC_SHADOW_METHOD_unref', - '#define DH_compute_key GRPC_SHADOW_DH_compute_key', - '#define DH_free GRPC_SHADOW_DH_free', - '#define DH_generate_key GRPC_SHADOW_DH_generate_key', - '#define DH_generate_parameters_ex GRPC_SHADOW_DH_generate_parameters_ex', - '#define DH_get0_key GRPC_SHADOW_DH_get0_key', - '#define DH_get0_pqg GRPC_SHADOW_DH_get0_pqg', - '#define DH_get_ex_data GRPC_SHADOW_DH_get_ex_data', - '#define DH_get_ex_new_index GRPC_SHADOW_DH_get_ex_new_index', - '#define DH_new GRPC_SHADOW_DH_new', - '#define DH_num_bits GRPC_SHADOW_DH_num_bits', - '#define DH_set0_key GRPC_SHADOW_DH_set0_key', - '#define DH_set0_pqg GRPC_SHADOW_DH_set0_pqg', - '#define DH_set_ex_data GRPC_SHADOW_DH_set_ex_data', - '#define DH_size GRPC_SHADOW_DH_size', - '#define DH_up_ref GRPC_SHADOW_DH_up_ref', - '#define DHparams_dup GRPC_SHADOW_DHparams_dup', - '#define BN_get_rfc3526_prime_1536 GRPC_SHADOW_BN_get_rfc3526_prime_1536', - '#define DH_check GRPC_SHADOW_DH_check', - '#define DH_check_pub_key GRPC_SHADOW_DH_check_pub_key', - '#define DH_marshal_parameters GRPC_SHADOW_DH_marshal_parameters', - '#define DH_parse_parameters GRPC_SHADOW_DH_parse_parameters', - '#define d2i_DHparams GRPC_SHADOW_d2i_DHparams', - '#define i2d_DHparams GRPC_SHADOW_i2d_DHparams', - '#define DSA_SIG_free GRPC_SHADOW_DSA_SIG_free', - '#define DSA_SIG_new GRPC_SHADOW_DSA_SIG_new', - '#define DSA_check_signature GRPC_SHADOW_DSA_check_signature', - '#define DSA_do_check_signature GRPC_SHADOW_DSA_do_check_signature', - '#define DSA_do_sign GRPC_SHADOW_DSA_do_sign', - '#define DSA_do_verify GRPC_SHADOW_DSA_do_verify', - '#define DSA_dup_DH GRPC_SHADOW_DSA_dup_DH', - '#define DSA_free GRPC_SHADOW_DSA_free', - '#define DSA_generate_key GRPC_SHADOW_DSA_generate_key', - '#define DSA_generate_parameters_ex GRPC_SHADOW_DSA_generate_parameters_ex', - '#define DSA_get0_key GRPC_SHADOW_DSA_get0_key', - '#define DSA_get0_pqg GRPC_SHADOW_DSA_get0_pqg', - '#define DSA_get_ex_data GRPC_SHADOW_DSA_get_ex_data', - '#define DSA_get_ex_new_index GRPC_SHADOW_DSA_get_ex_new_index', - '#define DSA_new GRPC_SHADOW_DSA_new', - '#define DSA_set0_key GRPC_SHADOW_DSA_set0_key', - '#define DSA_set0_pqg GRPC_SHADOW_DSA_set0_pqg', - '#define DSA_set_ex_data GRPC_SHADOW_DSA_set_ex_data', - '#define DSA_sign GRPC_SHADOW_DSA_sign', - '#define DSA_size GRPC_SHADOW_DSA_size', - '#define DSA_up_ref GRPC_SHADOW_DSA_up_ref', - '#define DSA_verify GRPC_SHADOW_DSA_verify', - '#define DSAparams_dup GRPC_SHADOW_DSAparams_dup', - '#define DSA_SIG_marshal GRPC_SHADOW_DSA_SIG_marshal', - '#define DSA_SIG_parse GRPC_SHADOW_DSA_SIG_parse', - '#define DSA_marshal_parameters GRPC_SHADOW_DSA_marshal_parameters', - '#define DSA_marshal_private_key GRPC_SHADOW_DSA_marshal_private_key', - '#define DSA_marshal_public_key GRPC_SHADOW_DSA_marshal_public_key', - '#define DSA_parse_parameters GRPC_SHADOW_DSA_parse_parameters', - '#define DSA_parse_private_key GRPC_SHADOW_DSA_parse_private_key', - '#define DSA_parse_public_key GRPC_SHADOW_DSA_parse_public_key', - '#define d2i_DSAPrivateKey GRPC_SHADOW_d2i_DSAPrivateKey', - '#define d2i_DSAPublicKey GRPC_SHADOW_d2i_DSAPublicKey', - '#define d2i_DSA_SIG GRPC_SHADOW_d2i_DSA_SIG', - '#define d2i_DSAparams GRPC_SHADOW_d2i_DSAparams', - '#define i2d_DSAPrivateKey GRPC_SHADOW_i2d_DSAPrivateKey', - '#define i2d_DSAPublicKey GRPC_SHADOW_i2d_DSAPublicKey', - '#define i2d_DSA_SIG GRPC_SHADOW_i2d_DSA_SIG', - '#define i2d_DSAparams GRPC_SHADOW_i2d_DSAparams', - '#define RSAPrivateKey_dup GRPC_SHADOW_RSAPrivateKey_dup', - '#define RSAPublicKey_dup GRPC_SHADOW_RSAPublicKey_dup', - '#define RSA_marshal_private_key GRPC_SHADOW_RSA_marshal_private_key', - '#define RSA_marshal_public_key GRPC_SHADOW_RSA_marshal_public_key', - '#define RSA_parse_private_key GRPC_SHADOW_RSA_parse_private_key', - '#define RSA_parse_public_key GRPC_SHADOW_RSA_parse_public_key', - '#define RSA_private_key_from_bytes GRPC_SHADOW_RSA_private_key_from_bytes', - '#define RSA_private_key_to_bytes GRPC_SHADOW_RSA_private_key_to_bytes', - '#define RSA_public_key_from_bytes GRPC_SHADOW_RSA_public_key_from_bytes', - '#define RSA_public_key_to_bytes GRPC_SHADOW_RSA_public_key_to_bytes', - '#define d2i_RSAPrivateKey GRPC_SHADOW_d2i_RSAPrivateKey', - '#define d2i_RSAPublicKey GRPC_SHADOW_d2i_RSAPublicKey', - '#define i2d_RSAPrivateKey GRPC_SHADOW_i2d_RSAPrivateKey', - '#define i2d_RSAPublicKey GRPC_SHADOW_i2d_RSAPublicKey', - '#define EC_KEY_marshal_curve_name GRPC_SHADOW_EC_KEY_marshal_curve_name', - '#define EC_KEY_marshal_private_key GRPC_SHADOW_EC_KEY_marshal_private_key', - '#define EC_KEY_parse_curve_name GRPC_SHADOW_EC_KEY_parse_curve_name', - '#define EC_KEY_parse_parameters GRPC_SHADOW_EC_KEY_parse_parameters', - '#define EC_KEY_parse_private_key GRPC_SHADOW_EC_KEY_parse_private_key', - '#define EC_POINT_point2cbb GRPC_SHADOW_EC_POINT_point2cbb', - '#define d2i_ECParameters GRPC_SHADOW_d2i_ECParameters', - '#define d2i_ECPrivateKey GRPC_SHADOW_d2i_ECPrivateKey', - '#define i2d_ECParameters GRPC_SHADOW_i2d_ECParameters', - '#define i2d_ECPrivateKey GRPC_SHADOW_i2d_ECPrivateKey', - '#define i2o_ECPublicKey GRPC_SHADOW_i2o_ECPublicKey', - '#define o2i_ECPublicKey GRPC_SHADOW_o2i_ECPublicKey', - '#define ECDH_compute_key GRPC_SHADOW_ECDH_compute_key', - '#define ECDSA_SIG_from_bytes GRPC_SHADOW_ECDSA_SIG_from_bytes', - '#define ECDSA_SIG_marshal GRPC_SHADOW_ECDSA_SIG_marshal', - '#define ECDSA_SIG_max_len GRPC_SHADOW_ECDSA_SIG_max_len', - '#define ECDSA_SIG_parse GRPC_SHADOW_ECDSA_SIG_parse', - '#define ECDSA_SIG_to_bytes GRPC_SHADOW_ECDSA_SIG_to_bytes', - '#define ECDSA_sign GRPC_SHADOW_ECDSA_sign', - '#define ECDSA_size GRPC_SHADOW_ECDSA_size', - '#define ECDSA_verify GRPC_SHADOW_ECDSA_verify', - '#define d2i_ECDSA_SIG GRPC_SHADOW_d2i_ECDSA_SIG', - '#define i2d_ECDSA_SIG GRPC_SHADOW_i2d_ECDSA_SIG', - '#define AES_CMAC GRPC_SHADOW_AES_CMAC', - '#define CMAC_CTX_free GRPC_SHADOW_CMAC_CTX_free', - '#define CMAC_CTX_new GRPC_SHADOW_CMAC_CTX_new', - '#define CMAC_Final GRPC_SHADOW_CMAC_Final', - '#define CMAC_Init GRPC_SHADOW_CMAC_Init', - '#define CMAC_Reset GRPC_SHADOW_CMAC_Reset', - '#define CMAC_Update GRPC_SHADOW_CMAC_Update', - '#define EVP_DigestSign GRPC_SHADOW_EVP_DigestSign', - '#define EVP_DigestSignFinal GRPC_SHADOW_EVP_DigestSignFinal', - '#define EVP_DigestSignInit GRPC_SHADOW_EVP_DigestSignInit', - '#define EVP_DigestSignUpdate GRPC_SHADOW_EVP_DigestSignUpdate', - '#define EVP_DigestVerify GRPC_SHADOW_EVP_DigestVerify', - '#define EVP_DigestVerifyFinal GRPC_SHADOW_EVP_DigestVerifyFinal', - '#define EVP_DigestVerifyInit GRPC_SHADOW_EVP_DigestVerifyInit', - '#define EVP_DigestVerifyUpdate GRPC_SHADOW_EVP_DigestVerifyUpdate', - '#define EVP_PKEY_CTX_get_signature_md GRPC_SHADOW_EVP_PKEY_CTX_get_signature_md', - '#define EVP_PKEY_CTX_set_signature_md GRPC_SHADOW_EVP_PKEY_CTX_set_signature_md', - '#define EVP_PKEY_assign GRPC_SHADOW_EVP_PKEY_assign', - '#define EVP_PKEY_assign_DSA GRPC_SHADOW_EVP_PKEY_assign_DSA', - '#define EVP_PKEY_assign_EC_KEY GRPC_SHADOW_EVP_PKEY_assign_EC_KEY', - '#define EVP_PKEY_assign_RSA GRPC_SHADOW_EVP_PKEY_assign_RSA', - '#define EVP_PKEY_bits GRPC_SHADOW_EVP_PKEY_bits', - '#define EVP_PKEY_cmp GRPC_SHADOW_EVP_PKEY_cmp', - '#define EVP_PKEY_cmp_parameters GRPC_SHADOW_EVP_PKEY_cmp_parameters', - '#define EVP_PKEY_copy_parameters GRPC_SHADOW_EVP_PKEY_copy_parameters', - '#define EVP_PKEY_free GRPC_SHADOW_EVP_PKEY_free', - '#define EVP_PKEY_get0_DH GRPC_SHADOW_EVP_PKEY_get0_DH', - '#define EVP_PKEY_get0_DSA GRPC_SHADOW_EVP_PKEY_get0_DSA', - '#define EVP_PKEY_get0_EC_KEY GRPC_SHADOW_EVP_PKEY_get0_EC_KEY', - '#define EVP_PKEY_get0_RSA GRPC_SHADOW_EVP_PKEY_get0_RSA', - '#define EVP_PKEY_get1_DSA GRPC_SHADOW_EVP_PKEY_get1_DSA', - '#define EVP_PKEY_get1_EC_KEY GRPC_SHADOW_EVP_PKEY_get1_EC_KEY', - '#define EVP_PKEY_get1_RSA GRPC_SHADOW_EVP_PKEY_get1_RSA', - '#define EVP_PKEY_id GRPC_SHADOW_EVP_PKEY_id', - '#define EVP_PKEY_is_opaque GRPC_SHADOW_EVP_PKEY_is_opaque', - '#define EVP_PKEY_missing_parameters GRPC_SHADOW_EVP_PKEY_missing_parameters', - '#define EVP_PKEY_new GRPC_SHADOW_EVP_PKEY_new', - '#define EVP_PKEY_set1_DSA GRPC_SHADOW_EVP_PKEY_set1_DSA', - '#define EVP_PKEY_set1_EC_KEY GRPC_SHADOW_EVP_PKEY_set1_EC_KEY', - '#define EVP_PKEY_set1_RSA GRPC_SHADOW_EVP_PKEY_set1_RSA', - '#define EVP_PKEY_set_type GRPC_SHADOW_EVP_PKEY_set_type', - '#define EVP_PKEY_size GRPC_SHADOW_EVP_PKEY_size', - '#define EVP_PKEY_type GRPC_SHADOW_EVP_PKEY_type', - '#define EVP_PKEY_up_ref GRPC_SHADOW_EVP_PKEY_up_ref', - '#define EVP_cleanup GRPC_SHADOW_EVP_cleanup', - '#define OPENSSL_add_all_algorithms_conf GRPC_SHADOW_OPENSSL_add_all_algorithms_conf', - '#define OpenSSL_add_all_algorithms GRPC_SHADOW_OpenSSL_add_all_algorithms', - '#define OpenSSL_add_all_ciphers GRPC_SHADOW_OpenSSL_add_all_ciphers', - '#define OpenSSL_add_all_digests GRPC_SHADOW_OpenSSL_add_all_digests', - '#define EVP_marshal_private_key GRPC_SHADOW_EVP_marshal_private_key', - '#define EVP_marshal_public_key GRPC_SHADOW_EVP_marshal_public_key', - '#define EVP_parse_private_key GRPC_SHADOW_EVP_parse_private_key', - '#define EVP_parse_public_key GRPC_SHADOW_EVP_parse_public_key', - '#define d2i_AutoPrivateKey GRPC_SHADOW_d2i_AutoPrivateKey', - '#define d2i_PrivateKey GRPC_SHADOW_d2i_PrivateKey', - '#define i2d_PublicKey GRPC_SHADOW_i2d_PublicKey', - '#define EVP_PKEY_CTX_ctrl GRPC_SHADOW_EVP_PKEY_CTX_ctrl', - '#define EVP_PKEY_CTX_dup GRPC_SHADOW_EVP_PKEY_CTX_dup', - '#define EVP_PKEY_CTX_free GRPC_SHADOW_EVP_PKEY_CTX_free', - '#define EVP_PKEY_CTX_get0_pkey GRPC_SHADOW_EVP_PKEY_CTX_get0_pkey', - '#define EVP_PKEY_CTX_new GRPC_SHADOW_EVP_PKEY_CTX_new', - '#define EVP_PKEY_CTX_new_id GRPC_SHADOW_EVP_PKEY_CTX_new_id', - '#define EVP_PKEY_decrypt GRPC_SHADOW_EVP_PKEY_decrypt', - '#define EVP_PKEY_decrypt_init GRPC_SHADOW_EVP_PKEY_decrypt_init', - '#define EVP_PKEY_derive GRPC_SHADOW_EVP_PKEY_derive', - '#define EVP_PKEY_derive_init GRPC_SHADOW_EVP_PKEY_derive_init', - '#define EVP_PKEY_derive_set_peer GRPC_SHADOW_EVP_PKEY_derive_set_peer', - '#define EVP_PKEY_encrypt GRPC_SHADOW_EVP_PKEY_encrypt', - '#define EVP_PKEY_encrypt_init GRPC_SHADOW_EVP_PKEY_encrypt_init', - '#define EVP_PKEY_keygen GRPC_SHADOW_EVP_PKEY_keygen', - '#define EVP_PKEY_keygen_init GRPC_SHADOW_EVP_PKEY_keygen_init', - '#define EVP_PKEY_sign GRPC_SHADOW_EVP_PKEY_sign', - '#define EVP_PKEY_sign_init GRPC_SHADOW_EVP_PKEY_sign_init', - '#define EVP_PKEY_verify GRPC_SHADOW_EVP_PKEY_verify', - '#define EVP_PKEY_verify_init GRPC_SHADOW_EVP_PKEY_verify_init', - '#define EVP_PKEY_verify_recover GRPC_SHADOW_EVP_PKEY_verify_recover', - '#define EVP_PKEY_verify_recover_init GRPC_SHADOW_EVP_PKEY_verify_recover_init', - '#define dsa_asn1_meth GRPC_SHADOW_dsa_asn1_meth', - '#define ec_pkey_meth GRPC_SHADOW_ec_pkey_meth', - '#define ec_asn1_meth GRPC_SHADOW_ec_asn1_meth', - '#define ed25519_pkey_meth GRPC_SHADOW_ed25519_pkey_meth', - '#define EVP_PKEY_new_ed25519_private GRPC_SHADOW_EVP_PKEY_new_ed25519_private', - '#define EVP_PKEY_new_ed25519_public GRPC_SHADOW_EVP_PKEY_new_ed25519_public', - '#define ed25519_asn1_meth GRPC_SHADOW_ed25519_asn1_meth', - '#define EVP_PKEY_CTX_get0_rsa_oaep_label GRPC_SHADOW_EVP_PKEY_CTX_get0_rsa_oaep_label', - '#define EVP_PKEY_CTX_get_rsa_mgf1_md GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_mgf1_md', - '#define EVP_PKEY_CTX_get_rsa_oaep_md GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_oaep_md', - '#define EVP_PKEY_CTX_get_rsa_padding GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_padding', - '#define EVP_PKEY_CTX_get_rsa_pss_saltlen GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_pss_saltlen', - '#define EVP_PKEY_CTX_set0_rsa_oaep_label GRPC_SHADOW_EVP_PKEY_CTX_set0_rsa_oaep_label', - '#define EVP_PKEY_CTX_set_rsa_keygen_bits GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_keygen_bits', - '#define EVP_PKEY_CTX_set_rsa_keygen_pubexp GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_keygen_pubexp', - '#define EVP_PKEY_CTX_set_rsa_mgf1_md GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_mgf1_md', - '#define EVP_PKEY_CTX_set_rsa_oaep_md GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_oaep_md', - '#define EVP_PKEY_CTX_set_rsa_padding GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_padding', - '#define EVP_PKEY_CTX_set_rsa_pss_saltlen GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_pss_saltlen', - '#define rsa_pkey_meth GRPC_SHADOW_rsa_pkey_meth', - '#define rsa_asn1_meth GRPC_SHADOW_rsa_asn1_meth', - '#define PKCS5_PBKDF2_HMAC GRPC_SHADOW_PKCS5_PBKDF2_HMAC', - '#define PKCS5_PBKDF2_HMAC_SHA1 GRPC_SHADOW_PKCS5_PBKDF2_HMAC_SHA1', - '#define EVP_PKEY_print_params GRPC_SHADOW_EVP_PKEY_print_params', - '#define EVP_PKEY_print_private GRPC_SHADOW_EVP_PKEY_print_private', - '#define EVP_PKEY_print_public GRPC_SHADOW_EVP_PKEY_print_public', - '#define EVP_PBE_scrypt GRPC_SHADOW_EVP_PBE_scrypt', - '#define EVP_SignFinal GRPC_SHADOW_EVP_SignFinal', - '#define EVP_SignInit GRPC_SHADOW_EVP_SignInit', - '#define EVP_SignInit_ex GRPC_SHADOW_EVP_SignInit_ex', - '#define EVP_SignUpdate GRPC_SHADOW_EVP_SignUpdate', - '#define EVP_VerifyFinal GRPC_SHADOW_EVP_VerifyFinal', - '#define EVP_VerifyInit GRPC_SHADOW_EVP_VerifyInit', - '#define EVP_VerifyInit_ex GRPC_SHADOW_EVP_VerifyInit_ex', - '#define EVP_VerifyUpdate GRPC_SHADOW_EVP_VerifyUpdate', - '#define HKDF GRPC_SHADOW_HKDF', - '#define HKDF_expand GRPC_SHADOW_HKDF_expand', - '#define HKDF_extract GRPC_SHADOW_HKDF_extract', - '#define PEM_read_DSAPrivateKey GRPC_SHADOW_PEM_read_DSAPrivateKey', - '#define PEM_read_DSA_PUBKEY GRPC_SHADOW_PEM_read_DSA_PUBKEY', - '#define PEM_read_DSAparams GRPC_SHADOW_PEM_read_DSAparams', - '#define PEM_read_ECPrivateKey GRPC_SHADOW_PEM_read_ECPrivateKey', - '#define PEM_read_EC_PUBKEY GRPC_SHADOW_PEM_read_EC_PUBKEY', - '#define PEM_read_PUBKEY GRPC_SHADOW_PEM_read_PUBKEY', - '#define PEM_read_RSAPrivateKey GRPC_SHADOW_PEM_read_RSAPrivateKey', - '#define PEM_read_RSAPublicKey GRPC_SHADOW_PEM_read_RSAPublicKey', - '#define PEM_read_RSA_PUBKEY GRPC_SHADOW_PEM_read_RSA_PUBKEY', - '#define PEM_read_X509_CRL GRPC_SHADOW_PEM_read_X509_CRL', - '#define PEM_read_X509_REQ GRPC_SHADOW_PEM_read_X509_REQ', - '#define PEM_read_bio_DSAPrivateKey GRPC_SHADOW_PEM_read_bio_DSAPrivateKey', - '#define PEM_read_bio_DSA_PUBKEY GRPC_SHADOW_PEM_read_bio_DSA_PUBKEY', - '#define PEM_read_bio_DSAparams GRPC_SHADOW_PEM_read_bio_DSAparams', - '#define PEM_read_bio_ECPrivateKey GRPC_SHADOW_PEM_read_bio_ECPrivateKey', - '#define PEM_read_bio_EC_PUBKEY GRPC_SHADOW_PEM_read_bio_EC_PUBKEY', - '#define PEM_read_bio_PUBKEY GRPC_SHADOW_PEM_read_bio_PUBKEY', - '#define PEM_read_bio_RSAPrivateKey GRPC_SHADOW_PEM_read_bio_RSAPrivateKey', - '#define PEM_read_bio_RSAPublicKey GRPC_SHADOW_PEM_read_bio_RSAPublicKey', - '#define PEM_read_bio_RSA_PUBKEY GRPC_SHADOW_PEM_read_bio_RSA_PUBKEY', - '#define PEM_read_bio_X509_CRL GRPC_SHADOW_PEM_read_bio_X509_CRL', - '#define PEM_read_bio_X509_REQ GRPC_SHADOW_PEM_read_bio_X509_REQ', - '#define PEM_write_DHparams GRPC_SHADOW_PEM_write_DHparams', - '#define PEM_write_DSAPrivateKey GRPC_SHADOW_PEM_write_DSAPrivateKey', - '#define PEM_write_DSA_PUBKEY GRPC_SHADOW_PEM_write_DSA_PUBKEY', - '#define PEM_write_DSAparams GRPC_SHADOW_PEM_write_DSAparams', - '#define PEM_write_ECPrivateKey GRPC_SHADOW_PEM_write_ECPrivateKey', - '#define PEM_write_EC_PUBKEY GRPC_SHADOW_PEM_write_EC_PUBKEY', - '#define PEM_write_PUBKEY GRPC_SHADOW_PEM_write_PUBKEY', - '#define PEM_write_RSAPrivateKey GRPC_SHADOW_PEM_write_RSAPrivateKey', - '#define PEM_write_RSAPublicKey GRPC_SHADOW_PEM_write_RSAPublicKey', - '#define PEM_write_RSA_PUBKEY GRPC_SHADOW_PEM_write_RSA_PUBKEY', - '#define PEM_write_X509_CRL GRPC_SHADOW_PEM_write_X509_CRL', - '#define PEM_write_X509_REQ GRPC_SHADOW_PEM_write_X509_REQ', - '#define PEM_write_X509_REQ_NEW GRPC_SHADOW_PEM_write_X509_REQ_NEW', - '#define PEM_write_bio_DHparams GRPC_SHADOW_PEM_write_bio_DHparams', - '#define PEM_write_bio_DSAPrivateKey GRPC_SHADOW_PEM_write_bio_DSAPrivateKey', - '#define PEM_write_bio_DSA_PUBKEY GRPC_SHADOW_PEM_write_bio_DSA_PUBKEY', - '#define PEM_write_bio_DSAparams GRPC_SHADOW_PEM_write_bio_DSAparams', - '#define PEM_write_bio_ECPrivateKey GRPC_SHADOW_PEM_write_bio_ECPrivateKey', - '#define PEM_write_bio_EC_PUBKEY GRPC_SHADOW_PEM_write_bio_EC_PUBKEY', - '#define PEM_write_bio_PUBKEY GRPC_SHADOW_PEM_write_bio_PUBKEY', - '#define PEM_write_bio_RSAPrivateKey GRPC_SHADOW_PEM_write_bio_RSAPrivateKey', - '#define PEM_write_bio_RSAPublicKey GRPC_SHADOW_PEM_write_bio_RSAPublicKey', - '#define PEM_write_bio_RSA_PUBKEY GRPC_SHADOW_PEM_write_bio_RSA_PUBKEY', - '#define PEM_write_bio_X509_CRL GRPC_SHADOW_PEM_write_bio_X509_CRL', - '#define PEM_write_bio_X509_REQ GRPC_SHADOW_PEM_write_bio_X509_REQ', - '#define PEM_write_bio_X509_REQ_NEW GRPC_SHADOW_PEM_write_bio_X509_REQ_NEW', - '#define PEM_X509_INFO_read GRPC_SHADOW_PEM_X509_INFO_read', - '#define PEM_X509_INFO_read_bio GRPC_SHADOW_PEM_X509_INFO_read_bio', - '#define PEM_X509_INFO_write_bio GRPC_SHADOW_PEM_X509_INFO_write_bio', - '#define PEM_ASN1_read GRPC_SHADOW_PEM_ASN1_read', - '#define PEM_ASN1_write GRPC_SHADOW_PEM_ASN1_write', - '#define PEM_ASN1_write_bio GRPC_SHADOW_PEM_ASN1_write_bio', - '#define PEM_bytes_read_bio GRPC_SHADOW_PEM_bytes_read_bio', - '#define PEM_def_callback GRPC_SHADOW_PEM_def_callback', - '#define PEM_dek_info GRPC_SHADOW_PEM_dek_info', - '#define PEM_do_header GRPC_SHADOW_PEM_do_header', - '#define PEM_get_EVP_CIPHER_INFO GRPC_SHADOW_PEM_get_EVP_CIPHER_INFO', - '#define PEM_proc_type GRPC_SHADOW_PEM_proc_type', - '#define PEM_read GRPC_SHADOW_PEM_read', - '#define PEM_read_bio GRPC_SHADOW_PEM_read_bio', - '#define PEM_write GRPC_SHADOW_PEM_write', - '#define PEM_write_bio GRPC_SHADOW_PEM_write_bio', - '#define PEM_ASN1_read_bio GRPC_SHADOW_PEM_ASN1_read_bio', - '#define PEM_read_PKCS8 GRPC_SHADOW_PEM_read_PKCS8', - '#define PEM_read_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_read_PKCS8_PRIV_KEY_INFO', - '#define PEM_read_bio_PKCS8 GRPC_SHADOW_PEM_read_bio_PKCS8', - '#define PEM_read_bio_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_read_bio_PKCS8_PRIV_KEY_INFO', - '#define PEM_write_PKCS8 GRPC_SHADOW_PEM_write_PKCS8', - '#define PEM_write_PKCS8PrivateKey GRPC_SHADOW_PEM_write_PKCS8PrivateKey', - '#define PEM_write_PKCS8PrivateKey_nid GRPC_SHADOW_PEM_write_PKCS8PrivateKey_nid', - '#define PEM_write_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_write_PKCS8_PRIV_KEY_INFO', - '#define PEM_write_bio_PKCS8 GRPC_SHADOW_PEM_write_bio_PKCS8', - '#define PEM_write_bio_PKCS8PrivateKey GRPC_SHADOW_PEM_write_bio_PKCS8PrivateKey', - '#define PEM_write_bio_PKCS8PrivateKey_nid GRPC_SHADOW_PEM_write_bio_PKCS8PrivateKey_nid', - '#define PEM_write_bio_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_write_bio_PKCS8_PRIV_KEY_INFO', - '#define d2i_PKCS8PrivateKey_bio GRPC_SHADOW_d2i_PKCS8PrivateKey_bio', - '#define d2i_PKCS8PrivateKey_fp GRPC_SHADOW_d2i_PKCS8PrivateKey_fp', - '#define i2d_PKCS8PrivateKey_bio GRPC_SHADOW_i2d_PKCS8PrivateKey_bio', - '#define i2d_PKCS8PrivateKey_fp GRPC_SHADOW_i2d_PKCS8PrivateKey_fp', - '#define i2d_PKCS8PrivateKey_nid_bio GRPC_SHADOW_i2d_PKCS8PrivateKey_nid_bio', - '#define i2d_PKCS8PrivateKey_nid_fp GRPC_SHADOW_i2d_PKCS8PrivateKey_nid_fp', - '#define PEM_read_DHparams GRPC_SHADOW_PEM_read_DHparams', - '#define PEM_read_PrivateKey GRPC_SHADOW_PEM_read_PrivateKey', - '#define PEM_read_bio_DHparams GRPC_SHADOW_PEM_read_bio_DHparams', - '#define PEM_read_bio_PrivateKey GRPC_SHADOW_PEM_read_bio_PrivateKey', - '#define PEM_write_PrivateKey GRPC_SHADOW_PEM_write_PrivateKey', - '#define PEM_write_bio_PrivateKey GRPC_SHADOW_PEM_write_bio_PrivateKey', - '#define PEM_read_X509 GRPC_SHADOW_PEM_read_X509', - '#define PEM_read_bio_X509 GRPC_SHADOW_PEM_read_bio_X509', - '#define PEM_write_X509 GRPC_SHADOW_PEM_write_X509', - '#define PEM_write_bio_X509 GRPC_SHADOW_PEM_write_bio_X509', - '#define PEM_read_X509_AUX GRPC_SHADOW_PEM_read_X509_AUX', - '#define PEM_read_bio_X509_AUX GRPC_SHADOW_PEM_read_bio_X509_AUX', - '#define PEM_write_X509_AUX GRPC_SHADOW_PEM_write_X509_AUX', - '#define PEM_write_bio_X509_AUX GRPC_SHADOW_PEM_write_bio_X509_AUX', - '#define ASN1_digest GRPC_SHADOW_ASN1_digest', - '#define ASN1_item_digest GRPC_SHADOW_ASN1_item_digest', - '#define ASN1_item_sign GRPC_SHADOW_ASN1_item_sign', - '#define ASN1_item_sign_ctx GRPC_SHADOW_ASN1_item_sign_ctx', - '#define ASN1_STRING_print_ex GRPC_SHADOW_ASN1_STRING_print_ex', - '#define ASN1_STRING_print_ex_fp GRPC_SHADOW_ASN1_STRING_print_ex_fp', - '#define ASN1_STRING_to_UTF8 GRPC_SHADOW_ASN1_STRING_to_UTF8', - '#define X509_NAME_print_ex GRPC_SHADOW_X509_NAME_print_ex', - '#define X509_NAME_print_ex_fp GRPC_SHADOW_X509_NAME_print_ex_fp', - '#define ASN1_item_verify GRPC_SHADOW_ASN1_item_verify', - '#define x509_digest_sign_algorithm GRPC_SHADOW_x509_digest_sign_algorithm', - '#define x509_digest_verify_init GRPC_SHADOW_x509_digest_verify_init', - '#define ASN1_generate_nconf GRPC_SHADOW_ASN1_generate_nconf', - '#define ASN1_generate_v3 GRPC_SHADOW_ASN1_generate_v3', - '#define X509_LOOKUP_hash_dir GRPC_SHADOW_X509_LOOKUP_hash_dir', - '#define X509_LOOKUP_file GRPC_SHADOW_X509_LOOKUP_file', - '#define X509_load_cert_crl_file GRPC_SHADOW_X509_load_cert_crl_file', - '#define X509_load_cert_file GRPC_SHADOW_X509_load_cert_file', - '#define X509_load_crl_file GRPC_SHADOW_X509_load_crl_file', - '#define i2d_PrivateKey GRPC_SHADOW_i2d_PrivateKey', - '#define RSA_PSS_PARAMS_free GRPC_SHADOW_RSA_PSS_PARAMS_free', - '#define RSA_PSS_PARAMS_it GRPC_SHADOW_RSA_PSS_PARAMS_it', - '#define RSA_PSS_PARAMS_new GRPC_SHADOW_RSA_PSS_PARAMS_new', - '#define d2i_RSA_PSS_PARAMS GRPC_SHADOW_d2i_RSA_PSS_PARAMS', - '#define i2d_RSA_PSS_PARAMS GRPC_SHADOW_i2d_RSA_PSS_PARAMS', - '#define x509_print_rsa_pss_params GRPC_SHADOW_x509_print_rsa_pss_params', - '#define x509_rsa_ctx_to_pss GRPC_SHADOW_x509_rsa_ctx_to_pss', - '#define x509_rsa_pss_to_ctx GRPC_SHADOW_x509_rsa_pss_to_ctx', - '#define X509_CRL_print GRPC_SHADOW_X509_CRL_print', - '#define X509_CRL_print_fp GRPC_SHADOW_X509_CRL_print_fp', - '#define X509_REQ_print GRPC_SHADOW_X509_REQ_print', - '#define X509_REQ_print_ex GRPC_SHADOW_X509_REQ_print_ex', - '#define X509_REQ_print_fp GRPC_SHADOW_X509_REQ_print_fp', - '#define ASN1_GENERALIZEDTIME_print GRPC_SHADOW_ASN1_GENERALIZEDTIME_print', - '#define ASN1_STRING_print GRPC_SHADOW_ASN1_STRING_print', - '#define ASN1_TIME_print GRPC_SHADOW_ASN1_TIME_print', - '#define ASN1_UTCTIME_print GRPC_SHADOW_ASN1_UTCTIME_print', - '#define X509_NAME_print GRPC_SHADOW_X509_NAME_print', - '#define X509_ocspid_print GRPC_SHADOW_X509_ocspid_print', - '#define X509_print GRPC_SHADOW_X509_print', - '#define X509_print_ex GRPC_SHADOW_X509_print_ex', - '#define X509_print_ex_fp GRPC_SHADOW_X509_print_ex_fp', - '#define X509_print_fp GRPC_SHADOW_X509_print_fp', - '#define X509_signature_print GRPC_SHADOW_X509_signature_print', - '#define X509_CERT_AUX_print GRPC_SHADOW_X509_CERT_AUX_print', - '#define PKCS8_pkey_get0 GRPC_SHADOW_PKCS8_pkey_get0', - '#define PKCS8_pkey_set0 GRPC_SHADOW_PKCS8_pkey_set0', - '#define X509_signature_dump GRPC_SHADOW_X509_signature_dump', - '#define X509_ATTRIBUTE_count GRPC_SHADOW_X509_ATTRIBUTE_count', - '#define X509_ATTRIBUTE_create_by_NID GRPC_SHADOW_X509_ATTRIBUTE_create_by_NID', - '#define X509_ATTRIBUTE_create_by_OBJ GRPC_SHADOW_X509_ATTRIBUTE_create_by_OBJ', - '#define X509_ATTRIBUTE_create_by_txt GRPC_SHADOW_X509_ATTRIBUTE_create_by_txt', - '#define X509_ATTRIBUTE_get0_data GRPC_SHADOW_X509_ATTRIBUTE_get0_data', - '#define X509_ATTRIBUTE_get0_object GRPC_SHADOW_X509_ATTRIBUTE_get0_object', - '#define X509_ATTRIBUTE_get0_type GRPC_SHADOW_X509_ATTRIBUTE_get0_type', - '#define X509_ATTRIBUTE_set1_data GRPC_SHADOW_X509_ATTRIBUTE_set1_data', - '#define X509_ATTRIBUTE_set1_object GRPC_SHADOW_X509_ATTRIBUTE_set1_object', - '#define X509at_add1_attr GRPC_SHADOW_X509at_add1_attr', - '#define X509at_add1_attr_by_NID GRPC_SHADOW_X509at_add1_attr_by_NID', - '#define X509at_add1_attr_by_OBJ GRPC_SHADOW_X509at_add1_attr_by_OBJ', - '#define X509at_add1_attr_by_txt GRPC_SHADOW_X509at_add1_attr_by_txt', - '#define X509at_delete_attr GRPC_SHADOW_X509at_delete_attr', - '#define X509at_get0_data_by_OBJ GRPC_SHADOW_X509at_get0_data_by_OBJ', - '#define X509at_get_attr GRPC_SHADOW_X509at_get_attr', - '#define X509at_get_attr_by_NID GRPC_SHADOW_X509at_get_attr_by_NID', - '#define X509at_get_attr_by_OBJ GRPC_SHADOW_X509at_get_attr_by_OBJ', - '#define X509at_get_attr_count GRPC_SHADOW_X509at_get_attr_count', - '#define X509_CRL_check_suiteb GRPC_SHADOW_X509_CRL_check_suiteb', - '#define X509_CRL_cmp GRPC_SHADOW_X509_CRL_cmp', - '#define X509_CRL_match GRPC_SHADOW_X509_CRL_match', - '#define X509_NAME_cmp GRPC_SHADOW_X509_NAME_cmp', - '#define X509_NAME_hash GRPC_SHADOW_X509_NAME_hash', - '#define X509_NAME_hash_old GRPC_SHADOW_X509_NAME_hash_old', - '#define X509_chain_check_suiteb GRPC_SHADOW_X509_chain_check_suiteb', - '#define X509_chain_up_ref GRPC_SHADOW_X509_chain_up_ref', - '#define X509_check_private_key GRPC_SHADOW_X509_check_private_key', - '#define X509_cmp GRPC_SHADOW_X509_cmp', - '#define X509_find_by_issuer_and_serial GRPC_SHADOW_X509_find_by_issuer_and_serial', - '#define X509_find_by_subject GRPC_SHADOW_X509_find_by_subject', - '#define X509_get0_pubkey_bitstr GRPC_SHADOW_X509_get0_pubkey_bitstr', - '#define X509_get_issuer_name GRPC_SHADOW_X509_get_issuer_name', - '#define X509_get_pubkey GRPC_SHADOW_X509_get_pubkey', - '#define X509_get_serialNumber GRPC_SHADOW_X509_get_serialNumber', - '#define X509_get_subject_name GRPC_SHADOW_X509_get_subject_name', - '#define X509_issuer_and_serial_cmp GRPC_SHADOW_X509_issuer_and_serial_cmp', - '#define X509_issuer_and_serial_hash GRPC_SHADOW_X509_issuer_and_serial_hash', - '#define X509_issuer_name_cmp GRPC_SHADOW_X509_issuer_name_cmp', - '#define X509_issuer_name_hash GRPC_SHADOW_X509_issuer_name_hash', - '#define X509_issuer_name_hash_old GRPC_SHADOW_X509_issuer_name_hash_old', - '#define X509_subject_name_cmp GRPC_SHADOW_X509_subject_name_cmp', - '#define X509_subject_name_hash GRPC_SHADOW_X509_subject_name_hash', - '#define X509_subject_name_hash_old GRPC_SHADOW_X509_subject_name_hash_old', - '#define X509_STORE_load_locations GRPC_SHADOW_X509_STORE_load_locations', - '#define X509_STORE_set_default_paths GRPC_SHADOW_X509_STORE_set_default_paths', - '#define X509_get_default_cert_area GRPC_SHADOW_X509_get_default_cert_area', - '#define X509_get_default_cert_dir GRPC_SHADOW_X509_get_default_cert_dir', - '#define X509_get_default_cert_dir_env GRPC_SHADOW_X509_get_default_cert_dir_env', - '#define X509_get_default_cert_file GRPC_SHADOW_X509_get_default_cert_file', - '#define X509_get_default_cert_file_env GRPC_SHADOW_X509_get_default_cert_file_env', - '#define X509_get_default_private_dir GRPC_SHADOW_X509_get_default_private_dir', - '#define X509_CRL_add1_ext_i2d GRPC_SHADOW_X509_CRL_add1_ext_i2d', - '#define X509_CRL_add_ext GRPC_SHADOW_X509_CRL_add_ext', - '#define X509_CRL_delete_ext GRPC_SHADOW_X509_CRL_delete_ext', - '#define X509_CRL_get_ext GRPC_SHADOW_X509_CRL_get_ext', - '#define X509_CRL_get_ext_by_NID GRPC_SHADOW_X509_CRL_get_ext_by_NID', - '#define X509_CRL_get_ext_by_OBJ GRPC_SHADOW_X509_CRL_get_ext_by_OBJ', - '#define X509_CRL_get_ext_by_critical GRPC_SHADOW_X509_CRL_get_ext_by_critical', - '#define X509_CRL_get_ext_count GRPC_SHADOW_X509_CRL_get_ext_count', - '#define X509_CRL_get_ext_d2i GRPC_SHADOW_X509_CRL_get_ext_d2i', - '#define X509_REVOKED_add1_ext_i2d GRPC_SHADOW_X509_REVOKED_add1_ext_i2d', - '#define X509_REVOKED_add_ext GRPC_SHADOW_X509_REVOKED_add_ext', - '#define X509_REVOKED_delete_ext GRPC_SHADOW_X509_REVOKED_delete_ext', - '#define X509_REVOKED_get_ext GRPC_SHADOW_X509_REVOKED_get_ext', - '#define X509_REVOKED_get_ext_by_NID GRPC_SHADOW_X509_REVOKED_get_ext_by_NID', - '#define X509_REVOKED_get_ext_by_OBJ GRPC_SHADOW_X509_REVOKED_get_ext_by_OBJ', - '#define X509_REVOKED_get_ext_by_critical GRPC_SHADOW_X509_REVOKED_get_ext_by_critical', - '#define X509_REVOKED_get_ext_count GRPC_SHADOW_X509_REVOKED_get_ext_count', - '#define X509_REVOKED_get_ext_d2i GRPC_SHADOW_X509_REVOKED_get_ext_d2i', - '#define X509_add1_ext_i2d GRPC_SHADOW_X509_add1_ext_i2d', - '#define X509_add_ext GRPC_SHADOW_X509_add_ext', - '#define X509_delete_ext GRPC_SHADOW_X509_delete_ext', - '#define X509_get_ext GRPC_SHADOW_X509_get_ext', - '#define X509_get_ext_by_NID GRPC_SHADOW_X509_get_ext_by_NID', - '#define X509_get_ext_by_OBJ GRPC_SHADOW_X509_get_ext_by_OBJ', - '#define X509_get_ext_by_critical GRPC_SHADOW_X509_get_ext_by_critical', - '#define X509_get_ext_count GRPC_SHADOW_X509_get_ext_count', - '#define X509_get_ext_d2i GRPC_SHADOW_X509_get_ext_d2i', - '#define X509_LOOKUP_by_alias GRPC_SHADOW_X509_LOOKUP_by_alias', - '#define X509_LOOKUP_by_fingerprint GRPC_SHADOW_X509_LOOKUP_by_fingerprint', - '#define X509_LOOKUP_by_issuer_serial GRPC_SHADOW_X509_LOOKUP_by_issuer_serial', - '#define X509_LOOKUP_by_subject GRPC_SHADOW_X509_LOOKUP_by_subject', - '#define X509_LOOKUP_ctrl GRPC_SHADOW_X509_LOOKUP_ctrl', - '#define X509_LOOKUP_free GRPC_SHADOW_X509_LOOKUP_free', - '#define X509_LOOKUP_init GRPC_SHADOW_X509_LOOKUP_init', - '#define X509_LOOKUP_new GRPC_SHADOW_X509_LOOKUP_new', - '#define X509_LOOKUP_shutdown GRPC_SHADOW_X509_LOOKUP_shutdown', - '#define X509_OBJECT_free_contents GRPC_SHADOW_X509_OBJECT_free_contents', - '#define X509_OBJECT_get0_X509 GRPC_SHADOW_X509_OBJECT_get0_X509', - '#define X509_OBJECT_get_type GRPC_SHADOW_X509_OBJECT_get_type', - '#define X509_OBJECT_idx_by_subject GRPC_SHADOW_X509_OBJECT_idx_by_subject', - '#define X509_OBJECT_retrieve_by_subject GRPC_SHADOW_X509_OBJECT_retrieve_by_subject', - '#define X509_OBJECT_retrieve_match GRPC_SHADOW_X509_OBJECT_retrieve_match', - '#define X509_OBJECT_up_ref_count GRPC_SHADOW_X509_OBJECT_up_ref_count', - '#define X509_STORE_CTX_get0_store GRPC_SHADOW_X509_STORE_CTX_get0_store', - '#define X509_STORE_CTX_get1_issuer GRPC_SHADOW_X509_STORE_CTX_get1_issuer', - '#define X509_STORE_add_cert GRPC_SHADOW_X509_STORE_add_cert', - '#define X509_STORE_add_crl GRPC_SHADOW_X509_STORE_add_crl', - '#define X509_STORE_add_lookup GRPC_SHADOW_X509_STORE_add_lookup', - '#define X509_STORE_free GRPC_SHADOW_X509_STORE_free', - '#define X509_STORE_get0_objects GRPC_SHADOW_X509_STORE_get0_objects', - '#define X509_STORE_get0_param GRPC_SHADOW_X509_STORE_get0_param', - '#define X509_STORE_get1_certs GRPC_SHADOW_X509_STORE_get1_certs', - '#define X509_STORE_get1_crls GRPC_SHADOW_X509_STORE_get1_crls', - '#define X509_STORE_get_by_subject GRPC_SHADOW_X509_STORE_get_by_subject', - '#define X509_STORE_new GRPC_SHADOW_X509_STORE_new', - '#define X509_STORE_set0_additional_untrusted GRPC_SHADOW_X509_STORE_set0_additional_untrusted', - '#define X509_STORE_set1_param GRPC_SHADOW_X509_STORE_set1_param', - '#define X509_STORE_set_depth GRPC_SHADOW_X509_STORE_set_depth', - '#define X509_STORE_set_flags GRPC_SHADOW_X509_STORE_set_flags', - '#define X509_STORE_set_lookup_crls_cb GRPC_SHADOW_X509_STORE_set_lookup_crls_cb', - '#define X509_STORE_set_purpose GRPC_SHADOW_X509_STORE_set_purpose', - '#define X509_STORE_set_trust GRPC_SHADOW_X509_STORE_set_trust', - '#define X509_STORE_set_verify_cb GRPC_SHADOW_X509_STORE_set_verify_cb', - '#define X509_STORE_up_ref GRPC_SHADOW_X509_STORE_up_ref', - '#define X509_NAME_oneline GRPC_SHADOW_X509_NAME_oneline', - '#define X509_REQ_to_X509 GRPC_SHADOW_X509_REQ_to_X509', - '#define X509_REQ_add1_attr GRPC_SHADOW_X509_REQ_add1_attr', - '#define X509_REQ_add1_attr_by_NID GRPC_SHADOW_X509_REQ_add1_attr_by_NID', - '#define X509_REQ_add1_attr_by_OBJ GRPC_SHADOW_X509_REQ_add1_attr_by_OBJ', - '#define X509_REQ_add1_attr_by_txt GRPC_SHADOW_X509_REQ_add1_attr_by_txt', - '#define X509_REQ_add_extensions GRPC_SHADOW_X509_REQ_add_extensions', - '#define X509_REQ_add_extensions_nid GRPC_SHADOW_X509_REQ_add_extensions_nid', - '#define X509_REQ_check_private_key GRPC_SHADOW_X509_REQ_check_private_key', - '#define X509_REQ_delete_attr GRPC_SHADOW_X509_REQ_delete_attr', - '#define X509_REQ_extension_nid GRPC_SHADOW_X509_REQ_extension_nid', - '#define X509_REQ_get_attr GRPC_SHADOW_X509_REQ_get_attr', - '#define X509_REQ_get_attr_by_NID GRPC_SHADOW_X509_REQ_get_attr_by_NID', - '#define X509_REQ_get_attr_by_OBJ GRPC_SHADOW_X509_REQ_get_attr_by_OBJ', - '#define X509_REQ_get_attr_count GRPC_SHADOW_X509_REQ_get_attr_count', - '#define X509_REQ_get_extension_nids GRPC_SHADOW_X509_REQ_get_extension_nids', - '#define X509_REQ_get_extensions GRPC_SHADOW_X509_REQ_get_extensions', - '#define X509_REQ_get_pubkey GRPC_SHADOW_X509_REQ_get_pubkey', - '#define X509_REQ_set_extension_nids GRPC_SHADOW_X509_REQ_set_extension_nids', - '#define X509_to_X509_REQ GRPC_SHADOW_X509_to_X509_REQ', - '#define X509_get0_extensions GRPC_SHADOW_X509_get0_extensions', - '#define X509_get0_notAfter GRPC_SHADOW_X509_get0_notAfter', - '#define X509_get0_notBefore GRPC_SHADOW_X509_get0_notBefore', - '#define X509_set_issuer_name GRPC_SHADOW_X509_set_issuer_name', - '#define X509_set_notAfter GRPC_SHADOW_X509_set_notAfter', - '#define X509_set_notBefore GRPC_SHADOW_X509_set_notBefore', - '#define X509_set_pubkey GRPC_SHADOW_X509_set_pubkey', - '#define X509_set_serialNumber GRPC_SHADOW_X509_set_serialNumber', - '#define X509_set_subject_name GRPC_SHADOW_X509_set_subject_name', - '#define X509_set_version GRPC_SHADOW_X509_set_version', - '#define X509_TRUST_add GRPC_SHADOW_X509_TRUST_add', - '#define X509_TRUST_cleanup GRPC_SHADOW_X509_TRUST_cleanup', - '#define X509_TRUST_get0 GRPC_SHADOW_X509_TRUST_get0', - '#define X509_TRUST_get0_name GRPC_SHADOW_X509_TRUST_get0_name', - '#define X509_TRUST_get_by_id GRPC_SHADOW_X509_TRUST_get_by_id', - '#define X509_TRUST_get_count GRPC_SHADOW_X509_TRUST_get_count', - '#define X509_TRUST_get_flags GRPC_SHADOW_X509_TRUST_get_flags', - '#define X509_TRUST_get_trust GRPC_SHADOW_X509_TRUST_get_trust', - '#define X509_TRUST_set GRPC_SHADOW_X509_TRUST_set', - '#define X509_TRUST_set_default GRPC_SHADOW_X509_TRUST_set_default', - '#define X509_check_trust GRPC_SHADOW_X509_check_trust', - '#define X509_verify_cert_error_string GRPC_SHADOW_X509_verify_cert_error_string', - '#define X509_EXTENSION_create_by_NID GRPC_SHADOW_X509_EXTENSION_create_by_NID', - '#define X509_EXTENSION_create_by_OBJ GRPC_SHADOW_X509_EXTENSION_create_by_OBJ', - '#define X509_EXTENSION_get_critical GRPC_SHADOW_X509_EXTENSION_get_critical', - '#define X509_EXTENSION_get_data GRPC_SHADOW_X509_EXTENSION_get_data', - '#define X509_EXTENSION_get_object GRPC_SHADOW_X509_EXTENSION_get_object', - '#define X509_EXTENSION_set_critical GRPC_SHADOW_X509_EXTENSION_set_critical', - '#define X509_EXTENSION_set_data GRPC_SHADOW_X509_EXTENSION_set_data', - '#define X509_EXTENSION_set_object GRPC_SHADOW_X509_EXTENSION_set_object', - '#define X509v3_add_ext GRPC_SHADOW_X509v3_add_ext', - '#define X509v3_delete_ext GRPC_SHADOW_X509v3_delete_ext', - '#define X509v3_get_ext GRPC_SHADOW_X509v3_get_ext', - '#define X509v3_get_ext_by_NID GRPC_SHADOW_X509v3_get_ext_by_NID', - '#define X509v3_get_ext_by_OBJ GRPC_SHADOW_X509v3_get_ext_by_OBJ', - '#define X509v3_get_ext_by_critical GRPC_SHADOW_X509v3_get_ext_by_critical', - '#define X509v3_get_ext_count GRPC_SHADOW_X509v3_get_ext_count', - '#define X509_CRL_diff GRPC_SHADOW_X509_CRL_diff', - '#define X509_STORE_CTX_cleanup GRPC_SHADOW_X509_STORE_CTX_cleanup', - '#define X509_STORE_CTX_free GRPC_SHADOW_X509_STORE_CTX_free', - '#define X509_STORE_CTX_get0_current_crl GRPC_SHADOW_X509_STORE_CTX_get0_current_crl', - '#define X509_STORE_CTX_get0_current_issuer GRPC_SHADOW_X509_STORE_CTX_get0_current_issuer', - '#define X509_STORE_CTX_get0_param GRPC_SHADOW_X509_STORE_CTX_get0_param', - '#define X509_STORE_CTX_get0_parent_ctx GRPC_SHADOW_X509_STORE_CTX_get0_parent_ctx', - '#define X509_STORE_CTX_get0_policy_tree GRPC_SHADOW_X509_STORE_CTX_get0_policy_tree', - '#define X509_STORE_CTX_get0_untrusted GRPC_SHADOW_X509_STORE_CTX_get0_untrusted', - '#define X509_STORE_CTX_get1_chain GRPC_SHADOW_X509_STORE_CTX_get1_chain', - '#define X509_STORE_CTX_get_chain GRPC_SHADOW_X509_STORE_CTX_get_chain', - '#define X509_STORE_CTX_get_current_cert GRPC_SHADOW_X509_STORE_CTX_get_current_cert', - '#define X509_STORE_CTX_get_error GRPC_SHADOW_X509_STORE_CTX_get_error', - '#define X509_STORE_CTX_get_error_depth GRPC_SHADOW_X509_STORE_CTX_get_error_depth', - '#define X509_STORE_CTX_get_ex_data GRPC_SHADOW_X509_STORE_CTX_get_ex_data', - '#define X509_STORE_CTX_get_ex_new_index GRPC_SHADOW_X509_STORE_CTX_get_ex_new_index', - '#define X509_STORE_CTX_get_explicit_policy GRPC_SHADOW_X509_STORE_CTX_get_explicit_policy', - '#define X509_STORE_CTX_init GRPC_SHADOW_X509_STORE_CTX_init', - '#define X509_STORE_CTX_new GRPC_SHADOW_X509_STORE_CTX_new', - '#define X509_STORE_CTX_purpose_inherit GRPC_SHADOW_X509_STORE_CTX_purpose_inherit', - '#define X509_STORE_CTX_set0_crls GRPC_SHADOW_X509_STORE_CTX_set0_crls', - '#define X509_STORE_CTX_set0_param GRPC_SHADOW_X509_STORE_CTX_set0_param', - '#define X509_STORE_CTX_set_cert GRPC_SHADOW_X509_STORE_CTX_set_cert', - '#define X509_STORE_CTX_set_chain GRPC_SHADOW_X509_STORE_CTX_set_chain', - '#define X509_STORE_CTX_set_default GRPC_SHADOW_X509_STORE_CTX_set_default', - '#define X509_STORE_CTX_set_depth GRPC_SHADOW_X509_STORE_CTX_set_depth', - '#define X509_STORE_CTX_set_error GRPC_SHADOW_X509_STORE_CTX_set_error', - '#define X509_STORE_CTX_set_ex_data GRPC_SHADOW_X509_STORE_CTX_set_ex_data', - '#define X509_STORE_CTX_set_flags GRPC_SHADOW_X509_STORE_CTX_set_flags', - '#define X509_STORE_CTX_set_purpose GRPC_SHADOW_X509_STORE_CTX_set_purpose', - '#define X509_STORE_CTX_set_time GRPC_SHADOW_X509_STORE_CTX_set_time', - '#define X509_STORE_CTX_set_trust GRPC_SHADOW_X509_STORE_CTX_set_trust', - '#define X509_STORE_CTX_set_verify_cb GRPC_SHADOW_X509_STORE_CTX_set_verify_cb', - '#define X509_STORE_CTX_trusted_stack GRPC_SHADOW_X509_STORE_CTX_trusted_stack', - '#define X509_STORE_CTX_zero GRPC_SHADOW_X509_STORE_CTX_zero', - '#define X509_cmp_current_time GRPC_SHADOW_X509_cmp_current_time', - '#define X509_cmp_time GRPC_SHADOW_X509_cmp_time', - '#define X509_gmtime_adj GRPC_SHADOW_X509_gmtime_adj', - '#define X509_time_adj GRPC_SHADOW_X509_time_adj', - '#define X509_time_adj_ex GRPC_SHADOW_X509_time_adj_ex', - '#define X509_verify_cert GRPC_SHADOW_X509_verify_cert', - '#define X509_VERIFY_PARAM_add0_policy GRPC_SHADOW_X509_VERIFY_PARAM_add0_policy', - '#define X509_VERIFY_PARAM_add0_table GRPC_SHADOW_X509_VERIFY_PARAM_add0_table', - '#define X509_VERIFY_PARAM_add1_host GRPC_SHADOW_X509_VERIFY_PARAM_add1_host', - '#define X509_VERIFY_PARAM_clear_flags GRPC_SHADOW_X509_VERIFY_PARAM_clear_flags', - '#define X509_VERIFY_PARAM_free GRPC_SHADOW_X509_VERIFY_PARAM_free', - '#define X509_VERIFY_PARAM_get0 GRPC_SHADOW_X509_VERIFY_PARAM_get0', - '#define X509_VERIFY_PARAM_get0_name GRPC_SHADOW_X509_VERIFY_PARAM_get0_name', - '#define X509_VERIFY_PARAM_get0_peername GRPC_SHADOW_X509_VERIFY_PARAM_get0_peername', - '#define X509_VERIFY_PARAM_get_count GRPC_SHADOW_X509_VERIFY_PARAM_get_count', - '#define X509_VERIFY_PARAM_get_depth GRPC_SHADOW_X509_VERIFY_PARAM_get_depth', - '#define X509_VERIFY_PARAM_get_flags GRPC_SHADOW_X509_VERIFY_PARAM_get_flags', - '#define X509_VERIFY_PARAM_inherit GRPC_SHADOW_X509_VERIFY_PARAM_inherit', - '#define X509_VERIFY_PARAM_lookup GRPC_SHADOW_X509_VERIFY_PARAM_lookup', - '#define X509_VERIFY_PARAM_new GRPC_SHADOW_X509_VERIFY_PARAM_new', - '#define X509_VERIFY_PARAM_set1 GRPC_SHADOW_X509_VERIFY_PARAM_set1', - '#define X509_VERIFY_PARAM_set1_email GRPC_SHADOW_X509_VERIFY_PARAM_set1_email', - '#define X509_VERIFY_PARAM_set1_host GRPC_SHADOW_X509_VERIFY_PARAM_set1_host', - '#define X509_VERIFY_PARAM_set1_ip GRPC_SHADOW_X509_VERIFY_PARAM_set1_ip', - '#define X509_VERIFY_PARAM_set1_ip_asc GRPC_SHADOW_X509_VERIFY_PARAM_set1_ip_asc', - '#define X509_VERIFY_PARAM_set1_name GRPC_SHADOW_X509_VERIFY_PARAM_set1_name', - '#define X509_VERIFY_PARAM_set1_policies GRPC_SHADOW_X509_VERIFY_PARAM_set1_policies', - '#define X509_VERIFY_PARAM_set_depth GRPC_SHADOW_X509_VERIFY_PARAM_set_depth', - '#define X509_VERIFY_PARAM_set_flags GRPC_SHADOW_X509_VERIFY_PARAM_set_flags', - '#define X509_VERIFY_PARAM_set_hostflags GRPC_SHADOW_X509_VERIFY_PARAM_set_hostflags', - '#define X509_VERIFY_PARAM_set_purpose GRPC_SHADOW_X509_VERIFY_PARAM_set_purpose', - '#define X509_VERIFY_PARAM_set_time GRPC_SHADOW_X509_VERIFY_PARAM_set_time', - '#define X509_VERIFY_PARAM_set_trust GRPC_SHADOW_X509_VERIFY_PARAM_set_trust', - '#define X509_VERIFY_PARAM_table_cleanup GRPC_SHADOW_X509_VERIFY_PARAM_table_cleanup', - '#define X509_CRL_set_issuer_name GRPC_SHADOW_X509_CRL_set_issuer_name', - '#define X509_CRL_set_lastUpdate GRPC_SHADOW_X509_CRL_set_lastUpdate', - '#define X509_CRL_set_nextUpdate GRPC_SHADOW_X509_CRL_set_nextUpdate', - '#define X509_CRL_set_version GRPC_SHADOW_X509_CRL_set_version', - '#define X509_CRL_sort GRPC_SHADOW_X509_CRL_sort', - '#define X509_CRL_up_ref GRPC_SHADOW_X509_CRL_up_ref', - '#define X509_REVOKED_set_revocationDate GRPC_SHADOW_X509_REVOKED_set_revocationDate', - '#define X509_REVOKED_set_serialNumber GRPC_SHADOW_X509_REVOKED_set_serialNumber', - '#define X509_NAME_ENTRY_create_by_NID GRPC_SHADOW_X509_NAME_ENTRY_create_by_NID', - '#define X509_NAME_ENTRY_create_by_OBJ GRPC_SHADOW_X509_NAME_ENTRY_create_by_OBJ', - '#define X509_NAME_ENTRY_create_by_txt GRPC_SHADOW_X509_NAME_ENTRY_create_by_txt', - '#define X509_NAME_ENTRY_get_data GRPC_SHADOW_X509_NAME_ENTRY_get_data', - '#define X509_NAME_ENTRY_get_object GRPC_SHADOW_X509_NAME_ENTRY_get_object', - '#define X509_NAME_ENTRY_set_data GRPC_SHADOW_X509_NAME_ENTRY_set_data', - '#define X509_NAME_ENTRY_set_object GRPC_SHADOW_X509_NAME_ENTRY_set_object', - '#define X509_NAME_add_entry GRPC_SHADOW_X509_NAME_add_entry', - '#define X509_NAME_add_entry_by_NID GRPC_SHADOW_X509_NAME_add_entry_by_NID', - '#define X509_NAME_add_entry_by_OBJ GRPC_SHADOW_X509_NAME_add_entry_by_OBJ', - '#define X509_NAME_add_entry_by_txt GRPC_SHADOW_X509_NAME_add_entry_by_txt', - '#define X509_NAME_delete_entry GRPC_SHADOW_X509_NAME_delete_entry', - '#define X509_NAME_entry_count GRPC_SHADOW_X509_NAME_entry_count', - '#define X509_NAME_get_entry GRPC_SHADOW_X509_NAME_get_entry', - '#define X509_NAME_get_index_by_NID GRPC_SHADOW_X509_NAME_get_index_by_NID', - '#define X509_NAME_get_index_by_OBJ GRPC_SHADOW_X509_NAME_get_index_by_OBJ', - '#define X509_NAME_get_text_by_NID GRPC_SHADOW_X509_NAME_get_text_by_NID', - '#define X509_NAME_get_text_by_OBJ GRPC_SHADOW_X509_NAME_get_text_by_OBJ', - '#define X509_REQ_set_pubkey GRPC_SHADOW_X509_REQ_set_pubkey', - '#define X509_REQ_set_subject_name GRPC_SHADOW_X509_REQ_set_subject_name', - '#define X509_REQ_set_version GRPC_SHADOW_X509_REQ_set_version', - '#define NETSCAPE_SPKI_b64_decode GRPC_SHADOW_NETSCAPE_SPKI_b64_decode', - '#define NETSCAPE_SPKI_b64_encode GRPC_SHADOW_NETSCAPE_SPKI_b64_encode', - '#define NETSCAPE_SPKI_get_pubkey GRPC_SHADOW_NETSCAPE_SPKI_get_pubkey', - '#define NETSCAPE_SPKI_set_pubkey GRPC_SHADOW_NETSCAPE_SPKI_set_pubkey', - '#define X509_ALGORS_it GRPC_SHADOW_X509_ALGORS_it', - '#define X509_ALGOR_cmp GRPC_SHADOW_X509_ALGOR_cmp', - '#define X509_ALGOR_dup GRPC_SHADOW_X509_ALGOR_dup', - '#define X509_ALGOR_free GRPC_SHADOW_X509_ALGOR_free', - '#define X509_ALGOR_get0 GRPC_SHADOW_X509_ALGOR_get0', - '#define X509_ALGOR_it GRPC_SHADOW_X509_ALGOR_it', - '#define X509_ALGOR_new GRPC_SHADOW_X509_ALGOR_new', - '#define X509_ALGOR_set0 GRPC_SHADOW_X509_ALGOR_set0', - '#define X509_ALGOR_set_md GRPC_SHADOW_X509_ALGOR_set_md', - '#define d2i_X509_ALGOR GRPC_SHADOW_d2i_X509_ALGOR', - '#define d2i_X509_ALGORS GRPC_SHADOW_d2i_X509_ALGORS', - '#define i2d_X509_ALGOR GRPC_SHADOW_i2d_X509_ALGOR', - '#define i2d_X509_ALGORS GRPC_SHADOW_i2d_X509_ALGORS', - '#define NETSCAPE_SPKI_sign GRPC_SHADOW_NETSCAPE_SPKI_sign', - '#define NETSCAPE_SPKI_verify GRPC_SHADOW_NETSCAPE_SPKI_verify', - '#define X509_CRL_digest GRPC_SHADOW_X509_CRL_digest', - '#define X509_CRL_sign GRPC_SHADOW_X509_CRL_sign', - '#define X509_CRL_sign_ctx GRPC_SHADOW_X509_CRL_sign_ctx', - '#define X509_NAME_digest GRPC_SHADOW_X509_NAME_digest', - '#define X509_REQ_digest GRPC_SHADOW_X509_REQ_digest', - '#define X509_REQ_sign GRPC_SHADOW_X509_REQ_sign', - '#define X509_REQ_sign_ctx GRPC_SHADOW_X509_REQ_sign_ctx', - '#define X509_REQ_verify GRPC_SHADOW_X509_REQ_verify', - '#define X509_digest GRPC_SHADOW_X509_digest', - '#define X509_pubkey_digest GRPC_SHADOW_X509_pubkey_digest', - '#define X509_sign GRPC_SHADOW_X509_sign', - '#define X509_sign_ctx GRPC_SHADOW_X509_sign_ctx', - '#define X509_verify GRPC_SHADOW_X509_verify', - '#define d2i_DSAPrivateKey_bio GRPC_SHADOW_d2i_DSAPrivateKey_bio', - '#define d2i_DSAPrivateKey_fp GRPC_SHADOW_d2i_DSAPrivateKey_fp', - '#define d2i_DSA_PUBKEY_bio GRPC_SHADOW_d2i_DSA_PUBKEY_bio', - '#define d2i_DSA_PUBKEY_fp GRPC_SHADOW_d2i_DSA_PUBKEY_fp', - '#define d2i_ECPrivateKey_bio GRPC_SHADOW_d2i_ECPrivateKey_bio', - '#define d2i_ECPrivateKey_fp GRPC_SHADOW_d2i_ECPrivateKey_fp', - '#define d2i_EC_PUBKEY_bio GRPC_SHADOW_d2i_EC_PUBKEY_bio', - '#define d2i_EC_PUBKEY_fp GRPC_SHADOW_d2i_EC_PUBKEY_fp', - '#define d2i_PKCS8_PRIV_KEY_INFO_bio GRPC_SHADOW_d2i_PKCS8_PRIV_KEY_INFO_bio', - '#define d2i_PKCS8_PRIV_KEY_INFO_fp GRPC_SHADOW_d2i_PKCS8_PRIV_KEY_INFO_fp', - '#define d2i_PKCS8_bio GRPC_SHADOW_d2i_PKCS8_bio', - '#define d2i_PKCS8_fp GRPC_SHADOW_d2i_PKCS8_fp', - '#define d2i_PUBKEY_bio GRPC_SHADOW_d2i_PUBKEY_bio', - '#define d2i_PUBKEY_fp GRPC_SHADOW_d2i_PUBKEY_fp', - '#define d2i_PrivateKey_bio GRPC_SHADOW_d2i_PrivateKey_bio', - '#define d2i_PrivateKey_fp GRPC_SHADOW_d2i_PrivateKey_fp', - '#define d2i_RSAPrivateKey_bio GRPC_SHADOW_d2i_RSAPrivateKey_bio', - '#define d2i_RSAPrivateKey_fp GRPC_SHADOW_d2i_RSAPrivateKey_fp', - '#define d2i_RSAPublicKey_bio GRPC_SHADOW_d2i_RSAPublicKey_bio', - '#define d2i_RSAPublicKey_fp GRPC_SHADOW_d2i_RSAPublicKey_fp', - '#define d2i_RSA_PUBKEY_bio GRPC_SHADOW_d2i_RSA_PUBKEY_bio', - '#define d2i_RSA_PUBKEY_fp GRPC_SHADOW_d2i_RSA_PUBKEY_fp', - '#define d2i_X509_CRL_bio GRPC_SHADOW_d2i_X509_CRL_bio', - '#define d2i_X509_CRL_fp GRPC_SHADOW_d2i_X509_CRL_fp', - '#define d2i_X509_REQ_bio GRPC_SHADOW_d2i_X509_REQ_bio', - '#define d2i_X509_REQ_fp GRPC_SHADOW_d2i_X509_REQ_fp', - '#define d2i_X509_bio GRPC_SHADOW_d2i_X509_bio', - '#define d2i_X509_fp GRPC_SHADOW_d2i_X509_fp', - '#define i2d_DSAPrivateKey_bio GRPC_SHADOW_i2d_DSAPrivateKey_bio', - '#define i2d_DSAPrivateKey_fp GRPC_SHADOW_i2d_DSAPrivateKey_fp', - '#define i2d_DSA_PUBKEY_bio GRPC_SHADOW_i2d_DSA_PUBKEY_bio', - '#define i2d_DSA_PUBKEY_fp GRPC_SHADOW_i2d_DSA_PUBKEY_fp', - '#define i2d_ECPrivateKey_bio GRPC_SHADOW_i2d_ECPrivateKey_bio', - '#define i2d_ECPrivateKey_fp GRPC_SHADOW_i2d_ECPrivateKey_fp', - '#define i2d_EC_PUBKEY_bio GRPC_SHADOW_i2d_EC_PUBKEY_bio', - '#define i2d_EC_PUBKEY_fp GRPC_SHADOW_i2d_EC_PUBKEY_fp', - '#define i2d_PKCS8PrivateKeyInfo_bio GRPC_SHADOW_i2d_PKCS8PrivateKeyInfo_bio', - '#define i2d_PKCS8PrivateKeyInfo_fp GRPC_SHADOW_i2d_PKCS8PrivateKeyInfo_fp', - '#define i2d_PKCS8_PRIV_KEY_INFO_bio GRPC_SHADOW_i2d_PKCS8_PRIV_KEY_INFO_bio', - '#define i2d_PKCS8_PRIV_KEY_INFO_fp GRPC_SHADOW_i2d_PKCS8_PRIV_KEY_INFO_fp', - '#define i2d_PKCS8_bio GRPC_SHADOW_i2d_PKCS8_bio', - '#define i2d_PKCS8_fp GRPC_SHADOW_i2d_PKCS8_fp', - '#define i2d_PUBKEY_bio GRPC_SHADOW_i2d_PUBKEY_bio', - '#define i2d_PUBKEY_fp GRPC_SHADOW_i2d_PUBKEY_fp', - '#define i2d_PrivateKey_bio GRPC_SHADOW_i2d_PrivateKey_bio', - '#define i2d_PrivateKey_fp GRPC_SHADOW_i2d_PrivateKey_fp', - '#define i2d_RSAPrivateKey_bio GRPC_SHADOW_i2d_RSAPrivateKey_bio', - '#define i2d_RSAPrivateKey_fp GRPC_SHADOW_i2d_RSAPrivateKey_fp', - '#define i2d_RSAPublicKey_bio GRPC_SHADOW_i2d_RSAPublicKey_bio', - '#define i2d_RSAPublicKey_fp GRPC_SHADOW_i2d_RSAPublicKey_fp', - '#define i2d_RSA_PUBKEY_bio GRPC_SHADOW_i2d_RSA_PUBKEY_bio', - '#define i2d_RSA_PUBKEY_fp GRPC_SHADOW_i2d_RSA_PUBKEY_fp', - '#define i2d_X509_CRL_bio GRPC_SHADOW_i2d_X509_CRL_bio', - '#define i2d_X509_CRL_fp GRPC_SHADOW_i2d_X509_CRL_fp', - '#define i2d_X509_REQ_bio GRPC_SHADOW_i2d_X509_REQ_bio', - '#define i2d_X509_REQ_fp GRPC_SHADOW_i2d_X509_REQ_fp', - '#define i2d_X509_bio GRPC_SHADOW_i2d_X509_bio', - '#define i2d_X509_fp GRPC_SHADOW_i2d_X509_fp', - '#define X509_ATTRIBUTE_SET_it GRPC_SHADOW_X509_ATTRIBUTE_SET_it', - '#define X509_ATTRIBUTE_create GRPC_SHADOW_X509_ATTRIBUTE_create', - '#define X509_ATTRIBUTE_dup GRPC_SHADOW_X509_ATTRIBUTE_dup', - '#define X509_ATTRIBUTE_free GRPC_SHADOW_X509_ATTRIBUTE_free', - '#define X509_ATTRIBUTE_it GRPC_SHADOW_X509_ATTRIBUTE_it', - '#define X509_ATTRIBUTE_new GRPC_SHADOW_X509_ATTRIBUTE_new', - '#define d2i_X509_ATTRIBUTE GRPC_SHADOW_d2i_X509_ATTRIBUTE', - '#define i2d_X509_ATTRIBUTE GRPC_SHADOW_i2d_X509_ATTRIBUTE', - '#define X509_CRL_INFO_free GRPC_SHADOW_X509_CRL_INFO_free', - '#define X509_CRL_INFO_it GRPC_SHADOW_X509_CRL_INFO_it', - '#define X509_CRL_INFO_new GRPC_SHADOW_X509_CRL_INFO_new', - '#define X509_CRL_METHOD_free GRPC_SHADOW_X509_CRL_METHOD_free', - '#define X509_CRL_METHOD_new GRPC_SHADOW_X509_CRL_METHOD_new', - '#define X509_CRL_add0_revoked GRPC_SHADOW_X509_CRL_add0_revoked', - '#define X509_CRL_dup GRPC_SHADOW_X509_CRL_dup', - '#define X509_CRL_free GRPC_SHADOW_X509_CRL_free', - '#define X509_CRL_get0_by_cert GRPC_SHADOW_X509_CRL_get0_by_cert', - '#define X509_CRL_get0_by_serial GRPC_SHADOW_X509_CRL_get0_by_serial', - '#define X509_CRL_get_meth_data GRPC_SHADOW_X509_CRL_get_meth_data', - '#define X509_CRL_it GRPC_SHADOW_X509_CRL_it', - '#define X509_CRL_new GRPC_SHADOW_X509_CRL_new', - '#define X509_CRL_set_default_method GRPC_SHADOW_X509_CRL_set_default_method', - '#define X509_CRL_set_meth_data GRPC_SHADOW_X509_CRL_set_meth_data', - '#define X509_CRL_verify GRPC_SHADOW_X509_CRL_verify', - '#define X509_REVOKED_dup GRPC_SHADOW_X509_REVOKED_dup', - '#define X509_REVOKED_free GRPC_SHADOW_X509_REVOKED_free', - '#define X509_REVOKED_it GRPC_SHADOW_X509_REVOKED_it', - '#define X509_REVOKED_new GRPC_SHADOW_X509_REVOKED_new', - '#define d2i_X509_CRL GRPC_SHADOW_d2i_X509_CRL', - '#define d2i_X509_CRL_INFO GRPC_SHADOW_d2i_X509_CRL_INFO', - '#define d2i_X509_REVOKED GRPC_SHADOW_d2i_X509_REVOKED', - '#define i2d_X509_CRL GRPC_SHADOW_i2d_X509_CRL', - '#define i2d_X509_CRL_INFO GRPC_SHADOW_i2d_X509_CRL_INFO', - '#define i2d_X509_REVOKED GRPC_SHADOW_i2d_X509_REVOKED', - '#define X509_EXTENSIONS_it GRPC_SHADOW_X509_EXTENSIONS_it', - '#define X509_EXTENSION_dup GRPC_SHADOW_X509_EXTENSION_dup', - '#define X509_EXTENSION_free GRPC_SHADOW_X509_EXTENSION_free', - '#define X509_EXTENSION_it GRPC_SHADOW_X509_EXTENSION_it', - '#define X509_EXTENSION_new GRPC_SHADOW_X509_EXTENSION_new', - '#define d2i_X509_EXTENSION GRPC_SHADOW_d2i_X509_EXTENSION', - '#define d2i_X509_EXTENSIONS GRPC_SHADOW_d2i_X509_EXTENSIONS', - '#define i2d_X509_EXTENSION GRPC_SHADOW_i2d_X509_EXTENSION', - '#define i2d_X509_EXTENSIONS GRPC_SHADOW_i2d_X509_EXTENSIONS', - '#define X509_INFO_free GRPC_SHADOW_X509_INFO_free', - '#define X509_INFO_new GRPC_SHADOW_X509_INFO_new', - '#define X509_NAME_ENTRIES_it GRPC_SHADOW_X509_NAME_ENTRIES_it', - '#define X509_NAME_ENTRY_dup GRPC_SHADOW_X509_NAME_ENTRY_dup', - '#define X509_NAME_ENTRY_free GRPC_SHADOW_X509_NAME_ENTRY_free', - '#define X509_NAME_ENTRY_it GRPC_SHADOW_X509_NAME_ENTRY_it', - '#define X509_NAME_ENTRY_new GRPC_SHADOW_X509_NAME_ENTRY_new', - '#define X509_NAME_ENTRY_set GRPC_SHADOW_X509_NAME_ENTRY_set', - '#define X509_NAME_INTERNAL_it GRPC_SHADOW_X509_NAME_INTERNAL_it', - '#define X509_NAME_dup GRPC_SHADOW_X509_NAME_dup', - '#define X509_NAME_free GRPC_SHADOW_X509_NAME_free', - '#define X509_NAME_get0_der GRPC_SHADOW_X509_NAME_get0_der', - '#define X509_NAME_it GRPC_SHADOW_X509_NAME_it', - '#define X509_NAME_new GRPC_SHADOW_X509_NAME_new', - '#define X509_NAME_set GRPC_SHADOW_X509_NAME_set', - '#define d2i_X509_NAME GRPC_SHADOW_d2i_X509_NAME', - '#define d2i_X509_NAME_ENTRY GRPC_SHADOW_d2i_X509_NAME_ENTRY', - '#define i2d_X509_NAME GRPC_SHADOW_i2d_X509_NAME', - '#define i2d_X509_NAME_ENTRY GRPC_SHADOW_i2d_X509_NAME_ENTRY', - '#define X509_PKEY_free GRPC_SHADOW_X509_PKEY_free', - '#define X509_PKEY_new GRPC_SHADOW_X509_PKEY_new', - '#define X509_PUBKEY_free GRPC_SHADOW_X509_PUBKEY_free', - '#define X509_PUBKEY_get GRPC_SHADOW_X509_PUBKEY_get', - '#define X509_PUBKEY_get0_param GRPC_SHADOW_X509_PUBKEY_get0_param', - '#define X509_PUBKEY_it GRPC_SHADOW_X509_PUBKEY_it', - '#define X509_PUBKEY_new GRPC_SHADOW_X509_PUBKEY_new', - '#define X509_PUBKEY_set GRPC_SHADOW_X509_PUBKEY_set', - '#define X509_PUBKEY_set0_param GRPC_SHADOW_X509_PUBKEY_set0_param', - '#define d2i_DSA_PUBKEY GRPC_SHADOW_d2i_DSA_PUBKEY', - '#define d2i_EC_PUBKEY GRPC_SHADOW_d2i_EC_PUBKEY', - '#define d2i_PUBKEY GRPC_SHADOW_d2i_PUBKEY', - '#define d2i_RSA_PUBKEY GRPC_SHADOW_d2i_RSA_PUBKEY', - '#define d2i_X509_PUBKEY GRPC_SHADOW_d2i_X509_PUBKEY', - '#define i2d_DSA_PUBKEY GRPC_SHADOW_i2d_DSA_PUBKEY', - '#define i2d_EC_PUBKEY GRPC_SHADOW_i2d_EC_PUBKEY', - '#define i2d_PUBKEY GRPC_SHADOW_i2d_PUBKEY', - '#define i2d_RSA_PUBKEY GRPC_SHADOW_i2d_RSA_PUBKEY', - '#define i2d_X509_PUBKEY GRPC_SHADOW_i2d_X509_PUBKEY', - '#define X509_REQ_INFO_free GRPC_SHADOW_X509_REQ_INFO_free', - '#define X509_REQ_INFO_it GRPC_SHADOW_X509_REQ_INFO_it', - '#define X509_REQ_INFO_new GRPC_SHADOW_X509_REQ_INFO_new', - '#define X509_REQ_dup GRPC_SHADOW_X509_REQ_dup', - '#define X509_REQ_free GRPC_SHADOW_X509_REQ_free', - '#define X509_REQ_it GRPC_SHADOW_X509_REQ_it', - '#define X509_REQ_new GRPC_SHADOW_X509_REQ_new', - '#define d2i_X509_REQ GRPC_SHADOW_d2i_X509_REQ', - '#define d2i_X509_REQ_INFO GRPC_SHADOW_d2i_X509_REQ_INFO', - '#define i2d_X509_REQ GRPC_SHADOW_i2d_X509_REQ', - '#define i2d_X509_REQ_INFO GRPC_SHADOW_i2d_X509_REQ_INFO', - '#define X509_SIG_free GRPC_SHADOW_X509_SIG_free', - '#define X509_SIG_it GRPC_SHADOW_X509_SIG_it', - '#define X509_SIG_new GRPC_SHADOW_X509_SIG_new', - '#define d2i_X509_SIG GRPC_SHADOW_d2i_X509_SIG', - '#define i2d_X509_SIG GRPC_SHADOW_i2d_X509_SIG', - '#define NETSCAPE_SPKAC_free GRPC_SHADOW_NETSCAPE_SPKAC_free', - '#define NETSCAPE_SPKAC_it GRPC_SHADOW_NETSCAPE_SPKAC_it', - '#define NETSCAPE_SPKAC_new GRPC_SHADOW_NETSCAPE_SPKAC_new', - '#define NETSCAPE_SPKI_free GRPC_SHADOW_NETSCAPE_SPKI_free', - '#define NETSCAPE_SPKI_it GRPC_SHADOW_NETSCAPE_SPKI_it', - '#define NETSCAPE_SPKI_new GRPC_SHADOW_NETSCAPE_SPKI_new', - '#define d2i_NETSCAPE_SPKAC GRPC_SHADOW_d2i_NETSCAPE_SPKAC', - '#define d2i_NETSCAPE_SPKI GRPC_SHADOW_d2i_NETSCAPE_SPKI', - '#define i2d_NETSCAPE_SPKAC GRPC_SHADOW_i2d_NETSCAPE_SPKAC', - '#define i2d_NETSCAPE_SPKI GRPC_SHADOW_i2d_NETSCAPE_SPKI', - '#define X509_VAL_free GRPC_SHADOW_X509_VAL_free', - '#define X509_VAL_it GRPC_SHADOW_X509_VAL_it', - '#define X509_VAL_new GRPC_SHADOW_X509_VAL_new', - '#define d2i_X509_VAL GRPC_SHADOW_d2i_X509_VAL', - '#define i2d_X509_VAL GRPC_SHADOW_i2d_X509_VAL', - '#define X509_CINF_free GRPC_SHADOW_X509_CINF_free', - '#define X509_CINF_it GRPC_SHADOW_X509_CINF_it', - '#define X509_CINF_new GRPC_SHADOW_X509_CINF_new', - '#define X509_dup GRPC_SHADOW_X509_dup', - '#define X509_free GRPC_SHADOW_X509_free', - '#define X509_get0_signature GRPC_SHADOW_X509_get0_signature', - '#define X509_get_ex_data GRPC_SHADOW_X509_get_ex_data', - '#define X509_get_ex_new_index GRPC_SHADOW_X509_get_ex_new_index', - '#define X509_get_signature_nid GRPC_SHADOW_X509_get_signature_nid', - '#define X509_it GRPC_SHADOW_X509_it', - '#define X509_new GRPC_SHADOW_X509_new', - '#define X509_parse_from_buffer GRPC_SHADOW_X509_parse_from_buffer', - '#define X509_set_ex_data GRPC_SHADOW_X509_set_ex_data', - '#define X509_up_ref GRPC_SHADOW_X509_up_ref', - '#define d2i_X509 GRPC_SHADOW_d2i_X509', - '#define d2i_X509_AUX GRPC_SHADOW_d2i_X509_AUX', - '#define d2i_X509_CINF GRPC_SHADOW_d2i_X509_CINF', - '#define i2d_X509 GRPC_SHADOW_i2d_X509', - '#define i2d_X509_AUX GRPC_SHADOW_i2d_X509_AUX', - '#define i2d_X509_CINF GRPC_SHADOW_i2d_X509_CINF', - '#define X509_CERT_AUX_free GRPC_SHADOW_X509_CERT_AUX_free', - '#define X509_CERT_AUX_it GRPC_SHADOW_X509_CERT_AUX_it', - '#define X509_CERT_AUX_new GRPC_SHADOW_X509_CERT_AUX_new', - '#define X509_add1_reject_object GRPC_SHADOW_X509_add1_reject_object', - '#define X509_add1_trust_object GRPC_SHADOW_X509_add1_trust_object', - '#define X509_alias_get0 GRPC_SHADOW_X509_alias_get0', - '#define X509_alias_set1 GRPC_SHADOW_X509_alias_set1', - '#define X509_keyid_get0 GRPC_SHADOW_X509_keyid_get0', - '#define X509_keyid_set1 GRPC_SHADOW_X509_keyid_set1', - '#define X509_reject_clear GRPC_SHADOW_X509_reject_clear', - '#define X509_trust_clear GRPC_SHADOW_X509_trust_clear', - '#define d2i_X509_CERT_AUX GRPC_SHADOW_d2i_X509_CERT_AUX', - '#define i2d_X509_CERT_AUX GRPC_SHADOW_i2d_X509_CERT_AUX', - '#define policy_cache_find_data GRPC_SHADOW_policy_cache_find_data', - '#define policy_cache_free GRPC_SHADOW_policy_cache_free', - '#define policy_cache_set GRPC_SHADOW_policy_cache_set', - '#define policy_data_free GRPC_SHADOW_policy_data_free', - '#define policy_data_new GRPC_SHADOW_policy_data_new', - '#define X509_policy_level_get0_node GRPC_SHADOW_X509_policy_level_get0_node', - '#define X509_policy_level_node_count GRPC_SHADOW_X509_policy_level_node_count', - '#define X509_policy_node_get0_parent GRPC_SHADOW_X509_policy_node_get0_parent', - '#define X509_policy_node_get0_policy GRPC_SHADOW_X509_policy_node_get0_policy', - '#define X509_policy_node_get0_qualifiers GRPC_SHADOW_X509_policy_node_get0_qualifiers', - '#define X509_policy_tree_get0_level GRPC_SHADOW_X509_policy_tree_get0_level', - '#define X509_policy_tree_get0_policies GRPC_SHADOW_X509_policy_tree_get0_policies', - '#define X509_policy_tree_get0_user_policies GRPC_SHADOW_X509_policy_tree_get0_user_policies', - '#define X509_policy_tree_level_count GRPC_SHADOW_X509_policy_tree_level_count', - '#define policy_cache_set_mapping GRPC_SHADOW_policy_cache_set_mapping', - '#define level_add_node GRPC_SHADOW_level_add_node', - '#define level_find_node GRPC_SHADOW_level_find_node', - '#define policy_node_cmp_new GRPC_SHADOW_policy_node_cmp_new', - '#define policy_node_free GRPC_SHADOW_policy_node_free', - '#define policy_node_match GRPC_SHADOW_policy_node_match', - '#define tree_find_sk GRPC_SHADOW_tree_find_sk', - '#define X509_policy_check GRPC_SHADOW_X509_policy_check', - '#define X509_policy_tree_free GRPC_SHADOW_X509_policy_tree_free', - '#define v3_akey_id GRPC_SHADOW_v3_akey_id', - '#define AUTHORITY_KEYID_free GRPC_SHADOW_AUTHORITY_KEYID_free', - '#define AUTHORITY_KEYID_it GRPC_SHADOW_AUTHORITY_KEYID_it', - '#define AUTHORITY_KEYID_new GRPC_SHADOW_AUTHORITY_KEYID_new', - '#define d2i_AUTHORITY_KEYID GRPC_SHADOW_d2i_AUTHORITY_KEYID', - '#define i2d_AUTHORITY_KEYID GRPC_SHADOW_i2d_AUTHORITY_KEYID', - '#define GENERAL_NAME_print GRPC_SHADOW_GENERAL_NAME_print', - '#define a2i_GENERAL_NAME GRPC_SHADOW_a2i_GENERAL_NAME', - '#define i2v_GENERAL_NAME GRPC_SHADOW_i2v_GENERAL_NAME', - '#define i2v_GENERAL_NAMES GRPC_SHADOW_i2v_GENERAL_NAMES', - '#define v2i_GENERAL_NAME GRPC_SHADOW_v2i_GENERAL_NAME', - '#define v2i_GENERAL_NAMES GRPC_SHADOW_v2i_GENERAL_NAMES', - '#define v2i_GENERAL_NAME_ex GRPC_SHADOW_v2i_GENERAL_NAME_ex', - '#define v3_alt GRPC_SHADOW_v3_alt', - '#define BASIC_CONSTRAINTS_free GRPC_SHADOW_BASIC_CONSTRAINTS_free', - '#define BASIC_CONSTRAINTS_it GRPC_SHADOW_BASIC_CONSTRAINTS_it', - '#define BASIC_CONSTRAINTS_new GRPC_SHADOW_BASIC_CONSTRAINTS_new', - '#define d2i_BASIC_CONSTRAINTS GRPC_SHADOW_d2i_BASIC_CONSTRAINTS', - '#define i2d_BASIC_CONSTRAINTS GRPC_SHADOW_i2d_BASIC_CONSTRAINTS', - '#define v3_bcons GRPC_SHADOW_v3_bcons', - '#define i2v_ASN1_BIT_STRING GRPC_SHADOW_i2v_ASN1_BIT_STRING', - '#define v2i_ASN1_BIT_STRING GRPC_SHADOW_v2i_ASN1_BIT_STRING', - '#define v3_key_usage GRPC_SHADOW_v3_key_usage', - '#define v3_nscert GRPC_SHADOW_v3_nscert', - '#define X509V3_EXT_CRL_add_nconf GRPC_SHADOW_X509V3_EXT_CRL_add_nconf', - '#define X509V3_EXT_REQ_add_nconf GRPC_SHADOW_X509V3_EXT_REQ_add_nconf', - '#define X509V3_EXT_add_nconf GRPC_SHADOW_X509V3_EXT_add_nconf', - '#define X509V3_EXT_add_nconf_sk GRPC_SHADOW_X509V3_EXT_add_nconf_sk', - '#define X509V3_EXT_i2d GRPC_SHADOW_X509V3_EXT_i2d', - '#define X509V3_EXT_nconf GRPC_SHADOW_X509V3_EXT_nconf', - '#define X509V3_EXT_nconf_nid GRPC_SHADOW_X509V3_EXT_nconf_nid', - '#define X509V3_get_section GRPC_SHADOW_X509V3_get_section', - '#define X509V3_get_string GRPC_SHADOW_X509V3_get_string', - '#define X509V3_section_free GRPC_SHADOW_X509V3_section_free', - '#define X509V3_set_ctx GRPC_SHADOW_X509V3_set_ctx', - '#define X509V3_set_nconf GRPC_SHADOW_X509V3_set_nconf', - '#define X509V3_string_free GRPC_SHADOW_X509V3_string_free', - '#define CERTIFICATEPOLICIES_free GRPC_SHADOW_CERTIFICATEPOLICIES_free', - '#define CERTIFICATEPOLICIES_it GRPC_SHADOW_CERTIFICATEPOLICIES_it', - '#define CERTIFICATEPOLICIES_new GRPC_SHADOW_CERTIFICATEPOLICIES_new', - '#define NOTICEREF_free GRPC_SHADOW_NOTICEREF_free', - '#define NOTICEREF_it GRPC_SHADOW_NOTICEREF_it', - '#define NOTICEREF_new GRPC_SHADOW_NOTICEREF_new', - '#define POLICYINFO_free GRPC_SHADOW_POLICYINFO_free', - '#define POLICYINFO_it GRPC_SHADOW_POLICYINFO_it', - '#define POLICYINFO_new GRPC_SHADOW_POLICYINFO_new', - '#define POLICYQUALINFO_free GRPC_SHADOW_POLICYQUALINFO_free', - '#define POLICYQUALINFO_it GRPC_SHADOW_POLICYQUALINFO_it', - '#define POLICYQUALINFO_new GRPC_SHADOW_POLICYQUALINFO_new', - '#define USERNOTICE_free GRPC_SHADOW_USERNOTICE_free', - '#define USERNOTICE_it GRPC_SHADOW_USERNOTICE_it', - '#define USERNOTICE_new GRPC_SHADOW_USERNOTICE_new', - '#define X509_POLICY_NODE_print GRPC_SHADOW_X509_POLICY_NODE_print', - '#define d2i_CERTIFICATEPOLICIES GRPC_SHADOW_d2i_CERTIFICATEPOLICIES', - '#define d2i_NOTICEREF GRPC_SHADOW_d2i_NOTICEREF', - '#define d2i_POLICYINFO GRPC_SHADOW_d2i_POLICYINFO', - '#define d2i_POLICYQUALINFO GRPC_SHADOW_d2i_POLICYQUALINFO', - '#define d2i_USERNOTICE GRPC_SHADOW_d2i_USERNOTICE', - '#define i2d_CERTIFICATEPOLICIES GRPC_SHADOW_i2d_CERTIFICATEPOLICIES', - '#define i2d_NOTICEREF GRPC_SHADOW_i2d_NOTICEREF', - '#define i2d_POLICYINFO GRPC_SHADOW_i2d_POLICYINFO', - '#define i2d_POLICYQUALINFO GRPC_SHADOW_i2d_POLICYQUALINFO', - '#define i2d_USERNOTICE GRPC_SHADOW_i2d_USERNOTICE', - '#define v3_cpols GRPC_SHADOW_v3_cpols', - '#define CRL_DIST_POINTS_free GRPC_SHADOW_CRL_DIST_POINTS_free', - '#define CRL_DIST_POINTS_it GRPC_SHADOW_CRL_DIST_POINTS_it', - '#define CRL_DIST_POINTS_new GRPC_SHADOW_CRL_DIST_POINTS_new', - '#define DIST_POINT_NAME_free GRPC_SHADOW_DIST_POINT_NAME_free', - '#define DIST_POINT_NAME_it GRPC_SHADOW_DIST_POINT_NAME_it', - '#define DIST_POINT_NAME_new GRPC_SHADOW_DIST_POINT_NAME_new', - '#define DIST_POINT_free GRPC_SHADOW_DIST_POINT_free', - '#define DIST_POINT_it GRPC_SHADOW_DIST_POINT_it', - '#define DIST_POINT_new GRPC_SHADOW_DIST_POINT_new', - '#define DIST_POINT_set_dpname GRPC_SHADOW_DIST_POINT_set_dpname', - '#define ISSUING_DIST_POINT_free GRPC_SHADOW_ISSUING_DIST_POINT_free', - '#define ISSUING_DIST_POINT_it GRPC_SHADOW_ISSUING_DIST_POINT_it', - '#define ISSUING_DIST_POINT_new GRPC_SHADOW_ISSUING_DIST_POINT_new', - '#define d2i_CRL_DIST_POINTS GRPC_SHADOW_d2i_CRL_DIST_POINTS', - '#define d2i_DIST_POINT GRPC_SHADOW_d2i_DIST_POINT', - '#define d2i_DIST_POINT_NAME GRPC_SHADOW_d2i_DIST_POINT_NAME', - '#define d2i_ISSUING_DIST_POINT GRPC_SHADOW_d2i_ISSUING_DIST_POINT', - '#define i2d_CRL_DIST_POINTS GRPC_SHADOW_i2d_CRL_DIST_POINTS', - '#define i2d_DIST_POINT GRPC_SHADOW_i2d_DIST_POINT', - '#define i2d_DIST_POINT_NAME GRPC_SHADOW_i2d_DIST_POINT_NAME', - '#define i2d_ISSUING_DIST_POINT GRPC_SHADOW_i2d_ISSUING_DIST_POINT', - '#define v3_crld GRPC_SHADOW_v3_crld', - '#define v3_freshest_crl GRPC_SHADOW_v3_freshest_crl', - '#define v3_idp GRPC_SHADOW_v3_idp', - '#define i2s_ASN1_ENUMERATED_TABLE GRPC_SHADOW_i2s_ASN1_ENUMERATED_TABLE', - '#define v3_crl_reason GRPC_SHADOW_v3_crl_reason', - '#define EXTENDED_KEY_USAGE_free GRPC_SHADOW_EXTENDED_KEY_USAGE_free', - '#define EXTENDED_KEY_USAGE_it GRPC_SHADOW_EXTENDED_KEY_USAGE_it', - '#define EXTENDED_KEY_USAGE_new GRPC_SHADOW_EXTENDED_KEY_USAGE_new', - '#define d2i_EXTENDED_KEY_USAGE GRPC_SHADOW_d2i_EXTENDED_KEY_USAGE', - '#define i2d_EXTENDED_KEY_USAGE GRPC_SHADOW_i2d_EXTENDED_KEY_USAGE', - '#define v3_ext_ku GRPC_SHADOW_v3_ext_ku', - '#define v3_ocsp_accresp GRPC_SHADOW_v3_ocsp_accresp', - '#define EDIPARTYNAME_free GRPC_SHADOW_EDIPARTYNAME_free', - '#define EDIPARTYNAME_it GRPC_SHADOW_EDIPARTYNAME_it', - '#define EDIPARTYNAME_new GRPC_SHADOW_EDIPARTYNAME_new', - '#define GENERAL_NAMES_free GRPC_SHADOW_GENERAL_NAMES_free', - '#define GENERAL_NAMES_it GRPC_SHADOW_GENERAL_NAMES_it', - '#define GENERAL_NAMES_new GRPC_SHADOW_GENERAL_NAMES_new', - '#define GENERAL_NAME_cmp GRPC_SHADOW_GENERAL_NAME_cmp', - '#define GENERAL_NAME_dup GRPC_SHADOW_GENERAL_NAME_dup', - '#define GENERAL_NAME_free GRPC_SHADOW_GENERAL_NAME_free', - '#define GENERAL_NAME_get0_otherName GRPC_SHADOW_GENERAL_NAME_get0_otherName', - '#define GENERAL_NAME_get0_value GRPC_SHADOW_GENERAL_NAME_get0_value', - '#define GENERAL_NAME_it GRPC_SHADOW_GENERAL_NAME_it', - '#define GENERAL_NAME_new GRPC_SHADOW_GENERAL_NAME_new', - '#define GENERAL_NAME_set0_othername GRPC_SHADOW_GENERAL_NAME_set0_othername', - '#define GENERAL_NAME_set0_value GRPC_SHADOW_GENERAL_NAME_set0_value', - '#define OTHERNAME_cmp GRPC_SHADOW_OTHERNAME_cmp', - '#define OTHERNAME_free GRPC_SHADOW_OTHERNAME_free', - '#define OTHERNAME_it GRPC_SHADOW_OTHERNAME_it', - '#define OTHERNAME_new GRPC_SHADOW_OTHERNAME_new', - '#define d2i_EDIPARTYNAME GRPC_SHADOW_d2i_EDIPARTYNAME', - '#define d2i_GENERAL_NAME GRPC_SHADOW_d2i_GENERAL_NAME', - '#define d2i_GENERAL_NAMES GRPC_SHADOW_d2i_GENERAL_NAMES', - '#define d2i_OTHERNAME GRPC_SHADOW_d2i_OTHERNAME', - '#define i2d_EDIPARTYNAME GRPC_SHADOW_i2d_EDIPARTYNAME', - '#define i2d_GENERAL_NAME GRPC_SHADOW_i2d_GENERAL_NAME', - '#define i2d_GENERAL_NAMES GRPC_SHADOW_i2d_GENERAL_NAMES', - '#define i2d_OTHERNAME GRPC_SHADOW_i2d_OTHERNAME', - '#define v3_ns_ia5_list GRPC_SHADOW_v3_ns_ia5_list', - '#define ACCESS_DESCRIPTION_free GRPC_SHADOW_ACCESS_DESCRIPTION_free', - '#define ACCESS_DESCRIPTION_it GRPC_SHADOW_ACCESS_DESCRIPTION_it', - '#define ACCESS_DESCRIPTION_new GRPC_SHADOW_ACCESS_DESCRIPTION_new', - '#define AUTHORITY_INFO_ACCESS_free GRPC_SHADOW_AUTHORITY_INFO_ACCESS_free', - '#define AUTHORITY_INFO_ACCESS_it GRPC_SHADOW_AUTHORITY_INFO_ACCESS_it', - '#define AUTHORITY_INFO_ACCESS_new GRPC_SHADOW_AUTHORITY_INFO_ACCESS_new', - '#define d2i_ACCESS_DESCRIPTION GRPC_SHADOW_d2i_ACCESS_DESCRIPTION', - '#define d2i_AUTHORITY_INFO_ACCESS GRPC_SHADOW_d2i_AUTHORITY_INFO_ACCESS', - '#define i2a_ACCESS_DESCRIPTION GRPC_SHADOW_i2a_ACCESS_DESCRIPTION', - '#define i2d_ACCESS_DESCRIPTION GRPC_SHADOW_i2d_ACCESS_DESCRIPTION', - '#define i2d_AUTHORITY_INFO_ACCESS GRPC_SHADOW_i2d_AUTHORITY_INFO_ACCESS', - '#define v3_info GRPC_SHADOW_v3_info', - '#define v3_sinfo GRPC_SHADOW_v3_sinfo', - '#define v3_crl_num GRPC_SHADOW_v3_crl_num', - '#define v3_delta_crl GRPC_SHADOW_v3_delta_crl', - '#define v3_inhibit_anyp GRPC_SHADOW_v3_inhibit_anyp', - '#define X509V3_EXT_add GRPC_SHADOW_X509V3_EXT_add', - '#define X509V3_EXT_add_alias GRPC_SHADOW_X509V3_EXT_add_alias', - '#define X509V3_EXT_add_list GRPC_SHADOW_X509V3_EXT_add_list', - '#define X509V3_EXT_cleanup GRPC_SHADOW_X509V3_EXT_cleanup', - '#define X509V3_EXT_d2i GRPC_SHADOW_X509V3_EXT_d2i', - '#define X509V3_EXT_free GRPC_SHADOW_X509V3_EXT_free', - '#define X509V3_EXT_get GRPC_SHADOW_X509V3_EXT_get', - '#define X509V3_EXT_get_nid GRPC_SHADOW_X509V3_EXT_get_nid', - '#define X509V3_add1_i2d GRPC_SHADOW_X509V3_add1_i2d', - '#define X509V3_add_standard_extensions GRPC_SHADOW_X509V3_add_standard_extensions', - '#define X509V3_get_d2i GRPC_SHADOW_X509V3_get_d2i', - '#define GENERAL_SUBTREE_free GRPC_SHADOW_GENERAL_SUBTREE_free', - '#define GENERAL_SUBTREE_it GRPC_SHADOW_GENERAL_SUBTREE_it', - '#define GENERAL_SUBTREE_new GRPC_SHADOW_GENERAL_SUBTREE_new', - '#define NAME_CONSTRAINTS_check GRPC_SHADOW_NAME_CONSTRAINTS_check', - '#define NAME_CONSTRAINTS_free GRPC_SHADOW_NAME_CONSTRAINTS_free', - '#define NAME_CONSTRAINTS_it GRPC_SHADOW_NAME_CONSTRAINTS_it', - '#define NAME_CONSTRAINTS_new GRPC_SHADOW_NAME_CONSTRAINTS_new', - '#define v3_name_constraints GRPC_SHADOW_v3_name_constraints', - '#define v3_pci GRPC_SHADOW_v3_pci', - '#define PROXY_CERT_INFO_EXTENSION_free GRPC_SHADOW_PROXY_CERT_INFO_EXTENSION_free', - '#define PROXY_CERT_INFO_EXTENSION_it GRPC_SHADOW_PROXY_CERT_INFO_EXTENSION_it', - '#define PROXY_CERT_INFO_EXTENSION_new GRPC_SHADOW_PROXY_CERT_INFO_EXTENSION_new', - '#define PROXY_POLICY_free GRPC_SHADOW_PROXY_POLICY_free', - '#define PROXY_POLICY_it GRPC_SHADOW_PROXY_POLICY_it', - '#define PROXY_POLICY_new GRPC_SHADOW_PROXY_POLICY_new', - '#define d2i_PROXY_CERT_INFO_EXTENSION GRPC_SHADOW_d2i_PROXY_CERT_INFO_EXTENSION', - '#define d2i_PROXY_POLICY GRPC_SHADOW_d2i_PROXY_POLICY', - '#define i2d_PROXY_CERT_INFO_EXTENSION GRPC_SHADOW_i2d_PROXY_CERT_INFO_EXTENSION', - '#define i2d_PROXY_POLICY GRPC_SHADOW_i2d_PROXY_POLICY', - '#define POLICY_CONSTRAINTS_free GRPC_SHADOW_POLICY_CONSTRAINTS_free', - '#define POLICY_CONSTRAINTS_it GRPC_SHADOW_POLICY_CONSTRAINTS_it', - '#define POLICY_CONSTRAINTS_new GRPC_SHADOW_POLICY_CONSTRAINTS_new', - '#define v3_policy_constraints GRPC_SHADOW_v3_policy_constraints', - '#define PKEY_USAGE_PERIOD_free GRPC_SHADOW_PKEY_USAGE_PERIOD_free', - '#define PKEY_USAGE_PERIOD_it GRPC_SHADOW_PKEY_USAGE_PERIOD_it', - '#define PKEY_USAGE_PERIOD_new GRPC_SHADOW_PKEY_USAGE_PERIOD_new', - '#define d2i_PKEY_USAGE_PERIOD GRPC_SHADOW_d2i_PKEY_USAGE_PERIOD', - '#define i2d_PKEY_USAGE_PERIOD GRPC_SHADOW_i2d_PKEY_USAGE_PERIOD', - '#define v3_pkey_usage_period GRPC_SHADOW_v3_pkey_usage_period', - '#define POLICY_MAPPINGS_it GRPC_SHADOW_POLICY_MAPPINGS_it', - '#define POLICY_MAPPING_free GRPC_SHADOW_POLICY_MAPPING_free', - '#define POLICY_MAPPING_it GRPC_SHADOW_POLICY_MAPPING_it', - '#define POLICY_MAPPING_new GRPC_SHADOW_POLICY_MAPPING_new', - '#define v3_policy_mappings GRPC_SHADOW_v3_policy_mappings', - '#define X509V3_EXT_print GRPC_SHADOW_X509V3_EXT_print', - '#define X509V3_EXT_print_fp GRPC_SHADOW_X509V3_EXT_print_fp', - '#define X509V3_EXT_val_prn GRPC_SHADOW_X509V3_EXT_val_prn', - '#define X509V3_extensions_print GRPC_SHADOW_X509V3_extensions_print', - '#define X509_PURPOSE_add GRPC_SHADOW_X509_PURPOSE_add', - '#define X509_PURPOSE_cleanup GRPC_SHADOW_X509_PURPOSE_cleanup', - '#define X509_PURPOSE_get0 GRPC_SHADOW_X509_PURPOSE_get0', - '#define X509_PURPOSE_get0_name GRPC_SHADOW_X509_PURPOSE_get0_name', - '#define X509_PURPOSE_get0_sname GRPC_SHADOW_X509_PURPOSE_get0_sname', - '#define X509_PURPOSE_get_by_id GRPC_SHADOW_X509_PURPOSE_get_by_id', - '#define X509_PURPOSE_get_by_sname GRPC_SHADOW_X509_PURPOSE_get_by_sname', - '#define X509_PURPOSE_get_count GRPC_SHADOW_X509_PURPOSE_get_count', - '#define X509_PURPOSE_get_id GRPC_SHADOW_X509_PURPOSE_get_id', - '#define X509_PURPOSE_get_trust GRPC_SHADOW_X509_PURPOSE_get_trust', - '#define X509_PURPOSE_set GRPC_SHADOW_X509_PURPOSE_set', - '#define X509_check_akid GRPC_SHADOW_X509_check_akid', - '#define X509_check_ca GRPC_SHADOW_X509_check_ca', - '#define X509_check_issued GRPC_SHADOW_X509_check_issued', - '#define X509_check_purpose GRPC_SHADOW_X509_check_purpose', - '#define X509_supported_extension GRPC_SHADOW_X509_supported_extension', - '#define i2s_ASN1_OCTET_STRING GRPC_SHADOW_i2s_ASN1_OCTET_STRING', - '#define s2i_ASN1_OCTET_STRING GRPC_SHADOW_s2i_ASN1_OCTET_STRING', - '#define v3_skey_id GRPC_SHADOW_v3_skey_id', - '#define SXNETID_free GRPC_SHADOW_SXNETID_free', - '#define SXNETID_it GRPC_SHADOW_SXNETID_it', - '#define SXNETID_new GRPC_SHADOW_SXNETID_new', - '#define SXNET_add_id_INTEGER GRPC_SHADOW_SXNET_add_id_INTEGER', - '#define SXNET_add_id_asc GRPC_SHADOW_SXNET_add_id_asc', - '#define SXNET_add_id_ulong GRPC_SHADOW_SXNET_add_id_ulong', - '#define SXNET_free GRPC_SHADOW_SXNET_free', - '#define SXNET_get_id_INTEGER GRPC_SHADOW_SXNET_get_id_INTEGER', - '#define SXNET_get_id_asc GRPC_SHADOW_SXNET_get_id_asc', - '#define SXNET_get_id_ulong GRPC_SHADOW_SXNET_get_id_ulong', - '#define SXNET_it GRPC_SHADOW_SXNET_it', - '#define SXNET_new GRPC_SHADOW_SXNET_new', - '#define d2i_SXNET GRPC_SHADOW_d2i_SXNET', - '#define d2i_SXNETID GRPC_SHADOW_d2i_SXNETID', - '#define i2d_SXNET GRPC_SHADOW_i2d_SXNET', - '#define i2d_SXNETID GRPC_SHADOW_i2d_SXNETID', - '#define v3_sxnet GRPC_SHADOW_v3_sxnet', - '#define X509V3_NAME_from_section GRPC_SHADOW_X509V3_NAME_from_section', - '#define X509V3_add_value GRPC_SHADOW_X509V3_add_value', - '#define X509V3_add_value_bool GRPC_SHADOW_X509V3_add_value_bool', - '#define X509V3_add_value_bool_nf GRPC_SHADOW_X509V3_add_value_bool_nf', - '#define X509V3_add_value_int GRPC_SHADOW_X509V3_add_value_int', - '#define X509V3_add_value_uchar GRPC_SHADOW_X509V3_add_value_uchar', - '#define X509V3_conf_free GRPC_SHADOW_X509V3_conf_free', - '#define X509V3_get_value_bool GRPC_SHADOW_X509V3_get_value_bool', - '#define X509V3_get_value_int GRPC_SHADOW_X509V3_get_value_int', - '#define X509V3_parse_list GRPC_SHADOW_X509V3_parse_list', - '#define X509_REQ_get1_email GRPC_SHADOW_X509_REQ_get1_email', - '#define X509_check_email GRPC_SHADOW_X509_check_email', - '#define X509_check_host GRPC_SHADOW_X509_check_host', - '#define X509_check_ip GRPC_SHADOW_X509_check_ip', - '#define X509_check_ip_asc GRPC_SHADOW_X509_check_ip_asc', - '#define X509_email_free GRPC_SHADOW_X509_email_free', - '#define X509_get1_email GRPC_SHADOW_X509_get1_email', - '#define X509_get1_ocsp GRPC_SHADOW_X509_get1_ocsp', - '#define a2i_IPADDRESS GRPC_SHADOW_a2i_IPADDRESS', - '#define a2i_IPADDRESS_NC GRPC_SHADOW_a2i_IPADDRESS_NC', - '#define a2i_ipadd GRPC_SHADOW_a2i_ipadd', - '#define hex_to_string GRPC_SHADOW_hex_to_string', - '#define i2s_ASN1_ENUMERATED GRPC_SHADOW_i2s_ASN1_ENUMERATED', - '#define i2s_ASN1_INTEGER GRPC_SHADOW_i2s_ASN1_INTEGER', - '#define name_cmp GRPC_SHADOW_name_cmp', - '#define s2i_ASN1_INTEGER GRPC_SHADOW_s2i_ASN1_INTEGER', - '#define string_to_hex GRPC_SHADOW_string_to_hex', - '#define PKCS7_get_raw_certificates GRPC_SHADOW_PKCS7_get_raw_certificates', - '#define pkcs7_bundle GRPC_SHADOW_pkcs7_bundle', - '#define pkcs7_parse_header GRPC_SHADOW_pkcs7_parse_header', - '#define PKCS7_bundle_CRLs GRPC_SHADOW_PKCS7_bundle_CRLs', - '#define PKCS7_bundle_certificates GRPC_SHADOW_PKCS7_bundle_certificates', - '#define PKCS7_get_CRLs GRPC_SHADOW_PKCS7_get_CRLs', - '#define PKCS7_get_PEM_CRLs GRPC_SHADOW_PKCS7_get_PEM_CRLs', - '#define PKCS7_get_PEM_certificates GRPC_SHADOW_PKCS7_get_PEM_certificates', - '#define PKCS7_get_certificates GRPC_SHADOW_PKCS7_get_certificates', - '#define PKCS8_marshal_encrypted_private_key GRPC_SHADOW_PKCS8_marshal_encrypted_private_key', - '#define PKCS8_parse_encrypted_private_key GRPC_SHADOW_PKCS8_parse_encrypted_private_key', - '#define pkcs12_key_gen GRPC_SHADOW_pkcs12_key_gen', - '#define pkcs8_pbe_decrypt GRPC_SHADOW_pkcs8_pbe_decrypt', - '#define EVP_PKCS82PKEY GRPC_SHADOW_EVP_PKCS82PKEY', - '#define EVP_PKEY2PKCS8 GRPC_SHADOW_EVP_PKEY2PKCS8', - '#define PKCS12_PBE_add GRPC_SHADOW_PKCS12_PBE_add', - '#define PKCS12_free GRPC_SHADOW_PKCS12_free', - '#define PKCS12_get_key_and_certs GRPC_SHADOW_PKCS12_get_key_and_certs', - '#define PKCS12_parse GRPC_SHADOW_PKCS12_parse', - '#define PKCS12_verify_mac GRPC_SHADOW_PKCS12_verify_mac', - '#define PKCS8_PRIV_KEY_INFO_free GRPC_SHADOW_PKCS8_PRIV_KEY_INFO_free', - '#define PKCS8_PRIV_KEY_INFO_it GRPC_SHADOW_PKCS8_PRIV_KEY_INFO_it', - '#define PKCS8_PRIV_KEY_INFO_new GRPC_SHADOW_PKCS8_PRIV_KEY_INFO_new', - '#define PKCS8_decrypt GRPC_SHADOW_PKCS8_decrypt', - '#define PKCS8_encrypt GRPC_SHADOW_PKCS8_encrypt', - '#define d2i_PKCS12 GRPC_SHADOW_d2i_PKCS12', - '#define d2i_PKCS12_bio GRPC_SHADOW_d2i_PKCS12_bio', - '#define d2i_PKCS12_fp GRPC_SHADOW_d2i_PKCS12_fp', - '#define d2i_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_d2i_PKCS8_PRIV_KEY_INFO', - '#define i2d_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_i2d_PKCS8_PRIV_KEY_INFO', - '#define PKCS5_pbe2_decrypt_init GRPC_SHADOW_PKCS5_pbe2_decrypt_init', - '#define PKCS5_pbe2_encrypt_init GRPC_SHADOW_PKCS5_pbe2_encrypt_init' - end + ${expand_symbol_list(settings.grpc_shadow_boringssl_symbols)} + end \ No newline at end of file From 5fc904a5e52e3e310eab4ae5425039dc4ae9718f Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 17 Jan 2019 11:56:56 -0800 Subject: [PATCH 096/814] Attempt to fix brew-update/rvm installation issue on mac --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 5b6b2569393..7b9b02b6318 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -40,6 +40,7 @@ fi set +ex # rvm script is very verbose and exits with errorcode # Advice from https://github.com/Homebrew/homebrew-cask/issues/8629#issuecomment-68641176 brew update && brew upgrade brew-cask && brew cleanup && brew cask cleanup +rvm --debug requirements ruby-2.5.0 source $HOME/.rvm/scripts/rvm set -e # rvm commands are very verbose time rvm install 2.5.0 From 140e518cfe970819bb701f3bfd50478d83b22fab Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 17 Jan 2019 17:11:25 -0800 Subject: [PATCH 097/814] Avoid broken symlinks when yapfing code --- tools/distrib/yapf_code.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/distrib/yapf_code.sh b/tools/distrib/yapf_code.sh index 27c5e3129dd..9ded3f3762a 100755 --- a/tools/distrib/yapf_code.sh +++ b/tools/distrib/yapf_code.sh @@ -54,7 +54,7 @@ else tempdir=$(mktemp -d) cp -RT "${dir}" "${tempdir}" yapf "${tempdir}" - diff -x '*.pyc' -ru "${dir}" "${tempdir}" || ok=no + diff -x 'LICENSE' -x '*.pyc' -ru "${dir}" "${tempdir}" || ok=no rm -rf "${tempdir}" done if [[ ${ok} == no ]]; then From 23061cdfc281218b6e88e6f7e711027dc51bc490 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 17 Jan 2019 17:48:30 -0800 Subject: [PATCH 098/814] Collect OPT_STATS along with tx timestamps --- src/core/lib/iomgr/buffer_list.cc | 123 +++++++++++++++++++++++-- src/core/lib/iomgr/buffer_list.h | 81 ++++++++++++++-- src/core/lib/iomgr/internal_errqueue.h | 35 ++++++- src/core/lib/iomgr/tcp_posix.cc | 24 ++++- test/core/iomgr/buffer_list_test.cc | 23 ++++- 5 files changed, 262 insertions(+), 24 deletions(-) diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index ace17a108d1..7d59608120c 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -24,6 +24,7 @@ #include #ifdef GRPC_LINUX_ERRQUEUE +#include #include #include "src/core/lib/gprpp/memory.h" @@ -34,10 +35,10 @@ void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* new_elem = New(seq_no, arg); /* Store the current time as the sendmsg time. */ - new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME); - new_elem->ts_.scheduled_time = gpr_inf_past(GPR_CLOCK_REALTIME); - new_elem->ts_.sent_time = gpr_inf_past(GPR_CLOCK_REALTIME); - new_elem->ts_.acked_time = gpr_inf_past(GPR_CLOCK_REALTIME); + new_elem->ts_.sendmsg_time.time = gpr_now(GPR_CLOCK_REALTIME); + new_elem->ts_.scheduled_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); + new_elem->ts_.sent_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); + new_elem->ts_.acked_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); if (*head == nullptr) { *head = new_elem; return; @@ -68,10 +69,114 @@ void default_timestamps_callback(void* arg, grpc_core::Timestamps* ts, void (*timestamps_callback)(void*, grpc_core::Timestamps*, grpc_error* shutdown_err) = default_timestamps_callback; + +/* Used to extract individual opt stats from cmsg, so as to avoid troubles with + * unaligned reads */ +template +T read_unaligned(const void* ptr) { + T val; + memcpy(&val, ptr, sizeof(val)); + return val; +} + +/** Adds opt stats statistics from the given control message to the connection + * metrics. */ +void ExtractOptStats(ConnectionMetrics* conn_metrics, + const cmsghdr* opt_stats) { + if (opt_stats == nullptr) { + return; + } + const auto* data = CMSG_DATA(opt_stats); + constexpr int64_t cmsg_hdr_len = CMSG_ALIGN(sizeof(struct cmsghdr)); + const int64_t len = opt_stats->cmsg_len - cmsg_hdr_len; + int64_t offset = 0; + + while (offset < len) { + const auto* attr = reinterpret_cast(data + offset); + const void* val = data + offset + NLA_HDRLEN; + switch (attr->nla_type) { + case TCP_NLA_BUSY: { + conn_metrics->busy_usec.set(read_unaligned(val)); + break; + } + case TCP_NLA_RWND_LIMITED: { + conn_metrics->rwnd_limited_usec.set(read_unaligned(val)); + break; + } + case TCP_NLA_SNDBUF_LIMITED: { + conn_metrics->sndbuf_limited_usec.set(read_unaligned(val)); + break; + } + case TCP_NLA_PACING_RATE: { + conn_metrics->pacing_rate.set(read_unaligned(val)); + break; + } + case TCP_NLA_DELIVERY_RATE: { + conn_metrics->delivery_rate.set(read_unaligned(val)); + break; + } + case TCP_NLA_DELIVERY_RATE_APP_LMT: { + conn_metrics->is_delivery_rate_app_limited = + read_unaligned(val); + break; + } + case TCP_NLA_SND_CWND: { + conn_metrics->congestion_window.set(read_unaligned(val)); + break; + } + case TCP_NLA_MIN_RTT: { + conn_metrics->min_rtt.set(read_unaligned(val)); + break; + } + case TCP_NLA_SRTT: { + conn_metrics->srtt.set(read_unaligned(val)); + break; + } + case TCP_NLA_RECUR_RETRANS: { + conn_metrics->recurring_retrans.set(read_unaligned(val)); + break; + } + case TCP_NLA_BYTES_SENT: { + conn_metrics->data_sent.set(read_unaligned(val)); + break; + } + case TCP_NLA_DATA_SEGS_OUT: { + conn_metrics->packet_sent.set(read_unaligned(val)); + break; + } + case TCP_NLA_TOTAL_RETRANS: { + conn_metrics->packet_retx.set(read_unaligned(val)); + break; + } + case TCP_NLA_DELIVERED: { + conn_metrics->packet_delivered.set(read_unaligned(val)); + break; + } + case TCP_NLA_DELIVERED_CE: { + conn_metrics->packet_delivered_ce.set(read_unaligned(val)); + break; + } + case TCP_NLA_BYTES_RETRANS: { + conn_metrics->data_retx.set(read_unaligned(val)); + break; + } + case TCP_NLA_REORDERING: { + conn_metrics->reordering.set(read_unaligned(val)); + break; + } + case TCP_NLA_SND_SSTHRESH: { + conn_metrics->snd_ssthresh.set(read_unaligned(val)); + break; + } + } + offset += NLA_ALIGN(attr->nla_len); + } +} } /* namespace */ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, struct sock_extended_err* serr, + struct cmsghdr* opt_stats, struct scm_timestamping* tss) { GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* elem = *head; @@ -82,15 +187,19 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, if (serr->ee_data >= elem->seq_no_) { switch (serr->ee_info) { case SCM_TSTAMP_SCHED: - fill_gpr_from_timestamp(&(elem->ts_.scheduled_time), &(tss->ts[0])); + fill_gpr_from_timestamp(&(elem->ts_.scheduled_time.time), + &(tss->ts[0])); + ExtractOptStats(&(elem->ts_.scheduled_time.metrics), opt_stats); elem = elem->next_; break; case SCM_TSTAMP_SND: - fill_gpr_from_timestamp(&(elem->ts_.sent_time), &(tss->ts[0])); + fill_gpr_from_timestamp(&(elem->ts_.sent_time.time), &(tss->ts[0])); + ExtractOptStats(&(elem->ts_.sent_time.metrics), opt_stats); elem = elem->next_; break; case SCM_TSTAMP_ACK: - fill_gpr_from_timestamp(&(elem->ts_.acked_time), &(tss->ts[0])); + fill_gpr_from_timestamp(&(elem->ts_.acked_time.time), &(tss->ts[0])); + ExtractOptStats(&(elem->ts_.acked_time.metrics), opt_stats); /* Got all timestamps. Do the callback and free this TracedBuffer. * The thing below can be passed by value if we don't want the * restriction on the lifetime. */ diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 627f1bde99a..8b08a7b5114 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -30,13 +30,81 @@ #include "src/core/lib/iomgr/internal_errqueue.h" namespace grpc_core { + +/* A make-shift alternative for absl::Optional. This can be removed in favor of + * that once is absl dependencies can be introduced. */ +template +class Optional { + public: + void set(const T& val) { + value_ = val; + set_ = true; + } + + bool has_value() { return set_; } + + void reset() { set_ = false; } + + T value() { return value_; } + T value_; + bool set_ = false; +}; + +struct ConnectionMetrics { + /* Delivery rate in Bps. */ + Optional delivery_rate; + /* If the delivery rate is limited by the application, this is set to true. */ + bool is_delivery_rate_app_limited = true; + /* Total packets retransmitted. */ + Optional packet_retx; + /* Total packets sent. */ + Optional packet_sent; + /* Total packets delivered. */ + Optional packet_delivered; + /* Total packets delivered with ECE marked. This metric is smaller than or + equal to packet_delivered. */ + Optional packet_delivered_ce; + /* Total bytes lost so far. */ + Optional data_retx; + /* Total bytes sent so far. */ + Optional data_sent; + /* Pacing rate of the connection in Bps */ + Optional pacing_rate; + /* Minimum RTT observed in usec. */ + Optional min_rtt; + /* Smoothed RTT in usec */ + Optional srtt; + /* Send congestion window. */ + Optional congestion_window; + /* Slow start threshold in packets. */ + Optional snd_ssthresh; + /* Maximum degree of reordering (i.e., maximum number of packets reodered) + on the connection. */ + Optional reordering; + /* Represents the number of recurring retransmissions of the first sequence + that is not acknowledged yet. */ + Optional recurring_retrans; + /* The cumulative time (in usec) that the transport protocol was busy + sending data. */ + Optional busy_usec; + /* The cumulative time (in usec) that the transport protocol was limited by + the receive window size. */ + Optional rwnd_limited_usec; + /* The cumulative time (in usec) that the transport protocol was limited by + the send buffer size. */ + Optional sndbuf_limited_usec; +}; + +struct Timestamp { + gpr_timespec time; + ConnectionMetrics metrics; /* Metrics collected with this timestamp */ +}; + struct Timestamps { - /* TODO(yashykt): This would also need to store OPTSTAT once support is added - */ - gpr_timespec sendmsg_time; - gpr_timespec scheduled_time; - gpr_timespec sent_time; - gpr_timespec acked_time; + Timestamp sendmsg_time; + Timestamp scheduled_time; + Timestamp sent_time; + Timestamp acked_time; uint32_t byte_offset; /* byte offset relative to the start of the RPC */ }; @@ -65,6 +133,7 @@ class TracedBuffer { * timestamp type is SCM_TSTAMP_ACK. */ static void ProcessTimestamp(grpc_core::TracedBuffer** head, struct sock_extended_err* serr, + struct cmsghdr* opt_stats, struct scm_timestamping* tss); /** Cleans the list by calling the callback for each traced buffer in the list diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h index f8644c2536c..05b6dbccb83 100644 --- a/src/core/lib/iomgr/internal_errqueue.h +++ b/src/core/lib/iomgr/internal_errqueue.h @@ -37,6 +37,7 @@ #ifdef GRPC_LINUX_ERRQUEUE #include #include +#include #include #endif /* GRPC_LINUX_ERRQUEUE */ @@ -63,13 +64,41 @@ constexpr uint32_t SOF_TIMESTAMPING_OPT_ID = 1u << 7; constexpr uint32_t SOF_TIMESTAMPING_TX_SCHED = 1u << 8; constexpr uint32_t SOF_TIMESTAMPING_TX_ACK = 1u << 9; constexpr uint32_t SOF_TIMESTAMPING_OPT_TSONLY = 1u << 11; +constexpr uint32_t SOF_TIMESTAMPING_OPT_STATS = 1u << 12; -constexpr uint32_t kTimestampingSocketOptions = SOF_TIMESTAMPING_SOFTWARE | - SOF_TIMESTAMPING_OPT_ID | - SOF_TIMESTAMPING_OPT_TSONLY; +constexpr uint32_t kTimestampingSocketOptions = + SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_OPT_ID | + SOF_TIMESTAMPING_OPT_TSONLY | SOF_TIMESTAMPING_OPT_STATS; constexpr uint32_t kTimestampingRecordingOptions = SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_TX_ACK; + +/* Netlink attribute types used for TCP opt stats. */ +enum TCPOptStats { + TCP_NLA_PAD, + TCP_NLA_BUSY, /* Time (usec) busy sending data. */ + TCP_NLA_RWND_LIMITED, /* Time (usec) limited by receive window. */ + TCP_NLA_SNDBUF_LIMITED, /* Time (usec) limited by send buffer. */ + TCP_NLA_DATA_SEGS_OUT, // Data pkts sent including retransmission. */ + TCP_NLA_TOTAL_RETRANS, // Data pkts retransmitted. */ + TCP_NLA_PACING_RATE, // Pacing rate in Bps. */ + TCP_NLA_DELIVERY_RATE, // Delivery rate in Bps. */ + TCP_NLA_SND_CWND, // Sending congestion window. */ + TCP_NLA_REORDERING, // Reordering metric. */ + TCP_NLA_MIN_RTT, // minimum RTT. */ + TCP_NLA_RECUR_RETRANS, // Recurring retransmits for the current pkt. */ + TCP_NLA_DELIVERY_RATE_APP_LMT, // Delivery rate application limited? */ + TCP_NLA_SNDQ_SIZE, // Data (bytes) pending in send queue */ + TCP_NLA_CA_STATE, // ca_state of socket */ + TCP_NLA_SND_SSTHRESH, // Slow start size threshold */ + TCP_NLA_DELIVERED, // Data pkts delivered incl. out-of-order */ + TCP_NLA_DELIVERED_CE, // Like above but only ones w/ CE marks */ + TCP_NLA_BYTES_SENT, // Data bytes sent including retransmission */ + TCP_NLA_BYTES_RETRANS, // Data bytes retransmitted */ + TCP_NLA_DSACK_DUPS, // DSACK blocks received */ + TCP_NLA_REORD_SEEN, // reordering events seen */ + TCP_NLA_SRTT, // smoothed RTT in usecs */ +}; #endif /* GRPC_LINUX_ERRQUEUE */ /* Returns true if kernel is capable of supporting errqueue and timestamping. diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index d0642c015ff..446613c91b7 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -648,6 +648,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, struct cmsghdr* cmsg) { auto next_cmsg = CMSG_NXTHDR(msg, cmsg); + cmsghdr* opt_stats = nullptr; if (next_cmsg == nullptr) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_ERROR, "Received timestamp without extended error"); @@ -655,6 +656,19 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, return cmsg; } + /* Check if next_cmsg is an OPT_STATS msg */ + if (next_cmsg->cmsg_level == SOL_SOCKET && + next_cmsg->cmsg_type == SCM_TIMESTAMPING_OPT_STATS) { + opt_stats = next_cmsg; + next_cmsg = CMSG_NXTHDR(msg, opt_stats); + if (next_cmsg == nullptr) { + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_ERROR, "Received timestamp without extended error"); + } + } + return opt_stats; + } + if (!(next_cmsg->cmsg_level == SOL_IP || next_cmsg->cmsg_level == SOL_IPV6) || !(next_cmsg->cmsg_type == IP_RECVERR || next_cmsg->cmsg_type == IPV6_RECVERR)) { @@ -676,7 +690,8 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, * to protect the traced buffer list. A lock free list might be better. Using * a simple mutex for now. */ gpr_mu_lock(&tcp->tb_mu); - grpc_core::TracedBuffer::ProcessTimestamp(&tcp->tb_head, serr, tss); + grpc_core::TracedBuffer::ProcessTimestamp(&tcp->tb_head, serr, opt_stats, + tss); gpr_mu_unlock(&tcp->tb_mu); return next_cmsg; } @@ -696,10 +711,11 @@ static void process_errors(grpc_tcp* tcp) { msg.msg_iovlen = 0; msg.msg_flags = 0; + // Allocate aligned space for cmsgs received along with a timestamps union { - char rbuf[1024 /*CMSG_SPACE(sizeof(scm_timestamping)) + - CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in))*/ - ]; + char rbuf[CMSG_SPACE(sizeof(scm_timestamping)) + + CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in)) + + CMSG_SPACE(16 * NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t)))]; struct cmsghdr align; } aligned_buf; memset(&aligned_buf, 0, sizeof(aligned_buf)); diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index eca8f76e673..9b2f169b89a 100644 --- a/test/core/iomgr/buffer_list_test.cc +++ b/test/core/iomgr/buffer_list_test.cc @@ -63,9 +63,9 @@ static void TestVerifierCalledOnAckVerifier(void* arg, grpc_error* error) { GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(arg != nullptr); - GPR_ASSERT(ts->acked_time.clock_type == GPR_CLOCK_REALTIME); - GPR_ASSERT(ts->acked_time.tv_sec == 123); - GPR_ASSERT(ts->acked_time.tv_nsec == 456); + GPR_ASSERT(ts->acked_time.time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->acked_time.time.tv_sec == 123); + GPR_ASSERT(ts->acked_time.time.tv_nsec == 456); gpr_atm* done = reinterpret_cast(arg); gpr_atm_rel_store(done, static_cast(1)); } @@ -85,7 +85,7 @@ static void TestVerifierCalledOnAck() { gpr_atm verifier_called; gpr_atm_rel_store(&verifier_called, static_cast(0)); grpc_core::TracedBuffer::AddNewEntry(&list, 213, &verifier_called); - grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, &tss); + grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, nullptr, &tss); GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast(1)); GPR_ASSERT(list == nullptr); grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE); @@ -96,10 +96,25 @@ static void TestTcpBufferList() { TestShutdownFlushesList(); } +/* Tests grpc_core::Optional */ +static void TestOptional() { + grpc_core::Optional opt_val; + GPR_ASSERT(opt_val.has_value() == false); + const int kTestVal = 123; + + opt_val.set(kTestVal); + GPR_ASSERT(opt_val.has_value()); + GPR_ASSERT(opt_val.value() == 123); + + opt_val.reset(); + GPR_ASSERT(opt_val.has_value() == false); +} + int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); TestTcpBufferList(); + TestOptional(); grpc_shutdown(); return 0; } From 6753be0cf96b6f6fdc1e16bd0aa43c3a5360f5cd Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 17 Jan 2019 18:13:34 -0800 Subject: [PATCH 099/814] Add definition for SCM_TIMESTAMPING_OPT_STATS in case it is not defined --- src/core/lib/iomgr/internal_errqueue.h | 44 +++++++++++++++----------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h index 05b6dbccb83..e8c3ef4acf9 100644 --- a/src/core/lib/iomgr/internal_errqueue.h +++ b/src/core/lib/iomgr/internal_errqueue.h @@ -57,6 +57,12 @@ constexpr int SCM_TSTAMP_SND = 0; constexpr int SCM_TSTAMP_SCHED = 1; /* The timestamp type for when data acknowledged by peer. */ constexpr int SCM_TSTAMP_ACK = 2; + +/* Control message type containing OPT_STATS */ +#ifndef SCM_TIMESTAMPING_OPT_STATS +#define SCM_TIMESTAMPING_OPT_STATS 54 +#endif + /* Redefine required constants from */ constexpr uint32_t SOF_TIMESTAMPING_TX_SOFTWARE = 1u << 1; constexpr uint32_t SOF_TIMESTAMPING_SOFTWARE = 1u << 4; @@ -79,25 +85,25 @@ enum TCPOptStats { TCP_NLA_BUSY, /* Time (usec) busy sending data. */ TCP_NLA_RWND_LIMITED, /* Time (usec) limited by receive window. */ TCP_NLA_SNDBUF_LIMITED, /* Time (usec) limited by send buffer. */ - TCP_NLA_DATA_SEGS_OUT, // Data pkts sent including retransmission. */ - TCP_NLA_TOTAL_RETRANS, // Data pkts retransmitted. */ - TCP_NLA_PACING_RATE, // Pacing rate in Bps. */ - TCP_NLA_DELIVERY_RATE, // Delivery rate in Bps. */ - TCP_NLA_SND_CWND, // Sending congestion window. */ - TCP_NLA_REORDERING, // Reordering metric. */ - TCP_NLA_MIN_RTT, // minimum RTT. */ - TCP_NLA_RECUR_RETRANS, // Recurring retransmits for the current pkt. */ - TCP_NLA_DELIVERY_RATE_APP_LMT, // Delivery rate application limited? */ - TCP_NLA_SNDQ_SIZE, // Data (bytes) pending in send queue */ - TCP_NLA_CA_STATE, // ca_state of socket */ - TCP_NLA_SND_SSTHRESH, // Slow start size threshold */ - TCP_NLA_DELIVERED, // Data pkts delivered incl. out-of-order */ - TCP_NLA_DELIVERED_CE, // Like above but only ones w/ CE marks */ - TCP_NLA_BYTES_SENT, // Data bytes sent including retransmission */ - TCP_NLA_BYTES_RETRANS, // Data bytes retransmitted */ - TCP_NLA_DSACK_DUPS, // DSACK blocks received */ - TCP_NLA_REORD_SEEN, // reordering events seen */ - TCP_NLA_SRTT, // smoothed RTT in usecs */ + TCP_NLA_DATA_SEGS_OUT, /* Data pkts sent including retransmission. */ + TCP_NLA_TOTAL_RETRANS, /* Data pkts retransmitted. */ + TCP_NLA_PACING_RATE, /* Pacing rate in Bps. */ + TCP_NLA_DELIVERY_RATE, /* Delivery rate in Bps. */ + TCP_NLA_SND_CWND, /* Sending congestion window. */ + TCP_NLA_REORDERING, /* Reordering metric. */ + TCP_NLA_MIN_RTT, /* minimum RTT. */ + TCP_NLA_RECUR_RETRANS, /* Recurring retransmits for the current pkt. */ + TCP_NLA_DELIVERY_RATE_APP_LMT, /* Delivery rate application limited? */ + TCP_NLA_SNDQ_SIZE, /* Data (bytes) pending in send queue */ + TCP_NLA_CA_STATE, /* ca_state of socket */ + TCP_NLA_SND_SSTHRESH, /* Slow start size threshold */ + TCP_NLA_DELIVERED, /* Data pkts delivered incl. out-of-order */ + TCP_NLA_DELIVERED_CE, /* Like above but only ones w/ CE marks */ + TCP_NLA_BYTES_SENT, /* Data bytes sent including retransmission */ + TCP_NLA_BYTES_RETRANS, /* Data bytes retransmitted */ + TCP_NLA_DSACK_DUPS, /* DSACK blocks received */ + TCP_NLA_REORD_SEEN, /* reordering events seen */ + TCP_NLA_SRTT, /* smoothed RTT in usecs */ }; #endif /* GRPC_LINUX_ERRQUEUE */ From cbb157a0de6be6d89dce4b10db3cf11bb884b8fe Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 17 Jan 2019 18:37:17 -0800 Subject: [PATCH 100/814] Add metric for spurious retries --- src/core/lib/iomgr/buffer_list.cc | 44 ++++++++++++++++--------------- src/core/lib/iomgr/buffer_list.h | 3 +++ 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index 7d59608120c..58814d0e84f 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -81,8 +81,7 @@ T read_unaligned(const void* ptr) { /** Adds opt stats statistics from the given control message to the connection * metrics. */ -void ExtractOptStats(ConnectionMetrics* conn_metrics, - const cmsghdr* opt_stats) { +void ExtractOptStats(ConnectionMetrics* metrics, const cmsghdr* opt_stats) { if (opt_stats == nullptr) { return; } @@ -96,76 +95,79 @@ void ExtractOptStats(ConnectionMetrics* conn_metrics, const void* val = data + offset + NLA_HDRLEN; switch (attr->nla_type) { case TCP_NLA_BUSY: { - conn_metrics->busy_usec.set(read_unaligned(val)); + metrics->busy_usec.set(read_unaligned(val)); break; } case TCP_NLA_RWND_LIMITED: { - conn_metrics->rwnd_limited_usec.set(read_unaligned(val)); + metrics->rwnd_limited_usec.set(read_unaligned(val)); break; } case TCP_NLA_SNDBUF_LIMITED: { - conn_metrics->sndbuf_limited_usec.set(read_unaligned(val)); + metrics->sndbuf_limited_usec.set(read_unaligned(val)); break; } case TCP_NLA_PACING_RATE: { - conn_metrics->pacing_rate.set(read_unaligned(val)); + metrics->pacing_rate.set(read_unaligned(val)); break; } case TCP_NLA_DELIVERY_RATE: { - conn_metrics->delivery_rate.set(read_unaligned(val)); + metrics->delivery_rate.set(read_unaligned(val)); break; } case TCP_NLA_DELIVERY_RATE_APP_LMT: { - conn_metrics->is_delivery_rate_app_limited = - read_unaligned(val); + metrics->is_delivery_rate_app_limited = read_unaligned(val); break; } case TCP_NLA_SND_CWND: { - conn_metrics->congestion_window.set(read_unaligned(val)); + metrics->congestion_window.set(read_unaligned(val)); break; } case TCP_NLA_MIN_RTT: { - conn_metrics->min_rtt.set(read_unaligned(val)); + metrics->min_rtt.set(read_unaligned(val)); break; } case TCP_NLA_SRTT: { - conn_metrics->srtt.set(read_unaligned(val)); + metrics->srtt.set(read_unaligned(val)); break; } case TCP_NLA_RECUR_RETRANS: { - conn_metrics->recurring_retrans.set(read_unaligned(val)); + metrics->recurring_retrans.set(read_unaligned(val)); break; } case TCP_NLA_BYTES_SENT: { - conn_metrics->data_sent.set(read_unaligned(val)); + metrics->data_sent.set(read_unaligned(val)); break; } case TCP_NLA_DATA_SEGS_OUT: { - conn_metrics->packet_sent.set(read_unaligned(val)); + metrics->packet_sent.set(read_unaligned(val)); break; } case TCP_NLA_TOTAL_RETRANS: { - conn_metrics->packet_retx.set(read_unaligned(val)); + metrics->packet_retx.set(read_unaligned(val)); break; } case TCP_NLA_DELIVERED: { - conn_metrics->packet_delivered.set(read_unaligned(val)); + metrics->packet_delivered.set(read_unaligned(val)); break; } case TCP_NLA_DELIVERED_CE: { - conn_metrics->packet_delivered_ce.set(read_unaligned(val)); + metrics->packet_delivered_ce.set(read_unaligned(val)); break; } case TCP_NLA_BYTES_RETRANS: { - conn_metrics->data_retx.set(read_unaligned(val)); + metrics->data_retx.set(read_unaligned(val)); + break; + } + case TCP_NLA_DSACK_DUPS: { + metrics->packet_spurious_retx.set(read_unaligned(val)); break; } case TCP_NLA_REORDERING: { - conn_metrics->reordering.set(read_unaligned(val)); + metrics->reordering.set(read_unaligned(val)); break; } case TCP_NLA_SND_SSTHRESH: { - conn_metrics->snd_ssthresh.set(read_unaligned(val)); + metrics->snd_ssthresh.set(read_unaligned(val)); break; } } diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 8b08a7b5114..4e4275d9665 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -57,6 +57,9 @@ struct ConnectionMetrics { bool is_delivery_rate_app_limited = true; /* Total packets retransmitted. */ Optional packet_retx; + /* Total packets retransmitted spuriously. This metric is smaller than or + equal to packet_retx. */ + Optional packet_spurious_retx; /* Total packets sent. */ Optional packet_sent; /* Total packets delivered. */ From 1ec65a2c9be95c85d59cc58ada4f9bc7514aff57 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 17 Jan 2019 18:57:51 -0800 Subject: [PATCH 101/814] Fix tests --- src/core/lib/iomgr/tcp_posix.cc | 2 +- test/core/iomgr/tcp_posix_test.cc | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 446613c91b7..e04dbe59f5c 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -665,8 +665,8 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, if (grpc_tcp_trace.enabled()) { gpr_log(GPR_ERROR, "Received timestamp without extended error"); } + return opt_stats; } - return opt_stats; } if (!(next_cmsg->cmsg_level == SOL_IP || next_cmsg->cmsg_level == SOL_IPV6) || diff --git a/test/core/iomgr/tcp_posix_test.cc b/test/core/iomgr/tcp_posix_test.cc index 80f17a914fa..5b601b1ae5f 100644 --- a/test/core/iomgr/tcp_posix_test.cc +++ b/test/core/iomgr/tcp_posix_test.cc @@ -384,9 +384,9 @@ void timestamps_verifier(void* arg, grpc_core::Timestamps* ts, grpc_error* error) { GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(arg != nullptr); - GPR_ASSERT(ts->sendmsg_time.clock_type == GPR_CLOCK_REALTIME); - GPR_ASSERT(ts->scheduled_time.clock_type == GPR_CLOCK_REALTIME); - GPR_ASSERT(ts->acked_time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->sendmsg_time.time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->scheduled_time.time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->acked_time.time.clock_type == GPR_CLOCK_REALTIME); gpr_atm* done_timestamps = (gpr_atm*)arg; gpr_atm_rel_store(done_timestamps, static_cast(1)); } From 862faf55baaeef0e7b44f172f98386802027f4a1 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 17 Jan 2019 20:50:21 -0800 Subject: [PATCH 102/814] Use getsockopt to get the tcp_info struct with sendmsg timestamp --- src/core/lib/iomgr/buffer_list.cc | 90 ++++++++++++++++++-------- src/core/lib/iomgr/buffer_list.h | 4 +- src/core/lib/iomgr/internal_errqueue.h | 67 +++++++++++++++++++ src/core/lib/iomgr/tcp_posix.cc | 14 +++- test/core/iomgr/buffer_list_test.cc | 4 +- 5 files changed, 148 insertions(+), 31 deletions(-) diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index 58814d0e84f..70c1a820d74 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -30,27 +30,6 @@ #include "src/core/lib/gprpp/memory.h" namespace grpc_core { -void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, - void* arg) { - GPR_DEBUG_ASSERT(head != nullptr); - TracedBuffer* new_elem = New(seq_no, arg); - /* Store the current time as the sendmsg time. */ - new_elem->ts_.sendmsg_time.time = gpr_now(GPR_CLOCK_REALTIME); - new_elem->ts_.scheduled_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); - new_elem->ts_.sent_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); - new_elem->ts_.acked_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); - if (*head == nullptr) { - *head = new_elem; - return; - } - /* Append at the end. */ - TracedBuffer* ptr = *head; - while (ptr->next_ != nullptr) { - ptr = ptr->next_; - } - ptr->next_ = new_elem; -} - namespace { /** Fills gpr_timespec gts based on values from timespec ts */ void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) { @@ -79,9 +58,41 @@ T read_unaligned(const void* ptr) { return val; } -/** Adds opt stats statistics from the given control message to the connection - * metrics. */ -void ExtractOptStats(ConnectionMetrics* metrics, const cmsghdr* opt_stats) { +/* Extracts opt stats from the tcp_info struct \a info to \a metrics */ +void extract_opt_stats_from_tcp_info(ConnectionMetrics* metrics, + const grpc_core::tcp_info* info) { + if (info == nullptr) { + return; + } + if (info->length > offsetof(grpc_core::tcp_info, tcpi_sndbuf_limited)) { + metrics->recurring_retrans.set(info->tcpi_retransmits); + metrics->is_delivery_rate_app_limited = + info->tcpi_delivery_rate_app_limited; + metrics->congestion_window.set(info->tcpi_snd_cwnd); + metrics->reordering.set(info->tcpi_reordering); + metrics->packet_retx.set(info->tcpi_total_retrans); + metrics->pacing_rate.set(info->tcpi_pacing_rate); + metrics->data_notsent.set(info->tcpi_notsent_bytes); + if (info->tcpi_min_rtt != UINT32_MAX) { + metrics->min_rtt.set(info->tcpi_min_rtt); + } + metrics->packet_sent.set(info->tcpi_data_segs_out); + metrics->delivery_rate.set(info->tcpi_delivery_rate); + metrics->busy_usec.set(info->tcpi_busy_time); + metrics->rwnd_limited_usec.set(info->tcpi_rwnd_limited); + metrics->sndbuf_limited_usec.set(info->tcpi_sndbuf_limited); + } + if (info->length > offsetof(grpc_core::tcp_info, tcpi_dsack_dups)) { + metrics->data_sent.set(info->tcpi_bytes_sent); + metrics->data_retx.set(info->tcpi_bytes_retrans); + metrics->packet_spurious_retx.set(info->tcpi_dsack_dups); + } +} + +/** Extracts opt stats from the given control message \a opt_stats to the + * connection metrics \a metrics */ +void extract_opt_stats_from_cmsg(ConnectionMetrics* metrics, + const cmsghdr* opt_stats) { if (opt_stats == nullptr) { return; } @@ -176,6 +187,28 @@ void ExtractOptStats(ConnectionMetrics* metrics, const cmsghdr* opt_stats) { } } /* namespace */ +void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, + const grpc_core::tcp_info* info, void* arg) { + GPR_DEBUG_ASSERT(head != nullptr); + TracedBuffer* new_elem = New(seq_no, arg); + /* Store the current time as the sendmsg time. */ + new_elem->ts_.sendmsg_time.time = gpr_now(GPR_CLOCK_REALTIME); + new_elem->ts_.scheduled_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); + new_elem->ts_.sent_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); + new_elem->ts_.acked_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); + extract_opt_stats_from_tcp_info(&new_elem->ts_.sendmsg_time.metrics, info); + if (*head == nullptr) { + *head = new_elem; + return; + } + /* Append at the end. */ + TracedBuffer* ptr = *head; + while (ptr->next_ != nullptr) { + ptr = ptr->next_; + } + ptr->next_ = new_elem; +} + void TracedBuffer::ProcessTimestamp(TracedBuffer** head, struct sock_extended_err* serr, struct cmsghdr* opt_stats, @@ -191,17 +224,20 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, case SCM_TSTAMP_SCHED: fill_gpr_from_timestamp(&(elem->ts_.scheduled_time.time), &(tss->ts[0])); - ExtractOptStats(&(elem->ts_.scheduled_time.metrics), opt_stats); + extract_opt_stats_from_cmsg(&(elem->ts_.scheduled_time.metrics), + opt_stats); elem = elem->next_; break; case SCM_TSTAMP_SND: fill_gpr_from_timestamp(&(elem->ts_.sent_time.time), &(tss->ts[0])); - ExtractOptStats(&(elem->ts_.sent_time.metrics), opt_stats); + extract_opt_stats_from_cmsg(&(elem->ts_.sent_time.metrics), + opt_stats); elem = elem->next_; break; case SCM_TSTAMP_ACK: fill_gpr_from_timestamp(&(elem->ts_.acked_time.time), &(tss->ts[0])); - ExtractOptStats(&(elem->ts_.acked_time.metrics), opt_stats); + extract_opt_stats_from_cmsg(&(elem->ts_.acked_time.metrics), + opt_stats); /* Got all timestamps. Do the callback and free this TracedBuffer. * The thing below can be passed by value if we don't want the * restriction on the lifetime. */ diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 4e4275d9665..7acd92afa27 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -71,6 +71,8 @@ struct ConnectionMetrics { Optional data_retx; /* Total bytes sent so far. */ Optional data_sent; + /* Total bytes in write queue but not sent. */ + Optional data_notsent; /* Pacing rate of the connection in Bps */ Optional pacing_rate; /* Minimum RTT observed in usec. */ @@ -129,7 +131,7 @@ class TracedBuffer { /** Add a new entry in the TracedBuffer list pointed to by head. Also saves * sendmsg_time with the current timestamp. */ static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no, - void* arg); + const grpc_core::tcp_info* info, void* arg); /** Processes a received timestamp based on sock_extended_err and * scm_timestamping structures. It will invoke the timestamps callback if the diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h index e8c3ef4acf9..b9fe411769f 100644 --- a/src/core/lib/iomgr/internal_errqueue.h +++ b/src/core/lib/iomgr/internal_errqueue.h @@ -105,6 +105,73 @@ enum TCPOptStats { TCP_NLA_REORD_SEEN, /* reordering events seen */ TCP_NLA_SRTT, /* smoothed RTT in usecs */ }; + +/* tcp_info from from linux/tcp.h */ +struct tcp_info { + uint8_t tcpi_state; + uint8_t tcpi_ca_state; + uint8_t tcpi_retransmits; + uint8_t tcpi_probes; + uint8_t tcpi_backoff; + uint8_t tcpi_options; + uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; + uint8_t tcpi_delivery_rate_app_limited : 1; + uint32_t tcpi_rto; + uint32_t tcpi_ato; + uint32_t tcpi_snd_mss; + uint32_t tcpi_rcv_mss; + uint32_t tcpi_unacked; + uint32_t tcpi_sacked; + uint32_t tcpi_lost; + uint32_t tcpi_retrans; + uint32_t tcpi_fackets; + /* Times. */ + uint32_t tcpi_last_data_sent; + uint32_t tcpi_last_ack_sent; /* Not remembered, sorry. */ + uint32_t tcpi_last_data_recv; + uint32_t tcpi_last_ack_recv; + /* Metrics. */ + uint32_t tcpi_pmtu; + uint32_t tcpi_rcv_ssthresh; + uint32_t tcpi_rtt; + uint32_t tcpi_rttvar; + uint32_t tcpi_snd_ssthresh; + uint32_t tcpi_snd_cwnd; + uint32_t tcpi_advmss; + uint32_t tcpi_reordering; + uint32_t tcpi_rcv_rtt; + uint32_t tcpi_rcv_space; + uint32_t tcpi_total_retrans; + uint64_t tcpi_pacing_rate; + uint64_t tcpi_max_pacing_rate; + uint64_t tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ + uint64_t tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ + + uint32_t tcpi_segs_out; /* RFC4898 tcpEStatsPerfSegsOut */ + uint32_t tcpi_segs_in; /* RFC4898 tcpEStatsPerfSegsIn */ + uint32_t tcpi_notsent_bytes; + uint32_t tcpi_min_rtt; + + uint32_t tcpi_data_segs_in; /* RFC4898 tcpEStatsDataSegsIn */ + uint32_t tcpi_data_segs_out; /* RFC4898 tcpEStatsDataSegsOut */ + + uint64_t tcpi_delivery_rate; + uint64_t tcpi_busy_time; /* Time (usec) busy sending data */ + uint64_t tcpi_rwnd_limited; /* Time (usec) limited by receive window */ + uint64_t tcpi_sndbuf_limited; /* Time (usec) limited by send buffer */ + + uint32_t tcpi_delivered; + uint32_t tcpi_delivered_ce; + uint64_t tcpi_bytes_sent; /* RFC4898 tcpEStatsPerfHCDataOctetsOut */ + uint64_t tcpi_bytes_retrans; /* RFC4898 tcpEStatsPerfOctetsRetrans */ + uint32_t tcpi_dsack_dups; /* RFC4898 tcpEStatsStackDSACKDups */ + uint32_t tcpi_reord_seen; /* reordering events seen */ + socklen_t length; /* Length of struct returned by kernel */ +}; + +#ifndef TCP_INFO +#define TCP_INFO 11 +#endif #endif /* GRPC_LINUX_ERRQUEUE */ /* Returns true if kernel is capable of supporting errqueue and timestamping. diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index e04dbe59f5c..902301e7b53 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -593,6 +593,12 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); #ifdef GRPC_LINUX_ERRQUEUE +static int get_socket_tcp_info(grpc_core::tcp_info* info, int fd) { + info->length = sizeof(*info) - sizeof(socklen_t); + memset(info, 0, sizeof(*info)); + return getsockopt(fd, IPPROTO_TCP, TCP_INFO, info, &(info->length)); +} + static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, ssize_t* sent_length) { @@ -629,9 +635,15 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, /* Only save timestamps if all the bytes were taken by sendmsg. */ if (sending_length == static_cast(length)) { gpr_mu_lock(&tcp->tb_mu); + grpc_core::tcp_info info; + auto* info_ptr = &info; + if (get_socket_tcp_info(info_ptr, tcp->fd) != 0) { + /* Failed to get tcp_info */ + info_ptr = nullptr; + } grpc_core::TracedBuffer::AddNewEntry( &tcp->tb_head, static_cast(tcp->bytes_counter + length), - tcp->outgoing_buffer_arg); + info_ptr, tcp->outgoing_buffer_arg); gpr_mu_unlock(&tcp->tb_mu); tcp->outgoing_buffer_arg = nullptr; } diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index 9b2f169b89a..5355a469b66 100644 --- a/test/core/iomgr/buffer_list_test.cc +++ b/test/core/iomgr/buffer_list_test.cc @@ -48,7 +48,7 @@ static void TestShutdownFlushesList() { for (auto i = 0; i < NUM_ELEM; i++) { gpr_atm_rel_store(&verifier_called[i], static_cast(0)); grpc_core::TracedBuffer::AddNewEntry( - &list, i, static_cast(&verifier_called[i])); + &list, i, nullptr, static_cast(&verifier_called[i])); } grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE); GPR_ASSERT(list == nullptr); @@ -84,7 +84,7 @@ static void TestVerifierCalledOnAck() { grpc_core::TracedBuffer* list = nullptr; gpr_atm verifier_called; gpr_atm_rel_store(&verifier_called, static_cast(0)); - grpc_core::TracedBuffer::AddNewEntry(&list, 213, &verifier_called); + grpc_core::TracedBuffer::AddNewEntry(&list, 213, nullptr, &verifier_called); grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, nullptr, &tss); GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast(1)); GPR_ASSERT(list == nullptr); From bf48d410a748cbb3a0e385121ebf49583ac52053 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 18 Jan 2019 09:33:35 +0100 Subject: [PATCH 103/814] change suffix for protected ServerCallContext members to *Core --- .../TestServerCallContext.cs | 24 ++++----- .../Internal/DefaultServerCallContext.cs | 24 ++++----- src/csharp/Grpc.Core/ServerCallContext.cs | 52 +++++++++---------- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs index ff4fb66c6c9..e6297e61226 100644 --- a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs +++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs @@ -74,31 +74,31 @@ namespace Grpc.Core.Testing this.writeOptionsSetter = writeOptionsSetter; } - protected override string MethodInternal => method; + protected override string MethodCore => method; - protected override string HostInternal => host; + protected override string HostCore => host; - protected override string PeerInternal => peer; + protected override string PeerCore => peer; - protected override DateTime DeadlineInternal => deadline; + protected override DateTime DeadlineCore => deadline; - protected override Metadata RequestHeadersInternal => requestHeaders; + protected override Metadata RequestHeadersCore => requestHeaders; - protected override CancellationToken CancellationTokenInternal => cancellationToken; + protected override CancellationToken CancellationTokenCore => cancellationToken; - protected override Metadata ResponseTrailersInternal => responseTrailers; + protected override Metadata ResponseTrailersCore => responseTrailers; - protected override Status StatusInternal { get => status; set => status = value; } - protected override WriteOptions WriteOptionsInternal { get => writeOptionsGetter(); set => writeOptionsSetter(value); } + protected override Status StatusCore { get => status; set => status = value; } + protected override WriteOptions WriteOptionsCore { get => writeOptionsGetter(); set => writeOptionsSetter(value); } - protected override AuthContext AuthContextInternal => authContext; + protected override AuthContext AuthContextCore => authContext; - protected override ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options) + protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) { return contextPropagationToken; } - protected override Task WriteResponseHeadersInternalAsync(Metadata responseHeaders) + protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) { return writeHeadersFunc(responseHeaders); } diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs index b6a29af2edb..8220e599f92 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -61,43 +61,43 @@ namespace Grpc.Core this.authContext = new Lazy(GetAuthContextEager); } - protected override ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options) + protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) { return new ContextPropagationToken(callHandle, deadline, cancellationToken, options); } - protected override Task WriteResponseHeadersInternalAsync(Metadata responseHeaders) + protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) { return serverResponseStream.WriteResponseHeadersAsync(responseHeaders); } - protected override string MethodInternal => method; + protected override string MethodCore => method; - protected override string HostInternal => host; + protected override string HostCore => host; - protected override string PeerInternal => callHandle.GetPeer(); + protected override string PeerCore => callHandle.GetPeer(); - protected override DateTime DeadlineInternal => deadline; + protected override DateTime DeadlineCore => deadline; - protected override Metadata RequestHeadersInternal => requestHeaders; + protected override Metadata RequestHeadersCore => requestHeaders; - protected override CancellationToken CancellationTokenInternal => cancellationToken; + protected override CancellationToken CancellationTokenCore => cancellationToken; - protected override Metadata ResponseTrailersInternal => responseTrailers; + protected override Metadata ResponseTrailersCore => responseTrailers; - protected override Status StatusInternal + protected override Status StatusCore { get => status; set => status = value; } - protected override WriteOptions WriteOptionsInternal + protected override WriteOptions WriteOptionsCore { get => serverResponseStream.WriteOptions; set => serverResponseStream.WriteOptions = value; } - protected override AuthContext AuthContextInternal => authContext.Value; + protected override AuthContext AuthContextCore => authContext.Value; private AuthContext GetAuthContextEager() { diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs index 17aa1fe0661..90b6e9419f0 100644 --- a/src/csharp/Grpc.Core/ServerCallContext.cs +++ b/src/csharp/Grpc.Core/ServerCallContext.cs @@ -43,7 +43,7 @@ namespace Grpc.Core /// The task that finished once response headers have been written. public Task WriteResponseHeadersAsync(Metadata responseHeaders) { - return WriteResponseHeadersInternalAsync(responseHeaders); + return WriteResponseHeadersAsyncCore(responseHeaders); } /// @@ -51,41 +51,41 @@ namespace Grpc.Core /// public ContextPropagationToken CreatePropagationToken(ContextPropagationOptions options = null) { - return CreatePropagationTokenInternal(options); + return CreatePropagationTokenCore(options); } /// Name of method called in this RPC. - public string Method => MethodInternal; + public string Method => MethodCore; /// Name of host called in this RPC. - public string Host => HostInternal; + public string Host => HostCore; /// Address of the remote endpoint in URI format. - public string Peer => PeerInternal; + public string Peer => PeerCore; /// Deadline for this RPC. - public DateTime Deadline => DeadlineInternal; + public DateTime Deadline => DeadlineCore; /// Initial metadata sent by client. - public Metadata RequestHeaders => RequestHeadersInternal; + public Metadata RequestHeaders => RequestHeadersCore; /// Cancellation token signals when call is cancelled. - public CancellationToken CancellationToken => CancellationTokenInternal; + public CancellationToken CancellationToken => CancellationTokenCore; /// Trailers to send back to client after RPC finishes. - public Metadata ResponseTrailers => ResponseTrailersInternal; + public Metadata ResponseTrailers => ResponseTrailersCore; /// Status to send back to client after RPC finishes. public Status Status { get { - return StatusInternal; + return StatusCore; } set { - StatusInternal = value; + StatusCore = value; } } @@ -98,12 +98,12 @@ namespace Grpc.Core { get { - return WriteOptionsInternal; + return WriteOptionsCore; } set { - WriteOptionsInternal = value; + WriteOptionsCore = value; } } @@ -111,31 +111,31 @@ namespace Grpc.Core /// Gets the AuthContext associated with this call. /// Note: Access to AuthContext is an experimental API that can change without any prior notice. /// - public AuthContext AuthContext => AuthContextInternal; + public AuthContext AuthContext => AuthContextCore; /// Provides implementation of a non-virtual public member. - protected abstract Task WriteResponseHeadersInternalAsync(Metadata responseHeaders); + protected abstract Task WriteResponseHeadersAsyncCore(Metadata responseHeaders); /// Provides implementation of a non-virtual public member. - protected abstract ContextPropagationToken CreatePropagationTokenInternal(ContextPropagationOptions options); + protected abstract ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options); /// Provides implementation of a non-virtual public member. - protected abstract string MethodInternal { get; } + protected abstract string MethodCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract string HostInternal { get; } + protected abstract string HostCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract string PeerInternal { get; } + protected abstract string PeerCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract DateTime DeadlineInternal { get; } + protected abstract DateTime DeadlineCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract Metadata RequestHeadersInternal { get; } + protected abstract Metadata RequestHeadersCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract CancellationToken CancellationTokenInternal { get; } + protected abstract CancellationToken CancellationTokenCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract Metadata ResponseTrailersInternal { get; } + protected abstract Metadata ResponseTrailersCore { get; } /// Provides implementation of a non-virtual public member. - protected abstract Status StatusInternal { get; set; } + protected abstract Status StatusCore { get; set; } /// Provides implementation of a non-virtual public member. - protected abstract WriteOptions WriteOptionsInternal { get; set; } + protected abstract WriteOptions WriteOptionsCore { get; set; } /// Provides implementation of a non-virtual public member. - protected abstract AuthContext AuthContextInternal { get; } + protected abstract AuthContext AuthContextCore { get; } } } From d67009124fd258d7f42aef0ca87b1c0dddf3e018 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 17 Jan 2019 17:10:18 +0100 Subject: [PATCH 104/814] commenting on PRs is no longer used --- .../prepare_build_linux_perf_rc | 7 ---- .../helper_scripts/prepare_build_macos_rc | 6 --- .../pull_request/grpc_ios_binary_size.cfg | 1 - tools/run_tests/python_utils/comment_on_pr.py | 37 ------------------- 4 files changed, 51 deletions(-) delete mode 100644 tools/run_tests/python_utils/comment_on_pr.py diff --git a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc index ec1ec1179d3..ff5593e031a 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc @@ -21,15 +21,8 @@ ulimit -c unlimited # Performance PR testing needs GH API key and PR metadata to comment results if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - set +x sudo apt-get install -y jq export ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) - - gsutil cp gs://grpc-testing-secrets/github_credentials/oauth_token.txt ~/ - # TODO(matt-kwong): rename this to GITHUB_OAUTH_TOKEN after Jenkins deprecation - export JENKINS_OAUTH_TOKEN=$(cat ~/oauth_token.txt) - export ghprbPullId=$KOKORO_GITHUB_PULL_REQUEST_NUMBER - set -x fi sudo pip install tabulate diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 7b9b02b6318..23619ecbb8b 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -25,16 +25,10 @@ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db3 # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - set +x brew update brew install jq || brew upgrade jq ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch" - - # TODO(matt-kwong): rename this to GITHUB_OAUTH_TOKEN after Jenkins deprecation - export JENKINS_OAUTH_TOKEN=$(cat ${KOKORO_GFILE_DIR}/oauth_token.txt) - export ghprbPullId=$KOKORO_GITHUB_PULL_REQUEST_NUMBER - set -x fi set +ex # rvm script is very verbose and exits with errorcode diff --git a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg index 1c4f7b23109..dc35ce81ffd 100644 --- a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg @@ -17,7 +17,6 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/macos/grpc_ios_binary_size.sh" timeout_mins: 60 -gfile_resources: "/bigstore/grpc-testing-secrets/github_credentials/oauth_token.txt" before_action { fetch_keystore { keystore_resource { diff --git a/tools/run_tests/python_utils/comment_on_pr.py b/tools/run_tests/python_utils/comment_on_pr.py deleted file mode 100644 index 399c996d4db..00000000000 --- a/tools/run_tests/python_utils/comment_on_pr.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2017 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import json -import urllib2 - - -def comment_on_pr(text): - if 'JENKINS_OAUTH_TOKEN' not in os.environ: - print 'Missing JENKINS_OAUTH_TOKEN env var: not commenting' - return - if 'ghprbPullId' not in os.environ: - print 'Missing ghprbPullId env var: not commenting' - return - req = urllib2.Request( - url='https://api.github.com/repos/grpc/grpc/issues/%s/comments' % - os.environ['ghprbPullId'], - data=json.dumps({ - 'body': text - }), - headers={ - 'Authorization': 'token %s' % os.environ['JENKINS_OAUTH_TOKEN'], - 'Content-Type': 'application/json', - }) - print urllib2.urlopen(req).read() From 034bfe755255e7c01f3def256b3340c8b415f0d9 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 18 Jan 2019 10:05:37 -0800 Subject: [PATCH 105/814] generate_projects --- src/objective-c/BoringSSL-GRPC.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/BoringSSL-GRPC.podspec b/src/objective-c/BoringSSL-GRPC.podspec index 6ec3747faef..99bb5397aef 100644 --- a/src/objective-c/BoringSSL-GRPC.podspec +++ b/src/objective-c/BoringSSL-GRPC.podspec @@ -4527,4 +4527,4 @@ Pod::Spec.new do |s| '#define i2d_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_i2d_PKCS8_PRIV_KEY_INFO', '#define PKCS5_pbe2_decrypt_init GRPC_SHADOW_PKCS5_pbe2_decrypt_init', '#define PKCS5_pbe2_encrypt_init GRPC_SHADOW_PKCS5_pbe2_encrypt_init' -end +end \ No newline at end of file From b5966a281ce925f9db213b3c44c7f68e6d05d9f6 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 18 Jan 2019 10:16:12 -0800 Subject: [PATCH 106/814] Fix percent decode fuzzer --- test/core/slice/percent_decode_fuzzer.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/core/slice/percent_decode_fuzzer.cc b/test/core/slice/percent_decode_fuzzer.cc index 81eb031014f..762e86f23a3 100644 --- a/test/core/slice/percent_decode_fuzzer.cc +++ b/test/core/slice/percent_decode_fuzzer.cc @@ -31,9 +31,8 @@ bool squelch = true; bool leak_check = true; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - struct grpc_memory_counters counters; + grpc_core::testing::LeakDetector leak_detector(true); grpc_init(); - grpc_memory_counters_init(); grpc_slice input = grpc_slice_from_copied_buffer((const char*)data, size); grpc_slice output; if (grpc_strict_percent_decode_slice( @@ -46,9 +45,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); grpc_slice_unref(input); - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); grpc_shutdown(); - GPR_ASSERT(counters.total_size_relative == 0); return 0; } From 0d22c2ff48d2cbe2212f0153aad4782c8bec491b Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 18 Jan 2019 11:38:24 -0800 Subject: [PATCH 107/814] Add comment to keep Dockerfile up to date against oss-fuzz --- tools/dockerfile/test/bazel/Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index 0aa6209f4fd..b52b6bdbf29 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -14,6 +14,12 @@ FROM gcr.io/oss-fuzz-base/base-builder +############################ WARNING ###################################### +# If you are making changes to this file, consider changing +# https://github.com/google/oss-fuzz/blob/master/projects/grpc/Dockerfile +# accordingly. +########################################################################### + # Install basic packages and Bazel dependencies. RUN apt-get update && apt-get install -y software-properties-common python-software-properties RUN add-apt-repository ppa:webupd8team/java From d748d9c01d4e5de93c0290401cfd8429dc89ef99 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 18 Jan 2019 21:41:42 +0100 Subject: [PATCH 108/814] Refactor ContextPropagationToken --- src/csharp/Grpc.Core.Tests/CallOptionsTest.cs | 6 +- .../Grpc.Core.Tests/ContextPropagationTest.cs | 2 +- src/csharp/Grpc.Core/CallOptions.cs | 12 +- .../Grpc.Core/ContextPropagationOptions.cs | 59 +++++++++ .../Grpc.Core/ContextPropagationToken.cs | 124 +----------------- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 5 +- .../Internal/ContextPropagationFlags.cs | 34 +++++ .../Internal/ContextPropagationTokenImpl.cs | 118 +++++++++++++++++ .../Internal/DefaultServerCallContext.cs | 2 +- 9 files changed, 228 insertions(+), 134 deletions(-) create mode 100644 src/csharp/Grpc.Core/ContextPropagationOptions.cs create mode 100644 src/csharp/Grpc.Core/Internal/ContextPropagationFlags.cs create mode 100644 src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs diff --git a/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs b/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs index 8e5c411cadd..1fd48812b54 100644 --- a/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs +++ b/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs @@ -45,7 +45,7 @@ namespace Grpc.Core.Tests var writeOptions = new WriteOptions(); Assert.AreSame(writeOptions, options.WithWriteOptions(writeOptions).WriteOptions); - var propagationToken = new ContextPropagationToken(CallSafeHandle.NullInstance, DateTime.UtcNow, + var propagationToken = new ContextPropagationTokenImpl(CallSafeHandle.NullInstance, DateTime.UtcNow, CancellationToken.None, ContextPropagationOptions.Default); Assert.AreSame(propagationToken, options.WithPropagationToken(propagationToken).PropagationToken); @@ -72,13 +72,13 @@ namespace Grpc.Core.Tests Assert.AreEqual(DateTime.MaxValue, new CallOptions().Normalize().Deadline.Value); var deadline = DateTime.UtcNow; - var propagationToken1 = new ContextPropagationToken(CallSafeHandle.NullInstance, deadline, CancellationToken.None, + var propagationToken1 = new ContextPropagationTokenImpl(CallSafeHandle.NullInstance, deadline, CancellationToken.None, new ContextPropagationOptions(propagateDeadline: true, propagateCancellation: false)); Assert.AreEqual(deadline, new CallOptions(propagationToken: propagationToken1).Normalize().Deadline.Value); Assert.Throws(typeof(ArgumentException), () => new CallOptions(deadline: deadline, propagationToken: propagationToken1).Normalize()); var token = new CancellationTokenSource().Token; - var propagationToken2 = new ContextPropagationToken(CallSafeHandle.NullInstance, deadline, token, + var propagationToken2 = new ContextPropagationTokenImpl(CallSafeHandle.NullInstance, deadline, token, new ContextPropagationOptions(propagateDeadline: false, propagateCancellation: true)); Assert.AreEqual(token, new CallOptions(propagationToken: propagationToken2).Normalize().CancellationToken); Assert.Throws(typeof(ArgumentException), () => new CallOptions(cancellationToken: token, propagationToken: propagationToken2).Normalize()); diff --git a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs index c8bc372202d..9a878bde436 100644 --- a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs +++ b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs @@ -72,7 +72,7 @@ namespace Grpc.Core.Tests helper.ClientStreamingHandler = new ClientStreamingServerMethod(async (requestStream, context) => { var propagationToken = context.CreatePropagationToken(); - Assert.IsNotNull(propagationToken.ParentCall); + Assert.IsNotNull(propagationToken.AsImplOrNull().ParentCall); var callOptions = new CallOptions(propagationToken: propagationToken); try diff --git a/src/csharp/Grpc.Core/CallOptions.cs b/src/csharp/Grpc.Core/CallOptions.cs index 75d8906a691..89fd047a1ea 100644 --- a/src/csharp/Grpc.Core/CallOptions.cs +++ b/src/csharp/Grpc.Core/CallOptions.cs @@ -236,22 +236,24 @@ namespace Grpc.Core internal CallOptions Normalize() { var newOptions = this; + // silently ignore the context propagation token if it wasn't produced by "us" + var propagationTokenImpl = propagationToken.AsImplOrNull(); if (propagationToken != null) { - if (propagationToken.Options.IsPropagateDeadline) + if (propagationTokenImpl.Options.IsPropagateDeadline) { GrpcPreconditions.CheckArgument(!newOptions.deadline.HasValue, "Cannot propagate deadline from parent call. The deadline has already been set explicitly."); - newOptions.deadline = propagationToken.ParentDeadline; + newOptions.deadline = propagationTokenImpl.ParentDeadline; } - if (propagationToken.Options.IsPropagateCancellation) + if (propagationTokenImpl.Options.IsPropagateCancellation) { GrpcPreconditions.CheckArgument(!newOptions.cancellationToken.CanBeCanceled, "Cannot propagate cancellation token from parent call. The cancellation token has already been set to a non-default value."); - newOptions.cancellationToken = propagationToken.ParentCancellationToken; + newOptions.cancellationToken = propagationTokenImpl.ParentCancellationToken; } } - + newOptions.headers = newOptions.headers ?? Metadata.Empty; newOptions.deadline = newOptions.deadline ?? DateTime.MaxValue; return newOptions; diff --git a/src/csharp/Grpc.Core/ContextPropagationOptions.cs b/src/csharp/Grpc.Core/ContextPropagationOptions.cs new file mode 100644 index 00000000000..160d10dc82c --- /dev/null +++ b/src/csharp/Grpc.Core/ContextPropagationOptions.cs @@ -0,0 +1,59 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; + +namespace Grpc.Core +{ + /// + /// Options for . + /// + public class ContextPropagationOptions + { + /// + /// The context propagation options that will be used by default. + /// + public static readonly ContextPropagationOptions Default = new ContextPropagationOptions(); + + bool propagateDeadline; + bool propagateCancellation; + + /// + /// Creates new context propagation options. + /// + /// If set to true parent call's deadline will be propagated to the child call. + /// If set to true parent call's cancellation token will be propagated to the child call. + public ContextPropagationOptions(bool propagateDeadline = true, bool propagateCancellation = true) + { + this.propagateDeadline = propagateDeadline; + this.propagateCancellation = propagateCancellation; + } + + /// true if parent call's deadline should be propagated to the child call. + public bool IsPropagateDeadline + { + get { return this.propagateDeadline; } + } + + /// true if parent call's cancellation token should be propagated to the child call. + public bool IsPropagateCancellation + { + get { return this.propagateCancellation; } + } + } +} diff --git a/src/csharp/Grpc.Core/ContextPropagationToken.cs b/src/csharp/Grpc.Core/ContextPropagationToken.cs index fe5c8a5c99a..d0c3f0cd1d3 100644 --- a/src/csharp/Grpc.Core/ContextPropagationToken.cs +++ b/src/csharp/Grpc.Core/ContextPropagationToken.cs @@ -16,12 +16,6 @@ #endregion -using System; -using System.Threading; - -using Grpc.Core.Internal; -using Grpc.Core.Utils; - namespace Grpc.Core { /// @@ -32,124 +26,10 @@ namespace Grpc.Core /// The gRPC native layer provides some other contexts (like tracing context) that /// are not accessible to explicitly C# layer, but this token still allows propagating them. /// - public class ContextPropagationToken + public abstract class ContextPropagationToken { - /// - /// Default propagation mask used by C core. - /// - private const ContextPropagationFlags DefaultCoreMask = (ContextPropagationFlags)0xffff; - - /// - /// Default propagation mask used by C# - we want to propagate deadline - /// and cancellation token by our own means. - /// - internal const ContextPropagationFlags DefaultMask = DefaultCoreMask - & ~ContextPropagationFlags.Deadline & ~ContextPropagationFlags.Cancellation; - - readonly CallSafeHandle parentCall; - readonly DateTime deadline; - readonly CancellationToken cancellationToken; - readonly ContextPropagationOptions options; - - internal ContextPropagationToken(CallSafeHandle parentCall, DateTime deadline, CancellationToken cancellationToken, ContextPropagationOptions options) + internal ContextPropagationToken() { - this.parentCall = GrpcPreconditions.CheckNotNull(parentCall); - this.deadline = deadline; - this.cancellationToken = cancellationToken; - this.options = options ?? ContextPropagationOptions.Default; } - - /// - /// Gets the native handle of the parent call. - /// - internal CallSafeHandle ParentCall - { - get - { - return this.parentCall; - } - } - - /// - /// Gets the parent call's deadline. - /// - internal DateTime ParentDeadline - { - get - { - return this.deadline; - } - } - - /// - /// Gets the parent call's cancellation token. - /// - internal CancellationToken ParentCancellationToken - { - get - { - return this.cancellationToken; - } - } - - /// - /// Get the context propagation options. - /// - internal ContextPropagationOptions Options - { - get - { - return this.options; - } - } - } - - /// - /// Options for . - /// - public class ContextPropagationOptions - { - /// - /// The context propagation options that will be used by default. - /// - public static readonly ContextPropagationOptions Default = new ContextPropagationOptions(); - - bool propagateDeadline; - bool propagateCancellation; - - /// - /// Creates new context propagation options. - /// - /// If set to true parent call's deadline will be propagated to the child call. - /// If set to true parent call's cancellation token will be propagated to the child call. - public ContextPropagationOptions(bool propagateDeadline = true, bool propagateCancellation = true) - { - this.propagateDeadline = propagateDeadline; - this.propagateCancellation = propagateCancellation; - } - - /// true if parent call's deadline should be propagated to the child call. - public bool IsPropagateDeadline - { - get { return this.propagateDeadline; } - } - - /// true if parent call's cancellation token should be propagated to the child call. - public bool IsPropagateCancellation - { - get { return this.propagateCancellation; } - } - } - - /// - /// Context propagation flags from grpc/grpc.h. - /// - [Flags] - internal enum ContextPropagationFlags - { - Deadline = 1, - CensusStatsContext = 2, - CensusTracingContext = 4, - Cancellation = 8 } } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index b6d687f71e7..e2a018e871b 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -494,13 +494,14 @@ namespace Grpc.Core.Internal return injectedNativeCall; // allows injecting a mock INativeCall in tests. } - var parentCall = details.Options.PropagationToken != null ? details.Options.PropagationToken.ParentCall : CallSafeHandle.NullInstance; + var parentCall = details.Options.PropagationToken != null ? details.Options.PropagationToken.AsImplOrNull().ParentCall : CallSafeHandle.NullInstance; var credentials = details.Options.Credentials; using (var nativeCredentials = credentials != null ? credentials.ToNativeCredentials() : null) { + // TODO(jtattermusch): is the "DefaultMask" correct here?? var result = details.Channel.Handle.CreateCall( - parentCall, ContextPropagationToken.DefaultMask, cq, + parentCall, ContextPropagationTokenImpl.DefaultMask, cq, details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value), nativeCredentials); return result; } diff --git a/src/csharp/Grpc.Core/Internal/ContextPropagationFlags.cs b/src/csharp/Grpc.Core/Internal/ContextPropagationFlags.cs new file mode 100644 index 00000000000..11a9c93a67d --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/ContextPropagationFlags.cs @@ -0,0 +1,34 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; + +namespace Grpc.Core.Internal +{ + /// + /// Context propagation flags from grpc/grpc.h. + /// + [Flags] + internal enum ContextPropagationFlags + { + Deadline = 1, + CensusStatsContext = 2, + CensusTracingContext = 4, + Cancellation = 8 + } +} diff --git a/src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs b/src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs new file mode 100644 index 00000000000..1fd994e607c --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs @@ -0,0 +1,118 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Threading; + +using Grpc.Core.Utils; + +namespace Grpc.Core.Internal +{ + /// + /// Implementation of ContextPropagationToken that carries + /// all fields needed for context propagation by C-core based implementation of gRPC. + /// Instances of ContextPropagationToken that are not of this + /// type will be recognized as "foreign" and will be silently ignored + /// (treated as if null). + /// + internal class ContextPropagationTokenImpl : ContextPropagationToken + { + /// + /// Default propagation mask used by C core. + /// + private const ContextPropagationFlags DefaultCoreMask = (ContextPropagationFlags)0xffff; + + /// + /// Default propagation mask used by C# - we want to propagate deadline + /// and cancellation token by our own means. + /// + internal const ContextPropagationFlags DefaultMask = DefaultCoreMask + & ~ContextPropagationFlags.Deadline & ~ContextPropagationFlags.Cancellation; + + readonly CallSafeHandle parentCall; + readonly DateTime deadline; + readonly CancellationToken cancellationToken; + readonly ContextPropagationOptions options; + + internal ContextPropagationTokenImpl(CallSafeHandle parentCall, DateTime deadline, CancellationToken cancellationToken, ContextPropagationOptions options) + { + this.parentCall = GrpcPreconditions.CheckNotNull(parentCall); + this.deadline = deadline; + this.cancellationToken = cancellationToken; + this.options = options ?? ContextPropagationOptions.Default; + } + + /// + /// Gets the native handle of the parent call. + /// + internal CallSafeHandle ParentCall + { + get + { + return this.parentCall; + } + } + + /// + /// Gets the parent call's deadline. + /// + internal DateTime ParentDeadline + { + get + { + return this.deadline; + } + } + + /// + /// Gets the parent call's cancellation token. + /// + internal CancellationToken ParentCancellationToken + { + get + { + return this.cancellationToken; + } + } + + /// + /// Get the context propagation options. + /// + internal ContextPropagationOptions Options + { + get + { + return this.options; + } + } + } + + internal static class ContextPropagationTokenExtensions + { + /// + /// Converts given ContextPropagationToken to ContextPropagationTokenImpl + /// if possible or returns null. + /// Being able to convert means that the context propagation token is recognized as + /// "ours" (was created by this implementation). + /// + public static ContextPropagationTokenImpl AsImplOrNull(this ContextPropagationToken instanceOrNull) + { + return instanceOrNull as ContextPropagationTokenImpl; + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs index 8220e599f92..b33cb631e26 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -63,7 +63,7 @@ namespace Grpc.Core protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) { - return new ContextPropagationToken(callHandle, deadline, cancellationToken, options); + return new ContextPropagationTokenImpl(callHandle, deadline, cancellationToken, options); } protected override Task WriteResponseHeadersAsyncCore(Metadata responseHeaders) From f29c56bff5a5da32b10bb785e473f0f24dabf1c3 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 18 Jan 2019 13:16:55 -0800 Subject: [PATCH 109/814] Update templates too --- templates/tools/dockerfile/test/bazel/Dockerfile.template | 6 ++++++ tools/dockerfile/test/bazel/Dockerfile | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/templates/tools/dockerfile/test/bazel/Dockerfile.template b/templates/tools/dockerfile/test/bazel/Dockerfile.template index 50aa72edb35..864c9893a14 100644 --- a/templates/tools/dockerfile/test/bazel/Dockerfile.template +++ b/templates/tools/dockerfile/test/bazel/Dockerfile.template @@ -16,6 +16,12 @@ FROM gcr.io/oss-fuzz-base/base-builder + # -------------------------- WARNING -------------------------------------- + # If you are making changes to this file, consider changing + # https://github.com/google/oss-fuzz/blob/master/projects/grpc/Dockerfile + # accordingly. + # ------------------------------------------------------------------------- + # Install basic packages and Bazel dependencies. RUN apt-get update && apt-get install -y software-properties-common python-software-properties RUN add-apt-repository ppa:webupd8team/java diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index b52b6bdbf29..22d5d7c71c2 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -14,11 +14,11 @@ FROM gcr.io/oss-fuzz-base/base-builder -############################ WARNING ###################################### +# -------------------------- WARNING -------------------------------------- # If you are making changes to this file, consider changing # https://github.com/google/oss-fuzz/blob/master/projects/grpc/Dockerfile # accordingly. -########################################################################### +# ------------------------------------------------------------------------- # Install basic packages and Bazel dependencies. RUN apt-get update && apt-get install -y software-properties-common python-software-properties From 44402ad0a1b36770f3546393d346f8c0419e46cf Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 17 Jan 2019 23:21:08 -0800 Subject: [PATCH 110/814] Make executor look more like the rest of the codebase (namespace, etc) --- .../chttp2/transport/chttp2_transport.cc | 6 +- src/core/lib/iomgr/combiner.cc | 7 +- src/core/lib/iomgr/executor.cc | 201 ++++++++++-------- src/core/lib/iomgr/executor.h | 101 ++++----- src/core/lib/iomgr/fork_posix.cc | 6 +- src/core/lib/iomgr/iomgr.cc | 4 +- src/core/lib/iomgr/iomgr_custom.cc | 2 +- src/core/lib/iomgr/resolve_address_posix.cc | 5 +- src/core/lib/iomgr/resolve_address_windows.cc | 3 +- src/core/lib/iomgr/tcp_posix.cc | 8 +- src/core/lib/iomgr/udp_server.cc | 10 +- src/core/lib/surface/init.cc | 2 +- src/core/lib/surface/server.cc | 5 +- src/core/lib/transport/transport.cc | 2 +- test/core/end2end/fuzzers/api_fuzzer.cc | 2 +- test/core/end2end/fuzzers/client_fuzzer.cc | 2 +- test/core/end2end/fuzzers/server_fuzzer.cc | 2 +- test/core/iomgr/resolve_address_test.cc | 2 +- 18 files changed, 204 insertions(+), 166 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 7f4627fa773..fe88d4818e4 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -968,19 +968,19 @@ static grpc_closure_scheduler* write_scheduler(grpc_chttp2_transport* t, get better latency overall if we switch writing work elsewhere and continue with application work above */ if (!t->is_first_write_in_batch) { - return grpc_executor_scheduler(GRPC_EXECUTOR_SHORT); + return grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT); } /* equivalently, if it's a partial write, we *know* we're going to be taking a thread jump to write it because of the above, may as well do so immediately */ if (partial_write) { - return grpc_executor_scheduler(GRPC_EXECUTOR_SHORT); + return grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT); } switch (t->opt_target) { case GRPC_CHTTP2_OPTIMIZE_FOR_THROUGHPUT: /* executor gives us the largest probability of being able to batch a * write with others on this transport */ - return grpc_executor_scheduler(GRPC_EXECUTOR_SHORT); + return grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT); case GRPC_CHTTP2_OPTIMIZE_FOR_LATENCY: return grpc_schedule_on_exec_ctx; } diff --git a/src/core/lib/iomgr/combiner.cc b/src/core/lib/iomgr/combiner.cc index 402f8904eae..4fc4a9dccf4 100644 --- a/src/core/lib/iomgr/combiner.cc +++ b/src/core/lib/iomgr/combiner.cc @@ -83,8 +83,9 @@ grpc_combiner* grpc_combiner_create(void) { gpr_atm_no_barrier_store(&lock->state, STATE_UNORPHANED); gpr_mpscq_init(&lock->queue); grpc_closure_list_init(&lock->final_list); - GRPC_CLOSURE_INIT(&lock->offload, offload, lock, - grpc_executor_scheduler(GRPC_EXECUTOR_SHORT)); + GRPC_CLOSURE_INIT( + &lock->offload, offload, lock, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)); GRPC_COMBINER_TRACE(gpr_log(GPR_INFO, "C:%p create", lock)); return lock; } @@ -235,7 +236,7 @@ bool grpc_combiner_continue_exec_ctx() { // 3. the DEFAULT executor is threaded // 4. the current thread is not a worker for any background poller if (contended && grpc_core::ExecCtx::Get()->IsReadyToFinish() && - grpc_executor_is_threaded() && + grpc_core::Executor::IsThreadedDefault() && !grpc_iomgr_is_any_background_poller_thread()) { GPR_TIMER_MARK("offload_from_finished_exec_ctx", 0); // this execution context wants to move on: schedule remaining work to be diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index 45d96b80eb4..2703e1a0b77 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -45,20 +45,70 @@ gpr_log(GPR_INFO, "EXECUTOR " str); \ } -grpc_core::TraceFlag executor_trace(false, "executor"); +namespace grpc_core { +namespace { GPR_TLS_DECL(g_this_thread_state); -GrpcExecutor::GrpcExecutor(const char* name) : name_(name) { +Executor* executors[static_cast(ExecutorType::NUM_EXECUTORS)]; + +void default_enqueue_short(grpc_closure* closure, grpc_error* error) { + executors[static_cast(ExecutorType::DEFAULT)]->Enqueue( + closure, error, true /* is_short */); +} + +void default_enqueue_long(grpc_closure* closure, grpc_error* error) { + executors[static_cast(ExecutorType::DEFAULT)]->Enqueue( + closure, error, false /* is_short */); +} + +void resolver_enqueue_short(grpc_closure* closure, grpc_error* error) { + executors[static_cast(ExecutorType::RESOLVER)]->Enqueue( + closure, error, true /* is_short */); +} + +void resolver_enqueue_long(grpc_closure* closure, grpc_error* error) { + executors[static_cast(ExecutorType::RESOLVER)]->Enqueue( + closure, error, false /* is_short */); +} + +const grpc_closure_scheduler_vtable + vtables_[static_cast(ExecutorType::NUM_EXECUTORS)] + [static_cast(ExecutorJobType::NUM_JOB_TYPES)] = { + {{&default_enqueue_short, &default_enqueue_short, + "def-ex-short"}, + {&default_enqueue_long, &default_enqueue_long, "def-ex-long"}}, + {{&resolver_enqueue_short, &resolver_enqueue_short, + "res-ex-short"}, + {&resolver_enqueue_long, &resolver_enqueue_long, + "res-ex-long"}}}; + +grpc_closure_scheduler + schedulers_[static_cast(ExecutorType::NUM_EXECUTORS)] + [static_cast(ExecutorJobType::NUM_JOB_TYPES)] = { + {{&vtables_[static_cast(ExecutorType::DEFAULT)] + [static_cast(ExecutorJobType::SHORT)]}, + {&vtables_[static_cast(ExecutorType::DEFAULT)] + [static_cast(ExecutorJobType::LONG)]}}, + {{&vtables_[static_cast(ExecutorType::RESOLVER)] + [static_cast(ExecutorJobType::SHORT)]}, + {&vtables_[static_cast(ExecutorType::RESOLVER)] + [static_cast(ExecutorJobType::LONG)]}}}; + +} // namespace + +TraceFlag executor_trace(false, "executor"); + +Executor::Executor(const char* name) : name_(name) { adding_thread_lock_ = GPR_SPINLOCK_STATIC_INITIALIZER; gpr_atm_rel_store(&num_threads_, 0); max_threads_ = GPR_MAX(1, 2 * gpr_cpu_num_cores()); } -void GrpcExecutor::Init() { SetThreading(true); } +void Executor::Init() { SetThreading(true); } -size_t GrpcExecutor::RunClosures(const char* executor_name, - grpc_closure_list list) { +size_t Executor::RunClosures(const char* executor_name, + grpc_closure_list list) { size_t n = 0; grpc_closure* c = list.head; @@ -82,11 +132,11 @@ size_t GrpcExecutor::RunClosures(const char* executor_name, return n; } -bool GrpcExecutor::IsThreaded() const { +bool Executor::IsThreaded() const { return gpr_atm_acq_load(&num_threads_) > 0; } -void GrpcExecutor::SetThreading(bool threading) { +void Executor::SetThreading(bool threading) { gpr_atm curr_num_threads = gpr_atm_acq_load(&num_threads_); EXECUTOR_TRACE("(%s) SetThreading(%d) begin", name_, threading); @@ -112,7 +162,7 @@ void GrpcExecutor::SetThreading(bool threading) { } thd_state_[0].thd = - grpc_core::Thread(name_, &GrpcExecutor::ThreadMain, &thd_state_[0]); + grpc_core::Thread(name_, &Executor::ThreadMain, &thd_state_[0]); thd_state_[0].thd.Start(); } else { // !threading if (curr_num_threads == 0) { @@ -153,9 +203,9 @@ void GrpcExecutor::SetThreading(bool threading) { EXECUTOR_TRACE("(%s) SetThreading(%d) done", name_, threading); } -void GrpcExecutor::Shutdown() { SetThreading(false); } +void Executor::Shutdown() { SetThreading(false); } -void GrpcExecutor::ThreadMain(void* arg) { +void Executor::ThreadMain(void* arg) { ThreadState* ts = static_cast(arg); gpr_tls_set(&g_this_thread_state, reinterpret_cast(ts)); @@ -192,8 +242,8 @@ void GrpcExecutor::ThreadMain(void* arg) { } } -void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, - bool is_short) { +void Executor::Enqueue(grpc_closure* closure, grpc_error* error, + bool is_short) { bool retry_push; if (is_short) { GRPC_STATS_INC_EXECUTOR_SCHEDULED_SHORT_ITEMS(); @@ -304,7 +354,7 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, gpr_atm_rel_store(&num_threads_, cur_thread_count + 1); thd_state_[cur_thread_count].thd = grpc_core::Thread( - name_, &GrpcExecutor::ThreadMain, &thd_state_[cur_thread_count]); + name_, &Executor::ThreadMain, &thd_state_[cur_thread_count]); thd_state_[cur_thread_count].thd.Start(); } gpr_spinlock_unlock(&adding_thread_lock_); @@ -316,85 +366,52 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error, } while (retry_push); } -static GrpcExecutor* executors[GRPC_NUM_EXECUTORS]; - -void default_enqueue_short(grpc_closure* closure, grpc_error* error) { - executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error, - true /* is_short */); -} - -void default_enqueue_long(grpc_closure* closure, grpc_error* error) { - executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error, - false /* is_short */); -} - -void resolver_enqueue_short(grpc_closure* closure, grpc_error* error) { - executors[GRPC_RESOLVER_EXECUTOR]->Enqueue(closure, error, - true /* is_short */); -} - -void resolver_enqueue_long(grpc_closure* closure, grpc_error* error) { - executors[GRPC_RESOLVER_EXECUTOR]->Enqueue(closure, error, - false /* is_short */); -} - -static const grpc_closure_scheduler_vtable - vtables_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = { - {{&default_enqueue_short, &default_enqueue_short, "def-ex-short"}, - {&default_enqueue_long, &default_enqueue_long, "def-ex-long"}}, - {{&resolver_enqueue_short, &resolver_enqueue_short, "res-ex-short"}, - {&resolver_enqueue_long, &resolver_enqueue_long, "res-ex-long"}}}; - -static grpc_closure_scheduler - schedulers_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = { - {{&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_SHORT]}, - {&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_LONG]}}, - {{&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_SHORT]}, - {&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_LONG]}}}; - -// grpc_executor_init() and grpc_executor_shutdown() functions are called in the +// Executor::InitAll() and Executor::ShutdownAll() functions are called in the // the grpc_init() and grpc_shutdown() code paths which are protected by a // global mutex. So it is okay to assume that these functions are thread-safe -void grpc_executor_init() { - EXECUTOR_TRACE0("grpc_executor_init() enter"); +void Executor::InitAll() { + EXECUTOR_TRACE0("Executor::InitAll() enter"); - // Return if grpc_executor_init() is already called earlier - if (executors[GRPC_DEFAULT_EXECUTOR] != nullptr) { - GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] != nullptr); + // Return if Executor::InitAll() is already called earlier + if (executors[static_cast(ExecutorType::DEFAULT)] != nullptr) { + GPR_ASSERT(executors[static_cast(ExecutorType::RESOLVER)] != + nullptr); return; } - executors[GRPC_DEFAULT_EXECUTOR] = - grpc_core::New("default-executor"); - executors[GRPC_RESOLVER_EXECUTOR] = - grpc_core::New("resolver-executor"); + executors[static_cast(ExecutorType::DEFAULT)] = + grpc_core::New("default-executor"); + executors[static_cast(ExecutorType::RESOLVER)] = + grpc_core::New("resolver-executor"); - executors[GRPC_DEFAULT_EXECUTOR]->Init(); - executors[GRPC_RESOLVER_EXECUTOR]->Init(); + executors[static_cast(ExecutorType::DEFAULT)]->Init(); + executors[static_cast(ExecutorType::RESOLVER)]->Init(); - EXECUTOR_TRACE0("grpc_executor_init() done"); + EXECUTOR_TRACE0("Executor::InitAll() done"); } -grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type, - GrpcExecutorJobType job_type) { - return &schedulers_[executor_type][job_type]; +grpc_closure_scheduler* Executor::Scheduler(ExecutorType executor_type, + ExecutorJobType job_type) { + return &schedulers_[static_cast(executor_type)] + [static_cast(job_type)]; } -grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type) { - return grpc_executor_scheduler(GRPC_DEFAULT_EXECUTOR, job_type); +grpc_closure_scheduler* Executor::Scheduler(ExecutorJobType job_type) { + return Executor::Scheduler(ExecutorType::DEFAULT, job_type); } -void grpc_executor_shutdown() { - EXECUTOR_TRACE0("grpc_executor_shutdown() enter"); +void Executor::ShutdownAll() { + EXECUTOR_TRACE0("Executor::ShutdownAll() enter"); - // Return if grpc_executor_shutdown() is already called earlier - if (executors[GRPC_DEFAULT_EXECUTOR] == nullptr) { - GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] == nullptr); + // Return if Executor:SshutdownAll() is already called earlier + if (executors[static_cast(ExecutorType::DEFAULT)] == nullptr) { + GPR_ASSERT(executors[static_cast(ExecutorType::RESOLVER)] == + nullptr); return; } - executors[GRPC_DEFAULT_EXECUTOR]->Shutdown(); - executors[GRPC_RESOLVER_EXECUTOR]->Shutdown(); + executors[static_cast(ExecutorType::DEFAULT)]->Shutdown(); + executors[static_cast(ExecutorType::RESOLVER)]->Shutdown(); // Delete the executor objects. // @@ -408,26 +425,36 @@ void grpc_executor_shutdown() { // By ensuring that all executors are shutdown first, we are also ensuring // that no thread is active across all executors. - grpc_core::Delete(executors[GRPC_DEFAULT_EXECUTOR]); - grpc_core::Delete(executors[GRPC_RESOLVER_EXECUTOR]); - executors[GRPC_DEFAULT_EXECUTOR] = nullptr; - executors[GRPC_RESOLVER_EXECUTOR] = nullptr; + grpc_core::Delete( + executors[static_cast(ExecutorType::DEFAULT)]); + grpc_core::Delete( + executors[static_cast(ExecutorType::RESOLVER)]); + executors[static_cast(ExecutorType::DEFAULT)] = nullptr; + executors[static_cast(ExecutorType::RESOLVER)] = nullptr; - EXECUTOR_TRACE0("grpc_executor_shutdown() done"); + EXECUTOR_TRACE0("Executor::ShutdownAll() done"); } -bool grpc_executor_is_threaded(GrpcExecutorType executor_type) { - GPR_ASSERT(executor_type < GRPC_NUM_EXECUTORS); - return executors[executor_type]->IsThreaded(); +bool Executor::IsThreaded(ExecutorType executor_type) { + GPR_ASSERT(executor_type < ExecutorType::NUM_EXECUTORS); + return executors[static_cast(executor_type)]->IsThreaded(); } -bool grpc_executor_is_threaded() { - return grpc_executor_is_threaded(GRPC_DEFAULT_EXECUTOR); +bool Executor::IsThreadedDefault() { + return Executor::IsThreaded(ExecutorType::DEFAULT); } -void grpc_executor_set_threading(bool enable) { - EXECUTOR_TRACE("grpc_executor_set_threading(%d) called", enable); - for (int i = 0; i < GRPC_NUM_EXECUTORS; i++) { +void Executor::SetThreadingAll(bool enable) { + EXECUTOR_TRACE("Executor::SetThreadingAll(%d) called", enable); + for (size_t i = 0; i < static_cast(ExecutorType::NUM_EXECUTORS); + i++) { executors[i]->SetThreading(enable); } } + +void Executor::SetThreadingDefault(bool enable) { + EXECUTOR_TRACE("Executor::SetThreadingDefault(%d) called", enable); + executors[static_cast(ExecutorType::DEFAULT)]->SetThreading(enable); +} + +} // namespace grpc_core diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h index 8829138c5fa..9e472279b7b 100644 --- a/src/core/lib/iomgr/executor.h +++ b/src/core/lib/iomgr/executor.h @@ -25,7 +25,9 @@ #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/closure.h" -typedef struct { +namespace grpc_core { + +struct ThreadState { gpr_mu mu; size_t id; // For debugging purposes const char* name; // Thread state name @@ -35,17 +37,24 @@ typedef struct { bool shutdown; bool queued_long_job; grpc_core::Thread thd; -} ThreadState; +}; -typedef enum { - GRPC_EXECUTOR_SHORT = 0, - GRPC_EXECUTOR_LONG, - GRPC_NUM_EXECUTOR_JOB_TYPES // Add new values above this -} GrpcExecutorJobType; +enum class ExecutorType { + DEFAULT = 0, + RESOLVER, -class GrpcExecutor { + NUM_EXECUTORS // Add new values above this +}; + +enum class ExecutorJobType { + SHORT = 0, + LONG, + NUM_JOB_TYPES // Add new values above this +}; + +class Executor { public: - GrpcExecutor(const char* executor_name); + Executor(const char* executor_name); void Init(); @@ -62,6 +71,40 @@ class GrpcExecutor { * a short job (i.e expected to not block and complete quickly) */ void Enqueue(grpc_closure* closure, grpc_error* error, bool is_short); + // TODO(sreek): Currently we have two executors (available globally): The + // default executor and the resolver executor. + // + // Some of the functions below operate on the DEFAULT executor only while some + // operate of ALL the executors. This is a bit confusing and should be cleaned + // up in future (where we make all the following functions take ExecutorType + // and/or JobType) + + // Initialize ALL the executors + static void InitAll(); + + // Shutdown ALL the executors + static void ShutdownAll(); + + // Set the threading mode for ALL the executors + static void SetThreadingAll(bool enable); + + // Set the threading mode for ALL the executors + static void SetThreadingDefault(bool enable); + + // Get the DEFAULT executor scheduler for the given job_type + static grpc_closure_scheduler* Scheduler(ExecutorJobType job_type); + + // Get the executor scheduler for a given executor_type and a job_type + static grpc_closure_scheduler* Scheduler(ExecutorType executor_type, + ExecutorJobType job_type); + + // Return if a given executor is running in threaded mode (i.e if + // SetThreading(true) was called previously on that executor) + static bool IsThreaded(ExecutorType executor_type); + + // Return if the DEFAULT executor is threaded + static bool IsThreadedDefault(); + private: static size_t RunClosures(const char* executor_name, grpc_closure_list list); static void ThreadMain(void* arg); @@ -73,44 +116,6 @@ class GrpcExecutor { gpr_spinlock adding_thread_lock_; }; -// == Global executor functions == - -typedef enum { - GRPC_DEFAULT_EXECUTOR = 0, - GRPC_RESOLVER_EXECUTOR, - - GRPC_NUM_EXECUTORS // Add new values above this -} GrpcExecutorType; - -// TODO(sreek): Currently we have two executors (available globally): The -// default executor and the resolver executor. -// -// Some of the functions below operate on the DEFAULT executor only while some -// operate of ALL the executors. This is a bit confusing and should be cleaned -// up in future (where we make all the following functions take executor_type -// and/or job_type) - -// Initialize ALL the executors -void grpc_executor_init(); - -// Shutdown ALL the executors -void grpc_executor_shutdown(); - -// Set the threading mode for ALL the executors -void grpc_executor_set_threading(bool enable); - -// Get the DEFAULT executor scheduler for the given job_type -grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type); - -// Get the executor scheduler for a given executor_type and a job_type -grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type, - GrpcExecutorJobType job_type); - -// Return if a given executor is running in threaded mode (i.e if -// grpc_executor_set_threading(true) was called previously on that executor) -bool grpc_executor_is_threaded(GrpcExecutorType executor_type); - -// Return if the DEFAULT executor is threaded -bool grpc_executor_is_threaded(); +} // namespace grpc_core #endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */ diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index 05ecd2a49b7..2eebe3f26f6 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -71,7 +71,7 @@ void grpc_prefork() { return; } grpc_timer_manager_set_threading(false); - grpc_executor_set_threading(false); + grpc_core::Executor::SetThreadingAll(false); grpc_core::ExecCtx::Get()->Flush(); grpc_core::Fork::AwaitThreads(); skipped_handler = false; @@ -82,7 +82,7 @@ void grpc_postfork_parent() { grpc_core::Fork::AllowExecCtx(); grpc_core::ExecCtx exec_ctx; grpc_timer_manager_set_threading(true); - grpc_executor_set_threading(true); + grpc_core::Executor::SetThreadingAll(true); } } @@ -96,7 +96,7 @@ void grpc_postfork_child() { reset_polling_engine(); } grpc_timer_manager_set_threading(true); - grpc_executor_set_threading(true); + grpc_core::Executor::SetThreadingAll(true); } } diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index dcc69332e0b..33153d9cc3b 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -52,7 +52,7 @@ void grpc_iomgr_init() { g_shutdown = 0; gpr_mu_init(&g_mu); gpr_cv_init(&g_rcv); - grpc_executor_init(); + grpc_core::Executor::InitAll(); grpc_timer_list_init(); g_root_object.next = g_root_object.prev = &g_root_object; g_root_object.name = (char*)"root"; @@ -88,7 +88,7 @@ void grpc_iomgr_shutdown() { { grpc_timer_manager_shutdown(); grpc_iomgr_platform_flush(); - grpc_executor_shutdown(); + grpc_core::Executor::ShutdownAll(); gpr_mu_lock(&g_mu); g_shutdown = 1; diff --git a/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc index e1cd8f73104..3d07f1abe9a 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -34,7 +34,7 @@ gpr_thd_id g_init_thread; static void iomgr_platform_init(void) { grpc_core::ExecCtx exec_ctx; - grpc_executor_set_threading(false); + grpc_core::Executor::SetThreadingAll(false); g_init_thread = gpr_thd_currentid(); grpc_pollset_global_init(); } diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc index 2a03244ff7d..e6dd8f1ceab 100644 --- a/src/core/lib/iomgr/resolve_address_posix.cc +++ b/src/core/lib/iomgr/resolve_address_posix.cc @@ -150,7 +150,7 @@ typedef struct { void* arg; } request; -/* Callback to be passed to grpc_executor to asynch-ify +/* Callback to be passed to grpc Executor to asynch-ify * grpc_blocking_resolve_address */ static void do_request_thread(void* rp, grpc_error* error) { request* r = static_cast(rp); @@ -168,7 +168,8 @@ static void posix_resolve_address(const char* name, const char* default_port, request* r = static_cast(gpr_malloc(sizeof(request))); GRPC_CLOSURE_INIT( &r->request_closure, do_request_thread, r, - grpc_executor_scheduler(GRPC_RESOLVER_EXECUTOR, GRPC_EXECUTOR_SHORT)); + grpc_core::Executor::Scheduler(grpc_core::ExecutorType::RESOLVER, + grpc_core::ExecutorJobType::SHORT)); r->name = gpr_strdup(name); r->default_port = gpr_strdup(default_port); r->on_done = on_done; diff --git a/src/core/lib/iomgr/resolve_address_windows.cc b/src/core/lib/iomgr/resolve_address_windows.cc index 3e977dca2da..64351c38a8f 100644 --- a/src/core/lib/iomgr/resolve_address_windows.cc +++ b/src/core/lib/iomgr/resolve_address_windows.cc @@ -153,7 +153,8 @@ static void windows_resolve_address(const char* name, const char* default_port, request* r = (request*)gpr_malloc(sizeof(request)); GRPC_CLOSURE_INIT( &r->request_closure, do_request_thread, r, - grpc_executor_scheduler(GRPC_RESOLVER_EXECUTOR, GRPC_EXECUTOR_SHORT)); + grpc_core::Executor::Scheduler(grpc_core::ExecutorType::RESOLVER, + grpc_core::ExecutorJobType::SHORT)); r->name = gpr_strdup(name); r->default_port = gpr_strdup(default_port); r->on_done = on_done; diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index d0642c015ff..92f163b58e9 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -227,10 +227,10 @@ static void cover_self(grpc_tcp* tcp) { } grpc_pollset_init(BACKUP_POLLER_POLLSET(p), &p->pollset_mu); gpr_atm_rel_store(&g_backup_poller, (gpr_atm)p); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_INIT(&p->run_poller, run_poller, p, - grpc_executor_scheduler(GRPC_EXECUTOR_LONG)), - GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_INIT(&p->run_poller, run_poller, p, + grpc_core::Executor::Scheduler( + grpc_core::ExecutorJobType::LONG)), + GRPC_ERROR_NONE); } else { while ((p = (backup_poller*)gpr_atm_acq_load(&g_backup_poller)) == nullptr) { diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc index 3dd7cab855c..5f8865ca57f 100644 --- a/src/core/lib/iomgr/udp_server.cc +++ b/src/core/lib/iomgr/udp_server.cc @@ -481,8 +481,9 @@ void GrpcUdpListener::OnRead(grpc_error* error, void* do_read_arg) { if (udp_handler_->Read()) { /* There maybe more packets to read. Schedule read_more_cb_ closure to run * after finishing this event loop. */ - GRPC_CLOSURE_INIT(&do_read_closure_, do_read, do_read_arg, - grpc_executor_scheduler(GRPC_EXECUTOR_LONG)); + GRPC_CLOSURE_INIT( + &do_read_closure_, do_read, do_read_arg, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::LONG)); GRPC_CLOSURE_SCHED(&do_read_closure_, GRPC_ERROR_NONE); } else { /* Finish reading all the packets, re-arm the notification event so we can @@ -542,8 +543,9 @@ void GrpcUdpListener::OnCanWrite(grpc_error* error, void* do_write_arg) { } /* Schedule actual write in another thread. */ - GRPC_CLOSURE_INIT(&do_write_closure_, do_write, do_write_arg, - grpc_executor_scheduler(GRPC_EXECUTOR_LONG)); + GRPC_CLOSURE_INIT( + &do_write_closure_, do_write, do_write_arg, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::LONG)); GRPC_CLOSURE_SCHED(&do_write_closure_, GRPC_ERROR_NONE); } diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 67cf5d89bff..60f506ef5e2 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -165,7 +165,7 @@ void grpc_shutdown(void) { { grpc_timer_manager_set_threading( false); // shutdown timer_manager thread - grpc_executor_shutdown(); + grpc_core::Executor::ShutdownAll(); for (i = g_number_of_plugins; i >= 0; i--) { if (g_all_of_the_plugins[i].destroy != nullptr) { g_all_of_the_plugins[i].destroy(); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 7ae6e51a5fb..cdfd3336437 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1134,8 +1134,9 @@ void grpc_server_start(grpc_server* server) { server_ref(server); server->starting = true; GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(start_listeners, server, - grpc_executor_scheduler(GRPC_EXECUTOR_SHORT)), + GRPC_CLOSURE_CREATE( + start_listeners, server, + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), GRPC_ERROR_NONE); } diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index b32f9c6ec1a..43add28ce03 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -73,7 +73,7 @@ void grpc_stream_unref(grpc_stream_refcount* refcount) { Throw this over to the executor (on a core-owned thread) and process it there. */ refcount->destroy.scheduler = - grpc_executor_scheduler(GRPC_EXECUTOR_SHORT); + grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT); } GRPC_CLOSURE_SCHED(&refcount->destroy, GRPC_ERROR_NONE); } diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index a0b82904753..57bc8ad768c 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -706,7 +706,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_timer_manager_set_threading(false); { grpc_core::ExecCtx exec_ctx; - grpc_executor_set_threading(false); + grpc_core::Executor::SetThreadingAll(false); } grpc_set_resolver_impl(&fuzzer_resolver); grpc_dns_lookup_ares_locked = my_dns_lookup_ares_locked; diff --git a/test/core/end2end/fuzzers/client_fuzzer.cc b/test/core/end2end/fuzzers/client_fuzzer.cc index e21006bb673..8520fb53755 100644 --- a/test/core/end2end/fuzzers/client_fuzzer.cc +++ b/test/core/end2end/fuzzers/client_fuzzer.cc @@ -46,7 +46,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_init(); { grpc_core::ExecCtx exec_ctx; - grpc_executor_set_threading(false); + grpc_core::Executor::SetThreadingAll(false); grpc_resource_quota* resource_quota = grpc_resource_quota_create("client_fuzzer"); diff --git a/test/core/end2end/fuzzers/server_fuzzer.cc b/test/core/end2end/fuzzers/server_fuzzer.cc index d370dc7de85..644f98e37ac 100644 --- a/test/core/end2end/fuzzers/server_fuzzer.cc +++ b/test/core/end2end/fuzzers/server_fuzzer.cc @@ -43,7 +43,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_init(); { grpc_core::ExecCtx exec_ctx; - grpc_executor_set_threading(false); + grpc_core::Executor::SetThreadingAll(false); grpc_resource_quota* resource_quota = grpc_resource_quota_create("server_fuzzer"); diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index 1d9e1ee27e2..0ae0ec888b6 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -290,7 +290,7 @@ int main(int argc, char** argv) { test_invalid_ip_addresses(); test_unparseable_hostports(); } - grpc_executor_shutdown(); + grpc_core::Executor::ShutdownAll(); } gpr_cmdline_destroy(cl); From f6924ff2d1e506a553f0a6590801a50fca34fa27 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 18 Jan 2019 13:57:39 -0800 Subject: [PATCH 111/814] fix newline EOF --- templates/src/objective-c/BoringSSL-GRPC.podspec.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/src/objective-c/BoringSSL-GRPC.podspec.template b/templates/src/objective-c/BoringSSL-GRPC.podspec.template index 6804f75f1b0..f2abe0d61dc 100644 --- a/templates/src/objective-c/BoringSSL-GRPC.podspec.template +++ b/templates/src/objective-c/BoringSSL-GRPC.podspec.template @@ -1561,4 +1561,4 @@ # This is the last part of this file. s.prefix_header_contents = ${expand_symbol_list(settings.grpc_shadow_boringssl_symbols)} - end \ No newline at end of file + end From 9df6023dca89a288ad2650ca1cc1bc6bd3dccb2b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 18 Jan 2019 14:48:12 -0800 Subject: [PATCH 112/814] Move Optional to gprpp, and reviewer comments --- BUILD | 12 +++++ CMakeLists.txt | 40 +++++++++++++++ Makefile | 48 ++++++++++++++++++ build.yaml | 14 ++++++ gRPC-C++.podspec | 2 + gRPC-Core.podspec | 2 + grpc.gemspec | 1 + package.xml | 1 + src/core/lib/gprpp/optional.h | 45 +++++++++++++++++ src/core/lib/iomgr/buffer_list.cc | 6 +-- src/core/lib/iomgr/buffer_list.h | 22 +------- test/core/gprpp/BUILD | 13 +++++ test/core/gprpp/optional_test.cc | 50 +++++++++++++++++++ test/core/iomgr/buffer_list_test.cc | 15 ------ tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core.internal | 1 + .../generated/sources_and_headers.json | 20 ++++++++ tools/run_tests/generated/tests.json | 24 +++++++++ 18 files changed, 279 insertions(+), 38 deletions(-) create mode 100644 src/core/lib/gprpp/optional.h create mode 100644 test/core/gprpp/optional_test.cc diff --git a/BUILD b/BUILD index 03dc449cb02..55f8f199195 100644 --- a/BUILD +++ b/BUILD @@ -643,6 +643,17 @@ grpc_cc_library( public_hdrs = ["src/core/lib/gprpp/debug_location.h"], ) +grpc_cc_library( + name = "optional", + language = "c++", + public_hdrs = [ + "src/core/lib/gprpp/optional.h", + ], + deps = [ + "gpr_base", + ], +) + grpc_cc_library( name = "orphanable", language = "c++", @@ -976,6 +987,7 @@ grpc_cc_library( "grpc_codegen", "grpc_trace", "inlined_vector", + "optional", "orphanable", "ref_counted", "ref_counted_ptr", diff --git a/CMakeLists.txt b/CMakeLists.txt index bb1caaaf565..f0c7fcf57a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -652,6 +652,7 @@ add_dependencies(buildtests_cxx metrics_client) add_dependencies(buildtests_cxx mock_test) add_dependencies(buildtests_cxx nonblocking_test) add_dependencies(buildtests_cxx noop-benchmark) +add_dependencies(buildtests_cxx optional_test) add_dependencies(buildtests_cxx orphanable_test) add_dependencies(buildtests_cxx proto_server_reflection_test) add_dependencies(buildtests_cxx proto_utils_test) @@ -14443,6 +14444,45 @@ target_link_libraries(noop-benchmark ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(optional_test + test/core/gprpp/optional_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(optional_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(optional_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 1a64c9e9683..ccd9f73df2c 100644 --- a/Makefile +++ b/Makefile @@ -1213,6 +1213,7 @@ metrics_client: $(BINDIR)/$(CONFIG)/metrics_client mock_test: $(BINDIR)/$(CONFIG)/mock_test nonblocking_test: $(BINDIR)/$(CONFIG)/nonblocking_test noop-benchmark: $(BINDIR)/$(CONFIG)/noop-benchmark +optional_test: $(BINDIR)/$(CONFIG)/optional_test orphanable_test: $(BINDIR)/$(CONFIG)/orphanable_test proto_server_reflection_test: $(BINDIR)/$(CONFIG)/proto_server_reflection_test proto_utils_test: $(BINDIR)/$(CONFIG)/proto_utils_test @@ -1720,6 +1721,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/mock_test \ $(BINDIR)/$(CONFIG)/nonblocking_test \ $(BINDIR)/$(CONFIG)/noop-benchmark \ + $(BINDIR)/$(CONFIG)/optional_test \ $(BINDIR)/$(CONFIG)/orphanable_test \ $(BINDIR)/$(CONFIG)/proto_server_reflection_test \ $(BINDIR)/$(CONFIG)/proto_utils_test \ @@ -1906,6 +1908,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/mock_test \ $(BINDIR)/$(CONFIG)/nonblocking_test \ $(BINDIR)/$(CONFIG)/noop-benchmark \ + $(BINDIR)/$(CONFIG)/optional_test \ $(BINDIR)/$(CONFIG)/orphanable_test \ $(BINDIR)/$(CONFIG)/proto_server_reflection_test \ $(BINDIR)/$(CONFIG)/proto_utils_test \ @@ -2399,6 +2402,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/nonblocking_test || ( echo test nonblocking_test failed ; exit 1 ) $(E) "[RUN] Testing noop-benchmark" $(Q) $(BINDIR)/$(CONFIG)/noop-benchmark || ( echo test noop-benchmark failed ; exit 1 ) + $(E) "[RUN] Testing optional_test" + $(Q) $(BINDIR)/$(CONFIG)/optional_test || ( echo test optional_test failed ; exit 1 ) $(E) "[RUN] Testing orphanable_test" $(Q) $(BINDIR)/$(CONFIG)/orphanable_test || ( echo test orphanable_test failed ; exit 1 ) $(E) "[RUN] Testing proto_server_reflection_test" @@ -19442,6 +19447,49 @@ endif endif +OPTIONAL_TEST_SRC = \ + test/core/gprpp/optional_test.cc \ + +OPTIONAL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(OPTIONAL_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/optional_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/optional_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/optional_test: $(PROTOBUF_DEP) $(OPTIONAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(OPTIONAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/optional_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/gprpp/optional_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_optional_test: $(OPTIONAL_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(OPTIONAL_TEST_OBJS:.o=.dep) +endif +endif + + ORPHANABLE_TEST_SRC = \ test/core/gprpp/orphanable_test.cc \ diff --git a/build.yaml b/build.yaml index 8f310e0e59d..c8a32404373 100644 --- a/build.yaml +++ b/build.yaml @@ -430,6 +430,7 @@ filegroups: - src/core/lib/debug/stats_data.h - src/core/lib/gprpp/debug_location.h - src/core/lib/gprpp/inlined_vector.h + - src/core/lib/gprpp/optional.h - src/core/lib/gprpp/orphanable.h - src/core/lib/gprpp/ref_counted.h - src/core/lib/gprpp/ref_counted_ptr.h @@ -5057,6 +5058,19 @@ targets: deps: - benchmark defaults: benchmark +- name: optional_test + gtest: true + build: test + language: c++ + src: + - test/core/gprpp/optional_test.cc + deps: + - grpc_test_util + - grpc++ + - grpc + - gpr + uses: + - grpc++_test - name: orphanable_test gtest: true build: test diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 481892b63c7..710fc461441 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -402,6 +402,7 @@ Pod::Spec.new do |s| 'src/core/lib/debug/stats_data.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/inlined_vector.h', + 'src/core/lib/gprpp/optional.h', 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', @@ -595,6 +596,7 @@ Pod::Spec.new do |s| 'src/core/lib/debug/stats_data.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/inlined_vector.h', + 'src/core/lib/gprpp/optional.h', 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 5bb6a514bb9..4bb29321f8d 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -396,6 +396,7 @@ Pod::Spec.new do |s| 'src/core/lib/debug/stats_data.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/inlined_vector.h', + 'src/core/lib/gprpp/optional.h', 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', @@ -1024,6 +1025,7 @@ Pod::Spec.new do |s| 'src/core/lib/debug/stats_data.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/inlined_vector.h', + 'src/core/lib/gprpp/optional.h', 'src/core/lib/gprpp/orphanable.h', 'src/core/lib/gprpp/ref_counted.h', 'src/core/lib/gprpp/ref_counted_ptr.h', diff --git a/grpc.gemspec b/grpc.gemspec index 5e5eb65ed2f..d245c722037 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -332,6 +332,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/debug/stats_data.h ) s.files += %w( src/core/lib/gprpp/debug_location.h ) s.files += %w( src/core/lib/gprpp/inlined_vector.h ) + s.files += %w( src/core/lib/gprpp/optional.h ) s.files += %w( src/core/lib/gprpp/orphanable.h ) s.files += %w( src/core/lib/gprpp/ref_counted.h ) s.files += %w( src/core/lib/gprpp/ref_counted_ptr.h ) diff --git a/package.xml b/package.xml index 523f78f1db6..cb036c81daf 100644 --- a/package.xml +++ b/package.xml @@ -337,6 +337,7 @@ + diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h new file mode 100644 index 00000000000..593ef08c317 --- /dev/null +++ b/src/core/lib/gprpp/optional.h @@ -0,0 +1,45 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_GPRPP_OPTIONAL_H +#define GRPC_CORE_LIB_GPRPP_OPTIONAL_H + +namespace grpc_core { + +/* A make-shift alternative for absl::Optional. This can be removed in favor of + * that once absl dependencies can be introduced. */ +template +class Optional { + public: + void set(const T& val) { + value_ = val; + set_ = true; + } + + bool has_value() { return set_; } + + void reset() { set_ = false; } + + T value() { return value_; } + T value_; + bool set_ = false; +}; + +} /* namespace grpc_core */ + +#endif /* GRPC_CORE_LIB_GPRPP_OPTIONAL_H */ diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index 70c1a820d74..fa16194a3f0 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -66,8 +66,8 @@ void extract_opt_stats_from_tcp_info(ConnectionMetrics* metrics, } if (info->length > offsetof(grpc_core::tcp_info, tcpi_sndbuf_limited)) { metrics->recurring_retrans.set(info->tcpi_retransmits); - metrics->is_delivery_rate_app_limited = - info->tcpi_delivery_rate_app_limited; + metrics->is_delivery_rate_app_limited.set( + info->tcpi_delivery_rate_app_limited); metrics->congestion_window.set(info->tcpi_snd_cwnd); metrics->reordering.set(info->tcpi_reordering); metrics->packet_retx.set(info->tcpi_total_retrans); @@ -126,7 +126,7 @@ void extract_opt_stats_from_cmsg(ConnectionMetrics* metrics, break; } case TCP_NLA_DELIVERY_RATE_APP_LMT: { - metrics->is_delivery_rate_app_limited = read_unaligned(val); + metrics->is_delivery_rate_app_limited.set(read_unaligned(val)); break; } case TCP_NLA_SND_CWND: { diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 7acd92afa27..5fa26cecdc5 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -26,35 +26,17 @@ #include #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/optional.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/internal_errqueue.h" namespace grpc_core { -/* A make-shift alternative for absl::Optional. This can be removed in favor of - * that once is absl dependencies can be introduced. */ -template -class Optional { - public: - void set(const T& val) { - value_ = val; - set_ = true; - } - - bool has_value() { return set_; } - - void reset() { set_ = false; } - - T value() { return value_; } - T value_; - bool set_ = false; -}; - struct ConnectionMetrics { /* Delivery rate in Bps. */ Optional delivery_rate; /* If the delivery rate is limited by the application, this is set to true. */ - bool is_delivery_rate_app_limited = true; + Optional is_delivery_rate_app_limited; /* Total packets retransmitted. */ Optional packet_retx; /* Total packets retransmitted spuriously. This metric is smaller than or diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index fe3fea1df88..c8d47be5bb2 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -64,6 +64,19 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "optional_test", + srcs = ["optional_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:optional", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "orphanable_test", srcs = ["orphanable_test.cc"], diff --git a/test/core/gprpp/optional_test.cc b/test/core/gprpp/optional_test.cc new file mode 100644 index 00000000000..ce6f8692fd5 --- /dev/null +++ b/test/core/gprpp/optional_test.cc @@ -0,0 +1,50 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "src/core/lib/gprpp/optional.h" +#include +#include +#include "src/core/lib/gprpp/memory.h" +#include "test/core/util/test_config.h" + +namespace grpc_core { +namespace testing { + +namespace { +TEST(OptionalTest, BasicTest) { + grpc_core::Optional opt_val; + EXPECT_FALSE(opt_val.has_value()); + const int kTestVal = 123; + + opt_val.set(kTestVal); + EXPECT_TRUE(opt_val.has_value()); + EXPECT_EQ(opt_val.value(), kTestVal); + + opt_val.reset(); + EXPECT_EQ(opt_val.has_value(), false); +} +} // namespace + +} // namespace testing +} // namespace grpc_core + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index 5355a469b66..19ca7ea7838 100644 --- a/test/core/iomgr/buffer_list_test.cc +++ b/test/core/iomgr/buffer_list_test.cc @@ -96,25 +96,10 @@ static void TestTcpBufferList() { TestShutdownFlushesList(); } -/* Tests grpc_core::Optional */ -static void TestOptional() { - grpc_core::Optional opt_val; - GPR_ASSERT(opt_val.has_value() == false); - const int kTestVal = 123; - - opt_val.set(kTestVal); - GPR_ASSERT(opt_val.has_value()); - GPR_ASSERT(opt_val.value() == 123); - - opt_val.reset(); - GPR_ASSERT(opt_val.has_value() == false); -} - int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); TestTcpBufferList(); - TestOptional(); grpc_shutdown(); return 0; } diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 363df22aa15..8aec165a339 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1076,6 +1076,7 @@ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/memory.h \ src/core/lib/gprpp/mutex_lock.h \ +src/core/lib/gprpp/optional.h \ src/core/lib/gprpp/orphanable.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 51b9eda22b6..041c7382be5 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1167,6 +1167,7 @@ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/memory.h \ src/core/lib/gprpp/mutex_lock.h \ +src/core/lib/gprpp/optional.h \ src/core/lib/gprpp/orphanable.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8ab9c57142e..2b325944790 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4184,6 +4184,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "optional_test", + "src": [ + "test/core/gprpp/optional_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -9556,6 +9574,7 @@ "src/core/lib/debug/stats_data.h", "src/core/lib/gprpp/debug_location.h", "src/core/lib/gprpp/inlined_vector.h", + "src/core/lib/gprpp/optional.h", "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", @@ -9709,6 +9728,7 @@ "src/core/lib/debug/stats_data.h", "src/core/lib/gprpp/debug_location.h", "src/core/lib/gprpp/inlined_vector.h", + "src/core/lib/gprpp/optional.h", "src/core/lib/gprpp/orphanable.h", "src/core/lib/gprpp/ref_counted.h", "src/core/lib/gprpp/ref_counted_ptr.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 6c667f10c48..b41fef6b795 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -4887,6 +4887,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "optional_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From 222e93a2bca0de19ee6eb168428ecd9de174199c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 18 Jan 2019 14:49:13 -0800 Subject: [PATCH 113/814] /s/Bps/Bytes\/s --- src/core/lib/iomgr/buffer_list.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 5fa26cecdc5..1004c603986 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -33,7 +33,7 @@ namespace grpc_core { struct ConnectionMetrics { - /* Delivery rate in Bps. */ + /* Delivery rate in Bytes/s. */ Optional delivery_rate; /* If the delivery rate is limited by the application, this is set to true. */ Optional is_delivery_rate_app_limited; From dc85d5b5568f527498c685feece893dcf37333e8 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 18 Jan 2019 15:24:42 -0800 Subject: [PATCH 114/814] Allocate tcp_info on the heap to avoid stack frame limits --- src/core/lib/iomgr/buffer_list.cc | 17 ++++++++++++++--- src/core/lib/iomgr/buffer_list.h | 5 +++-- src/core/lib/iomgr/tcp_posix.cc | 13 +------------ test/core/iomgr/buffer_list_test.cc | 4 ++-- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index fa16194a3f0..321de539934 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -24,6 +24,7 @@ #include #ifdef GRPC_LINUX_ERRQUEUE +#include #include #include @@ -185,10 +186,16 @@ void extract_opt_stats_from_cmsg(ConnectionMetrics* metrics, offset += NLA_ALIGN(attr->nla_len); } } + +static int get_socket_tcp_info(grpc_core::tcp_info* info, int fd) { + info->length = sizeof(*info) - sizeof(socklen_t); + memset(info, 0, sizeof(*info)); + return getsockopt(fd, IPPROTO_TCP, TCP_INFO, info, &(info->length)); +} } /* namespace */ -void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, - const grpc_core::tcp_info* info, void* arg) { +void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, int fd, + void* arg) { GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* new_elem = New(seq_no, arg); /* Store the current time as the sendmsg time. */ @@ -196,7 +203,11 @@ void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, new_elem->ts_.scheduled_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); new_elem->ts_.sent_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); new_elem->ts_.acked_time.time = gpr_inf_past(GPR_CLOCK_REALTIME); - extract_opt_stats_from_tcp_info(&new_elem->ts_.sendmsg_time.metrics, info); + + if (get_socket_tcp_info(&new_elem->ts_.info, fd) == 0) { + extract_opt_stats_from_tcp_info(&new_elem->ts_.sendmsg_time.metrics, + &new_elem->ts_.info); + } if (*head == nullptr) { *head = new_elem; return; diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 1004c603986..c2ff9cb373b 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -93,7 +93,8 @@ struct Timestamps { Timestamp sent_time; Timestamp acked_time; - uint32_t byte_offset; /* byte offset relative to the start of the RPC */ + uint32_t byte_offset; /* byte offset relative to the start of the RPC */ + grpc_core::tcp_info info; /* tcp_info collected on sendmsg */ }; /** TracedBuffer is a class to keep track of timestamps for a specific buffer in @@ -113,7 +114,7 @@ class TracedBuffer { /** Add a new entry in the TracedBuffer list pointed to by head. Also saves * sendmsg_time with the current timestamp. */ static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no, - const grpc_core::tcp_info* info, void* arg); + int fd, void* arg); /** Processes a received timestamp based on sock_extended_err and * scm_timestamping structures. It will invoke the timestamps callback if the diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 902301e7b53..35e772a3605 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -593,11 +593,6 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); #ifdef GRPC_LINUX_ERRQUEUE -static int get_socket_tcp_info(grpc_core::tcp_info* info, int fd) { - info->length = sizeof(*info) - sizeof(socklen_t); - memset(info, 0, sizeof(*info)); - return getsockopt(fd, IPPROTO_TCP, TCP_INFO, info, &(info->length)); -} static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, @@ -635,15 +630,9 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, /* Only save timestamps if all the bytes were taken by sendmsg. */ if (sending_length == static_cast(length)) { gpr_mu_lock(&tcp->tb_mu); - grpc_core::tcp_info info; - auto* info_ptr = &info; - if (get_socket_tcp_info(info_ptr, tcp->fd) != 0) { - /* Failed to get tcp_info */ - info_ptr = nullptr; - } grpc_core::TracedBuffer::AddNewEntry( &tcp->tb_head, static_cast(tcp->bytes_counter + length), - info_ptr, tcp->outgoing_buffer_arg); + tcp->fd, tcp->outgoing_buffer_arg); gpr_mu_unlock(&tcp->tb_mu); tcp->outgoing_buffer_arg = nullptr; } diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index 19ca7ea7838..61a81e31c2b 100644 --- a/test/core/iomgr/buffer_list_test.cc +++ b/test/core/iomgr/buffer_list_test.cc @@ -48,7 +48,7 @@ static void TestShutdownFlushesList() { for (auto i = 0; i < NUM_ELEM; i++) { gpr_atm_rel_store(&verifier_called[i], static_cast(0)); grpc_core::TracedBuffer::AddNewEntry( - &list, i, nullptr, static_cast(&verifier_called[i])); + &list, i, 0, static_cast(&verifier_called[i])); } grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE); GPR_ASSERT(list == nullptr); @@ -84,7 +84,7 @@ static void TestVerifierCalledOnAck() { grpc_core::TracedBuffer* list = nullptr; gpr_atm verifier_called; gpr_atm_rel_store(&verifier_called, static_cast(0)); - grpc_core::TracedBuffer::AddNewEntry(&list, 213, nullptr, &verifier_called); + grpc_core::TracedBuffer::AddNewEntry(&list, 213, 0, &verifier_called); grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, nullptr, &tss); GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast(1)); GPR_ASSERT(list == nullptr); From dba6fdce914152bd9d5d25b32d8417bcc149da89 Mon Sep 17 00:00:00 2001 From: Sanjay Pujare Date: Fri, 18 Jan 2019 15:35:40 -0800 Subject: [PATCH 115/814] update interop client matrix to add 1.18 for core langs --- tools/interop_matrix/client_matrix.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 9b533867836..07f144d8250 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -98,6 +98,7 @@ LANG_RELEASE_MATRIX = { ('v1.15.0', ReleaseInfo()), ('v1.16.0', ReleaseInfo()), ('v1.17.1', ReleaseInfo()), + ('v1.18.0', ReleaseInfo()), ]), 'go': OrderedDict([ @@ -161,6 +162,7 @@ LANG_RELEASE_MATRIX = { ('v1.15.0', ReleaseInfo()), ('v1.16.0', ReleaseInfo()), ('v1.17.1', ReleaseInfo()), + ('v1.18.0', ReleaseInfo()), ]), 'node': OrderedDict([ @@ -225,6 +227,7 @@ LANG_RELEASE_MATRIX = { ('v1.15.0', ReleaseInfo()), ('v1.16.0', ReleaseInfo()), ('v1.17.1', ReleaseInfo()), + ('v1.18.0', ReleaseInfo()), ]), 'csharp': OrderedDict([ @@ -249,6 +252,7 @@ LANG_RELEASE_MATRIX = { ('v1.15.0', ReleaseInfo()), ('v1.16.0', ReleaseInfo()), ('v1.17.1', ReleaseInfo()), + ('v1.18.0', ReleaseInfo()), ]), } From 371d4cd519b8f838fd40e7a9c7fec1889b11dcfd Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 18 Jan 2019 15:51:31 -0800 Subject: [PATCH 116/814] Update pod versions --- gRPC-C++.podspec | 2 +- src/objective-c/BoringSSL-GRPC.podspec | 4 ++-- templates/gRPC-C++.podspec.template | 2 +- templates/src/objective-c/BoringSSL-GRPC.podspec.template | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 4c30e568a1b..08ca3da2650 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -24,7 +24,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized # version = '1.18.0-dev' - version = '0.0.6-dev' + version = '0.0.8-dev' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' diff --git a/src/objective-c/BoringSSL-GRPC.podspec b/src/objective-c/BoringSSL-GRPC.podspec index 99bb5397aef..528b96f32aa 100644 --- a/src/objective-c/BoringSSL-GRPC.podspec +++ b/src/objective-c/BoringSSL-GRPC.podspec @@ -39,7 +39,7 @@ Pod::Spec.new do |s| s.name = 'BoringSSL-GRPC' - version = '0.0.2' + version = '0.0.3' s.version = version s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.' # Adapted from the homepage: @@ -4527,4 +4527,4 @@ Pod::Spec.new do |s| '#define i2d_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_i2d_PKCS8_PRIV_KEY_INFO', '#define PKCS5_pbe2_decrypt_init GRPC_SHADOW_PKCS5_pbe2_decrypt_init', '#define PKCS5_pbe2_encrypt_init GRPC_SHADOW_PKCS5_pbe2_encrypt_init' -end \ No newline at end of file +end diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template index 371d25cd6ba..1ba4556ee10 100644 --- a/templates/gRPC-C++.podspec.template +++ b/templates/gRPC-C++.podspec.template @@ -140,7 +140,7 @@ s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized # version = '${settings.version}' - version = '${modify_podspec_version_string('0.0.6', settings.version)}' + version = '${modify_podspec_version_string('0.0.8', settings.version)}' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' diff --git a/templates/src/objective-c/BoringSSL-GRPC.podspec.template b/templates/src/objective-c/BoringSSL-GRPC.podspec.template index f2abe0d61dc..d86aa0c6cb4 100644 --- a/templates/src/objective-c/BoringSSL-GRPC.podspec.template +++ b/templates/src/objective-c/BoringSSL-GRPC.podspec.template @@ -44,7 +44,7 @@ Pod::Spec.new do |s| s.name = 'BoringSSL-GRPC' - version = '0.0.2' + version = '0.0.3' s.version = version s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.' # Adapted from the homepage: From 944b3114fee3abb77c8625b4e7b907391f9653c1 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 18 Jan 2019 16:26:41 -0800 Subject: [PATCH 117/814] Protect info member with GRPC_LINUX_ERRQUEUE guards --- src/core/lib/iomgr/buffer_list.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index c2ff9cb373b..fd310fabe51 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -93,8 +93,11 @@ struct Timestamps { Timestamp sent_time; Timestamp acked_time; - uint32_t byte_offset; /* byte offset relative to the start of the RPC */ + uint32_t byte_offset; /* byte offset relative to the start of the RPC */ + +#ifdef GRPC_LINUX_ERRQUEUE grpc_core::tcp_info info; /* tcp_info collected on sendmsg */ +#endif /* GRPC_LINUX_ERRQUEUE */ }; /** TracedBuffer is a class to keep track of timestamps for a specific buffer in From 2b328ee0ca023bdabb87f2c6e1feea077ea312f5 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 15 Jan 2019 12:23:57 -0800 Subject: [PATCH 118/814] Re-enable c-ares as the default resolver; but keep SRV queries off by default --- include/grpc/impl/codegen/grpc_types.h | 5 + .../resolver/dns/c_ares/dns_resolver_ares.cc | 17 ++-- .../client/secure/secure_channel_create.cc | 1 + .../composite/composite_credentials.h | 4 + .../lib/security/credentials/credentials.h | 8 ++ .../google_default_credentials.cc | 13 +++ .../google_default_credentials.h | 2 + .../resolver_component_tests_defs.include | 1 - .../resolvers/dns_resolver_test.cc | 2 +- test/cpp/naming/gen_build_yaml.py | 1 + test/cpp/naming/resolver_component_test.cc | 26 ++++- .../naming/resolver_component_tests_runner.py | 80 +++++++++++++++- .../naming/resolver_test_record_groups.yaml | 96 +++++++++++++++++++ 13 files changed, 246 insertions(+), 10 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index f9929186d58..8d7c21107f4 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -350,6 +350,11 @@ typedef struct { /** If set, inhibits health checking (which may be enabled via the * service config.) */ #define GRPC_ARG_INHIBIT_HEALTH_CHECKING "grpc.inhibit_health_checking" +/** If set, the channel's resolver is allowed to query for SRV records. + * For example, this is useful as a way to enable the "grpclb" + * load balancing policy. Note that this only works with the "ares" + * DNS resolver, and isn't supported by the "native" DNS resolver. */ +#define GRPC_ARG_DNS_ENABLE_SRV_QUERIES "grpc.dns_enable_srv_queries" /** If set, determines the number of milliseconds that the c-ares based * DNS resolver will wait on queries before cancelling them. The default value * is 10000. Setting this to "0" will disable c-ares query timeouts diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index abacd0c960d..bf8b0ea5f62 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -125,6 +125,8 @@ class AresDnsResolver : public Resolver { bool shutdown_initiated_ = false; // timeout in milliseconds for active DNS queries int query_timeout_ms_; + // whether or not to enable SRV DNS queries + bool enable_srv_queries_; }; AresDnsResolver::AresDnsResolver(const ResolverArgs& args) @@ -146,14 +148,18 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args) dns_server_ = gpr_strdup(args.uri->authority); } channel_args_ = grpc_channel_args_copy(args.args); + // Disable service config option const grpc_arg* arg = grpc_channel_args_find( channel_args_, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION); - grpc_integer_options integer_options = {false, false, true}; - request_service_config_ = !grpc_channel_arg_get_integer(arg, integer_options); + request_service_config_ = !grpc_channel_arg_get_bool(arg, false); + // Min time b/t resolutions option arg = grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS); min_time_between_resolutions_ = grpc_channel_arg_get_integer(arg, {1000, 0, INT_MAX}); + // Enable SRV queries option + arg = grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ENABLE_SRV_QUERIES); + enable_srv_queries_ = grpc_channel_arg_get_bool(arg, false); interested_parties_ = grpc_pollset_set_create(); if (args.pollset_set != nullptr) { grpc_pollset_set_add_pollset_set(interested_parties_, args.pollset_set); @@ -419,7 +425,7 @@ void AresDnsResolver::StartResolvingLocked() { service_config_json_ = nullptr; pending_request_ = grpc_dns_lookup_ares_locked( dns_server_, name_to_resolve_, kDefaultPort, interested_parties_, - &on_resolved_, &addresses_, true /* check_grpclb */, + &on_resolved_, &addresses_, enable_srv_queries_ /* check_grpclb */, request_service_config_ ? &service_config_json_ : nullptr, query_timeout_ms_, combiner()); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); @@ -472,13 +478,12 @@ static grpc_address_resolver_vtable ares_resolver = { grpc_resolve_address_ares, blocking_resolve_address_ares}; static bool should_use_ares(const char* resolver_env) { - return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0; + return resolver_env == nullptr || strlen(resolver_env) == 0 || + gpr_stricmp(resolver_env, "ares") == 0; } void grpc_resolver_dns_ares_init() { char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - /* TODO(zyc): Turn on c-ares based resolver by default after the address - sorter and the CNAME support are added. */ if (should_use_ares(resolver_env)) { gpr_log(GPR_DEBUG, "Using ares dns resolver"); address_sorting_init(); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index ddd538faa80..5985fa0cbdb 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -205,6 +205,7 @@ grpc_channel* grpc_secure_channel_create(grpc_channel_credentials* creds, grpc_channel_credentials_to_arg(creds)}; grpc_channel_args* new_args = grpc_channel_args_copy_and_add( args, args_to_add, GPR_ARRAY_SIZE(args_to_add)); + new_args = creds->update_arguments(new_args); // Create channel. channel = client_channel_factory_create_channel( &client_channel_factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, diff --git a/src/core/lib/security/credentials/composite/composite_credentials.h b/src/core/lib/security/credentials/composite/composite_credentials.h index 7a1c7d5e42b..0e6e5f9e14f 100644 --- a/src/core/lib/security/credentials/composite/composite_credentials.h +++ b/src/core/lib/security/credentials/composite/composite_credentials.h @@ -49,6 +49,10 @@ class grpc_composite_channel_credentials : public grpc_channel_credentials { const char* target, const grpc_channel_args* args, grpc_channel_args** new_args) override; + grpc_channel_args* update_arguments(grpc_channel_args* args) override { + return inner_creds_->update_arguments(args); + } + const grpc_channel_credentials* inner_creds() const { return inner_creds_.get(); } diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h index 4091ef3dfb5..4fb7ed85e70 100644 --- a/src/core/lib/security/credentials/credentials.h +++ b/src/core/lib/security/credentials/credentials.h @@ -123,6 +123,14 @@ struct grpc_channel_credentials return Ref(); } + // Allows credentials to optionally modify a parent channel's args. + // By default, leave channel args as is. The callee takes ownership + // of the passed-in channel args, and the caller takes ownership + // of the returned channel args. + virtual grpc_channel_args* update_arguments(grpc_channel_args* args) { + return args; + } + const char* type() const { return type_; } GRPC_ABSTRACT_BASE_CLASS diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc index a86a17d5864..a63bd5c0e56 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc @@ -114,6 +114,19 @@ grpc_google_default_channel_credentials::create_security_connector( return sc; } +grpc_channel_args* grpc_google_default_channel_credentials::update_arguments( + grpc_channel_args* args) { + grpc_channel_args* updated = args; + if (grpc_channel_args_find(args, GRPC_ARG_DNS_ENABLE_SRV_QUERIES) == + nullptr) { + grpc_arg new_srv_arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_DNS_ENABLE_SRV_QUERIES), true); + updated = grpc_channel_args_copy_and_add(args, &new_srv_arg, 1); + grpc_channel_args_destroy(args); + } + return updated; +} + static void on_metadata_server_detection_http_response(void* user_data, grpc_error* error) { metadata_server_detector* detector = diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.h b/src/core/lib/security/credentials/google_default/google_default_credentials.h index bf00f7285ad..8a945da31e2 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.h +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.h @@ -58,6 +58,8 @@ class grpc_google_default_channel_credentials const char* target, const grpc_channel_args* args, grpc_channel_args** new_args) override; + grpc_channel_args* update_arguments(grpc_channel_args* args) override; + const grpc_channel_credentials* alts_creds() const { return alts_creds_.get(); } diff --git a/templates/test/cpp/naming/resolver_component_tests_defs.include b/templates/test/cpp/naming/resolver_component_tests_defs.include index b34845e01a3..d38316cbe68 100644 --- a/templates/test/cpp/naming/resolver_component_tests_defs.include +++ b/templates/test/cpp/naming/resolver_component_tests_defs.include @@ -55,7 +55,6 @@ if cur_resolver and cur_resolver != 'ares': 'needs to use GRPC_DNS_RESOLVER=ares.')) test_runner_log('Exit 1 without running tests.') sys.exit(1) -os.environ.update({'GRPC_DNS_RESOLVER': 'ares'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index f426eab9592..6f153cc9bf6 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -75,7 +75,7 @@ int main(int argc, char** argv) { test_succeeds(dns, "dns:www.google.com"); test_succeeds(dns, "dns:///www.google.com"); char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { + if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) { test_fails(dns, "dns://8.8.8.8/8.8.8.8:8888"); } else { test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888"); diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py index da0effed935..aeff927824d 100755 --- a/test/cpp/naming/gen_build_yaml.py +++ b/test/cpp/naming/gen_build_yaml.py @@ -48,6 +48,7 @@ def _resolver_test_cases(resolver_component_data): ('expected_chosen_service_config', (test_case['expected_chosen_service_config'] or '')), ('expected_lb_policy', (test_case['expected_lb_policy'] or '')), + ('enable_srv_queries', test_case['enable_srv_queries']), ], }) return out diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 2ac2c237cea..ff9ebe70a8e 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -91,6 +92,13 @@ DEFINE_string(expected_chosen_service_config, "", DEFINE_string( local_dns_server_address, "", "Optional. This address is placed as the uri authority if present."); +DEFINE_string( + enable_srv_queries, "", + "Whether or not to enable SRV queries for the ares resolver instance." + "It would be better if this arg could be bool, but the way that we " + "generate " + "the python script runner doesn't allow us to pass a gflags bool to this " + "binary."); DEFINE_string(expected_lb_policy, "", "Expected lb policy name that appears in resolver result channel " "arg. Empty for none."); @@ -438,10 +446,26 @@ void RunResolvesRelevantRecordsTest(void (*OnDoneLocked)(void* arg, GPR_ASSERT(gpr_asprintf(&whole_uri, "dns://%s/%s", FLAGS_local_dns_server_address.c_str(), FLAGS_target_name.c_str())); + gpr_log(GPR_DEBUG, "resolver_component_test: --enable_srv_queries: %s", + FLAGS_enable_srv_queries.c_str()); + grpc_channel_args* resolver_args = nullptr; + // By default, SRV queries are disabled, so tests that expect no SRV query + // should avoid setting any channel arg. Test cases that do rely on the SRV + // query must explicitly enable SRV though. + if (FLAGS_enable_srv_queries == "True") { + grpc_arg srv_queries_arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_DNS_ENABLE_SRV_QUERIES), true); + resolver_args = + grpc_channel_args_copy_and_add(nullptr, &srv_queries_arg, 1); + } else if (FLAGS_enable_srv_queries != "False") { + gpr_log(GPR_DEBUG, "Invalid value for --enable_srv_queries."); + abort(); + } // create resolver and resolve grpc_core::OrphanablePtr resolver = - grpc_core::ResolverRegistry::CreateResolver(whole_uri, nullptr, + grpc_core::ResolverRegistry::CreateResolver(whole_uri, resolver_args, args.pollset_set, args.lock); + grpc_channel_args_destroy(resolver_args); gpr_free(whole_uri); grpc_closure on_resolver_result_changed; GRPC_CLOSURE_INIT(&on_resolver_result_changed, OnDoneLocked, (void*)&args, diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index 1873eec35bd..a4438cb100e 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -55,7 +55,6 @@ if cur_resolver and cur_resolver != 'ares': 'needs to use GRPC_DNS_RESOLVER=ares.')) test_runner_log('Exit 1 without running tests.') sys.exit(1) -os.environ.update({'GRPC_DNS_RESOLVER': 'ares'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, @@ -126,6 +125,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '5.5.5.5:443,False', '--expected_chosen_service_config', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -138,6 +138,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '1.2.3.4:1234,True', '--expected_chosen_service_config', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -150,6 +151,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '1.2.3.5:1234,True;1.2.3.6:1234,True;1.2.3.7:1234,True', '--expected_chosen_service_config', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -162,6 +164,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '[2607:f8b0:400a:801::1001]:1234,True', '--expected_chosen_service_config', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -174,6 +177,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1003]:1234,True;[2607:f8b0:400a:801::1004]:1234,True', '--expected_chosen_service_config', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -186,6 +190,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '1.2.3.4:1234,True', '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}', '--expected_lb_policy', 'round_robin', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -198,6 +203,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '1.2.3.4:443,False', '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}', '--expected_lb_policy', 'round_robin', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -210,6 +216,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '1.2.3.4:443,False', '--expected_chosen_service_config', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -222,6 +229,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '1.2.3.4:443,False', '--expected_chosen_service_config', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -234,6 +242,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '1.2.3.4:443,False', '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}', '--expected_lb_policy', 'round_robin', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -246,6 +255,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '1.2.3.4:443,False', '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}', '--expected_lb_policy', 'round_robin', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -258,6 +268,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '1.2.3.4:1234,True;1.2.3.4:443,False', '--expected_chosen_service_config', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -270,6 +281,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False', '--expected_chosen_service_config', '', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -282,6 +294,72 @@ current_test_subprocess = subprocess.Popen([ '--expected_addrs', '1.2.3.4:443,False', '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}', '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv4-single-target-srv-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-single-target-srv-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '2.3.4.5:443,False', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'False', + '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv4-multi-target-srv-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-multi-target-srv-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '9.2.3.5:443,False;9.2.3.6:443,False;9.2.3.7:443,False', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'False', + '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv6-single-target-srv-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv6-single-target-srv-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '[2600::1001]:443,False', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'False', + '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv6-multi-target-srv-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv6-multi-target-srv-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '[2600::1002]:443,False;[2600::1003]:443,False;[2600::1004]:443,False', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'False', + '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv4-simple-service-config-srv-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-simple-service-config-srv-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '5.5.3.4:443,False', + '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}', + '--expected_lb_policy', 'round_robin', + '--enable_srv_queries', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: diff --git a/test/cpp/naming/resolver_test_record_groups.yaml b/test/cpp/naming/resolver_test_record_groups.yaml index 3c51a00c7b1..3d8811a36f7 100644 --- a/test/cpp/naming/resolver_test_record_groups.yaml +++ b/test/cpp/naming/resolver_test_record_groups.yaml @@ -1,9 +1,11 @@ resolver_tests_common_zone_name: resolver-tests-version-4.grpctestingexp. resolver_component_tests: +# Tests for which we enable SRV queries - expected_addrs: - {address: '5.5.5.5:443', is_balancer: false} expected_chosen_service_config: null expected_lb_policy: null + enable_srv_queries: true record_to_resolve: no-srv-ipv4-single-target records: no-srv-ipv4-single-target: @@ -12,6 +14,7 @@ resolver_component_tests: - {address: '1.2.3.4:1234', is_balancer: true} expected_chosen_service_config: null expected_lb_policy: null + enable_srv_queries: true record_to_resolve: srv-ipv4-single-target records: _grpclb._tcp.srv-ipv4-single-target: @@ -24,6 +27,7 @@ resolver_component_tests: - {address: '1.2.3.7:1234', is_balancer: true} expected_chosen_service_config: null expected_lb_policy: null + enable_srv_queries: true record_to_resolve: srv-ipv4-multi-target records: _grpclb._tcp.srv-ipv4-multi-target: @@ -36,6 +40,7 @@ resolver_component_tests: - {address: '[2607:f8b0:400a:801::1001]:1234', is_balancer: true} expected_chosen_service_config: null expected_lb_policy: null + enable_srv_queries: true record_to_resolve: srv-ipv6-single-target records: _grpclb._tcp.srv-ipv6-single-target: @@ -48,6 +53,7 @@ resolver_component_tests: - {address: '[2607:f8b0:400a:801::1004]:1234', is_balancer: true} expected_chosen_service_config: null expected_lb_policy: null + enable_srv_queries: true record_to_resolve: srv-ipv6-multi-target records: _grpclb._tcp.srv-ipv6-multi-target: @@ -60,6 +66,7 @@ resolver_component_tests: - {address: '1.2.3.4:1234', is_balancer: true} expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}' expected_lb_policy: round_robin + enable_srv_queries: true record_to_resolve: srv-ipv4-simple-service-config records: _grpclb._tcp.srv-ipv4-simple-service-config: @@ -73,6 +80,7 @@ resolver_component_tests: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}' expected_lb_policy: round_robin + enable_srv_queries: true record_to_resolve: ipv4-no-srv-simple-service-config records: ipv4-no-srv-simple-service-config: @@ -84,6 +92,7 @@ resolver_component_tests: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: null expected_lb_policy: null + enable_srv_queries: true record_to_resolve: ipv4-no-config-for-cpp records: ipv4-no-config-for-cpp: @@ -95,6 +104,7 @@ resolver_component_tests: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: null expected_lb_policy: null + enable_srv_queries: true record_to_resolve: ipv4-cpp-config-has-zero-percentage records: ipv4-cpp-config-has-zero-percentage: @@ -106,6 +116,7 @@ resolver_component_tests: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}' expected_lb_policy: round_robin + enable_srv_queries: true record_to_resolve: ipv4-second-language-is-cpp records: ipv4-second-language-is-cpp: @@ -117,6 +128,7 @@ resolver_component_tests: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}' expected_lb_policy: round_robin + enable_srv_queries: true record_to_resolve: ipv4-config-with-percentages records: ipv4-config-with-percentages: @@ -129,6 +141,7 @@ resolver_component_tests: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: null expected_lb_policy: null + enable_srv_queries: true record_to_resolve: srv-ipv4-target-has-backend-and-balancer records: _grpclb._tcp.srv-ipv4-target-has-backend-and-balancer: @@ -142,6 +155,7 @@ resolver_component_tests: - {address: '[2607:f8b0:400a:801::1002]:443', is_balancer: false} expected_chosen_service_config: null expected_lb_policy: null + enable_srv_queries: true record_to_resolve: srv-ipv6-target-has-backend-and-balancer records: _grpclb._tcp.srv-ipv6-target-has-backend-and-balancer: @@ -154,6 +168,7 @@ resolver_component_tests: - {address: '1.2.3.4:443', is_balancer: false} expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}' expected_lb_policy: null + enable_srv_queries: true record_to_resolve: ipv4-config-causing-fallback-to-tcp records: ipv4-config-causing-fallback-to-tcp: @@ -161,3 +176,84 @@ resolver_component_tests: _grpc_config.ipv4-config-causing-fallback-to-tcp: - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}}]', type: TXT} +# Tests for which we don't enable SRV queries +- expected_addrs: + - {address: '2.3.4.5:443', is_balancer: false} + expected_chosen_service_config: null + expected_lb_policy: null + enable_srv_queries: false + record_to_resolve: srv-ipv4-single-target-srv-disabled + records: + _grpclb._tcp.srv-ipv4-single-target-srv-disabled: + - {TTL: '2100', data: 0 0 1234 ipv4-single-target-srv-disabled, type: SRV} + ipv4-single-target-srv-disabled: + - {TTL: '2100', data: 1.2.3.4, type: A} + srv-ipv4-single-target-srv-disabled: + - {TTL: '2100', data: 2.3.4.5, type: A} +- expected_addrs: + - {address: '9.2.3.5:443', is_balancer: false} + - {address: '9.2.3.6:443', is_balancer: false} + - {address: '9.2.3.7:443', is_balancer: false} + expected_chosen_service_config: null + expected_lb_policy: null + enable_srv_queries: false + record_to_resolve: srv-ipv4-multi-target-srv-disabled + records: + _grpclb._tcp.srv-ipv4-multi-target-srv-disabled: + - {TTL: '2100', data: 0 0 1234 ipv4-multi-target-srv-disabled, type: SRV} + ipv4-multi-target-srv-disabled: + - {TTL: '2100', data: 1.2.3.5, type: A} + - {TTL: '2100', data: 1.2.3.6, type: A} + - {TTL: '2100', data: 1.2.3.7, type: A} + srv-ipv4-multi-target-srv-disabled: + - {TTL: '2100', data: 9.2.3.5, type: A} + - {TTL: '2100', data: 9.2.3.6, type: A} + - {TTL: '2100', data: 9.2.3.7, type: A} +- expected_addrs: + - {address: '[2600::1001]:443', is_balancer: false} + expected_chosen_service_config: null + expected_lb_policy: null + enable_srv_queries: false + record_to_resolve: srv-ipv6-single-target-srv-disabled + records: + _grpclb._tcp.srv-ipv6-single-target-srv-disabled: + - {TTL: '2100', data: 0 0 1234 ipv6-single-target-srv-disabled, type: SRV} + ipv6-single-target-srv-disabled: + - {TTL: '2100', data: '2607:f8b0:400a:801::1001', type: AAAA} + srv-ipv6-single-target-srv-disabled: + - {TTL: '2100', data: '2600::1001', type: AAAA} +- expected_addrs: + - {address: '[2600::1002]:443', is_balancer: false} + - {address: '[2600::1003]:443', is_balancer: false} + - {address: '[2600::1004]:443', is_balancer: false} + expected_chosen_service_config: null + expected_lb_policy: null + enable_srv_queries: false + record_to_resolve: srv-ipv6-multi-target-srv-disabled + records: + _grpclb._tcp.srv-ipv6-multi-target-srv-disabled: + - {TTL: '2100', data: 0 0 1234 ipv6-multi-target-srv-disabled, type: SRV} + ipv6-multi-target-srv-disabled: + - {TTL: '2100', data: '2607:f8b0:400a:801::1002', type: AAAA} + - {TTL: '2100', data: '2607:f8b0:400a:801::1003', type: AAAA} + - {TTL: '2100', data: '2607:f8b0:400a:801::1004', type: AAAA} + srv-ipv6-multi-target-srv-disabled: + - {TTL: '2100', data: '2600::1002', type: AAAA} + - {TTL: '2100', data: '2600::1003', type: AAAA} + - {TTL: '2100', data: '2600::1004', type: AAAA} +- expected_addrs: + - {address: '5.5.3.4:443', is_balancer: false} + expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}' + expected_lb_policy: round_robin + enable_srv_queries: false + record_to_resolve: srv-ipv4-simple-service-config-srv-disabled + records: + _grpclb._tcp.srv-ipv4-simple-service-config-srv-disabled: + - {TTL: '2100', data: 0 0 1234 ipv4-simple-service-config-srv-disabled, type: SRV} + ipv4-simple-service-config-srv-disabled: + - {TTL: '2100', data: 1.2.3.4, type: A} + srv-ipv4-simple-service-config-srv-disabled: + - {TTL: '2100', data: 5.5.3.4, type: A} + _grpc_config.srv-ipv4-simple-service-config-srv-disabled: + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}}]', + type: TXT} From 789870a00bd358f84ac65dd63a630d6d42f84d31 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Sat, 19 Jan 2019 12:39:11 -0800 Subject: [PATCH 119/814] Reviewer comments --- src/core/lib/gprpp/optional.h | 2 ++ src/core/lib/iomgr/buffer_list.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index 593ef08c317..e517c6edccc 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -36,6 +36,8 @@ class Optional { void reset() { set_ = false; } T value() { return value_; } + + private: T value_; bool set_ = false; }; diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index fd310fabe51..215ab03a563 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -36,7 +36,7 @@ struct ConnectionMetrics { /* Delivery rate in Bytes/s. */ Optional delivery_rate; /* If the delivery rate is limited by the application, this is set to true. */ - Optional is_delivery_rate_app_limited; + Optional is_delivery_rate_app_limited; /* Total packets retransmitted. */ Optional packet_retx; /* Total packets retransmitted spuriously. This metric is smaller than or From eb40dafe41f23ec0ceab0d7879612c521cd6d49c Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sun, 20 Jan 2019 22:43:32 -0500 Subject: [PATCH 120/814] Cache the default mdelem for client authority. We create a mdelem based on the default authority value for every call in `authority_start_transport_stream_op_batch()`. Since the key and value are identical for all calls on channels of a given process, they all map to the same shard of interned mdelem, creating a signficant contention on the mutex of that shard. This is observable in the profiles we have 1000s of connections between two hosts, exchanging a high rate of RPCs. Instead create the default mdelem and cache it in channel_data. Simply ref this mdelem in `authority_start_transport_stream_op_batch()`. This commit eliminates a signficant contention (2s in a 30s profile) on client side. --- src/core/ext/filters/http/client_authority_filter.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc index 6383f125944..125059c93a9 100644 --- a/src/core/ext/filters/http/client_authority_filter.cc +++ b/src/core/ext/filters/http/client_authority_filter.cc @@ -45,6 +45,7 @@ struct call_data { struct channel_data { grpc_slice default_authority; + grpc_mdelem default_authority_mdelem; }; void authority_start_transport_stream_op_batch( @@ -59,8 +60,7 @@ void authority_start_transport_stream_op_batch( initial_metadata->idx.named.authority == nullptr) { grpc_error* error = grpc_metadata_batch_add_head( initial_metadata, &calld->authority_storage, - grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, chand->default_authority, - nullptr)); + GRPC_MDELEM_REF(chand->default_authority_mdelem)); if (error != GRPC_ERROR_NONE) { grpc_transport_stream_op_batch_finish_with_failure(batch, error, calld->call_combiner); @@ -103,6 +103,8 @@ grpc_error* init_channel_elem(grpc_channel_element* elem, } chand->default_authority = grpc_slice_intern(grpc_slice_from_static_string(default_authority_str)); + chand->default_authority_mdelem = grpc_mdelem_create( + GRPC_MDSTR_AUTHORITY, chand->default_authority, nullptr); GPR_ASSERT(!args->is_last); return GRPC_ERROR_NONE; } @@ -111,6 +113,7 @@ grpc_error* init_channel_elem(grpc_channel_element* elem, void destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); grpc_slice_unref_internal(chand->default_authority); + GRPC_MDELEM_UNREF(chand->default_authority_mdelem); } } // namespace From f019339cecd3b6b3972d6aa31d47e7f8d23ab89e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 21 Jan 2019 14:42:23 +0100 Subject: [PATCH 121/814] improve ContextPropagationToken doc comment --- src/csharp/Grpc.Core/ContextPropagationToken.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core/ContextPropagationToken.cs b/src/csharp/Grpc.Core/ContextPropagationToken.cs index d0c3f0cd1d3..60e407dc781 100644 --- a/src/csharp/Grpc.Core/ContextPropagationToken.cs +++ b/src/csharp/Grpc.Core/ContextPropagationToken.cs @@ -23,8 +23,8 @@ namespace Grpc.Core /// In situations when a backend is making calls to another backend, /// it makes sense to propagate properties like deadline and cancellation /// token of the server call to the child call. - /// The gRPC native layer provides some other contexts (like tracing context) that - /// are not accessible to explicitly C# layer, but this token still allows propagating them. + /// Underlying gRPC implementation may provide other "opaque" contexts (like tracing context) that + /// are not explicitly accesible via the public C# API, but this token still allows propagating them. /// public abstract class ContextPropagationToken { From 50854e952122176a241c708a28b412a3ceefc0f6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 21 Jan 2019 14:51:30 +0100 Subject: [PATCH 122/814] remove unsubstantiated TODO --- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 1 - src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index e2a018e871b..f80ac4a2f9d 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -499,7 +499,6 @@ namespace Grpc.Core.Internal var credentials = details.Options.Credentials; using (var nativeCredentials = credentials != null ? credentials.ToNativeCredentials() : null) { - // TODO(jtattermusch): is the "DefaultMask" correct here?? var result = details.Channel.Handle.CreateCall( parentCall, ContextPropagationTokenImpl.DefaultMask, cq, details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value), nativeCredentials); diff --git a/src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs b/src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs index 1fd994e607c..e2528e84cff 100644 --- a/src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs +++ b/src/csharp/Grpc.Core/Internal/ContextPropagationTokenImpl.cs @@ -39,7 +39,8 @@ namespace Grpc.Core.Internal /// /// Default propagation mask used by C# - we want to propagate deadline - /// and cancellation token by our own means. + /// and cancellation token by our own means, everything else will be propagated + /// by C core automatically (according to DefaultCoreMask). /// internal const ContextPropagationFlags DefaultMask = DefaultCoreMask & ~ContextPropagationFlags.Deadline & ~ContextPropagationFlags.Cancellation; From b273ffb609908f5a7a2e3aa2feb2cd446a2fbdc6 Mon Sep 17 00:00:00 2001 From: Jerry Date: Mon, 21 Jan 2019 11:55:47 -0800 Subject: [PATCH 123/814] create a valgrind.include, and include it in php and php7 docker images --- .../dockerfile/test/php7_jessie_x64/Dockerfile.template | 1 + .../dockerfile/test/php_jessie_x64/Dockerfile.template | 1 + templates/tools/dockerfile/valgrind.include | 8 ++++++++ tools/dockerfile/test/php7_jessie_x64/Dockerfile | 8 ++++++++ tools/dockerfile/test/php_jessie_x64/Dockerfile | 8 ++++++++ 5 files changed, 26 insertions(+) create mode 100644 templates/tools/dockerfile/valgrind.include diff --git a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template index e7b6c0d5f9c..f6f52805b8c 100644 --- a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template @@ -19,6 +19,7 @@ <%include file="../../php7_deps.include"/> <%include file="../../gcp_api_libraries.include"/> <%include file="../../python_deps.include"/> + <%include file="../../valgrind.include"/> <%include file="../../run_tests_addons.include"/> # Define the default command. CMD ["bash"] diff --git a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template index fdbad53c391..1a07522c011 100644 --- a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template @@ -20,6 +20,7 @@ <%include file="../../gcp_api_libraries.include"/> <%include file="../../python_deps.include"/> <%include file="../../php_deps.include"/> + <%include file="../../valgrind.include"/> <%include file="../../run_tests_addons.include"/> # Define the default command. CMD ["bash"] diff --git a/templates/tools/dockerfile/valgrind.include b/templates/tools/dockerfile/valgrind.include new file mode 100644 index 00000000000..d86cc7158bf --- /dev/null +++ b/templates/tools/dockerfile/valgrind.include @@ -0,0 +1,8 @@ +#================= +# PHP dependencies + +# Install dependencies + +RUN apt-get update && apt-get install -y ${'\\'} + valgrind + \ No newline at end of file diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile index 0dff8399047..e4daf169285 100644 --- a/tools/dockerfile/test/php7_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile @@ -79,6 +79,14 @@ RUN pip install --upgrade pip==10.0.1 RUN pip install virtualenv RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 +#================= +# PHP dependencies + +# Install dependencies + +RUN apt-get update && apt-get install -y \ + valgrind + RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile index ed59e569956..8698deec835 100644 --- a/tools/dockerfile/test/php_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php_jessie_x64/Dockerfile @@ -76,6 +76,14 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t RUN apt-get update && apt-get install -y \ git php5 php5-dev phpunit unzip +#================= +# PHP dependencies + +# Install dependencies + +RUN apt-get update && apt-get install -y \ + valgrind + RUN mkdir /var/local/jenkins From 412bba83548a7bf11d4822eb355c26f8b27a020f Mon Sep 17 00:00:00 2001 From: Jerry Date: Mon, 21 Jan 2019 11:59:39 -0800 Subject: [PATCH 124/814] changed comment in valgrind.include --- templates/tools/dockerfile/valgrind.include | 3 +-- tools/dockerfile/test/php7_jessie_x64/Dockerfile | 4 ++-- tools/dockerfile/test/php_jessie_x64/Dockerfile | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/templates/tools/dockerfile/valgrind.include b/templates/tools/dockerfile/valgrind.include index d86cc7158bf..f1f3b67d826 100644 --- a/templates/tools/dockerfile/valgrind.include +++ b/templates/tools/dockerfile/valgrind.include @@ -1,8 +1,7 @@ #================= -# PHP dependencies +# PHP Test dependencies # Install dependencies RUN apt-get update && apt-get install -y ${'\\'} valgrind - \ No newline at end of file diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile index e4daf169285..529ebb9127b 100644 --- a/tools/dockerfile/test/php7_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile @@ -80,13 +80,13 @@ RUN pip install virtualenv RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 #================= -# PHP dependencies +# PHP Test dependencies # Install dependencies RUN apt-get update && apt-get install -y \ valgrind - + RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile index 8698deec835..f69f7e65a20 100644 --- a/tools/dockerfile/test/php_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php_jessie_x64/Dockerfile @@ -77,13 +77,13 @@ RUN apt-get update && apt-get install -y \ git php5 php5-dev phpunit unzip #================= -# PHP dependencies +# PHP Test dependencies # Install dependencies RUN apt-get update && apt-get install -y \ valgrind - + RUN mkdir /var/local/jenkins From 51ba492d6dcb73bd7a7b6f6cfdd6d29ca42393ce Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 21 Jan 2019 16:26:33 -0800 Subject: [PATCH 125/814] Minimize the change --- .../python/grpcio_tools/grpc_tools/command.py | 114 ++++-------------- 1 file changed, 22 insertions(+), 92 deletions(-) diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/command.py b/tools/distrib/python/grpcio_tools/grpc_tools/command.py index ee311144225..85273a65aea 100644 --- a/tools/distrib/python/grpcio_tools/grpc_tools/command.py +++ b/tools/distrib/python/grpcio_tools/grpc_tools/command.py @@ -21,32 +21,8 @@ import setuptools from grpc_tools import protoc -_WELL_KNOWN_PROTOS_INCLUDE = pkg_resources.resource_filename( - 'grpc_tools', '_proto') - -def _compile_proto(proto_file, - include='', - python_out='', - grpc_python_out='', - strict=False): - command = [ - 'grpc_tools.protoc', - '--proto_path={}'.format(include), - '--proto_path={}'.format(_WELL_KNOWN_PROTOS_INCLUDE), - '--python_out={}'.format(python_out), - '--grpc_python_out={}'.format(grpc_python_out), - ] + [proto_file] - if protoc.main(command) != 0: - if strict: - sys.stderr.write('error: {} failed'.format(command)) - else: - sys.stderr.write('warning: {} failed'.format(command)) - return False - return True - - -def build_package_protos(package_root): +def build_package_protos(package_root, strict_mode=False): proto_files = [] inclusion_root = os.path.abspath(package_root) for root, _, files in os.walk(inclusion_root): @@ -55,59 +31,33 @@ def build_package_protos(package_root): proto_files.append( os.path.abspath(os.path.join(root, filename))) - for proto_file in proto_files: - _compile_proto( - proto_file, - include=inclusion_root, - python_out=inclusion_root, - grpc_python_out=inclusion_root, - strict=False, - ) - - -def build_package_protos_strict(package_root): - proto_files = [] - inclusion_root = os.path.abspath(package_root) - for root, _, files in os.walk(inclusion_root): - for filename in files: - if filename.endswith('.proto'): - proto_files.append( - os.path.abspath(os.path.join(root, filename))) - - tmp_out_directory = tempfile.mkdtemp() - compile_failed = False - for proto_file in proto_files: - # Output all the errors across all the files instead of exiting on the - # first error proto file. - compile_failed |= not _compile_proto( - proto_file, - include=inclusion_root, - python_out=tmp_out_directory, - grpc_python_out=tmp_out_directory, - strict=True, - ) - - if compile_failed: - sys.exit(1) + well_known_protos_include = pkg_resources.resource_filename( + 'grpc_tools', '_proto') for proto_file in proto_files: - _compile_proto( - proto_file, - include=inclusion_root, - python_out=inclusion_root, - grpc_python_out=inclusion_root, - strict=False, - ) + command = [ + 'grpc_tools.protoc', + '--proto_path={}'.format(inclusion_root), + '--proto_path={}'.format(well_known_protos_include), + '--python_out={}'.format(inclusion_root), + '--grpc_python_out={}'.format(inclusion_root), + ] + [proto_file] + if protoc.main(command) != 0: + if strict_mode: + raise Exception('error: {} failed'.format(command)) + else: + sys.stderr.write('warning: {} failed'.format(command)) class BuildPackageProtos(setuptools.Command): """Command to generate project *_pb2.py modules from proto files.""" description = 'build grpc protobuf modules' - user_options = [] + user_options = [('strict-mode', 's', + 'exit with non-zero value if the proto compiling fails.')] def initialize_options(self): - pass + self.strict_mode = False def finalize_options(self): pass @@ -117,27 +67,7 @@ class BuildPackageProtos(setuptools.Command): # directory is provided as an 'include' directory. We assume it's the '' key # to `self.distribution.package_dir` (and get a key error if it's not # there). - build_package_protos(self.distribution.package_dir['']) - - -class BuildPackageProtosStrict(setuptools.Command): - """Command to strictly generate project *_pb2.py modules from proto files. - - The generation will abort if any of the proto files contains error. - """ - - description = 'strictly build grpc protobuf modules' - user_options = [] - - def initialize_options(self): - pass - - def finalize_options(self): - pass - - def run(self): - # due to limitations of the proto generator, we require that only *one* - # directory is provided as an 'include' directory. We assume it's the '' key - # to `self.distribution.package_dir` (and get a key error if it's not - # there). - build_package_protos_strict(self.distribution.package_dir['']) + if self.strict_mode: + self.announce('Building Package Protos in Strict Mode') + build_package_protos(self.distribution.package_dir[''], + self.strict_mode) From 31bce3b12720fc290761d82067795867b6b46b1f Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 21 Jan 2019 16:49:36 -0800 Subject: [PATCH 126/814] Remove redundent lines --- tools/distrib/python/grpcio_tools/grpc_tools/command.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/command.py b/tools/distrib/python/grpcio_tools/grpc_tools/command.py index 85273a65aea..1e556f5fd66 100644 --- a/tools/distrib/python/grpcio_tools/grpc_tools/command.py +++ b/tools/distrib/python/grpcio_tools/grpc_tools/command.py @@ -15,7 +15,6 @@ import os import pkg_resources import sys -import tempfile import setuptools @@ -67,7 +66,5 @@ class BuildPackageProtos(setuptools.Command): # directory is provided as an 'include' directory. We assume it's the '' key # to `self.distribution.package_dir` (and get a key error if it's not # there). - if self.strict_mode: - self.announce('Building Package Protos in Strict Mode') build_package_protos(self.distribution.package_dir[''], self.strict_mode) From 958f4535c435796286432272d7a066a42c3c03a9 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 21 Jan 2019 19:15:35 -0800 Subject: [PATCH 127/814] Fix TSAN issue in filter_status_code test --- test/core/end2end/tests/filter_status_code.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/core/end2end/tests/filter_status_code.cc b/test/core/end2end/tests/filter_status_code.cc index 5ffc3d00a3f..6d85c1b0724 100644 --- a/test/core/end2end/tests/filter_status_code.cc +++ b/test/core/end2end/tests/filter_status_code.cc @@ -260,6 +260,7 @@ typedef struct final_status_data { static void server_start_transport_stream_op_batch( grpc_call_element* elem, grpc_transport_stream_op_batch* op) { auto* data = static_cast(elem->call_data); + gpr_mu_lock(&g_mu); if (data->call == g_server_call_stack) { if (op->send_initial_metadata) { auto* batch = op->payload->send_initial_metadata.send_initial_metadata; @@ -270,6 +271,7 @@ static void server_start_transport_stream_op_batch( } } } + gpr_mu_unlock(&g_mu); grpc_call_next_op(elem, op); } From bf8777dc307e2938a7d7e02ff761580b9917f529 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 21 Jan 2019 19:57:52 -0800 Subject: [PATCH 128/814] Add const qualifiers to member methods in Optional --- src/core/lib/gprpp/optional.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index e517c6edccc..a8e3ce1505e 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -31,11 +31,11 @@ class Optional { set_ = true; } - bool has_value() { return set_; } + bool has_value() const { return set_; } void reset() { set_ = false; } - T value() { return value_; } + T value() const { return value_; } private: T value_; From 3a51b54b0923610bb8cce76c65a54db763f2aa79 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 21 Jan 2019 20:08:45 -0800 Subject: [PATCH 129/814] Add namespace qualifier to scm_timestamping --- src/core/lib/iomgr/tcp_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 02478f40657..e0b999ecea9 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -714,7 +714,7 @@ static void process_errors(grpc_tcp* tcp) { // Allocate aligned space for cmsgs received along with a timestamps union { - char rbuf[CMSG_SPACE(sizeof(scm_timestamping)) + + char rbuf[CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in)) + CMSG_SPACE(16 * NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t)))]; struct cmsghdr align; From f7c165627147773e6a07bd80d108bbdc6ac0161d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 22 Jan 2019 11:25:58 +0100 Subject: [PATCH 130/814] interop_matrix: integrate testcases file to release info --- tools/interop_matrix/client_matrix.py | 131 +++++++----------- .../run_interop_matrix_tests.py | 24 ++-- tools/interop_matrix/testcases/csharp__v1.3.9 | 20 +++ .../testcases/csharpcoreclr__v1.3.9 | 20 +++ .../interop_matrix/testcases/python__v1.11.1 | 20 +++ 5 files changed, 124 insertions(+), 91 deletions(-) create mode 100644 tools/interop_matrix/testcases/csharp__v1.3.9 create mode 100644 tools/interop_matrix/testcases/csharpcoreclr__v1.3.9 create mode 100755 tools/interop_matrix/testcases/python__v1.11.1 diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 07f144d8250..dba10c7e7fd 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -74,7 +74,7 @@ class ReleaseInfo: def __init__(self, patch=[], runtime_subset=[], testcases_file=None): self.patch = patch self.runtime_subset = runtime_subset - self.testcases_file = None + self.testcases_file = testcases_file # Dictionary of known releases for given language. @@ -145,33 +145,33 @@ LANG_RELEASE_MATRIX = { ]), 'python': OrderedDict([ - ('v1.0.x', ReleaseInfo()), - ('v1.1.4', ReleaseInfo()), - ('v1.2.5', ReleaseInfo()), - ('v1.3.9', ReleaseInfo()), - ('v1.4.2', ReleaseInfo()), - ('v1.6.6', ReleaseInfo()), - ('v1.7.2', ReleaseInfo()), - ('v1.8.1', ReleaseInfo()), - ('v1.9.1', ReleaseInfo()), - ('v1.10.1', ReleaseInfo()), - ('v1.11.1', ReleaseInfo()), - ('v1.12.0', ReleaseInfo()), - ('v1.13.0', ReleaseInfo()), - ('v1.14.1', ReleaseInfo()), - ('v1.15.0', ReleaseInfo()), - ('v1.16.0', ReleaseInfo()), - ('v1.17.1', ReleaseInfo()), + ('v1.0.x', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.1.4', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.2.5', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.3.9', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.4.2', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.6.6', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.7.2', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.8.1', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.9.1', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.10.1', ReleaseInfo(testcases_file='python__v1.0.x')), + ('v1.11.1', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.12.0', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.13.0', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.14.1', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.15.0', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.16.0', ReleaseInfo(testcases_file='python__v1.11.1')), + ('v1.17.1', ReleaseInfo(testcases_file='python__v1.11.1')), ('v1.18.0', ReleaseInfo()), ]), 'node': OrderedDict([ - ('v1.0.1', ReleaseInfo()), - ('v1.1.4', ReleaseInfo()), - ('v1.2.5', ReleaseInfo()), - ('v1.3.9', ReleaseInfo()), - ('v1.4.2', ReleaseInfo()), - ('v1.6.6', ReleaseInfo()), + ('v1.0.1', ReleaseInfo(testcases_file='node__v1.0.1')), + ('v1.1.4', ReleaseInfo(testcases_file='node__v1.1.4')), + ('v1.2.5', ReleaseInfo(testcases_file='node__v1.1.4')), + ('v1.3.9', ReleaseInfo(testcases_file='node__v1.1.4')), + ('v1.4.2', ReleaseInfo(testcases_file='node__v1.1.4')), + ('v1.6.6', ReleaseInfo(testcases_file='node__v1.1.4')), # TODO: https://github.com/grpc/grpc-node/issues/235. # ('v1.7.2', ReleaseInfo()), ('v1.8.4', ReleaseInfo()), @@ -183,10 +183,12 @@ LANG_RELEASE_MATRIX = { 'ruby': OrderedDict([ ('v1.0.1', - ReleaseInfo(patch=[ - 'tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile', - 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', - ])), + ReleaseInfo( + patch=[ + 'tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile', + 'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh', + ], + testcases_file='ruby__v1.0.1')), ('v1.1.4', ReleaseInfo()), ('v1.2.5', ReleaseInfo()), ('v1.3.9', ReleaseInfo()), @@ -232,57 +234,28 @@ LANG_RELEASE_MATRIX = { 'csharp': OrderedDict([ ('v1.0.1', - ReleaseInfo(patch=[ - 'tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile', - 'tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile', - ])), - ('v1.1.4', ReleaseInfo()), - ('v1.2.5', ReleaseInfo()), - ('v1.3.9', ReleaseInfo()), - ('v1.4.2', ReleaseInfo()), - ('v1.6.6', ReleaseInfo()), - ('v1.7.2', ReleaseInfo()), - ('v1.8.0', ReleaseInfo()), - ('v1.9.1', ReleaseInfo()), - ('v1.10.1', ReleaseInfo()), - ('v1.11.1', ReleaseInfo()), - ('v1.12.0', ReleaseInfo()), - ('v1.13.0', ReleaseInfo()), - ('v1.14.1', ReleaseInfo()), - ('v1.15.0', ReleaseInfo()), - ('v1.16.0', ReleaseInfo()), - ('v1.17.1', ReleaseInfo()), + ReleaseInfo( + patch=[ + 'tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile', + 'tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile', + ], + testcases_file='csharp__v1.1.4')), + ('v1.1.4', ReleaseInfo(testcases_file='csharp__v1.1.4')), + ('v1.2.5', ReleaseInfo(testcases_file='csharp__v1.1.4')), + ('v1.3.9', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.4.2', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.6.6', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.7.2', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.8.0', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.9.1', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.10.1', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.11.1', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.12.0', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.13.0', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.14.1', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.15.0', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.16.0', ReleaseInfo(testcases_file='csharp__v1.3.9')), + ('v1.17.1', ReleaseInfo(testcases_file='csharp__v1.3.9')), ('v1.18.0', ReleaseInfo()), ]), } - -# This matrix lists the version of testcases to use for a release. As new -# releases come out, some older docker commands for running tests need to be -# changed, hence the need for specifying which commands to use for a -# particular version in some cases. If not specified, xxx__master file will be -# used. For example, all java versions will run the commands in java__master. -# The testcases files exist under the testcases directory. -# TODO(jtattermusch): make this data part of LANG_RELEASE_MATRIX, -# there is no reason for this to be a separate data structure. -TESTCASES_VERSION_MATRIX = { - 'node_v1.0.1': 'node__v1.0.1', - 'node_v1.1.4': 'node__v1.1.4', - 'node_v1.2.5': 'node__v1.1.4', - 'node_v1.3.9': 'node__v1.1.4', - 'node_v1.4.2': 'node__v1.1.4', - 'node_v1.6.6': 'node__v1.1.4', - 'ruby_v1.0.1': 'ruby__v1.0.1', - 'csharp_v1.0.1': 'csharp__v1.1.4', - 'csharp_v1.1.4': 'csharp__v1.1.4', - 'csharp_v1.2.5': 'csharp__v1.1.4', - 'python_v1.0.x': 'python__v1.0.x', - 'python_v1.1.4': 'python__v1.0.x', - 'python_v1.2.5': 'python__v1.0.x', - 'python_v1.3.9': 'python__v1.0.x', - 'python_v1.4.2': 'python__v1.0.x', - 'python_v1.6.6': 'python__v1.0.x', - 'python_v1.7.2': 'python__v1.0.x', - 'python_v1.8.1': 'python__v1.0.x', - 'python_v1.9.1': 'python__v1.0.x', - 'python_v1.10.1': 'python__v1.0.x', -} diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index c855de3b1e8..d1d68ebed37 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -128,23 +128,23 @@ def _get_test_images_for_lang(lang, release_arg, image_path_prefix): def _read_test_cases_file(lang, runtime, release): """Read test cases from a bash-like file and return a list of commands""" - testcase_dir = os.path.join(os.path.dirname(__file__), 'testcases') - filename_prefix = lang - if lang == 'csharp': - # TODO(jtattermusch): remove this odd specialcase - filename_prefix = runtime # Check to see if we need to use a particular version of test cases. - lang_version = '%s_%s' % (filename_prefix, release) - if lang_version in client_matrix.TESTCASES_VERSION_MATRIX: - testcase_file = os.path.join( - testcase_dir, client_matrix.TESTCASES_VERSION_MATRIX[lang_version]) + release_info = client_matrix.LANG_RELEASE_MATRIX[lang].get(release) + if release_info: + testcases_file = release_info.testcases_files else: # TODO(jtattermusch): remove the double-underscore, it is pointless - testcase_file = os.path.join(testcase_dir, - '%s__master' % filename_prefix) + testcases_file = '%s__master' % lang + # For csharp, the testcases file used depends on the runtime + # TODO(jtattermusch): remove this odd specialcase + if lang == 'csharp' and runtime == 'csharpcoreclr': + testcases_file.replace('csharp_', 'csharpcoreclr_') + + testcases_filepath = os.path.join( + os.path.dirname(__file__), 'testcases', testcases_file) lines = [] - with open(testcase_file) as f: + with open(testcases_filepath) as f: for line in f.readlines(): line = re.sub('\\#.*$', '', line) # remove hash comments line = line.strip() diff --git a/tools/interop_matrix/testcases/csharp__v1.3.9 b/tools/interop_matrix/testcases/csharp__v1.3.9 new file mode 100644 index 00000000000..c3cd6a48f88 --- /dev/null +++ b/tools/interop_matrix/testcases/csharp__v1.3.9 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_csharp:a95229ca-d387-4127-ad48-69a7464e23b8}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" diff --git a/tools/interop_matrix/testcases/csharpcoreclr__v1.3.9 b/tools/interop_matrix/testcases/csharpcoreclr__v1.3.9 new file mode 100644 index 00000000000..aa8b9dd86d1 --- /dev/null +++ b/tools/interop_matrix/testcases/csharpcoreclr__v1.3.9 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:c7fbed09-e4c1-4aab-8dd9-1285b2c9598e}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" diff --git a/tools/interop_matrix/testcases/python__v1.11.1 b/tools/interop_matrix/testcases/python__v1.11.1 new file mode 100755 index 00000000000..467e41ff82f --- /dev/null +++ b/tools/interop_matrix/testcases/python__v1.11.1 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_python:797ca293-94e8-48d4-92e9-a4d52fcfcca9}" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server\"" From 0e1a2550d15c7591a6380f2ef2aef317c589f2ea Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 22 Jan 2019 11:26:32 +0100 Subject: [PATCH 131/814] generate new testcases for C# --- tools/interop_matrix/testcases/csharp__master | 40 ++++++++++--------- .../testcases/csharpcoreclr__master | 40 ++++++++++--------- 2 files changed, 42 insertions(+), 38 deletions(-) mode change 100644 => 100755 tools/interop_matrix/testcases/csharp__master mode change 100644 => 100755 tools/interop_matrix/testcases/csharpcoreclr__master diff --git a/tools/interop_matrix/testcases/csharp__master b/tools/interop_matrix/testcases/csharp__master old mode 100644 new mode 100755 index c3cd6a48f88..9f1cd05b177 --- a/tools/interop_matrix/testcases/csharp__master +++ b/tools/interop_matrix/testcases/csharp__master @@ -1,20 +1,22 @@ #!/bin/bash -echo "Testing ${docker_image:=grpc_interop_csharp:a95229ca-d387-4127-ad48-69a7464e23b8}" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_csharp:71b05977-476b-4e57-9752-dd211c9e3741}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45 --net=host $docker_image bash -c "mono Grpc.IntegrationTesting.Client.exe --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" diff --git a/tools/interop_matrix/testcases/csharpcoreclr__master b/tools/interop_matrix/testcases/csharpcoreclr__master old mode 100644 new mode 100755 index aa8b9dd86d1..3ca145e4c11 --- a/tools/interop_matrix/testcases/csharpcoreclr__master +++ b/tools/interop_matrix/testcases/csharpcoreclr__master @@ -1,20 +1,22 @@ #!/bin/bash -echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:c7fbed09-e4c1-4aab-8dd9-1285b2c9598e}" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:bae17a7e-5450-4781-8982-e82cb89db6dd}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true" From 23e9dcd5de2eea96630eda9dc1edf8f3557bccb1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 22 Jan 2019 12:09:31 +0100 Subject: [PATCH 132/814] add csharpcoreclr__v1.1.4 --- .../testcases/csharpcoreclr__v1.1.4 | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tools/interop_matrix/testcases/csharpcoreclr__v1.1.4 diff --git a/tools/interop_matrix/testcases/csharpcoreclr__v1.1.4 b/tools/interop_matrix/testcases/csharpcoreclr__v1.1.4 new file mode 100644 index 00000000000..aa8b9dd86d1 --- /dev/null +++ b/tools/interop_matrix/testcases/csharpcoreclr__v1.1.4 @@ -0,0 +1,20 @@ +#!/bin/bash +echo "Testing ${docker_image:=grpc_interop_csharpcoreclr:c7fbed09-e4c1-4aab-8dd9-1285b2c9598e}" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0 --net=host $docker_image bash -c "dotnet exec Grpc.IntegrationTesting.Client.dll --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" From fcf0a4dd0c9025f94c9e36f65b3c804e4b10acc2 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 22 Jan 2019 13:56:20 +0100 Subject: [PATCH 133/814] cleanup: get rid of IP literals from node__v1.1.4 testcases --- tools/interop_matrix/testcases/node__v1.1.4 | 36 ++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tools/interop_matrix/testcases/node__v1.1.4 b/tools/interop_matrix/testcases/node__v1.1.4 index 99ea2f0bc47..9e31fbf97dc 100644 --- a/tools/interop_matrix/testcases/node__v1.1.4 +++ b/tools/interop_matrix/testcases/node__v1.1.4 @@ -1,20 +1,20 @@ #!/bin/bash echo "Testing ${docker_image:=grpc_interop_node:1415ecbf-5d0f-423e-8c2c-e0cb6d154e73}" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host $docker_image bash -c "tools/run_tests/interop/with_nvm.sh node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" From f489b9b035dae644862b4ca0c3f3d8069e9bdc6a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 22 Jan 2019 18:25:23 +0100 Subject: [PATCH 134/814] interop_matrix: update python testcases for 1.18.0 --- tools/interop_matrix/testcases/python__master | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/tools/interop_matrix/testcases/python__master b/tools/interop_matrix/testcases/python__master index 467e41ff82f..39e160188c7 100755 --- a/tools/interop_matrix/testcases/python__master +++ b/tools/interop_matrix/testcases/python__master @@ -1,20 +1,22 @@ #!/bin/bash -echo "Testing ${docker_image:=grpc_interop_python:797ca293-94e8-48d4-92e9-a4d52fcfcca9}" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response\"" -docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py27_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server\"" +# DO NOT MODIFY +# This file is generated by run_interop_tests.py/create_testcases.sh +echo "Testing ${docker_image:=grpc_interop_python:4fa5bb4b-5d57-4882-8c8e-551fb899b86a}" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true\"" +docker run -i --rm=true -e PYTHONPATH=/var/local/git/grpc/src/python/gens -e LD_LIBRARY_PATH=/var/local/git/grpc/libs/opt -w /var/local/git/grpc --net=host $docker_image bash -c "py37_native/bin/python src/python/grpcio_tests/setup.py run_interop --client --args=\"--server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true\"" From fa575fe6b8fa2c00954ba4ab656a1e27d463249c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 22 Jan 2019 18:26:12 +0100 Subject: [PATCH 135/814] run_interop_matrix_tests.py fixes --- .../run_interop_matrix_tests.py | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index d1d68ebed37..de054e5d878 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -131,15 +131,15 @@ def _read_test_cases_file(lang, runtime, release): # Check to see if we need to use a particular version of test cases. release_info = client_matrix.LANG_RELEASE_MATRIX[lang].get(release) if release_info: - testcases_file = release_info.testcases_files - else: + testcases_file = release_info.testcases_file + if not testcases_file: # TODO(jtattermusch): remove the double-underscore, it is pointless testcases_file = '%s__master' % lang # For csharp, the testcases file used depends on the runtime # TODO(jtattermusch): remove this odd specialcase if lang == 'csharp' and runtime == 'csharpcoreclr': - testcases_file.replace('csharp_', 'csharpcoreclr_') + testcases_file = testcases_file.replace('csharp_', 'csharpcoreclr_') testcases_filepath = os.path.join( os.path.dirname(__file__), 'testcases', testcases_file) @@ -171,25 +171,35 @@ def _generate_test_case_jobspecs(lang, runtime, release, suite_name): for line in testcase_lines: # TODO(jtattermusch): revisit the logic for updating test case commands # what it currently being done seems fragile. - m = re.search('--test_case=(.*)"', line) - shortname = m.group(1) if m else 'unknown_test' - m = re.search('--server_host_override=(.*).sandbox.googleapis.com', - line) - server = m.group(1) if m else 'unknown_server' - # If server_host arg is not None, replace the original - # server_host with the one provided or append to the end of - # the command if server_host does not appear originally. - if args.server_host: - if line.find('--server_host=') > -1: - line = re.sub('--server_host=[^ ]*', - '--server_host=%s' % args.server_host, line) - else: - line = '%s --server_host=%s"' % (line[:-1], args.server_host) + # Extract test case name from the command line + m = re.search(r'--test_case=(\w+)', line) + testcase_name = m.group(1) if m else 'unknown_test' + + # Extract the server name from the command line + if '--server_host_override=' in line: + m = re.search( + r'--server_host_override=((.*).sandbox.googleapis.com)', line) + else: + m = re.search(r'--server_host=((.*).sandbox.googleapis.com)', line) + server = m.group(1) if m else 'unknown_server' + server_short = m.group(2) if m else 'unknown_server' + + # replace original server_host argument + assert '--server_host=' in line + line = re.sub(r'--server_host=[^ ]*', + r'--server_host=%s' % args.server_host, line) + + # some interop tests don't set server_host_override (see #17407), + # but we need to use it if different host is set via cmdline args. + if args.server_host != server and not '--server_host_override=' in line: + line = re.sub(r'(--server_host=[^ ]*)', + r'\1 --server_host_override=%s' % server, line) spec = jobset.JobSpec( cmdline=line, - shortname='%s:%s:%s:%s' % (suite_name, lang, server, shortname), + shortname='%s:%s:%s:%s' % (suite_name, lang, server_short, + testcase_name), timeout_seconds=_TEST_TIMEOUT_SECONDS, shell=True, flake_retries=5 if args.allow_flakes else 0) From 4f451c78a41e5c1a90d641754cdd2f4efc2e915d Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 22 Jan 2019 16:50:47 -0800 Subject: [PATCH 136/814] Add basic benchmark test for Python --- src/proto/grpc/core/BUILD | 18 +++- src/proto/grpc/testing/BUILD | 98 +++++++++++++---- src/python/grpcio_tests/tests/qps/BUILD | 89 ++++++++++++++++ src/python/grpcio_tests/tests/qps/README.md | 100 ++++++++++++++++++ .../tests/qps/basic_benchmark_test.sh | 45 ++++++++ .../grpcio_tests/tests/qps/scenarios.json | 96 +++++++++++++++++ test/cpp/qps/BUILD | 6 +- 7 files changed, 430 insertions(+), 22 deletions(-) create mode 100644 src/python/grpcio_tests/tests/qps/BUILD create mode 100644 src/python/grpcio_tests/tests/qps/README.md create mode 100755 src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh create mode 100644 src/python/grpcio_tests/tests/qps/scenarios.json diff --git a/src/proto/grpc/core/BUILD b/src/proto/grpc/core/BUILD index 46de9fae187..2543027821c 100644 --- a/src/proto/grpc/core/BUILD +++ b/src/proto/grpc/core/BUILD @@ -14,11 +14,25 @@ licenses(["notice"]) # Apache v2 -load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_package") +load("//bazel:grpc_build_system.bzl", "grpc_package", "grpc_proto_library") +load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") -grpc_package(name = "core", visibility = "public") +grpc_package( + name = "core", + visibility = "public", +) grpc_proto_library( name = "stats_proto", srcs = ["stats.proto"], ) + +py_proto_library( + name = "py_stats_proto", + protos = ["stats.proto"], + with_grpc = True, + deps = [ + requirement("protobuf"), + ], +) diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD index 9876d5160a1..0c658967942 100644 --- a/src/proto/grpc/testing/BUILD +++ b/src/proto/grpc/testing/BUILD @@ -14,11 +14,14 @@ licenses(["notice"]) # Apache v2 -load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_package") +load("//bazel:grpc_build_system.bzl", "grpc_package", "grpc_proto_library") load("@grpc_python_dependencies//:requirements.bzl", "requirement") load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") -grpc_package(name = "testing", visibility = "public") +grpc_package( + name = "testing", + visibility = "public", +) exports_files([ "echo.proto", @@ -50,9 +53,11 @@ grpc_proto_library( grpc_proto_library( name = "echo_proto", srcs = ["echo.proto"], - deps = ["echo_messages_proto", - "simple_messages_proto"], generate_mocks = True, + deps = [ + "echo_messages_proto", + "simple_messages_proto", + ], ) grpc_proto_library( @@ -63,10 +68,10 @@ grpc_proto_library( py_proto_library( name = "py_empty_proto", - protos = ["empty.proto",], + protos = ["empty.proto"], with_grpc = True, deps = [ - requirement('protobuf'), + requirement("protobuf"), ], ) @@ -78,10 +83,10 @@ grpc_proto_library( py_proto_library( name = "py_messages_proto", - protos = ["messages.proto",], + protos = ["messages.proto"], with_grpc = True, deps = [ - requirement('protobuf'), + requirement("protobuf"), ], ) @@ -100,7 +105,7 @@ grpc_proto_library( name = "benchmark_service_proto", srcs = ["benchmark_service.proto"], deps = [ - "messages_proto", + "messages_proto", ], ) @@ -108,7 +113,7 @@ grpc_proto_library( name = "report_qps_scenario_service_proto", srcs = ["report_qps_scenario_service.proto"], deps = [ - "control_proto", + "control_proto", ], ) @@ -116,7 +121,7 @@ grpc_proto_library( name = "worker_service_proto", srcs = ["worker_service.proto"], deps = [ - "control_proto", + "control_proto", ], ) @@ -132,7 +137,7 @@ grpc_proto_library( has_services = False, deps = [ "//src/proto/grpc/core:stats_proto", - ] + ], ) grpc_proto_library( @@ -146,14 +151,71 @@ grpc_proto_library( py_proto_library( name = "py_test_proto", - protos = ["test.proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], proto_deps = [ ":py_empty_proto", ":py_messages_proto", - ] + ], + protos = ["test.proto"], + with_grpc = True, + deps = [ + requirement("protobuf"), + ], ) +py_proto_library( + name = "py_benchmark_service_proto", + proto_deps = [ + ":py_messages_proto", + ], + protos = ["benchmark_service.proto"], + with_grpc = True, + deps = [ + requirement("protobuf"), + ], +) + +py_proto_library( + name = "py_payloads_proto", + protos = ["payloads.proto"], + with_grpc = True, + deps = [ + requirement("protobuf"), + ], +) + +py_proto_library( + name = "py_stats_proto", + proto_deps = [ + "//src/proto/grpc/core:py_stats_proto", + ], + protos = ["stats.proto"], + with_grpc = True, + deps = [ + requirement("protobuf"), + ], +) + +py_proto_library( + name = "py_control_proto", + proto_deps = [ + ":py_payloads_proto", + ":py_stats_proto", + ], + protos = ["control.proto"], + with_grpc = True, + deps = [ + requirement("protobuf"), + ], +) + +py_proto_library( + name = "py_worker_service_proto", + proto_deps = [ + ":py_control_proto", + ], + protos = ["worker_service.proto"], + with_grpc = True, + deps = [ + requirement("protobuf"), + ], +) diff --git a/src/python/grpcio_tests/tests/qps/BUILD b/src/python/grpcio_tests/tests/qps/BUILD new file mode 100644 index 00000000000..c1eb6b8e11a --- /dev/null +++ b/src/python/grpcio_tests/tests/qps/BUILD @@ -0,0 +1,89 @@ +package(default_visibility = ["//visibility:public"]) + +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +py_library( + name = "benchmark_client", + srcs = ["benchmark_client.py"], + imports = ["../../"], + deps = [ + requirement("six"), + "//src/proto/grpc/testing:py_benchmark_service_proto", + "//src/proto/grpc/testing:py_messages_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:resources", + "//src/python/grpcio_tests/tests/unit:test_common", + ], +) + +py_library( + name = "benchmark_server", + srcs = ["benchmark_server.py"], + imports = ["../../"], + deps = [ + "//src/proto/grpc/testing:py_benchmark_service_proto", + "//src/proto/grpc/testing:py_messages_proto", + ], +) + +py_library( + name = "client_runner", + srcs = ["client_runner.py"], + imports = ["../../"], +) + +py_library( + name = "histogram", + srcs = ["histogram.py"], + imports = ["../../"], + deps = [ + "//src/proto/grpc/testing:py_stats_proto", + ], +) + +py_library( + name = "worker_server", + srcs = ["worker_server.py"], + imports = ["../../"], + deps = [ + ":benchmark_client", + ":benchmark_server", + ":client_runner", + ":histogram", + "//src/proto/grpc/testing:py_benchmark_service_proto", + "//src/proto/grpc/testing:py_control_proto", + "//src/proto/grpc/testing:py_stats_proto", + "//src/proto/grpc/testing:py_worker_service_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:resources", + "//src/python/grpcio_tests/tests/unit:test_common", + ], +) + +py_binary( + name = "qps_worker", + srcs = ["qps_worker.py"], + imports = ["../../"], + main = "qps_worker.py", + deps = [ + ":worker_server", + "//src/proto/grpc/testing:py_worker_service_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:test_common", + ], +) + +filegroup( + name = "scenarios", + srcs = ["scenarios.json"], +) + +sh_test( + name = "basic_benchmark_test", + srcs = ["basic_benchmark_test.sh"], + data = [ + ":qps_worker", + ":scenarios", + "//test/cpp/qps:qps_json_driver", + ], +) diff --git a/src/python/grpcio_tests/tests/qps/README.md b/src/python/grpcio_tests/tests/qps/README.md new file mode 100644 index 00000000000..504a2189f73 --- /dev/null +++ b/src/python/grpcio_tests/tests/qps/README.md @@ -0,0 +1,100 @@ +# Python Benchmark Tools + +## Scenarios + +In `src/proto/grpc/testing/control.proto`, it defines the fields of a scenario. +In `tools/run_tests/performance/scenario_config.py`, the script generates actual scenario content that usually in json format, or piped to another script. + +All Python related benchmark scenarios are: +* netperf +* python_generic_sync_streaming_ping_pong +* python_protobuf_sync_streaming_ping_pong +* python_protobuf_async_unary_ping_pong +* python_protobuf_sync_unary_ping_pong +* python_protobuf_sync_unary_qps_unconstrained +* python_protobuf_sync_streaming_qps_unconstrained +* python_protobuf_sync_unary_ping_pong_1MB + +Here I picked the top 2 most representative scenarios of them, and reduce their benchmark duration from 30 seconds to 10 seconds: +* python_protobuf_async_unary_ping_pong +* python_protobuf_sync_streaming_ping_pong + +## Why keep the scenario file if it can be generated? + +Well... The `tools/run_tests/performance/scenario_config.py` is 1274 lines long. The intention of building these benchmark tools is reducing the complexity of existing infrastructure code. Depending on something that is + +## How to run it? + +```shell +bazel test --test_output=streamed src/python/grpcio_tests/tests/qps:basic_benchmark_test +``` + +## How is the output look like? + +``` +RUNNING SCENARIO: python_protobuf_async_unary_ping_pong +I0123 00:26:04.746195000 140736237159296 driver.cc:288] Starting server on localhost:10086 (worker #0) +D0123 00:26:04.747190000 140736237159296 ev_posix.cc:170] Using polling engine: poll +D0123 00:26:04.747264000 140736237159296 dns_resolver_ares.cc:488] Using ares dns resolver +I0123 00:26:04.748445000 140736237159296 subchannel.cc:869] Connect failed: {"created":"@1548203164.748403000","description":"Failed to connect to remote host: Connection refused","errno":61,"file":"src/core/lib/iomgr/tcp_client_posix.cc","file_line":207,"os_error":"Connection refused","syscall":"connect","target_address":"ipv6:[::1]:10086"} +I0123 00:26:04.748585000 140736237159296 subchannel.cc:869] Connect failed: {"created":"@1548203164.748564000","description":"Failed to connect to remote host: Connection refused","errno":61,"file":"src/core/lib/iomgr/tcp_client_posix.cc","file_line":207,"os_error":"Connection refused","syscall":"connect","target_address":"ipv4:127.0.0.1:10086"} +I0123 00:26:04.748596000 140736237159296 subchannel.cc:751] Subchannel 0x7fca43c19360: Retry in 999 milliseconds +I0123 00:26:05.751251000 123145571299328 subchannel.cc:710] Failed to connect to channel, retrying +I0123 00:26:05.752209000 140736237159296 subchannel.cc:832] New connected subchannel at 0x7fca45000060 for subchannel 0x7fca43c19360 +I0123 00:26:05.772291000 140736237159296 driver.cc:349] Starting client on localhost:10087 (worker #1) +D0123 00:26:05.772384000 140736237159296 driver.cc:373] Client 0 gets 1 channels +I0123 00:26:05.773286000 140736237159296 subchannel.cc:832] New connected subchannel at 0x7fca45004a80 for subchannel 0x7fca451034b0 +I0123 00:26:05.789797000 140736237159296 driver.cc:394] Initiating +I0123 00:26:05.790858000 140736237159296 driver.cc:415] Warming up +I0123 00:26:07.791078000 140736237159296 driver.cc:421] Starting +I0123 00:26:07.791860000 140736237159296 driver.cc:448] Running +I0123 00:26:17.790915000 140736237159296 driver.cc:462] Finishing clients +I0123 00:26:17.791821000 140736237159296 driver.cc:476] Received final status from client 0 +I0123 00:26:17.792148000 140736237159296 driver.cc:508] Finishing servers +I0123 00:26:17.792493000 140736237159296 driver.cc:522] Received final status from server 0 +I0123 00:26:17.795786000 140736237159296 report.cc:82] QPS: 2066.6 +I0123 00:26:17.795799000 140736237159296 report.cc:122] QPS: 2066.6 (258.3/server core) +I0123 00:26:17.795805000 140736237159296 report.cc:127] Latencies (50/90/95/99/99.9%-ile): 467.9/504.8/539.0/653.3/890.4 us +I0123 00:26:17.795811000 140736237159296 report.cc:137] Server system time: 100.00% +I0123 00:26:17.795815000 140736237159296 report.cc:139] Server user time: 100.00% +I0123 00:26:17.795818000 140736237159296 report.cc:141] Client system time: 100.00% +I0123 00:26:17.795821000 140736237159296 report.cc:143] Client user time: 100.00% +I0123 00:26:17.795825000 140736237159296 report.cc:148] Server CPU usage: 0.00% +I0123 00:26:17.795828000 140736237159296 report.cc:153] Client Polls per Request: 0.00 +I0123 00:26:17.795831000 140736237159296 report.cc:155] Server Polls per Request: 0.00 +I0123 00:26:17.795834000 140736237159296 report.cc:160] Server Queries/CPU-sec: 1033.19 +I0123 00:26:17.795837000 140736237159296 report.cc:162] Client Queries/CPU-sec: 1033.32 +RUNNING SCENARIO: python_protobuf_sync_streaming_ping_pong +I0123 00:26:17.795888000 140736237159296 driver.cc:288] Starting server on localhost:10086 (worker #0) +D0123 00:26:17.795964000 140736237159296 ev_posix.cc:170] Using polling engine: poll +D0123 00:26:17.795978000 140736237159296 dns_resolver_ares.cc:488] Using ares dns resolver +I0123 00:26:17.796613000 140736237159296 subchannel.cc:832] New connected subchannel at 0x7fca43c15820 for subchannel 0x7fca43d12140 +I0123 00:26:17.810911000 140736237159296 driver.cc:349] Starting client on localhost:10087 (worker #1) +D0123 00:26:17.811037000 140736237159296 driver.cc:373] Client 0 gets 1 channels +I0123 00:26:17.811892000 140736237159296 subchannel.cc:832] New connected subchannel at 0x7fca43d18f40 for subchannel 0x7fca43d16b80 +I0123 00:26:17.818902000 140736237159296 driver.cc:394] Initiating +I0123 00:26:17.820776000 140736237159296 driver.cc:415] Warming up +I0123 00:26:19.824685000 140736237159296 driver.cc:421] Starting +I0123 00:26:19.825970000 140736237159296 driver.cc:448] Running +I0123 00:26:29.821866000 140736237159296 driver.cc:462] Finishing clients +I0123 00:26:29.823259000 140736237159296 driver.cc:476] Received final status from client 0 +I0123 00:26:29.827195000 140736237159296 driver.cc:508] Finishing servers +I0123 00:26:29.827599000 140736237159296 driver.cc:522] Received final status from server 0 +I0123 00:26:29.828739000 140736237159296 report.cc:82] QPS: 619.5 +I0123 00:26:29.828752000 140736237159296 report.cc:122] QPS: 619.5 (77.4/server core) +I0123 00:26:29.828760000 140736237159296 report.cc:127] Latencies (50/90/95/99/99.9%-ile): 1589.8/1854.3/1920.4/2015.8/2204.8 us +I0123 00:26:29.828765000 140736237159296 report.cc:137] Server system time: 100.00% +I0123 00:26:29.828769000 140736237159296 report.cc:139] Server user time: 100.00% +I0123 00:26:29.828772000 140736237159296 report.cc:141] Client system time: 100.00% +I0123 00:26:29.828776000 140736237159296 report.cc:143] Client user time: 100.00% +I0123 00:26:29.828780000 140736237159296 report.cc:148] Server CPU usage: 0.00% +I0123 00:26:29.828784000 140736237159296 report.cc:153] Client Polls per Request: 0.00 +I0123 00:26:29.828788000 140736237159296 report.cc:155] Server Polls per Request: 0.00 +I0123 00:26:29.828792000 140736237159296 report.cc:160] Server Queries/CPU-sec: 309.58 +I0123 00:26:29.828795000 140736237159296 report.cc:162] Client Queries/CPU-sec: 309.75 +``` + +## Future Works (TODOs) + +1. Generate a target for each scenario. +2. Simplify the main entrance of our benchmark related code, or make it depends on Bazel. diff --git a/src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh b/src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh new file mode 100755 index 00000000000..6011a7e01c2 --- /dev/null +++ b/src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh @@ -0,0 +1,45 @@ +#! /bin/bash +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This test benchmarks Python client/server. +set -ex + +declare -a DRIVER_PORTS=("10086" "10087") +SCENARIOS_FILE=src/python/grpcio_tests/tests/qps/scenarios.json + +function join { local IFS="$1"; shift; echo "$*"; } + +if [[ -e "${SCENARIOS_FILE}" ]]; then + echo "Running against scenarios.json:" + cat "${SCENARIOS_FILE}" +else + echo "Failed to find scenarios.json!" + exit 1 +fi + +echo "Starting Python qps workers..." +qps_workers=() +for DRIVER_PORT in "${DRIVER_PORTS[@]}" +do + echo -e "\tRunning Python qps worker listening at localhost:${DRIVER_PORT}..." + src/python/grpcio_tests/tests/qps/qps_worker \ + --driver_port="${DRIVER_PORT}" & + qps_workers+=("localhost:${DRIVER_PORT}") +done + +echo "Running qps json driver..." +QPS_WORKERS=$(join , ${qps_workers[@]}) +export QPS_WORKERS +test/cpp/qps/qps_json_driver --scenarios_file="${SCENARIOS_FILE}" diff --git a/src/python/grpcio_tests/tests/qps/scenarios.json b/src/python/grpcio_tests/tests/qps/scenarios.json new file mode 100644 index 00000000000..03c91be1e71 --- /dev/null +++ b/src/python/grpcio_tests/tests/qps/scenarios.json @@ -0,0 +1,96 @@ +{ + "scenarios": [ + { + "name": "python_protobuf_async_unary_ping_pong", + "clientConfig": { + "clientType": "ASYNC_CLIENT", + "securityParams": { + "useTestCa": true, + "serverHostOverride": "foo.test.google.fr" + }, + "outstandingRpcsPerChannel": 1, + "clientChannels": 1, + "asyncClientThreads": 1, + "loadParams": { + "closedLoop": {} + }, + "payloadConfig": { + "simpleParams": {} + }, + "histogramParams": { + "resolution": 0.01, + "maxPossible": 60000000000 + }, + "channelArgs": [ + { + "name": "grpc.optimization_target", + "strValue": "latency" + } + ] + }, + "numClients": 1, + "serverConfig": { + "serverType": "ASYNC_SERVER", + "securityParams": { + "useTestCa": true, + "serverHostOverride": "foo.test.google.fr" + }, + "channelArgs": [ + { + "name": "grpc.optimization_target", + "strValue": "latency" + } + ] + }, + "numServers": 1, + "warmupSeconds": 2, + "benchmarkSeconds": 10 + }, + { + "name": "python_protobuf_sync_streaming_ping_pong", + "clientConfig": { + "securityParams": { + "useTestCa": true, + "serverHostOverride": "foo.test.google.fr" + }, + "outstandingRpcsPerChannel": 1, + "clientChannels": 1, + "asyncClientThreads": 1, + "rpcType": "STREAMING", + "loadParams": { + "closedLoop": {} + }, + "payloadConfig": { + "simpleParams": {} + }, + "histogramParams": { + "resolution": 0.01, + "maxPossible": 60000000000 + }, + "channelArgs": [ + { + "name": "grpc.optimization_target", + "strValue": "latency" + } + ] + }, + "numClients": 1, + "serverConfig": { + "serverType": "ASYNC_SERVER", + "securityParams": { + "useTestCa": true, + "serverHostOverride": "foo.test.google.fr" + }, + "channelArgs": [ + { + "name": "grpc.optimization_target", + "strValue": "latency" + } + ] + }, + "numServers": 1, + "warmupSeconds": 2, + "benchmarkSeconds": 10 + } + ] +} diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index 8855a1c155d..41ae5d41e0c 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -14,8 +14,10 @@ licenses(["notice"]) # Apache v2 -load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_library", "grpc_cc_binary", "grpc_package") -load("//test/cpp/qps:qps_benchmark_script.bzl", "qps_json_driver_batch", "json_run_localhost_batch") +package(default_visibility = ["//visibility:public"]) + +load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library", "grpc_cc_test", "grpc_package") +load("//test/cpp/qps:qps_benchmark_script.bzl", "json_run_localhost_batch", "qps_json_driver_batch") grpc_package(name = "test/cpp/qps") From 95d4120f4658716936437adccf40f8eda01229f4 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 22 Jan 2019 18:34:17 -0800 Subject: [PATCH 137/814] Add copyright to BUILD file --- src/python/grpcio_tests/tests/qps/BUILD | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/python/grpcio_tests/tests/qps/BUILD b/src/python/grpcio_tests/tests/qps/BUILD index c1eb6b8e11a..e1c7d138ef3 100644 --- a/src/python/grpcio_tests/tests/qps/BUILD +++ b/src/python/grpcio_tests/tests/qps/BUILD @@ -1,3 +1,17 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + package(default_visibility = ["//visibility:public"]) load("@grpc_python_dependencies//:requirements.bzl", "requirement") From 6ca6a060757cca9d268808f9ccfe295918f271e5 Mon Sep 17 00:00:00 2001 From: matoro Date: Fri, 28 Dec 2018 21:53:36 +0000 Subject: [PATCH 138/814] Ruby tooling: respect user toolchain overrides While compilation flag overrides for the Ruby native extension are currently functional, specifying an alternate compiler is not, as the Rbconfig values for key toolchain binaries are hardcoded at compile time of the Ruby interpreter. This patch allows them to be overrridden on the command line via standard environment variables, defaulting to the Rbconfig values only if unspecified by the user. --- src/ruby/ext/grpc/extconf.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index 505357021e0..9950976eeb1 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -24,10 +24,18 @@ grpc_config = ENV['GRPC_CONFIG'] || 'opt' ENV['MACOSX_DEPLOYMENT_TARGET'] = '10.7' -ENV['AR'] = RbConfig::CONFIG['AR'] + ' rcs' -ENV['CC'] = RbConfig::CONFIG['CC'] -ENV['CXX'] = RbConfig::CONFIG['CXX'] -ENV['LD'] = ENV['CC'] +if ENV['AR'].nil? || ENV['AR'].size == 0 + ENV['AR'] = RbConfig::CONFIG['AR'] + ' rcs' +end +if ENV['CC'].nil? || ENV['CC'].size == 0 + ENV['CC'] = RbConfig::CONFIG['CC'] +end +if ENV['CXX'].nil? || ENV['CXX'].size == 0 + ENV['CXX'] = RbConfig::CONFIG['CXX'] +end +if ENV['LD'].nil? || ENV['LD'].size == 0 + ENV['LD'] = ENV['CC'] +end ENV['AR'] = 'libtool -o' if RUBY_PLATFORM =~ /darwin/ From f99bd8c08a5edea16da36a96b7c57144435b07d3 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 22 Jan 2019 09:10:46 -0800 Subject: [PATCH 139/814] Pass LB policy args as non-const and using std::move(). --- .../ext/filters/client_channel/lb_policy.cc | 4 ++-- .../ext/filters/client_channel/lb_policy.h | 12 +++++------ .../client_channel/lb_policy/grpclb/grpclb.cc | 20 +++++++++--------- .../lb_policy/pick_first/pick_first.cc | 8 +++---- .../lb_policy/round_robin/round_robin.cc | 8 +++---- .../lb_policy/subchannel_list.h | 4 ++-- .../client_channel/lb_policy/xds/xds.cc | 20 +++++++++--------- .../client_channel/lb_policy_factory.h | 7 ++++++- .../client_channel/lb_policy_registry.cc | 4 ++-- .../client_channel/lb_policy_registry.h | 2 +- .../filters/client_channel/request_routing.cc | 2 +- test/core/util/test_lb_policies.cc | 21 ++++++++++++------- 12 files changed, 61 insertions(+), 51 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 31b0399d874..2450775109f 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -27,11 +27,11 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount( namespace grpc_core { -LoadBalancingPolicy::LoadBalancingPolicy(const Args& args) +LoadBalancingPolicy::LoadBalancingPolicy(Args args) : InternallyRefCounted(&grpc_trace_lb_policy_refcount), combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), client_channel_factory_(args.client_channel_factory), - subchannel_pool_(*args.subchannel_pool), + subchannel_pool_(std::move(args.subchannel_pool)), interested_parties_(grpc_pollset_set_create()), request_reresolution_(nullptr) {} diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 60e92f32087..08634917ac1 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -55,7 +55,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Used to create channels and subchannels. grpc_client_channel_factory* client_channel_factory = nullptr; /// Subchannel pool. - RefCountedPtr* subchannel_pool; + RefCountedPtr subchannel_pool; /// Channel args from the resolver. /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. @@ -187,10 +187,10 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_pollset_set* interested_parties() const { return interested_parties_; } - /// Returns a pointer to the subchannel pool of type - /// RefCountedPtr. - RefCountedPtr* subchannel_pool() { - return &subchannel_pool_; + // Callers that need their own reference can call the returned + // object's Ref() method. + SubchannelPoolInterface* subchannel_pool() const { + return subchannel_pool_.get(); } GRPC_ABSTRACT_BASE_CLASS @@ -198,7 +198,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { protected: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - explicit LoadBalancingPolicy(const Args& args); + explicit LoadBalancingPolicy(Args args); virtual ~LoadBalancingPolicy(); grpc_combiner* combiner() const { return combiner_; } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 51b61ecb92c..750b312fae9 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -125,7 +125,7 @@ constexpr char kGrpclb[] = "grpclb"; class GrpcLb : public LoadBalancingPolicy { public: - explicit GrpcLb(const Args& args); + explicit GrpcLb(Args args); const char* name() const override { return kGrpclb; } @@ -273,7 +273,7 @@ class GrpcLb : public LoadBalancingPolicy { // Methods for dealing with the RR policy. void CreateOrUpdateRoundRobinPolicyLocked(); grpc_channel_args* CreateRoundRobinPolicyArgsLocked(); - void CreateRoundRobinPolicyLocked(const Args& args); + void CreateRoundRobinPolicyLocked(Args args); bool PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, grpc_error** error); void UpdateConnectivityStateFromRoundRobinPolicyLocked( @@ -973,8 +973,8 @@ grpc_channel_args* BuildBalancerChannelArgs( // ctor and dtor // -GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args) - : LoadBalancingPolicy(args), +GrpcLb::GrpcLb(LoadBalancingPolicy::Args args) + : LoadBalancingPolicy(std::move(args)), response_generator_(MakeRefCounted()), lb_call_backoff_( BackOff::Options() @@ -1588,10 +1588,10 @@ bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, return pick_done; } -void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) { +void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { GPR_ASSERT(rr_policy_ == nullptr); rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - "round_robin", args); + "round_robin", std::move(args)); if (GPR_UNLIKELY(rr_policy_ == nullptr)) { gpr_log(GPR_ERROR, "[grpclb %p] Failure creating a RoundRobin policy", this); @@ -1693,8 +1693,8 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { lb_policy_args.combiner = combiner(); lb_policy_args.client_channel_factory = client_channel_factory(); lb_policy_args.args = args; - lb_policy_args.subchannel_pool = subchannel_pool(); - CreateRoundRobinPolicyLocked(lb_policy_args); + lb_policy_args.subchannel_pool = subchannel_pool()->Ref(); + CreateRoundRobinPolicyLocked(std::move(lb_policy_args)); } grpc_channel_args_destroy(args); } @@ -1802,7 +1802,7 @@ void GrpcLb::OnRoundRobinConnectivityChangedLocked(void* arg, class GrpcLbFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( - const LoadBalancingPolicy::Args& args) const override { + LoadBalancingPolicy::Args args) const override { /* Count the number of gRPC-LB addresses. There must be at least one. */ const ServerAddressList* addresses = FindServerAddressListChannelArg(args.args); @@ -1815,7 +1815,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { } } if (!found_balancer) return nullptr; - return OrphanablePtr(New(args)); + return OrphanablePtr(New(std::move(args))); } const char* name() const override { return kGrpclb; } diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 75eacb2e17e..ec5c782c469 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -46,7 +46,7 @@ constexpr char kPickFirst[] = "pick_first"; class PickFirst : public LoadBalancingPolicy { public: - explicit PickFirst(const Args& args); + explicit PickFirst(Args args); const char* name() const override { return kPickFirst; } @@ -154,7 +154,7 @@ class PickFirst : public LoadBalancingPolicy { channelz::ChildRefsList child_channels_; }; -PickFirst::PickFirst(const Args& args) : LoadBalancingPolicy(args) { +PickFirst::PickFirst(Args args) : LoadBalancingPolicy(std::move(args)) { GPR_ASSERT(args.client_channel_factory != nullptr); gpr_mu_init(&child_refs_mu_); grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, @@ -619,8 +619,8 @@ void PickFirst::PickFirstSubchannelData:: class PickFirstFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( - const LoadBalancingPolicy::Args& args) const override { - return OrphanablePtr(New(args)); + LoadBalancingPolicy::Args args) const override { + return OrphanablePtr(New(std::move(args))); } const char* name() const override { return kPickFirst; } diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 5143c6d8380..30316689ea7 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -56,7 +56,7 @@ constexpr char kRoundRobin[] = "round_robin"; class RoundRobin : public LoadBalancingPolicy { public: - explicit RoundRobin(const Args& args); + explicit RoundRobin(Args args); const char* name() const override { return kRoundRobin; } @@ -210,7 +210,7 @@ class RoundRobin : public LoadBalancingPolicy { channelz::ChildRefsList child_channels_; }; -RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) { +RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) { GPR_ASSERT(args.client_channel_factory != nullptr); gpr_mu_init(&child_refs_mu_); grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, @@ -697,8 +697,8 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, class RoundRobinFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( - const LoadBalancingPolicy::Args& args) const override { - return OrphanablePtr(New(args)); + LoadBalancingPolicy::Args args) const override { + return OrphanablePtr(New(std::move(args))); } const char* name() const override { return kRoundRobin; } diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 55f5d6da85a..2eb92b7ead0 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -514,8 +514,8 @@ SubchannelList::SubchannelList( // policy, which does not use a SubchannelList. GPR_ASSERT(!addresses[i].IsBalancer()); InlinedVector args_to_add; - args_to_add.emplace_back(SubchannelPoolInterface::CreateChannelArg( - policy_->subchannel_pool()->get())); + args_to_add.emplace_back( + SubchannelPoolInterface::CreateChannelArg(policy_->subchannel_pool())); const size_t subchannel_address_arg_index = args_to_add.size(); args_to_add.emplace_back( grpc_create_subchannel_address_arg(&addresses[i].address())); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 63bd8be011b..add38eedd20 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -118,7 +118,7 @@ constexpr char kXds[] = "xds_experimental"; class XdsLb : public LoadBalancingPolicy { public: - explicit XdsLb(const Args& args); + explicit XdsLb(Args args); const char* name() const override { return kXds; } @@ -265,7 +265,7 @@ class XdsLb : public LoadBalancingPolicy { // Methods for dealing with the child policy. void CreateOrUpdateChildPolicyLocked(); grpc_channel_args* CreateChildPolicyArgsLocked(); - void CreateChildPolicyLocked(const Args& args); + void CreateChildPolicyLocked(Args args); bool PickFromChildPolicyLocked(bool force_async, PendingPick* pp, grpc_error** error); void UpdateConnectivityStateFromChildPolicyLocked( @@ -892,8 +892,8 @@ grpc_channel_args* BuildBalancerChannelArgs( // // TODO(vishalpowar): Use lb_config in args to configure LB policy. -XdsLb::XdsLb(const LoadBalancingPolicy::Args& args) - : LoadBalancingPolicy(args), +XdsLb::XdsLb(LoadBalancingPolicy::Args args) + : LoadBalancingPolicy(std::move(args)), response_generator_(MakeRefCounted()), lb_call_backoff_( BackOff::Options() @@ -1436,10 +1436,10 @@ bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp, return pick_done; } -void XdsLb::CreateChildPolicyLocked(const Args& args) { +void XdsLb::CreateChildPolicyLocked(Args args) { GPR_ASSERT(child_policy_ == nullptr); child_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - "round_robin", args); + "round_robin", std::move(args)); if (GPR_UNLIKELY(child_policy_ == nullptr)) { gpr_log(GPR_ERROR, "[xdslb %p] Failure creating a child policy", this); return; @@ -1523,9 +1523,9 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); lb_policy_args.client_channel_factory = client_channel_factory(); - lb_policy_args.subchannel_pool = subchannel_pool(); + lb_policy_args.subchannel_pool = subchannel_pool()->Ref(); lb_policy_args.args = args; - CreateChildPolicyLocked(lb_policy_args); + CreateChildPolicyLocked(std::move(lb_policy_args)); if (grpc_lb_xds_trace.enabled()) { gpr_log(GPR_INFO, "[xdslb %p] Created a new child policy %p", this, child_policy_.get()); @@ -1637,7 +1637,7 @@ void XdsLb::OnChildPolicyConnectivityChangedLocked(void* arg, class XdsFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( - const LoadBalancingPolicy::Args& args) const override { + LoadBalancingPolicy::Args args) const override { /* Count the number of gRPC-LB addresses. There must be at least one. */ const ServerAddressList* addresses = FindServerAddressListChannelArg(args.args); @@ -1650,7 +1650,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { } } if (!found_balancer_address) return nullptr; - return OrphanablePtr(New(args)); + return OrphanablePtr(New(std::move(args))); } const char* name() const override { return kXds; } diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h index a165ebafaba..770bcbeee5c 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -31,7 +31,12 @@ class LoadBalancingPolicyFactory { public: /// Returns a new LB policy instance. virtual OrphanablePtr CreateLoadBalancingPolicy( - const LoadBalancingPolicy::Args& args) const GRPC_ABSTRACT; + LoadBalancingPolicy::Args args) const { + std::move(args); // Suppress clang-tidy complaint. + // The rest of this is copied from the GRPC_ABSTRACT macro. + gpr_log(GPR_ERROR, "Function marked GRPC_ABSTRACT was not implemented"); + GPR_ASSERT(false); + } /// Returns the LB policy name that this factory provides. /// Caller does NOT take ownership of result. diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc index ad459c9c8cf..99980d5500d 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -84,14 +84,14 @@ void LoadBalancingPolicyRegistry::Builder::RegisterLoadBalancingPolicyFactory( OrphanablePtr LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - const char* name, const LoadBalancingPolicy::Args& args) { + const char* name, LoadBalancingPolicy::Args args) { GPR_ASSERT(g_state != nullptr); // Find factory. LoadBalancingPolicyFactory* factory = g_state->GetLoadBalancingPolicyFactory(name); if (factory == nullptr) return nullptr; // Specified name not found. // Create policy via factory. - return factory->CreateLoadBalancingPolicy(args); + return factory->CreateLoadBalancingPolicy(std::move(args)); } bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h index 338f7c9f696..7472ba9f8a8 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -46,7 +46,7 @@ class LoadBalancingPolicyRegistry { /// Creates an LB policy of the type specified by \a name. static OrphanablePtr CreateLoadBalancingPolicy( - const char* name, const LoadBalancingPolicy::Args& args); + const char* name, LoadBalancingPolicy::Args args); /// Returns true if the LB policy factory specified by \a name exists in this /// registry. diff --git a/src/core/ext/filters/client_channel/request_routing.cc b/src/core/ext/filters/client_channel/request_routing.cc index 5e52456859e..d6ff34c99b5 100644 --- a/src/core/ext/filters/client_channel/request_routing.cc +++ b/src/core/ext/filters/client_channel/request_routing.cc @@ -676,7 +676,7 @@ void RequestRouter::CreateNewLbPolicyLocked( LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner_; lb_policy_args.client_channel_factory = client_channel_factory_; - lb_policy_args.subchannel_pool = &subchannel_pool_; + lb_policy_args.subchannel_pool = subchannel_pool_; lb_policy_args.args = resolver_result_; lb_policy_args.lb_config = lb_config; OrphanablePtr new_lb_policy = diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 5f042867dd9..d6d072101ac 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -48,11 +48,17 @@ namespace { // A minimal forwarding class to avoid implementing a standalone test LB. class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { public: - ForwardingLoadBalancingPolicy(const Args& args, + ForwardingLoadBalancingPolicy(Args args, const std::string& delegate_policy_name) - : LoadBalancingPolicy(args) { + : LoadBalancingPolicy(std::move(args)) { + Args delegate_args; + delegate_args.combiner = combiner(); + delegate_args.client_channel_factory = client_channel_factory(); + delegate_args.subchannel_pool = subchannel_pool()->Ref(); + delegate_args.args = args.args; + delegate_args.lb_config = args.lb_config; delegate_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - delegate_policy_name.c_str(), args); + delegate_policy_name.c_str(), std::move(delegate_args)); grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), interested_parties()); // Give re-resolution closure to delegate. @@ -143,9 +149,8 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy : public ForwardingLoadBalancingPolicy { public: InterceptRecvTrailingMetadataLoadBalancingPolicy( - const Args& args, InterceptRecvTrailingMetadataCallback cb, - void* user_data) - : ForwardingLoadBalancingPolicy(args, + Args args, InterceptRecvTrailingMetadataCallback cb, void* user_data) + : ForwardingLoadBalancingPolicy(std::move(args), /*delegate_lb_policy_name=*/"pick_first"), cb_(cb), user_data_(user_data) {} @@ -212,10 +217,10 @@ class InterceptTrailingFactory : public LoadBalancingPolicyFactory { grpc_core::OrphanablePtr CreateLoadBalancingPolicy( - const grpc_core::LoadBalancingPolicy::Args& args) const override { + grpc_core::LoadBalancingPolicy::Args args) const override { return grpc_core::OrphanablePtr( grpc_core::New( - args, cb_, user_data_)); + std::move(args), cb_, user_data_)); } const char* name() const override { From da9237a9c5566044974ac8e83d5830aeb71e9575 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 10 Jan 2019 18:49:09 -0800 Subject: [PATCH 140/814] Fix windows localhost address sorting bypass --- .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 4 +- test/core/iomgr/resolve_address_test.cc | 103 +++++++++++++++++- 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 1a7e5d06268..d41c8238f1c 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -548,13 +548,13 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( r, name, default_port); // Early out if the target is an ipv4 or ipv6 literal. if (resolve_as_ip_literal_locked(name, default_port, addrs)) { - GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + grpc_ares_complete_request_locked(r); return r; } // Early out if the target is localhost and we're on Windows. if (grpc_ares_maybe_resolve_localhost_manually_locked(name, default_port, addrs)) { - GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + grpc_ares_complete_request_locked(r); return r; } // Don't query for SRV and TXT records if the target is "localhost", so diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index 1d9e1ee27e2..e1c58bed852 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -23,6 +23,8 @@ #include #include +#include + #include #include "src/core/lib/gpr/env.h" @@ -120,6 +122,35 @@ static void must_fail(void* argsp, grpc_error* err) { gpr_mu_unlock(args->mu); } +// This test assumes the environment has an ipv6 loopback +static void must_succeed_with_ipv6_first(void* argsp, grpc_error* err) { + args_struct* args = static_cast(argsp); + GPR_ASSERT(err == GRPC_ERROR_NONE); + GPR_ASSERT(args->addrs != nullptr); + GPR_ASSERT(args->addrs->naddrs > 0); + const struct sockaddr* first_address = + reinterpret_cast(args->addrs->addrs[0].addr); + GPR_ASSERT(first_address->sa_family == AF_INET6); + gpr_atm_rel_store(&args->done_atm, 1); + gpr_mu_lock(args->mu); + GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); + gpr_mu_unlock(args->mu); +} + +static void must_succeed_with_ipv4_first(void* argsp, grpc_error* err) { + args_struct* args = static_cast(argsp); + GPR_ASSERT(err == GRPC_ERROR_NONE); + GPR_ASSERT(args->addrs != nullptr); + GPR_ASSERT(args->addrs->naddrs > 0); + const struct sockaddr* first_address = + reinterpret_cast(args->addrs->addrs[0].addr); + GPR_ASSERT(first_address->sa_family == AF_INET); + gpr_atm_rel_store(&args->done_atm, 1); + gpr_mu_lock(args->mu); + GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); + gpr_mu_unlock(args->mu); +} + static void test_localhost(void) { grpc_core::ExecCtx exec_ctx; args_struct args; @@ -146,6 +177,33 @@ static void test_default_port(void) { args_finish(&args); } +static void test_localhost_result_has_ipv6_first(void) { + grpc_core::ExecCtx exec_ctx; + args_struct args; + args_init(&args); + grpc_resolve_address("localhost:1", nullptr, args.pollset_set, + GRPC_CLOSURE_CREATE(must_succeed_with_ipv6_first, &args, + grpc_schedule_on_exec_ctx), + &args.addrs); + grpc_core::ExecCtx::Get()->Flush(); + poll_pollset_until_request_done(&args); + args_finish(&args); +} + +static void test_localhost_result_has_ipv4_first_when_ipv6_isnt_available( + void) { + grpc_core::ExecCtx exec_ctx; + args_struct args; + args_init(&args); + grpc_resolve_address("localhost:1", nullptr, args.pollset_set, + GRPC_CLOSURE_CREATE(must_succeed_with_ipv4_first, &args, + grpc_schedule_on_exec_ctx), + &args.addrs); + grpc_core::ExecCtx::Get()->Flush(); + poll_pollset_until_request_done(&args); + args_finish(&args); +} + static void test_non_numeric_default_port(void) { grpc_core::ExecCtx exec_ctx; args_struct args; @@ -245,6 +303,34 @@ static void test_unparseable_hostports(void) { } } +typedef struct mock_ipv6_disabled_source_addr_factory { + address_sorting_source_addr_factory base; +} mock_ipv6_disabled_source_addr_factory; + +static bool mock_ipv6_disabled_source_addr_factory_get_source_addr( + address_sorting_source_addr_factory* factory, + const address_sorting_address* dest_addr, + address_sorting_address* source_addr) { + // Mock lack of IPv6. For IPv4, set the source addr to be the same + // as the destination; tests won't actually connect on the result anyways. + if (address_sorting_abstract_get_family(dest_addr) == + ADDRESS_SORTING_AF_INET6) { + return false; + } + memcpy(source_addr->addr, &dest_addr->addr, dest_addr->len); + source_addr->len = dest_addr->len; + return true; +} + +void mock_ipv6_disabled_source_addr_factory_destroy( + address_sorting_source_addr_factory* factory) {} + +const address_sorting_source_addr_factory_vtable + kMockIpv6DisabledSourceAddrFactoryVtable = { + mock_ipv6_disabled_source_addr_factory_get_source_addr, + mock_ipv6_disabled_source_addr_factory_destroy, +}; + int main(int argc, char** argv) { // First set the resolver type based off of --resolver const char* resolver_type = nullptr; @@ -289,11 +375,26 @@ int main(int argc, char** argv) { // these unit tests under c-ares risks flakiness. test_invalid_ip_addresses(); test_unparseable_hostports(); + } else { + test_localhost_result_has_ipv6_first(); } grpc_executor_shutdown(); } gpr_cmdline_destroy(cl); - grpc_shutdown(); + // The following test uses + // "address_sorting_override_source_addr_factory_for_testing", which works + // on a per-grpc-init basis, and so it's simplest to run this next test + // within a standalone grpc_init/grpc_shutdown pair. + if (gpr_stricmp(resolver_type, "ares") == 0) { + // Run a test case in which c-ares's address sorter + // thinks that IPv4 is available and IPv6 isn't. + grpc_init(); + mock_ipv6_disabled_source_addr_factory factory; + factory.base.vtable = &kMockIpv6DisabledSourceAddrFactoryVtable; + address_sorting_override_source_addr_factory_for_testing(&factory.base); + test_localhost_result_has_ipv4_first_when_ipv6_isnt_available(); + grpc_shutdown(); + } return 0; } From fab05d336c311b83a7f9b6acecd40ab1b6bbe8f7 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 9 Jan 2019 21:49:24 -0800 Subject: [PATCH 141/814] Dynamic callback requesting, graceful server shutdown, and separate ExecCtx for callbacks --- include/grpc/impl/codegen/grpc_types.h | 4 + include/grpcpp/server.h | 30 ++- src/core/lib/iomgr/exec_ctx.cc | 1 + src/core/lib/iomgr/exec_ctx.h | 57 ++++- src/core/lib/iomgr/executor.cc | 7 + src/core/lib/iomgr/timer_manager.cc | 7 + src/core/lib/surface/call.cc | 6 +- src/core/lib/surface/completion_queue.cc | 5 +- src/core/lib/surface/server.cc | 23 +- src/cpp/common/alarm.cc | 3 + src/cpp/server/server_cc.cc | 236 +++++++++++++----- test/core/surface/completion_queue_test.cc | 71 +++--- .../microbenchmarks/bm_chttp2_transport.cc | 2 - 13 files changed, 332 insertions(+), 120 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 8d7c21107f4..79b182c4515 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -693,6 +693,10 @@ typedef struct grpc_experimental_completion_queue_functor { pointer to this functor and a boolean that indicates whether the operation succeeded (non-zero) or failed (zero) */ void (*functor_run)(struct grpc_experimental_completion_queue_functor*, int); + + /** The following fields are not API. They are meant for internal use. */ + int internal_success; + struct grpc_experimental_completion_queue_functor* internal_next; } grpc_experimental_completion_queue_functor; /* The upgrade to version 2 is currently experimental. */ diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index cdcac186cb6..5bbbd704a02 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -248,8 +248,22 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { /// the \a sync_server_cqs) std::vector> sync_req_mgrs_; - /// Outstanding callback requests - std::vector> callback_reqs_; + // Outstanding callback requests. The vector is indexed by method with a + // list per method. Each element should store its own iterator + // in the list and should erase it when the request is actually bound to + // an RPC. Synchronize this list with its own mu_ (not the server mu_) since + // these must be active at Shutdown when the server mu_ is locked + // TODO(vjpai): Merge with the core request matcher to avoid duplicate work + struct MethodReqList { + std::mutex reqs_mu; + // Maintain our own list size count since list::size is still linear + // for some libraries (supposed to be constant since C++11) + // TODO(vjpai): Remove reqs_list_sz and use list::size when possible + size_t reqs_list_sz{0}; + std::list reqs_list; + using iterator = decltype(reqs_list)::iterator; + }; + std::vector callback_reqs_; // Server status std::mutex mu_; @@ -259,6 +273,18 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { std::condition_variable shutdown_cv_; + // It is ok (but not required) to nest callback_reqs_mu_ under mu_ . + // Incrementing callback_reqs_outstanding_ is ok without a lock + // but it should only be decremented under the lock in case it is the + // last request and enables the server shutdown. The increment is + // performance-critical since it happens during periods of increasing + // load; the decrement happens only when memory is maxed out, during server + // shutdown, or (possibly in a future version) during decreasing load, so + // it is less performance-critical. + std::mutex callback_reqs_mu_; + std::condition_variable callback_reqs_done_cv_; + std::atomic_int callback_reqs_outstanding_{0}; + std::shared_ptr global_callbacks_; std::vector services_; diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc index 683dd2f6493..f45def43397 100644 --- a/src/core/lib/iomgr/exec_ctx.cc +++ b/src/core/lib/iomgr/exec_ctx.cc @@ -115,6 +115,7 @@ grpc_closure_scheduler* grpc_schedule_on_exec_ctx = &exec_ctx_scheduler; namespace grpc_core { GPR_TLS_CLASS_DEF(ExecCtx::exec_ctx_); +GPR_TLS_CLASS_DEF(ApplicationCallbackExecCtx::callback_exec_ctx_); // WARNING: for testing purposes only! void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) { diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index e90eb54cd35..36c1a907cbc 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -21,12 +21,14 @@ #include +#include #include #include #include #include "src/core/lib/gpr/tls.h" #include "src/core/lib/gprpp/fork.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/closure.h" typedef int64_t grpc_millis; @@ -34,9 +36,8 @@ typedef int64_t grpc_millis; #define GRPC_MILLIS_INF_FUTURE INT64_MAX #define GRPC_MILLIS_INF_PAST INT64_MIN -/** A workqueue represents a list of work to be executed asynchronously. - Forward declared here to avoid a circular dependency with workqueue.h. */ -typedef struct grpc_workqueue grpc_workqueue; +/** A combiner represents a list of work to be executed later. + Forward declared here to avoid a circular dependency with combiner.h. */ typedef struct grpc_combiner grpc_combiner; /* This exec_ctx is ready to return: either pre-populated, or cached as soon as @@ -226,6 +227,56 @@ class ExecCtx { GPR_TLS_CLASS_DECL(exec_ctx_); ExecCtx* last_exec_ctx_ = Get(); }; + +class ApplicationCallbackExecCtx { + public: + ApplicationCallbackExecCtx() { + if (reinterpret_cast( + gpr_tls_get(&callback_exec_ctx_)) == nullptr) { + grpc_core::Fork::IncExecCtxCount(); + gpr_tls_set(&callback_exec_ctx_, reinterpret_cast(this)); + } + } + ~ApplicationCallbackExecCtx() { + if (reinterpret_cast( + gpr_tls_get(&callback_exec_ctx_)) == this) { + while (head_ != nullptr) { + auto* f = head_; + head_ = f->internal_next; + if (f->internal_next == nullptr) { + tail_ = nullptr; + } + (*f->functor_run)(f, f->internal_success); + } + gpr_tls_set(&callback_exec_ctx_, reinterpret_cast(nullptr)); + grpc_core::Fork::DecExecCtxCount(); + } else { + GPR_DEBUG_ASSERT(head_ == nullptr); + GPR_DEBUG_ASSERT(tail_ == nullptr); + } + } + static void Enqueue(grpc_experimental_completion_queue_functor* functor, + int is_success) { + functor->internal_success = is_success; + functor->internal_next = nullptr; + + auto* ctx = reinterpret_cast( + gpr_tls_get(&callback_exec_ctx_)); + + if (ctx->head_ == nullptr) { + ctx->head_ = functor; + } + if (ctx->tail_ != nullptr) { + ctx->tail_->internal_next = functor; + } + ctx->tail_ = functor; + } + + private: + grpc_experimental_completion_queue_functor* head_{nullptr}; + grpc_experimental_completion_queue_functor* tail_{nullptr}; + GPR_TLS_CLASS_DECL(callback_exec_ctx_); +}; } // namespace grpc_core #endif /* GRPC_CORE_LIB_IOMGR_EXEC_CTX_H */ diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index 2703e1a0b77..34683273cf6 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -111,6 +111,13 @@ size_t Executor::RunClosures(const char* executor_name, grpc_closure_list list) { size_t n = 0; + // In the executor, the ExecCtx for the thread is declared + // in the executor thread itself, but this is the point where we + // could start seeing application-level callbacks. No need to + // create a new ExecCtx, though, since there already is one and it is + // flushed (but not destructed) in this function itself + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_closure* c = list.head; while (c != nullptr) { grpc_closure* next = c->next_data.next; diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index cb123298cf5..1da242938a2 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -105,6 +105,13 @@ void grpc_timer_manager_tick() { } static void run_some_timers() { + // In the case of timers, the ExecCtx for the thread is declared + // in the timer thread itself, but this is the point where we + // could start seeing application-level callbacks. No need to + // create a new ExecCtx, though, since there already is one and it is + // flushed (but not destructed) in this function itself + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + // if there's something to execute... gpr_mu_lock(&g_mu); // remove a waiter from the pool, and start another thread if necessary diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 89b3f77822c..d53eb704420 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -556,6 +556,7 @@ void grpc_call_unref(grpc_call* c) { GPR_TIMER_SCOPE("grpc_call_unref", 0); child_call* cc = c->child; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_call_unref(c=%p)", 1, (c)); @@ -597,6 +598,7 @@ void grpc_call_unref(grpc_call* c) { grpc_call_error grpc_call_cancel(grpc_call* call, void* reserved) { GRPC_API_TRACE("grpc_call_cancel(call=%p, reserved=%p)", 2, (call, reserved)); GPR_ASSERT(!reserved); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; cancel_with_error(call, GRPC_ERROR_CANCELLED); return GRPC_CALL_OK; @@ -646,6 +648,7 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call* c, grpc_status_code status, const char* description, void* reserved) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE( "grpc_call_cancel_with_status(" @@ -1894,7 +1897,6 @@ done_with_error: grpc_call_error grpc_call_start_batch(grpc_call* call, const grpc_op* ops, size_t nops, void* tag, void* reserved) { - grpc_core::ExecCtx exec_ctx; grpc_call_error err; GRPC_API_TRACE( @@ -1905,6 +1907,8 @@ grpc_call_error grpc_call_start_batch(grpc_call* call, const grpc_op* ops, if (reserved != nullptr) { err = GRPC_CALL_ERROR; } else { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; err = call_start_batch(call, ops, nops, tag, 0); } diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 661022ec5f1..426a4a3f24e 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -868,7 +868,7 @@ static void cq_end_op_for_callback( GRPC_ERROR_UNREF(error); auto* functor = static_cast(tag); - (*functor->functor_run)(functor, is_success); + grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, is_success); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, @@ -1352,7 +1352,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - (*callback->functor_run)(callback, true); + grpc_core::ApplicationCallbackExecCtx::Enqueue(callback, true); } static void cq_shutdown_callback(grpc_completion_queue* cq) { @@ -1385,6 +1385,7 @@ static void cq_shutdown_callback(grpc_completion_queue* cq) { to zero here, then enter shutdown mode and wake up any waiters */ void grpc_completion_queue_shutdown(grpc_completion_queue* cq) { GPR_TIMER_SCOPE("grpc_completion_queue_shutdown", 0); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_completion_queue_shutdown(cq=%p)", 1, (cq)); cq->vtable->shutdown(cq); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index cdfd3336437..c20796f5acf 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1302,6 +1302,7 @@ void grpc_server_shutdown_and_notify(grpc_server* server, listener* l; shutdown_tag* sdt; channel_broadcaster broadcaster; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3, @@ -1369,6 +1370,7 @@ void grpc_server_shutdown_and_notify(grpc_server* server, void grpc_server_cancel_all_calls(grpc_server* server) { channel_broadcaster broadcaster; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_server_cancel_all_calls(server=%p)", 1, (server)); @@ -1384,6 +1386,7 @@ void grpc_server_cancel_all_calls(grpc_server* server) { void grpc_server_destroy(grpc_server* server) { listener* l; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server)); @@ -1469,6 +1472,7 @@ grpc_call_error grpc_server_request_call( grpc_completion_queue* cq_bound_to_call, grpc_completion_queue* cq_for_notification, void* tag) { grpc_call_error error; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; requested_call* rc = static_cast(gpr_malloc(sizeof(*rc))); GRPC_STATS_INC_SERVER_REQUESTED_CALLS(); @@ -1515,11 +1519,11 @@ grpc_call_error grpc_server_request_registered_call( grpc_metadata_array* initial_metadata, grpc_byte_buffer** optional_payload, grpc_completion_queue* cq_bound_to_call, grpc_completion_queue* cq_for_notification, void* tag) { - grpc_call_error error; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; + GRPC_STATS_INC_SERVER_REQUESTED_CALLS(); requested_call* rc = static_cast(gpr_malloc(sizeof(*rc))); registered_method* rm = static_cast(rmp); - GRPC_STATS_INC_SERVER_REQUESTED_CALLS(); GRPC_API_TRACE( "grpc_server_request_registered_call(" "server=%p, rmp=%p, call=%p, deadline=%p, initial_metadata=%p, " @@ -1537,19 +1541,17 @@ grpc_call_error grpc_server_request_registered_call( } if (cq_idx == server->cq_count) { gpr_free(rc); - error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE; - goto done; + return GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE; } if ((optional_payload == nullptr) != (rm->payload_handling == GRPC_SRM_PAYLOAD_NONE)) { gpr_free(rc); - error = GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH; - goto done; + return GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH; } + if (grpc_cq_begin_op(cq_for_notification, tag) == false) { gpr_free(rc); - error = GRPC_CALL_ERROR_COMPLETION_QUEUE_SHUTDOWN; - goto done; + return GRPC_CALL_ERROR_COMPLETION_QUEUE_SHUTDOWN; } rc->cq_idx = cq_idx; rc->type = REGISTERED_CALL; @@ -1561,10 +1563,7 @@ grpc_call_error grpc_server_request_registered_call( rc->data.registered.deadline = deadline; rc->initial_metadata = initial_metadata; rc->data.registered.optional_payload = optional_payload; - error = queue_call_request(server, cq_idx, rc); -done: - - return error; + return queue_call_request(server, cq_idx, rc); } static void fail_call(grpc_server* server, size_t cq_idx, requested_call* rc, diff --git a/src/cpp/common/alarm.cc b/src/cpp/common/alarm.cc index 148f0b9bc94..6bfe26f04c4 100644 --- a/src/cpp/common/alarm.cc +++ b/src/cpp/common/alarm.cc @@ -52,6 +52,7 @@ class AlarmImpl : public ::grpc::internal::CompletionQueueTag { return true; } void Set(::grpc::CompletionQueue* cq, gpr_timespec deadline, void* tag) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; GRPC_CQ_INTERNAL_REF(cq->cq(), "alarm"); cq_ = cq->cq(); @@ -72,6 +73,7 @@ class AlarmImpl : public ::grpc::internal::CompletionQueueTag { &on_alarm_); } void Set(gpr_timespec deadline, std::function f) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; // Don't use any CQ at all. Instead just use the timer to fire the function callback_ = std::move(f); @@ -87,6 +89,7 @@ class AlarmImpl : public ::grpc::internal::CompletionQueueTag { &on_alarm_); } void Cancel() { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; grpc_timer_cancel(&timer_); } diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 13741ce7aa5..12aa52ef704 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -59,7 +59,15 @@ namespace { #define DEFAULT_MAX_SYNC_SERVER_THREADS INT_MAX // How many callback requests of each method should we pre-register at start -#define DEFAULT_CALLBACK_REQS_PER_METHOD 32 +#define DEFAULT_CALLBACK_REQS_PER_METHOD 512 + +// What is the (soft) limit for outstanding requests in the server +#define MAXIMUM_CALLBACK_REQS_OUTSTANDING 30000 + +// If the number of unmatched requests for a method drops below this amount, +// try to allocate extra unless it pushes the total number of callbacks above +// the soft maximum +#define SOFT_MINIMUM_SPARE_CALLBACK_REQS_PER_METHOD 128 class DefaultGlobalCallbacks final : public Server::GlobalCallbacks { public: @@ -343,9 +351,10 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { class Server::CallbackRequest final : public internal::CompletionQueueTag { public: - CallbackRequest(Server* server, internal::RpcServiceMethod* method, - void* method_tag) + CallbackRequest(Server* server, Server::MethodReqList* list, + internal::RpcServiceMethod* method, void* method_tag) : server_(server), + req_list_(list), method_(method), method_tag_(method_tag), has_request_payload_( @@ -353,12 +362,22 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { method->method_type() == internal::RpcMethod::SERVER_STREAMING), cq_(server->CallbackCQ()), tag_(this) { + server_->callback_reqs_outstanding_++; Setup(); } - ~CallbackRequest() { Clear(); } + ~CallbackRequest() { + Clear(); - void Request() { + // The counter of outstanding requests must be decremented + // under a lock in case it causes the server shutdown. + std::lock_guard l(server_->callback_reqs_mu_); + if (--server_->callback_reqs_outstanding_ == 0) { + server_->callback_reqs_done_cv_.notify_one(); + } + } + + bool Request() { if (method_tag_) { if (GRPC_CALL_OK != grpc_server_request_registered_call( @@ -366,7 +385,7 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { &request_metadata_, has_request_payload_ ? &request_payload_ : nullptr, cq_->cq(), cq_->cq(), static_cast(&tag_))) { - return; + return false; } } else { if (!call_details_) { @@ -376,9 +395,10 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { if (grpc_server_request_call(server_->c_server(), &call_, call_details_, &request_metadata_, cq_->cq(), cq_->cq(), static_cast(&tag_)) != GRPC_CALL_OK) { - return; + return false; } } + return true; } bool FinalizeResult(void** tag, bool* status) override { return false; } @@ -409,10 +429,48 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { GPR_ASSERT(!req_->FinalizeResult(&ignored, &new_ok)); GPR_ASSERT(ignored == req_); - if (!ok) { - // The call has been shutdown - req_->Clear(); - return; + bool spawn_new = false; + { + std::unique_lock l(req_->req_list_->reqs_mu); + req_->req_list_->reqs_list.erase(req_->req_list_iterator_); + req_->req_list_->reqs_list_sz--; + if (!ok) { + // The call has been shutdown. + // Delete its contents to free up the request. + // First release the lock in case the deletion of the request + // completes the full server shutdown and allows the destructor + // of the req_list to proceed. + l.unlock(); + delete req_; + return; + } + + // If this was the last request in the list or it is below the soft + // minimum and there are spare requests available, set up a new one, but + // do it outside the lock since the Request could otherwise deadlock + if (req_->req_list_->reqs_list_sz == 0 || + (req_->req_list_->reqs_list_sz < + SOFT_MINIMUM_SPARE_CALLBACK_REQS_PER_METHOD && + req_->server_->callback_reqs_outstanding_ < + MAXIMUM_CALLBACK_REQS_OUTSTANDING)) { + spawn_new = true; + } + } + if (spawn_new) { + auto* new_req = new CallbackRequest(req_->server_, req_->req_list_, + req_->method_, req_->method_tag_); + if (!new_req->Request()) { + // The server must have just decided to shutdown. Erase + // from the list under lock but release the lock before + // deleting the new_req (in case that request was what + // would allow the destruction of the req_list) + { + std::lock_guard l(new_req->req_list_->reqs_mu); + new_req->req_list_->reqs_list.erase(new_req->req_list_iterator_); + new_req->req_list_->reqs_list_sz--; + } + delete new_req; + } } // Bind the call, deadline, and metadata from what we got @@ -462,17 +520,30 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { internal::MethodHandler::HandlerParameter( call_, &req_->ctx_, req_->request_, req_->request_status_, [this] { - req_->Reset(); - req_->Request(); + // Recycle this request if there aren't too many outstanding. + // Note that we don't have to worry about a case where there + // are no requests waiting to match for this method since that + // is already taken care of when binding a request to a call. + // TODO(vjpai): Also don't recycle this request if the dynamic + // load no longer justifies it. Consider measuring + // dynamic load and setting a target accordingly. + if (req_->server_->callback_reqs_outstanding_ < + MAXIMUM_CALLBACK_REQS_OUTSTANDING) { + req_->Clear(); + req_->Setup(); + } else { + // We can free up this request because there are too many + delete req_; + return; + } + if (!req_->Request()) { + // The server must have just decided to shutdown. + delete req_; + } })); } }; - void Reset() { - Clear(); - Setup(); - } - void Clear() { if (call_details_) { delete call_details_; @@ -492,9 +563,15 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { request_payload_ = nullptr; request_ = nullptr; request_status_ = Status(); + std::lock_guard l(req_list_->reqs_mu); + req_list_->reqs_list.push_front(this); + req_list_->reqs_list_sz++; + req_list_iterator_ = req_list_->reqs_list.begin(); } Server* const server_; + Server::MethodReqList* req_list_; + Server::MethodReqList::iterator req_list_iterator_; internal::RpcServiceMethod* const method_; void* const method_tag_; const bool has_request_payload_; @@ -715,6 +792,13 @@ Server::~Server() { } grpc_server_destroy(server_); + for (auto* method_list : callback_reqs_) { + // The entries of the method_list should have already been emptied + // during Shutdown as each request is failed by Shutdown. Check that + // this actually happened. + GPR_ASSERT(method_list->reqs_list.empty()); + delete method_list; + } } void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) { @@ -794,10 +878,12 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { } } else { // a callback method. Register at least some callback requests + callback_reqs_.push_back(new Server::MethodReqList); + auto* method_req_list = callback_reqs_.back(); // TODO(vjpai): Register these dynamically based on need for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) { - auto* req = new CallbackRequest(this, method, method_registration_tag); - callback_reqs_.emplace_back(req); + new CallbackRequest(this, method_req_list, method, + method_registration_tag); } // Enqueue it so that it will be Request'ed later once // all request matchers are created at core server startup @@ -889,8 +975,10 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { (*it)->Start(); } - for (auto& cbreq : callback_reqs_) { - cbreq->Request(); + for (auto* cbmethods : callback_reqs_) { + for (auto* cbreq : cbmethods->reqs_list) { + GPR_ASSERT(cbreq->Request()); + } } if (default_health_check_service_impl != nullptr) { @@ -900,49 +988,69 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { void Server::ShutdownInternal(gpr_timespec deadline) { std::unique_lock lock(mu_); - if (!shutdown_) { - shutdown_ = true; - - /// The completion queue to use for server shutdown completion notification - CompletionQueue shutdown_cq; - ShutdownTag shutdown_tag; // Dummy shutdown tag - grpc_server_shutdown_and_notify(server_, shutdown_cq.cq(), &shutdown_tag); - - shutdown_cq.Shutdown(); - - void* tag; - bool ok; - CompletionQueue::NextStatus status = - shutdown_cq.AsyncNext(&tag, &ok, deadline); - - // If this timed out, it means we are done with the grace period for a clean - // shutdown. We should force a shutdown now by cancelling all inflight calls - if (status == CompletionQueue::NextStatus::TIMEOUT) { - grpc_server_cancel_all_calls(server_); - } - // Else in case of SHUTDOWN or GOT_EVENT, it means that the server has - // successfully shutdown - - // Shutdown all ThreadManagers. This will try to gracefully stop all the - // threads in the ThreadManagers (once they process any inflight requests) - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->Shutdown(); // ThreadManager's Shutdown() - } - - // Wait for threads in all ThreadManagers to terminate - for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { - (*it)->Wait(); - } - - // Drain the shutdown queue (if the previous call to AsyncNext() timed out - // and we didn't remove the tag from the queue yet) - while (shutdown_cq.Next(&tag, &ok)) { - // Nothing to be done here. Just ignore ok and tag values - } - - shutdown_notified_ = true; - shutdown_cv_.notify_all(); + if (shutdown_) { + return; } + + shutdown_ = true; + + /// The completion queue to use for server shutdown completion notification + CompletionQueue shutdown_cq; + ShutdownTag shutdown_tag; // Dummy shutdown tag + grpc_server_shutdown_and_notify(server_, shutdown_cq.cq(), &shutdown_tag); + + shutdown_cq.Shutdown(); + + void* tag; + bool ok; + CompletionQueue::NextStatus status = + shutdown_cq.AsyncNext(&tag, &ok, deadline); + + // If this timed out, it means we are done with the grace period for a clean + // shutdown. We should force a shutdown now by cancelling all inflight calls + if (status == CompletionQueue::NextStatus::TIMEOUT) { + grpc_server_cancel_all_calls(server_); + } + // Else in case of SHUTDOWN or GOT_EVENT, it means that the server has + // successfully shutdown + + // Shutdown all ThreadManagers. This will try to gracefully stop all the + // threads in the ThreadManagers (once they process any inflight requests) + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->Shutdown(); // ThreadManager's Shutdown() + } + + // Wait for threads in all ThreadManagers to terminate + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { + (*it)->Wait(); + } + + // Wait for all outstanding callback requests to complete + // (whether waiting for a match or already active). + // We know that no new requests will be created after this point + // because they are only created at server startup time or when + // we have a successful match on a request. During the shutdown phase, + // requests that have not yet matched will be failed rather than + // allowed to succeed, which will cause the server to delete the + // request and decrement the count. Possibly a request will match before + // the shutdown but then find that shutdown has already started by the + // time it tries to register a new request. In that case, the registration + // will report a failure, indicating a shutdown and again we won't end + // up incrementing the counter. + { + std::unique_lock cblock(callback_reqs_mu_); + callback_reqs_done_cv_.wait( + cblock, [this] { return callback_reqs_outstanding_ == 0; }); + } + + // Drain the shutdown queue (if the previous call to AsyncNext() timed out + // and we didn't remove the tag from the queue yet) + while (shutdown_cq.Next(&tag, &ok)) { + // Nothing to be done here. Just ignore ok and tag values + } + + shutdown_notified_ = true; + shutdown_cv_.notify_all(); } void Server::Wait() { diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index a157d75edab..7c3630eaf18 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -389,46 +389,49 @@ static void test_callback(void) { attr.cq_shutdown_cb = &shutdown_cb; for (size_t pidx = 0; pidx < GPR_ARRAY_SIZE(polling_types); pidx++) { - grpc_core::ExecCtx exec_ctx; // reset exec_ctx - attr.cq_polling_type = polling_types[pidx]; - cc = grpc_completion_queue_create( - grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); - + int sumtags = 0; int counter = 0; - class TagCallback : public grpc_experimental_completion_queue_functor { - public: - TagCallback(int* counter, int tag) : counter_(counter), tag_(tag) { - functor_run = &TagCallback::Run; - } - ~TagCallback() {} - static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { - GPR_ASSERT(static_cast(ok)); - auto* callback = static_cast(cb); - *callback->counter_ += callback->tag_; - grpc_core::Delete(callback); + { + // reset exec_ctx types + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ExecCtx exec_ctx; + attr.cq_polling_type = polling_types[pidx]; + cc = grpc_completion_queue_create( + grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); + + class TagCallback : public grpc_experimental_completion_queue_functor { + public: + TagCallback(int* counter, int tag) : counter_(counter), tag_(tag) { + functor_run = &TagCallback::Run; + } + ~TagCallback() {} + static void Run(grpc_experimental_completion_queue_functor* cb, + int ok) { + GPR_ASSERT(static_cast(ok)); + auto* callback = static_cast(cb); + *callback->counter_ += callback->tag_; + grpc_core::Delete(callback); + }; + + private: + int* counter_; + int tag_; }; - private: - int* counter_; - int tag_; - }; + for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { + tags[i] = static_cast(grpc_core::New(&counter, i)); + sumtags += i; + } - int sumtags = 0; - for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { - tags[i] = static_cast(grpc_core::New(&counter, i)); - sumtags += i; + for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { + GPR_ASSERT(grpc_cq_begin_op(cc, tags[i])); + grpc_cq_end_op(cc, tags[i], GRPC_ERROR_NONE, do_nothing_end_completion, + nullptr, &completions[i]); + } + + shutdown_and_destroy(cc); } - - for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { - GPR_ASSERT(grpc_cq_begin_op(cc, tags[i])); - grpc_cq_end_op(cc, tags[i], GRPC_ERROR_NONE, do_nothing_end_completion, - nullptr, &completions[i]); - } - GPR_ASSERT(sumtags == counter); - - shutdown_and_destroy(cc); - GPR_ASSERT(got_shutdown); got_shutdown = false; } diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 650152ecc0d..dcfaa684773 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -101,8 +101,6 @@ class DummyEndpoint : public grpc_endpoint { GRPC_CLOSURE_SCHED(cb, GRPC_ERROR_NONE); } - static grpc_workqueue* get_workqueue(grpc_endpoint* ep) { return nullptr; } - static void add_to_pollset(grpc_endpoint* ep, grpc_pollset* pollset) {} static void add_to_pollset_set(grpc_endpoint* ep, grpc_pollset_set* pollset) { From e230b2fce919b6d9ed9c97df12f337a28edb58ec Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 18 Jan 2019 16:56:29 -0800 Subject: [PATCH 142/814] Don't offload write to executor if already running from a background thread --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index fe88d4818e4..c2b57ed2905 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -43,6 +43,7 @@ #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" @@ -963,6 +964,10 @@ void grpc_chttp2_mark_stream_writable(grpc_chttp2_transport* t, static grpc_closure_scheduler* write_scheduler(grpc_chttp2_transport* t, bool early_results_scheduled, bool partial_write) { + // If we're already in a background poller, don't offload this to an executor + if (grpc_iomgr_is_any_background_poller_thread()) { + return grpc_schedule_on_exec_ctx; + } /* if it's not the first write in a batch, always offload to the executor: we'll probably end up queuing against the kernel anyway, so we'll likely get better latency overall if we switch writing work elsewhere and continue From 7b7d52e4cc0ccd7c1dc76afe9c9387f32edf399e Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 23 Jan 2019 11:42:45 -0800 Subject: [PATCH 143/814] Condition another executor offload on stream destruction --- src/core/lib/transport/transport.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index 43add28ce03..8be0b91b654 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -30,6 +30,7 @@ #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/transport/transport_impl.h" @@ -63,8 +64,9 @@ void grpc_stream_unref(grpc_stream_refcount* refcount, const char* reason) { void grpc_stream_unref(grpc_stream_refcount* refcount) { #endif if (gpr_unref(&refcount->refs)) { - if (grpc_core::ExecCtx::Get()->flags() & - GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP) { + if (!grpc_iomgr_is_any_background_poller_thread() && + (grpc_core::ExecCtx::Get()->flags() & + GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP)) { /* Ick. The thread we're running on MAY be owned (indirectly) by a call-stack. If that's the case, destroying the call-stack MAY try to destroy the From b60c5cdc82ef8a037cc8a83806f681267570aa46 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 23 Jan 2019 12:26:05 -0800 Subject: [PATCH 144/814] Adopte reviewer's suggestion --- src/python/grpcio_tests/tests/qps/README.md | 2 +- src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python/grpcio_tests/tests/qps/README.md b/src/python/grpcio_tests/tests/qps/README.md index 504a2189f73..f5149509ce3 100644 --- a/src/python/grpcio_tests/tests/qps/README.md +++ b/src/python/grpcio_tests/tests/qps/README.md @@ -21,7 +21,7 @@ Here I picked the top 2 most representative scenarios of them, and reduce their ## Why keep the scenario file if it can be generated? -Well... The `tools/run_tests/performance/scenario_config.py` is 1274 lines long. The intention of building these benchmark tools is reducing the complexity of existing infrastructure code. Depending on something that is +Well... The `tools/run_tests/performance/scenario_config.py` is 1274 lines long. The intention of building these benchmark tools is reducing the complexity of existing infrastructure code. So, instead of calling layers of abstraction to generate the scenario file, keeping a valid static copy is more preferable. ## How to run it? diff --git a/src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh b/src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh index 6011a7e01c2..fecb528396a 100755 --- a/src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh +++ b/src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh @@ -22,10 +22,10 @@ SCENARIOS_FILE=src/python/grpcio_tests/tests/qps/scenarios.json function join { local IFS="$1"; shift; echo "$*"; } if [[ -e "${SCENARIOS_FILE}" ]]; then - echo "Running against scenarios.json:" + echo "Running against ${SCENARIOS_FILE}:" cat "${SCENARIOS_FILE}" else - echo "Failed to find scenarios.json!" + echo "Failed to find ${SCENARIOS_FILE}!" exit 1 fi From 2fd079ff7cae2850174c525aeb3601673c683377 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 23 Jan 2019 20:10:17 +0100 Subject: [PATCH 145/814] Channel folding. --- include/grpcpp/channel.h | 84 +------------ include/grpcpp/channel_impl.h | 114 ++++++++++++++++++ include/grpcpp/impl/codegen/client_callback.h | 5 +- include/grpcpp/impl/codegen/client_context.h | 13 +- .../grpcpp/impl/codegen/client_interceptor.h | 7 +- .../grpcpp/impl/codegen/completion_queue.h | 9 +- .../grpcpp/impl/codegen/server_interface.h | 5 +- include/grpcpp/security/credentials.h | 17 ++- include/grpcpp/server.h | 1 + src/compiler/cpp_generator.cc | 4 +- src/cpp/client/channel_cc.cc | 48 ++++---- src/cpp/client/client_context.cc | 8 +- src/cpp/client/create_channel.cc | 4 +- src/cpp/client/create_channel_internal.cc | 7 +- src/cpp/client/create_channel_internal.h | 5 +- src/cpp/client/create_channel_posix.cc | 6 +- src/cpp/client/insecure_credentials.cc | 2 +- src/cpp/client/secure_credentials.cc | 2 +- src/cpp/client/secure_credentials.h | 10 +- src/cpp/server/server_cc.cc | 4 +- test/cpp/microbenchmarks/bm_call_create.cc | 2 +- test/cpp/microbenchmarks/fullstack_fixtures.h | 2 +- test/cpp/performance/writes_per_rpc_test.cc | 2 +- test/cpp/util/create_test_channel.h | 19 +-- 24 files changed, 234 insertions(+), 146 deletions(-) create mode 100644 include/grpcpp/channel_impl.h diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h index ee833960698..a2eba75c891 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -19,96 +19,18 @@ #ifndef GRPCPP_CHANNEL_H #define GRPCPP_CHANNEL_H -#include -#include - -#include -#include -#include -#include -#include -#include +#include struct grpc_channel; namespace grpc { +typedef ::grpc_impl::Channel Channel; + namespace experimental { -/// Resets the channel's connection backoff. -/// TODO(roth): Once we see whether this proves useful, either create a gRFC -/// and change this to be a method of the Channel class, or remove it. void ChannelResetConnectionBackoff(Channel* channel); } // namespace experimental -/// Channels represent a connection to an endpoint. Created by \a CreateChannel. -class Channel final : public ChannelInterface, - public internal::CallHook, - public std::enable_shared_from_this, - private GrpcLibraryCodegen { - public: - ~Channel(); - - /// Get the current channel state. If the channel is in IDLE and - /// \a try_to_connect is set to true, try to connect. - grpc_connectivity_state GetState(bool try_to_connect) override; - - /// Returns the LB policy name, or the empty string if not yet available. - grpc::string GetLoadBalancingPolicyName() const; - - /// Returns the service config in JSON form, or the empty string if - /// not available. - grpc::string GetServiceConfigJSON() const; - - private: - template - friend class internal::BlockingUnaryCallImpl; - friend void experimental::ChannelResetConnectionBackoff(Channel* channel); - friend std::shared_ptr CreateChannelInternal( - const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr> - interceptor_creators); - friend class internal::InterceptedChannel; - Channel(const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr> - interceptor_creators); - - internal::Call CreateCall(const internal::RpcMethod& method, - ClientContext* context, - CompletionQueue* cq) override; - void PerformOpsOnCall(internal::CallOpSetInterface* ops, - internal::Call* call) override; - void* RegisterMethod(const char* method) override; - - void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline, CompletionQueue* cq, - void* tag) override; - bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline) override; - - CompletionQueue* CallbackCQ() override; - - internal::Call CreateCallInternal(const internal::RpcMethod& method, - ClientContext* context, CompletionQueue* cq, - size_t interceptor_pos) override; - - const grpc::string host_; - grpc_channel* const c_channel_; // owned - - // mu_ protects callback_cq_ (the per-channel callbackable completion queue) - std::mutex mu_; - - // callback_cq_ references the callbackable completion queue associated - // with this channel (if any). It is set on the first call to CallbackCQ(). - // It is _not owned_ by the channel; ownership belongs with its internal - // shutdown callback tag (invoked when the CQ is fully shutdown). - CompletionQueue* callback_cq_ = nullptr; - - std::vector> - interceptor_creators_; -}; - } // namespace grpc #endif // GRPCPP_CHANNEL_H diff --git a/include/grpcpp/channel_impl.h b/include/grpcpp/channel_impl.h new file mode 100644 index 00000000000..19198655e99 --- /dev/null +++ b/include/grpcpp/channel_impl.h @@ -0,0 +1,114 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_CHANNEL_IMPL_H +#define GRPCPP_CHANNEL_IMPL_H + +#include +#include + +#include +#include +#include +#include +#include +#include + +struct grpc_channel; + +namespace grpc_impl { + +namespace experimental { +/// Resets the channel's connection backoff. +/// TODO(roth): Once we see whether this proves useful, either create a gRFC +/// and change this to be a method of the Channel class, or remove it. +void ChannelResetConnectionBackoff(Channel* channel); +} // namespace experimental + +/// Channels represent a connection to an endpoint. Created by \a CreateChannel. +class Channel final : public ::grpc::ChannelInterface, + public ::grpc::internal::CallHook, + public std::enable_shared_from_this, + private ::grpc::GrpcLibraryCodegen { + public: + ~Channel(); + + /// Get the current channel state. If the channel is in IDLE and + /// \a try_to_connect is set to true, try to connect. + grpc_connectivity_state GetState(bool try_to_connect) override; + + /// Returns the LB policy name, or the empty string if not yet available. + grpc::string GetLoadBalancingPolicyName() const; + + /// Returns the service config in JSON form, or the empty string if + /// not available. + grpc::string GetServiceConfigJSON() const; + + private: + template + friend class ::grpc::internal::BlockingUnaryCallImpl; + friend void experimental::ChannelResetConnectionBackoff(Channel* channel); + friend std::shared_ptr CreateChannelInternal( + const grpc::string& host, grpc_channel* c_channel, + std::vector< + std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> + interceptor_creators); + friend class ::grpc::internal::InterceptedChannel; + Channel(const grpc::string& host, grpc_channel* c_channel, + std::vector< + std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> + interceptor_creators); + + ::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method, + ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq) override; + void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, + ::grpc::internal::Call* call) override; + void* RegisterMethod(const char* method) override; + + void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, + gpr_timespec deadline, ::grpc::CompletionQueue* cq, + void* tag) override; + bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, + gpr_timespec deadline) override; + + ::grpc::CompletionQueue* CallbackCQ() override; + + ::grpc::internal::Call CreateCallInternal(const ::grpc::internal::RpcMethod& method, + ::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, + size_t interceptor_pos) override; + + const grpc::string host_; + grpc_channel* const c_channel_; // owned + + // mu_ protects callback_cq_ (the per-channel callbackable completion queue) + std::mutex mu_; + + // callback_cq_ references the callbackable completion queue associated + // with this channel (if any). It is set on the first call to CallbackCQ(). + // It is _not owned_ by the channel; ownership belongs with its internal + // shutdown callback tag (invoked when the CQ is fully shutdown). + ::grpc::CompletionQueue* callback_cq_ = nullptr; + + std::vector> + interceptor_creators_; +}; + +} // namespace grpc + +#endif // GRPCPP_CHANNEL_H diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 52bcea99706..6a0d0948cc6 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -29,9 +29,12 @@ #include #include +namespace grpc_impl { +class Channel; +} + namespace grpc { -class Channel; class ClientContext; class CompletionQueue; diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 5946488566e..edb583542dd 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -56,9 +56,14 @@ struct census_context; struct grpc_call; -namespace grpc { +namespace grpc_impl { class Channel; + +} + +namespace grpc { + class ChannelInterface; class CompletionQueue; class CallCredentials; @@ -391,7 +396,7 @@ class ClientContext { friend class ::grpc::testing::InteropClientContextInspector; friend class ::grpc::internal::CallOpClientRecvStatus; friend class ::grpc::internal::CallOpRecvInitialMetadata; - friend class Channel; + friend class ::grpc_impl::Channel; template friend class ::grpc::ClientReader; template @@ -423,7 +428,7 @@ class ClientContext { } grpc_call* call() const { return call_; } - void set_call(grpc_call* call, const std::shared_ptr& channel); + void set_call(grpc_call* call, const std::shared_ptr<::grpc_impl::Channel>& channel); experimental::ClientRpcInfo* set_client_rpc_info( const char* method, internal::RpcMethod::RpcType type, @@ -456,7 +461,7 @@ class ClientContext { bool wait_for_ready_explicitly_set_; bool idempotent_; bool cacheable_; - std::shared_ptr channel_; + std::shared_ptr<::grpc_impl::Channel> channel_; std::mutex mu_; grpc_call* call_; bool call_canceled_; diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 7dfe2290a3f..3e8eced6391 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -26,10 +26,15 @@ #include #include +namespace grpc_impl { + +class Channel; + +} + namespace grpc { class ClientContext; -class Channel; namespace internal { class InterceptorBatchMethodsImpl; diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index fb38788f7d6..7493aa8ba49 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -41,6 +41,12 @@ struct grpc_completion_queue; +namespace grpc_impl { + +class Channel; + +} + namespace grpc { template @@ -58,7 +64,6 @@ template class ServerReaderWriterBody; } // namespace internal -class Channel; class ChannelInterface; class ClientContext; class CompletionQueue; @@ -276,7 +281,7 @@ class CompletionQueue : private GrpcLibraryCodegen { friend class ::grpc::internal::BlockingUnaryCallImpl; // Friends that need access to constructor for callback CQ - friend class ::grpc::Channel; + friend class ::grpc_impl::Channel; /// EXPERIMENTAL /// Creates a Thread Local cache to store the first event diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index 890a5650d02..b056643269a 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -28,10 +28,13 @@ #include #include +namespace grpc_impl { +class Channel; +} + namespace grpc { class AsyncGenericService; -class Channel; class GenericServerContext; class ServerCompletionQueue; class ServerContext; diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index d8c9e04d778..551d9d1576f 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -32,9 +32,14 @@ struct grpc_call; +namespace grpc_impl { + +class Channel; + +} + namespace grpc { class ChannelArguments; -class Channel; class SecureChannelCredentials; class CallCredentials; class SecureCallCredentials; @@ -42,7 +47,7 @@ class SecureCallCredentials; class ChannelCredentials; namespace experimental { -std::shared_ptr CreateCustomChannelWithInterceptors( +std::shared_ptr<::grpc_impl::Channel> CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, @@ -70,12 +75,12 @@ class ChannelCredentials : private GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr CreateCustomChannel( + friend std::shared_ptr<::grpc_impl::Channel> CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args); - friend std::shared_ptr + friend std::shared_ptr<::grpc_impl::Channel> experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, @@ -84,12 +89,12 @@ class ChannelCredentials : private GrpcLibraryCodegen { std::unique_ptr> interceptor_creators); - virtual std::shared_ptr CreateChannel( + virtual std::shared_ptr<::grpc_impl::Channel> CreateChannel( const grpc::string& target, const ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is // implemented as a virtual function so that it does not break API. - virtual std::shared_ptr CreateChannelWithInterceptors( + virtual std::shared_ptr<::grpc_impl::Channel> CreateChannelWithInterceptors( const grpc::string& target, const ChannelArguments& args, std::vector< std::unique_ptr> diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index cdcac186cb6..caf03142918 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index b0046872502..e98abdd082a 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -145,9 +145,11 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, PrintIncludes(printer.get(), headers, params.use_system_headers, params.grpc_search_path); printer->Print(vars, "\n"); + printer->Print(vars, "namespace grpc_impl {\n"); + printer->Print(vars, "class Channel;\n"); + printer->Print(vars, "} // namespace grpc_impl\n\n"); printer->Print(vars, "namespace grpc {\n"); printer->Print(vars, "class CompletionQueue;\n"); - printer->Print(vars, "class Channel;\n"); printer->Print(vars, "class ServerCompletionQueue;\n"); printer->Print(vars, "class ServerContext;\n"); printer->Print(vars, "} // namespace grpc\n\n"); diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index a31d0b30b15..9724dcad08d 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -49,13 +49,17 @@ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/surface/completion_queue.h" -namespace grpc { +void grpc::experimental::ChannelResetConnectionBackoff(::grpc::Channel* channel) { + ChannelResetConnectionBackoff(channel); +} -static internal::GrpcLibraryInitializer g_gli_initializer; +namespace grpc_impl { + +static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; Channel::Channel( const grpc::string& host, grpc_channel* channel, std::vector< - std::unique_ptr> + std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators) : host_(host), c_channel_(channel) { interceptor_creators_ = std::move(interceptor_creators); @@ -72,7 +76,7 @@ Channel::~Channel() { namespace { inline grpc_slice SliceFromArray(const char* arr, size_t len) { - return g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); + return ::grpc::g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); } grpc::string GetChannelInfoField(grpc_channel* channel, @@ -110,9 +114,9 @@ void ChannelResetConnectionBackoff(Channel* channel) { } // namespace experimental -internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, - ClientContext* context, - CompletionQueue* cq, +::grpc::internal::Call Channel::CreateCallInternal(const ::grpc::internal::RpcMethod& method, + ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq, size_t interceptor_pos) { const bool kRegistered = method.channel_tag() && context->authority().empty(); grpc_call* c_call = nullptr; @@ -122,7 +126,7 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, context->propagation_options_.c_bitmask(), cq->cq(), method.channel_tag(), context->raw_deadline(), nullptr); } else { - const string* host_str = nullptr; + const ::grpc::string* host_str = nullptr; if (!context->authority_.empty()) { host_str = &context->authority_; } else if (!host_.empty()) { @@ -132,7 +136,7 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, SliceFromArray(method.name(), strlen(method.name())); grpc_slice host_slice; if (host_str != nullptr) { - host_slice = SliceFromCopiedString(*host_str); + host_slice = ::grpc::SliceFromCopiedString(*host_str); } c_call = grpc_channel_create_call( c_channel_, context->propagate_from_call_, @@ -154,17 +158,17 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, interceptor_creators_, interceptor_pos); context->set_call(c_call, shared_from_this()); - return internal::Call(c_call, this, cq, info); + return ::grpc::internal::Call(c_call, this, cq, info); } -internal::Call Channel::CreateCall(const internal::RpcMethod& method, - ClientContext* context, - CompletionQueue* cq) { +::grpc::internal::Call Channel::CreateCall(const ::grpc::internal::RpcMethod& method, + ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq) { return CreateCallInternal(method, context, cq, 0); } -void Channel::PerformOpsOnCall(internal::CallOpSetInterface* ops, - internal::Call* call) { +void Channel::PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, + ::grpc::internal::Call* call) { ops->FillOps( call); // Make a copy of call. It's fine since Call just has pointers } @@ -180,7 +184,7 @@ grpc_connectivity_state Channel::GetState(bool try_to_connect) { namespace { -class TagSaver final : public internal::CompletionQueueTag { +class TagSaver final : public ::grpc::internal::CompletionQueueTag { public: explicit TagSaver(void* tag) : tag_(tag) {} ~TagSaver() override {} @@ -198,7 +202,7 @@ class TagSaver final : public internal::CompletionQueueTag { void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline, - CompletionQueue* cq, void* tag) { + ::grpc::CompletionQueue* cq, void* tag) { TagSaver* tag_saver = new TagSaver(tag); grpc_channel_watch_connectivity_state(c_channel_, last_observed, deadline, cq->cq(), tag_saver); @@ -206,7 +210,7 @@ void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) { - CompletionQueue cq; + ::grpc::CompletionQueue cq; bool ok = false; void* tag = nullptr; NotifyOnStateChangeImpl(last_observed, deadline, &cq, nullptr); @@ -221,7 +225,7 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { ShutdownCallback() { functor_run = &ShutdownCallback::Run; } // TakeCQ takes ownership of the cq into the shutdown callback // so that the shutdown callback will be responsible for destroying it - void TakeCQ(CompletionQueue* cq) { cq_ = cq; } + void TakeCQ(::grpc::CompletionQueue* cq) { cq_ = cq; } // The Run function will get invoked by the completion queue library // when the shutdown is actually complete @@ -232,17 +236,17 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { } private: - CompletionQueue* cq_ = nullptr; + ::grpc::CompletionQueue* cq_ = nullptr; }; } // namespace -CompletionQueue* Channel::CallbackCQ() { +::grpc::CompletionQueue* Channel::CallbackCQ() { // TODO(vjpai): Consider using a single global CQ for the default CQ // if there is no explicit per-channel CQ registered std::lock_guard l(mu_); if (callback_cq_ == nullptr) { auto* shutdown_callback = new ShutdownCallback; - callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{ + callback_cq_ = new ::grpc::CompletionQueue(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, shutdown_callback}); diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index c9ea3e5f83b..68758cfc394 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -30,6 +30,12 @@ #include #include +namespace grpc_impl { + +class Channel; + +} + namespace grpc { class DefaultGlobalClientCallbacks final @@ -82,7 +88,7 @@ void ClientContext::AddMetadata(const grpc::string& meta_key, } void ClientContext::set_call(grpc_call* call, - const std::shared_ptr& channel) { + const std::shared_ptr<::grpc_impl::Channel>& channel) { std::unique_lock lock(mu_); GPR_ASSERT(call_ == nullptr); call_ = call; diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 457daa674c7..409edd207f4 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -40,7 +40,7 @@ std::shared_ptr CreateCustomChannel( const ChannelArguments& args) { GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds. return creds ? creds->CreateChannel(target, args) - : CreateChannelInternal( + : ::grpc_impl::CreateChannelInternal( "", grpc_lame_client_channel_create( nullptr, GRPC_STATUS_INVALID_ARGUMENT, @@ -70,7 +70,7 @@ std::shared_ptr CreateCustomChannelWithInterceptors( interceptor_creators) { return creds ? creds->CreateChannelWithInterceptors( target, args, std::move(interceptor_creators)) - : CreateChannelInternal( + : ::grpc_impl::CreateChannelInternal( "", grpc_lame_client_channel_create( nullptr, GRPC_STATUS_INVALID_ARGUMENT, diff --git a/src/cpp/client/create_channel_internal.cc b/src/cpp/client/create_channel_internal.cc index a0efb97f7ef..1aceee9d37b 100644 --- a/src/cpp/client/create_channel_internal.cc +++ b/src/cpp/client/create_channel_internal.cc @@ -22,14 +22,15 @@ struct grpc_channel; -namespace grpc { +namespace grpc_impl { std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, std::vector< - std::unique_ptr> + std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators) { return std::shared_ptr( new Channel(host, c_channel, std::move(interceptor_creators))); } -} // namespace grpc + +} diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h index a90c92c518d..caa8c5363fb 100644 --- a/src/cpp/client/create_channel_internal.h +++ b/src/cpp/client/create_channel_internal.h @@ -26,13 +26,14 @@ struct grpc_channel; -namespace grpc { +namespace grpc_impl { + class Channel; std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, std::vector< - std::unique_ptr> + std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators); } // namespace grpc diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index 3affc1ef391..79bf10d2801 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -32,7 +32,7 @@ std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, int fd) { internal::GrpcLibrary init_lib; init_lib.init(); - return CreateChannelInternal( + return ::grpc_impl::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr), std::vector< std::unique_ptr>()); @@ -44,7 +44,7 @@ std::shared_ptr CreateCustomInsecureChannelFromFd( init_lib.init(); grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return ::grpc_impl::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), std::vector< @@ -62,7 +62,7 @@ std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( init_lib.init(); grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return ::grpc_impl::CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), std::move(interceptor_creators)); diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 241ce918034..1fa832528b1 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -45,7 +45,7 @@ class InsecureChannelCredentialsImpl final : public ChannelCredentials { interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return ::grpc_impl::CreateChannelInternal( "", grpc_insecure_channel_create(target.c_str(), &channel_args, nullptr), std::move(interceptor_creators)); diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 4d0ed355aba..9ac07f58557 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -50,7 +50,7 @@ SecureChannelCredentials::CreateChannelWithInterceptors( interceptor_creators) { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return ::grpc_impl::CreateChannelInternal( args.GetSslTargetNameOverride(), grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args, nullptr), diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 4918bd5a4d7..04ef0b5e617 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -27,6 +27,12 @@ #include "src/core/lib/security/credentials/credentials.h" #include "src/cpp/server/thread_pool_interface.h" +namespace grpc_impl { + +class Channel; + +} + namespace grpc { class SecureChannelCredentials final : public ChannelCredentials { @@ -37,13 +43,13 @@ class SecureChannelCredentials final : public ChannelCredentials { } grpc_channel_credentials* GetRawCreds() { return c_creds_; } - std::shared_ptr CreateChannel( + std::shared_ptr<::grpc_impl::Channel> CreateChannel( const string& target, const grpc::ChannelArguments& args) override; SecureChannelCredentials* AsSecureCredentials() override { return this; } private: - std::shared_ptr CreateChannelWithInterceptors( + std::shared_ptr<::grpc_impl::Channel> CreateChannelWithInterceptors( const string& target, const grpc::ChannelArguments& args, std::vector< std::unique_ptr> diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 13741ce7aa5..e2b70c9af51 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -728,7 +728,7 @@ grpc_server* Server::c_server() { return server_; } std::shared_ptr Server::InProcessChannel( const ChannelArguments& args) { grpc_channel_args channel_args = args.c_channel_args(); - return CreateChannelInternal( + return ::grpc_impl::CreateChannelInternal( "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr), std::vector< std::unique_ptr>()); @@ -741,7 +741,7 @@ Server::experimental_type::InProcessChannelWithInterceptors( std::unique_ptr> interceptor_creators) { grpc_channel_args channel_args = args.c_channel_args(); - return CreateChannelInternal( + return ::grpc_impl::CreateChannelInternal( "inproc", grpc_inproc_channel_create(server_->server_, &channel_args, nullptr), std::move(interceptor_creators)); diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 125b1ce5c4e..5b3735f286d 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -131,7 +131,7 @@ static void* tag(int i) { static void BM_LameChannelCallCreateCpp(benchmark::State& state) { TrackCounters track_counters; auto stub = - grpc::testing::EchoTestService::NewStub(grpc::CreateChannelInternal( + grpc::testing::EchoTestService::NewStub(grpc_impl::CreateChannelInternal( "", grpc_lame_client_channel_create("localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah"), diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index 6bbf553bbd8..2d488d8b227 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -218,7 +218,7 @@ class EndpointPairFixture : public BaseFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport_); grpc_chttp2_transport_start_reading(client_transport_, nullptr, nullptr); - channel_ = CreateChannelInternal( + channel_ = ::grpc_impl::CreateChannelInternal( "", channel, std::vector>()); diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc index 7b22f23cf00..b531e08138a 100644 --- a/test/cpp/performance/writes_per_rpc_test.cc +++ b/test/cpp/performance/writes_per_rpc_test.cc @@ -118,7 +118,7 @@ class EndpointPairFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); - channel_ = CreateChannelInternal( + channel_ = ::grpc_impl::CreateChannelInternal( "", channel, std::vector>()); diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index c615fb76536..9e8169f3304 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -23,40 +23,45 @@ #include -namespace grpc { +namespace grpc_impl { + class Channel; +} + +namespace grpc { + namespace testing { typedef enum { INSECURE = 0, TLS, ALTS } transport_security; } // namespace testing -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, testing::transport_security security_type); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& cred_type, const grpc::string& override_hostname, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr CreateTestChannel( +std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( const grpc::string& server, const grpc::string& credential_type, const std::shared_ptr& creds); From b0e6cc9b5fd5b504ce54f785d663c24089bd8c7d Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 23 Jan 2019 22:23:49 +0100 Subject: [PATCH 146/814] Forgot to declare the header. --- BUILD | 1 + CMakeLists.txt | 3 +++ Makefile | 3 +++ build.yaml | 1 + gRPC-C++.podspec | 1 + tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/run_tests/generated/sources_and_headers.json | 2 ++ 8 files changed, 13 insertions(+) diff --git a/BUILD b/BUILD index 55f8f199195..689090be5c0 100644 --- a/BUILD +++ b/BUILD @@ -206,6 +206,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/alarm.h", "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", + "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index a36d06a703c..12c0ec64524 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2985,6 +2985,7 @@ foreach(_hdr include/grpcpp/alarm.h include/grpcpp/alarm_impl.h include/grpcpp/channel.h + include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h @@ -3577,6 +3578,7 @@ foreach(_hdr include/grpcpp/alarm.h include/grpcpp/alarm_impl.h include/grpcpp/channel.h + include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h @@ -4532,6 +4534,7 @@ foreach(_hdr include/grpcpp/alarm.h include/grpcpp/alarm_impl.h include/grpcpp/channel.h + include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h diff --git a/Makefile b/Makefile index fd76e8b7d72..5e06480338c 100644 --- a/Makefile +++ b/Makefile @@ -5386,6 +5386,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ + include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ @@ -5987,6 +5988,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ + include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ @@ -6899,6 +6901,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ + include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ diff --git a/build.yaml b/build.yaml index 3afe4a3e9ce..d1323ff98ab 100644 --- a/build.yaml +++ b/build.yaml @@ -1340,6 +1340,7 @@ filegroups: - include/grpcpp/alarm.h - include/grpcpp/alarm_impl.h - include/grpcpp/channel.h + - include/grpcpp/channel_impl.h - include/grpcpp/client_context.h - include/grpcpp/completion_queue.h - include/grpcpp/create_channel.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 710fc461441..4e347ee658d 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -80,6 +80,7 @@ Pod::Spec.new do |s| ss.source_files = 'include/grpcpp/alarm.h', 'include/grpcpp/alarm_impl.h', 'include/grpcpp/channel.h', + 'include/grpcpp/channel_impl.h', 'include/grpcpp/client_context.h', 'include/grpcpp/completion_queue.h', 'include/grpcpp/create_channel.h', diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index b0415fd4f64..4e18a238517 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -927,6 +927,7 @@ include/grpc/support/workaround_list.h \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ +include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 8aec165a339..e5df1939832 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -928,6 +928,7 @@ include/grpc/support/workaround_list.h \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ +include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index b5992c219d9..d832c71d23c 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11309,6 +11309,7 @@ "include/grpcpp/alarm.h", "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", + "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", @@ -11418,6 +11419,7 @@ "include/grpcpp/alarm.h", "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", + "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", From 3a429ecd552b46d29b5266ad0c5ed8bdaa2b8814 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 23 Jan 2019 17:08:14 -0800 Subject: [PATCH 147/814] Attempt to fix internal segv --- src/core/ext/filters/client_channel/subchannel.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 0c75ee046d9..8708cf21c3b 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -202,6 +202,7 @@ class ConnectedSubchannelStateWatcher // Must be instantiated while holding c->mu. explicit ConnectedSubchannelStateWatcher(grpc_subchannel* c) : subchannel_(c) { + gpr_mu_init(&mu_); // Steal subchannel ref for connecting. GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "state_watcher"); GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "connecting"); @@ -234,9 +235,13 @@ class ConnectedSubchannelStateWatcher ~ConnectedSubchannelStateWatcher() { GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "state_watcher"); + gpr_mu_destroy(&mu_); } - void Orphan() override { health_check_client_.reset(); } + void Orphan() override { + MutexLock lock(&mu_); + health_check_client_.reset(); + } private: static void OnConnectivityChanged(void* arg, grpc_error* error) { @@ -302,6 +307,7 @@ class ConnectedSubchannelStateWatcher static void OnHealthChanged(void* arg, grpc_error* error) { auto* self = static_cast(arg); + MutexLock health_state_lock(&self->mu_); if (self->health_state_ == GRPC_CHANNEL_SHUTDOWN) { self->Unref(); return; @@ -324,6 +330,8 @@ class ConnectedSubchannelStateWatcher grpc_core::OrphanablePtr health_check_client_; grpc_closure on_health_changed_; grpc_connectivity_state health_state_ = GRPC_CHANNEL_CONNECTING; + // Ensure atomic change to health_check_client_ and health_state_. + gpr_mu mu_; }; } // namespace grpc_core From d347ec7ce08db6e60130fe196540655995e71809 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 23 Jan 2019 19:11:51 -0800 Subject: [PATCH 148/814] Register for cq avalanching when interceptors are going to be run --- include/grpcpp/impl/codegen/call_op_set.h | 6 ++++ .../grpcpp/impl/codegen/completion_queue.h | 6 ++++ .../server_interceptors_end2end_test.cc | 35 +++++++++++-------- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index c0de5ed6025..521cafe439b 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -870,6 +871,9 @@ class CallOpSet : public CallOpSetInterface, if (RunInterceptors()) { ContinueFillOpsAfterInterception(); } else { + // This call is going to go through interceptors and would need to + // schedule new batches, so delay completion queue shutdown + call_.cq()->RegisterAvalanching(); // After the interceptors are run, ContinueFillOpsAfterInterception will // be run } @@ -947,6 +951,8 @@ class CallOpSet : public CallOpSetInterface, GPR_CODEGEN_ASSERT(GRPC_CALL_OK == g_core_codegen_interface->grpc_call_start_batch( call_.call(), nullptr, 0, core_cq_tag(), nullptr)); + // Complete the avalanching since we are done with this batch of ops + call_.cq()->CompleteAvalanching(); } private: diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index fb38788f7d6..6d0d56cef5a 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -84,6 +84,8 @@ template class ErrorMethodHandler; template class BlockingUnaryCallImpl; +template +class CallOpSet; } // namespace internal extern CoreCodegenInterface* g_core_codegen_interface; @@ -278,6 +280,10 @@ class CompletionQueue : private GrpcLibraryCodegen { // Friends that need access to constructor for callback CQ friend class ::grpc::Channel; + // For access to Register/CompleteAvalanching + template + friend class ::grpc::internal::CallOpSet; + /// EXPERIMENTAL /// Creates a Thread Local cache to store the first event /// On this completion queue queued from this thread. Once diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 82f142ba913..028191c93c3 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -504,7 +504,8 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { new DummyInterceptorFactory())); } builder.experimental().SetInterceptorCreators(std::move(creators)); - auto cq = builder.AddCompletionQueue(); + auto srv_cq = builder.AddCompletionQueue(); + CompletionQueue cli_cq; auto server = builder.BuildAndStart(); ChannelArguments args; @@ -527,28 +528,28 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { cli_ctx.AddMetadata("testkey", "testvalue"); std::unique_ptr call = - generic_stub.PrepareCall(&cli_ctx, kMethodName, cq.get()); + generic_stub.PrepareCall(&cli_ctx, kMethodName, &cli_cq); call->StartCall(tag(1)); - Verifier().Expect(1, true).Verify(cq.get()); + Verifier().Expect(1, true).Verify(&cli_cq); std::unique_ptr send_buffer = SerializeToByteBuffer(&send_request); call->Write(*send_buffer, tag(2)); // Send ByteBuffer can be destroyed after calling Write. send_buffer.reset(); - Verifier().Expect(2, true).Verify(cq.get()); + Verifier().Expect(2, true).Verify(&cli_cq); call->WritesDone(tag(3)); - Verifier().Expect(3, true).Verify(cq.get()); + Verifier().Expect(3, true).Verify(&cli_cq); - service.RequestCall(&srv_ctx, &stream, cq.get(), cq.get(), tag(4)); + service.RequestCall(&srv_ctx, &stream, srv_cq.get(), srv_cq.get(), tag(4)); - Verifier().Expect(4, true).Verify(cq.get()); + Verifier().Expect(4, true).Verify(srv_cq.get()); EXPECT_EQ(kMethodName, srv_ctx.method()); EXPECT_TRUE(CheckMetadata(srv_ctx.client_metadata(), "testkey", "testvalue")); srv_ctx.AddTrailingMetadata("testkey", "testvalue"); ByteBuffer recv_buffer; stream.Read(&recv_buffer, tag(5)); - Verifier().Expect(5, true).Verify(cq.get()); + Verifier().Expect(5, true).Verify(srv_cq.get()); EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); EXPECT_EQ(send_request.message(), recv_request.message()); @@ -556,18 +557,23 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { send_buffer = SerializeToByteBuffer(&send_response); stream.Write(*send_buffer, tag(6)); send_buffer.reset(); - Verifier().Expect(6, true).Verify(cq.get()); + Verifier().Expect(6, true).Verify(srv_cq.get()); stream.Finish(Status::OK, tag(7)); - Verifier().Expect(7, true).Verify(cq.get()); + // Shutdown srv_cq before we try to get the tag back, to verify that the + // interception API handles completion queue shutdowns that take place before + // all the tags are returned + srv_cq->Shutdown(); + Verifier().Expect(7, true).Verify(srv_cq.get()); recv_buffer.Clear(); call->Read(&recv_buffer, tag(8)); - Verifier().Expect(8, true).Verify(cq.get()); + Verifier().Expect(8, true).Verify(&cli_cq); EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); call->Finish(&recv_status, tag(9)); - Verifier().Expect(9, true).Verify(cq.get()); + cli_cq.Shutdown(); + Verifier().Expect(9, true).Verify(&cli_cq); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); @@ -578,10 +584,11 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); server->Shutdown(); - cq->Shutdown(); void* ignored_tag; bool ignored_ok; - while (cq->Next(&ignored_tag, &ignored_ok)) + while (cli_cq.Next(&ignored_tag, &ignored_ok)) + ; + while (srv_cq->Next(&ignored_tag, &ignored_ok)) ; grpc_recycle_unused_port(port); } From fb06f89af988d1c22afb86c595b5747ddbebe80d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 24 Jan 2019 10:32:14 +0100 Subject: [PATCH 149/814] move RBE test timeout configuration to a single place --- tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh | 2 +- tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh | 2 +- .../linux/pull_request/grpc_bazel_on_foundry_dbg.sh | 2 +- .../linux/pull_request/grpc_bazel_on_foundry_opt.sh | 2 +- tools/remote_build/manual.bazelrc | 4 ---- tools/remote_build/rbe_common.bazelrc | 4 ++++ 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh index fdd5b2e4cde..06b93f3d80f 100644 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh @@ -16,5 +16,5 @@ set -ex export UPLOAD_TEST_RESULTS=true -EXTRA_FLAGS="--config=dbg --test_timeout=300,450,1200,3600 --cache_test_results=no" +EXTRA_FLAGS="--config=dbg --cache_test_results=no" github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh index 30b2b17a674..66effabf972 100644 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh @@ -16,5 +16,5 @@ set -ex export UPLOAD_TEST_RESULTS=true -EXTRA_FLAGS="--config=opt --test_timeout=300,450,1200,3600 --cache_test_results=no" +EXTRA_FLAGS="--config=opt --cache_test_results=no" github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh index f1e6588517e..6cf7a881c70 100644 --- a/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh @@ -15,5 +15,5 @@ set -ex -EXTRA_FLAGS="--config=dbg --test_timeout=300,450,1200,3600" +EXTRA_FLAGS="--config=dbg" github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh index 77744de49fa..76df0b245e5 100644 --- a/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh +++ b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh @@ -15,5 +15,5 @@ set -ex -EXTRA_FLAGS="--config=opt --test_timeout=300,450,1200,3600" +EXTRA_FLAGS="--config=opt" github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" diff --git a/tools/remote_build/manual.bazelrc b/tools/remote_build/manual.bazelrc index b4fdc70637e..fcd41f57521 100644 --- a/tools/remote_build/manual.bazelrc +++ b/tools/remote_build/manual.bazelrc @@ -37,9 +37,5 @@ build --project_id=grpc-testing build --jobs=100 -# TODO(jtattermusch): this should be part of the common config -# but currently sanitizers use different test_timeout values -build --test_timeout=300,450,1200,3600 - # print output for tests that fail (default is "summary") build --test_output=errors diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index c4928fb83a7..9a86713f505 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -44,6 +44,10 @@ build --define GRPC_PORT_ISOLATED_RUNTIME=1 # without verbose gRPC logs the test outputs are not very useful test --test_env=GRPC_VERBOSITY=debug +# Default test timeouts for all RBE tests (sanitizers override these values) +# TODO(jtattermusch): revisit the non-standard test timeout values +build --test_timeout=300,450,1200,3600 + # address sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific build:asan --copt=-gmlt From 9e510cc5d4375f6d2b3ae80d190e1e7fc089dbb0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 24 Jan 2019 10:47:30 +0100 Subject: [PATCH 150/814] update test size to avoid RBE timeouts --- test/cpp/end2end/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 47cb6ba14c3..4c28eee4d15 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -222,6 +222,7 @@ grpc_cc_test( deps = [ ":end2end_test_lib", ], + size = "large", # with poll-cv this takes long, see #17493 ) grpc_cc_test( From df6cf7c7416eb2cd874c3bb61059d03a03187894 Mon Sep 17 00:00:00 2001 From: Chris Wilcox Date: Thu, 27 Dec 2018 09:35:00 -0800 Subject: [PATCH 151/814] Add period at end of metadata.google.internal to prevent unnecessary DNS lookups. --- src/core/lib/security/credentials/alts/alts_credentials.cc | 2 +- src/core/lib/security/credentials/credentials.h | 2 +- .../google_default/google_default_credentials.cc | 2 +- test/core/security/credentials_test.cc | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/lib/security/credentials/alts/alts_credentials.cc b/src/core/lib/security/credentials/alts/alts_credentials.cc index 06546492bc7..9a337903063 100644 --- a/src/core/lib/security/credentials/alts/alts_credentials.cc +++ b/src/core/lib/security/credentials/alts/alts_credentials.cc @@ -31,7 +31,7 @@ #include "src/core/lib/security/security_connector/alts/alts_security_connector.h" #define GRPC_CREDENTIALS_TYPE_ALTS "Alts" -#define GRPC_ALTS_HANDSHAKER_SERVICE_URL "metadata.google.internal:8080" +#define GRPC_ALTS_HANDSHAKER_SERVICE_URL "metadata.google.internal.:8080" grpc_alts_credentials::grpc_alts_credentials( const grpc_alts_credentials_options* options, diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h index 4091ef3dfb5..21bc50be4b2 100644 --- a/src/core/lib/security/credentials/credentials.h +++ b/src/core/lib/security/credentials/credentials.h @@ -60,7 +60,7 @@ typedef enum { #define GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS 60 -#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata.google.internal" +#define GRPC_COMPUTE_ENGINE_METADATA_HOST "metadata.google.internal." #define GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH \ "/computeMetadata/v1/instance/service-accounts/default/token" diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc index a86a17d5864..5ab7efd7c20 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc @@ -46,7 +46,7 @@ /* -- Constants. -- */ -#define GRPC_COMPUTE_ENGINE_DETECTION_HOST "metadata.google.internal" +#define GRPC_COMPUTE_ENGINE_DETECTION_HOST "metadata.google.internal." /* -- Default credentials. -- */ diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index b6555353359..11cfc8cc905 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -534,7 +534,7 @@ static void test_channel_oauth2_google_iam_composite_creds(void) { static void validate_compute_engine_http_request( const grpc_httpcli_request* request) { GPR_ASSERT(request->handshaker != &grpc_httpcli_ssl); - GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); + GPR_ASSERT(strcmp(request->host, "metadata.google.internal.") == 0); GPR_ASSERT( strcmp(request->http.path, "/computeMetadata/v1/instance/service-accounts/default/token") == @@ -930,7 +930,7 @@ static int default_creds_metadata_server_detection_httpcli_get_success_override( response->hdr_count = 1; response->hdrs = headers; GPR_ASSERT(strcmp(request->http.path, "/") == 0); - GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); + GPR_ASSERT(strcmp(request->host, "metadata.google.internal.") == 0); GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); return 1; } @@ -1020,7 +1020,7 @@ static int default_creds_gce_detection_httpcli_get_failure_override( grpc_closure* on_done, grpc_httpcli_response* response) { /* No magic header. */ GPR_ASSERT(strcmp(request->http.path, "/") == 0); - GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0); + GPR_ASSERT(strcmp(request->host, "metadata.google.internal.") == 0); *response = http_response(200, ""); GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); return 1; From dbad0522c3f92fdf533d56e9164bc2514e6d0d93 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 24 Jan 2019 10:10:22 -0800 Subject: [PATCH 152/814] Revert "Merge pull request #17752 from grpc/license-symlinks" This reverts commit 3f8e15e2a4a3765dfe4be1563f30ee89c5729735, reversing changes made to a8662121c719f7de3e6a0f7d8cac54affc1c2324. --- src/python/grpcio_channelz/LICENSE | 1 - .../grpcio_channelz/channelz_commands.py | 3 ++ src/python/grpcio_health_checking/LICENSE | 1 - .../grpcio_health_checking/health_commands.py | 3 ++ src/python/grpcio_reflection/LICENSE | 1 - .../grpcio_reflection/reflection_commands.py | 3 ++ src/python/grpcio_status/LICENSE | 1 - src/python/grpcio_status/setup.py | 19 ++++++--- src/python/grpcio_status/status_commands.py | 39 +++++++++++++++++++ src/python/grpcio_testing/LICENSE | 1 - src/python/grpcio_testing/setup.py | 16 ++++++-- src/python/grpcio_testing/testing_commands.py | 39 +++++++++++++++++++ tools/distrib/yapf_code.sh | 2 +- 13 files changed, 114 insertions(+), 15 deletions(-) delete mode 120000 src/python/grpcio_channelz/LICENSE delete mode 120000 src/python/grpcio_health_checking/LICENSE delete mode 120000 src/python/grpcio_reflection/LICENSE delete mode 120000 src/python/grpcio_status/LICENSE create mode 100644 src/python/grpcio_status/status_commands.py delete mode 120000 src/python/grpcio_testing/LICENSE create mode 100644 src/python/grpcio_testing/testing_commands.py diff --git a/src/python/grpcio_channelz/LICENSE b/src/python/grpcio_channelz/LICENSE deleted file mode 120000 index 5853aaea53b..00000000000 --- a/src/python/grpcio_channelz/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE \ No newline at end of file diff --git a/src/python/grpcio_channelz/channelz_commands.py b/src/python/grpcio_channelz/channelz_commands.py index 0137959e9d4..7f158c2a4bf 100644 --- a/src/python/grpcio_channelz/channelz_commands.py +++ b/src/python/grpcio_channelz/channelz_commands.py @@ -21,6 +21,7 @@ import setuptools ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) CHANNELZ_PROTO = os.path.join(ROOT_DIR, '../../proto/grpc/channelz/channelz.proto') +LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') class Preprocess(setuptools.Command): @@ -41,6 +42,8 @@ class Preprocess(setuptools.Command): shutil.copyfile(CHANNELZ_PROTO, os.path.join(ROOT_DIR, 'grpc_channelz/v1/channelz.proto')) + if os.path.isfile(LICENSE): + shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) class BuildPackageProtos(setuptools.Command): diff --git a/src/python/grpcio_health_checking/LICENSE b/src/python/grpcio_health_checking/LICENSE deleted file mode 120000 index 5853aaea53b..00000000000 --- a/src/python/grpcio_health_checking/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE \ No newline at end of file diff --git a/src/python/grpcio_health_checking/health_commands.py b/src/python/grpcio_health_checking/health_commands.py index d1bf03f7a9c..3820ef0bbad 100644 --- a/src/python/grpcio_health_checking/health_commands.py +++ b/src/python/grpcio_health_checking/health_commands.py @@ -20,6 +20,7 @@ import setuptools ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) HEALTH_PROTO = os.path.join(ROOT_DIR, '../../proto/grpc/health/v1/health.proto') +LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') class Preprocess(setuptools.Command): @@ -40,6 +41,8 @@ class Preprocess(setuptools.Command): shutil.copyfile(HEALTH_PROTO, os.path.join(ROOT_DIR, 'grpc_health/v1/health.proto')) + if os.path.isfile(LICENSE): + shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) class BuildPackageProtos(setuptools.Command): diff --git a/src/python/grpcio_reflection/LICENSE b/src/python/grpcio_reflection/LICENSE deleted file mode 120000 index 5853aaea53b..00000000000 --- a/src/python/grpcio_reflection/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE \ No newline at end of file diff --git a/src/python/grpcio_reflection/reflection_commands.py b/src/python/grpcio_reflection/reflection_commands.py index ac235576ae0..311ca4c4dba 100644 --- a/src/python/grpcio_reflection/reflection_commands.py +++ b/src/python/grpcio_reflection/reflection_commands.py @@ -21,6 +21,7 @@ import setuptools ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) REFLECTION_PROTO = os.path.join( ROOT_DIR, '../../proto/grpc/reflection/v1alpha/reflection.proto') +LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') class Preprocess(setuptools.Command): @@ -42,6 +43,8 @@ class Preprocess(setuptools.Command): REFLECTION_PROTO, os.path.join(ROOT_DIR, 'grpc_reflection/v1alpha/reflection.proto')) + if os.path.isfile(LICENSE): + shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) class BuildPackageProtos(setuptools.Command): diff --git a/src/python/grpcio_status/LICENSE b/src/python/grpcio_status/LICENSE deleted file mode 120000 index 5853aaea53b..00000000000 --- a/src/python/grpcio_status/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE \ No newline at end of file diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py index 2a39af721d9..983d3ea430b 100644 --- a/src/python/grpcio_status/setup.py +++ b/src/python/grpcio_status/setup.py @@ -63,11 +63,20 @@ INSTALL_REQUIRES = ( 'googleapis-common-protos>=1.5.5', ) -COMMAND_CLASS = { - # wire up commands to no-op not to break the external dependencies - 'preprocess': _NoOpCommand, - 'build_package_protos': _NoOpCommand, -} +try: + import status_commands as _status_commands + # we are in the build environment, otherwise the above import fails + COMMAND_CLASS = { + # Run preprocess from the repository *before* doing any packaging! + 'preprocess': _status_commands.Preprocess, + 'build_package_protos': _NoOpCommand, + } +except ImportError: + COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + 'build_package_protos': _NoOpCommand, + } setuptools.setup( name='grpcio-status', diff --git a/src/python/grpcio_status/status_commands.py b/src/python/grpcio_status/status_commands.py new file mode 100644 index 00000000000..78cd497f622 --- /dev/null +++ b/src/python/grpcio_status/status_commands.py @@ -0,0 +1,39 @@ +# Copyright 2018 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Provides distutils command classes for the GRPC Python setup process.""" + +import os +import shutil + +import setuptools + +ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) +LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') + + +class Preprocess(setuptools.Command): + """Command to copy LICENSE from root directory.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + if os.path.isfile(LICENSE): + shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) diff --git a/src/python/grpcio_testing/LICENSE b/src/python/grpcio_testing/LICENSE deleted file mode 120000 index 5853aaea53b..00000000000 --- a/src/python/grpcio_testing/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE \ No newline at end of file diff --git a/src/python/grpcio_testing/setup.py b/src/python/grpcio_testing/setup.py index b0df0915347..18db71e0f09 100644 --- a/src/python/grpcio_testing/setup.py +++ b/src/python/grpcio_testing/setup.py @@ -50,10 +50,18 @@ INSTALL_REQUIRES = ( 'grpcio>={version}'.format(version=grpc_version.VERSION), ) -COMMAND_CLASS = { - # wire up commands to no-op not to break the external dependencies - 'preprocess': _NoOpCommand, -} +try: + import testing_commands as _testing_commands + # we are in the build environment, otherwise the above import fails + COMMAND_CLASS = { + # Run preprocess from the repository *before* doing any packaging! + 'preprocess': _testing_commands.Preprocess, + } +except ImportError: + COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + } setuptools.setup( name='grpcio-testing', diff --git a/src/python/grpcio_testing/testing_commands.py b/src/python/grpcio_testing/testing_commands.py new file mode 100644 index 00000000000..fb40d37efb6 --- /dev/null +++ b/src/python/grpcio_testing/testing_commands.py @@ -0,0 +1,39 @@ +# Copyright 2018 gRPC Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Provides distutils command classes for the GRPC Python setup process.""" + +import os +import shutil + +import setuptools + +ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__))) +LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE') + + +class Preprocess(setuptools.Command): + """Command to copy LICENSE from root directory.""" + + description = '' + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + if os.path.isfile(LICENSE): + shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE')) diff --git a/tools/distrib/yapf_code.sh b/tools/distrib/yapf_code.sh index 9ded3f3762a..27c5e3129dd 100755 --- a/tools/distrib/yapf_code.sh +++ b/tools/distrib/yapf_code.sh @@ -54,7 +54,7 @@ else tempdir=$(mktemp -d) cp -RT "${dir}" "${tempdir}" yapf "${tempdir}" - diff -x 'LICENSE' -x '*.pyc' -ru "${dir}" "${tempdir}" || ok=no + diff -x '*.pyc' -ru "${dir}" "${tempdir}" || ok=no rm -rf "${tempdir}" done if [[ ${ok} == no ]]; then From 7d959465f2b457144f9e02ffca95d92b25095058 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 24 Jan 2019 10:27:12 -0800 Subject: [PATCH 153/814] Update podspec version --- gRPC-Core.podspec | 2 +- templates/gRPC-Core.podspec.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 1d69658bdb3..2d8d85bd16e 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -183,7 +183,7 @@ Pod::Spec.new do |s| ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL-GRPC', '0.0.2' + ss.dependency 'BoringSSL-GRPC', '0.0.3' ss.dependency 'nanopb', '~> 0.3' ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 1d68f0d0b93..17048765437 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -176,7 +176,7 @@ ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL-GRPC', '0.0.2' + ss.dependency 'BoringSSL-GRPC', '0.0.3' ss.dependency 'nanopb', '~> 0.3' ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' From 0c2fc6101d495242af00331bd4aec3d3b74a805b Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 24 Jan 2019 10:27:26 -0800 Subject: [PATCH 154/814] Parse xDS config --- .../ext/filters/client_channel/lb_policy.cc | 27 +++++++ .../ext/filters/client_channel/lb_policy.h | 4 + .../client_channel/lb_policy/xds/xds.cc | 81 +++++++++++++++++-- .../client_channel/resolver_result_parsing.cc | 42 ++-------- 4 files changed, 112 insertions(+), 42 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 2450775109f..d9b3927d1ca 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -20,6 +20,7 @@ #include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/lib/iomgr/combiner.h" grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount( @@ -27,6 +28,32 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount( namespace grpc_core { +grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( + const grpc_json* lb_config_array) { + if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { + return nullptr; + } + // Find the first LB policy that this client supports. + for (const grpc_json* lb_config = lb_config_array->child; + lb_config != nullptr; lb_config = lb_config->next) { + if (lb_config->type != GRPC_JSON_OBJECT) return nullptr; + grpc_json* policy = nullptr; + for (grpc_json* field = lb_config->child; field != nullptr; + field = field->next) { + if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) + return nullptr; + if (policy != nullptr) return nullptr; // Violate "oneof" type. + policy = field; + } + if (policy == nullptr) return nullptr; + // If we support this policy, then select it. + if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key)) { + return policy; + } + } + return nullptr; +} + LoadBalancingPolicy::LoadBalancingPolicy(Args args) : InternallyRefCounted(&grpc_trace_lb_policy_refcount), combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 08634917ac1..56bf1951cfb 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -179,6 +179,10 @@ class LoadBalancingPolicy : public InternallyRefCounted { GRPC_ERROR_NONE); } + /// Returns the JSON node of policy (with both policy name and config content) + /// given the JSON node of a LoadBalancingConfig array. + static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array); + /// Sets the re-resolution closure to \a request_reresolution. void SetReresolutionClosureLocked(grpc_closure* request_reresolution) { GPR_ASSERT(request_reresolution_ == nullptr); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index add38eedd20..678b4d75eb9 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -100,6 +100,7 @@ #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/channel_init.h" +#include "src/core/lib/transport/service_config.h" #include "src/core/lib/transport/static_metadata.h" #define GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS 1 @@ -247,6 +248,12 @@ class XdsLb : public LoadBalancingPolicy { // Helper function used in ctor and UpdateLocked(). void ProcessChannelArgsLocked(const grpc_channel_args& args); + // Parses the xds config given the JSON node of the first child of XdsConfig. + // If parsing succeeds, updates \a balancer_name, and updates \a + // child_policy_json_dump_ and \a fallback_policy_json_dump_ if they are also + // found. Does nothing upon failure. + void ParseLbConfig(grpc_json* xds_config_json); + // Methods for dealing with the balancer channel and call. void StartPickingLocked(); void StartBalancerCallLocked(); @@ -265,7 +272,7 @@ class XdsLb : public LoadBalancingPolicy { // Methods for dealing with the child policy. void CreateOrUpdateChildPolicyLocked(); grpc_channel_args* CreateChildPolicyArgsLocked(); - void CreateChildPolicyLocked(Args args); + void CreateChildPolicyLocked(const char* name, Args args); bool PickFromChildPolicyLocked(bool force_async, PendingPick* pp, grpc_error** error); void UpdateConnectivityStateFromChildPolicyLocked( @@ -278,6 +285,9 @@ class XdsLb : public LoadBalancingPolicy { // Who the client is trying to communicate with. const char* server_name_ = nullptr; + // Name of the balancer to connect to. + UniquePtr balancer_name_; + // Current channel args from the resolver. grpc_channel_args* args_ = nullptr; @@ -318,6 +328,7 @@ class XdsLb : public LoadBalancingPolicy { // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. + UniquePtr fallback_policy_json_string_; int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. UniquePtr fallback_backend_addresses_; @@ -331,6 +342,7 @@ class XdsLb : public LoadBalancingPolicy { // The policy to use for the backends. OrphanablePtr child_policy_; + UniquePtr child_policy_json_string_; grpc_connectivity_state child_connectivity_state_; grpc_closure on_child_connectivity_changed_; grpc_closure on_child_request_reresolution_; @@ -934,6 +946,8 @@ XdsLb::XdsLb(LoadBalancingPolicy::Args args) arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS); lb_fallback_timeout_ms_ = grpc_channel_arg_get_integer( arg, {GRPC_XDS_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX}); + // Parse the LB config. + ParseLbConfig(args.lb_config); // Process channel args. ProcessChannelArgsLocked(*args.args); } @@ -1184,8 +1198,44 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { grpc_channel_args_destroy(lb_channel_args); } -// TODO(vishalpowar): Use lb_config to configure LB policy. +void XdsLb::ParseLbConfig(grpc_json* xds_config_json) { + const char* balancer_name = nullptr; + grpc_json* child_policy = nullptr; + grpc_json* fallback_policy = nullptr; + for (grpc_json* field = xds_config_json; field != nullptr; + field = field->next) { + if (field->key == nullptr) return; + if (strcmp(field->key, "balancerName") == 0) { + if (balancer_name != nullptr) return; // Duplicate. + if (field->type != GRPC_JSON_STRING) return; + balancer_name = field->value; + } else if (strcmp(field->key, "childPolicy") == 0) { + if (child_policy != nullptr) return; // Duplicate. + child_policy = ParseLoadBalancingConfig(field); + } else if (strcmp(field->key, "fallbackPolicy") == 0) { + if (fallback_policy != nullptr) return; // Duplicate. + fallback_policy = ParseLoadBalancingConfig(field); + } + } + if (balancer_name == nullptr) return; // Required field. + if (child_policy != nullptr) { + child_policy_json_string_ = + UniquePtr(grpc_json_dump_to_string(child_policy, 0 /* indent */)); + } + if (fallback_policy != nullptr) { + fallback_policy_json_string_ = UniquePtr( + grpc_json_dump_to_string(fallback_policy, 0 /* indent */)); + } + balancer_name_ = UniquePtr(gpr_strdup(balancer_name)); +} + void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { + ParseLbConfig(lb_config); + // TODO(juanlishen): Pass fallback policy config update after fallback policy + // is added. + if (balancer_name_ == nullptr) { + gpr_log(GPR_ERROR, "[xdslb %p] LB config parsing fails.", this); + } ProcessChannelArgsLocked(args); // Update the existing child policy. // Note: We have disabled fallback mode in the code, so this child policy must @@ -1436,10 +1486,10 @@ bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp, return pick_done; } -void XdsLb::CreateChildPolicyLocked(Args args) { +void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { GPR_ASSERT(child_policy_ == nullptr); child_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - "round_robin", std::move(args)); + name, std::move(args)); if (GPR_UNLIKELY(child_policy_ == nullptr)) { gpr_log(GPR_ERROR, "[xdslb %p] Failure creating a child policy", this); return; @@ -1512,26 +1562,43 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { if (shutting_down_) return; grpc_channel_args* args = CreateChildPolicyArgsLocked(); GPR_ASSERT(args != nullptr); + const char* child_policy_name = nullptr; + grpc_json* child_policy_config = nullptr; + grpc_json* child_policy_json = + grpc_json_parse_string(child_policy_json_string_.get()); + // TODO(juanlishen): If the child policy is not configured via service config, + // use whatever algorithm is specified by the balancer. + if (child_policy_json != nullptr) { + child_policy_name = child_policy_json->key; + child_policy_config = child_policy_json->child; + } else { + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, "[xdslb %p] No valid child policy LB config", this); + } + child_policy_name = "round_robin"; + } + // TODO(juanlishen): Switch policy according to child_policy_config->key. if (child_policy_ != nullptr) { if (grpc_lb_xds_trace.enabled()) { gpr_log(GPR_INFO, "[xdslb %p] Updating the child policy %p", this, child_policy_.get()); } - // TODO(vishalpowar): Pass the correct LB config. - child_policy_->UpdateLocked(*args, nullptr); + child_policy_->UpdateLocked(*args, child_policy_config); } else { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); lb_policy_args.client_channel_factory = client_channel_factory(); lb_policy_args.subchannel_pool = subchannel_pool()->Ref(); lb_policy_args.args = args; - CreateChildPolicyLocked(std::move(lb_policy_args)); + lb_policy_args.lb_config = child_policy_config; + CreateChildPolicyLocked(child_policy_name, std::move(lb_policy_args)); if (grpc_lb_xds_trace.enabled()) { gpr_log(GPR_INFO, "[xdslb %p] Created a new child policy %p", this, child_policy_.get()); } } grpc_channel_args_destroy(args); + grpc_json_destroy(child_policy_json); } void XdsLb::OnChildPolicyRequestReresolutionLocked(void* arg, diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 9a0122e8ece..0af07dc4e64 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -141,42 +141,14 @@ void ProcessedResolverResult::ParseServiceConfig( void ProcessedResolverResult::ParseLbConfigFromServiceConfig( const grpc_json* field) { if (lb_policy_config_ != nullptr) return; // Already found. - // Find the LB config global parameter. - if (field->key == nullptr || strcmp(field->key, "loadBalancingConfig") != 0 || - field->type != GRPC_JSON_ARRAY) { - return; // Not valid lb config array. + if (field->key == nullptr || strcmp(field->key, "loadBalancingConfig") != 0) { + return; // Not the LB config global parameter. } - // Find the first LB policy that this client supports. - for (grpc_json* lb_config = field->child; lb_config != nullptr; - lb_config = lb_config->next) { - if (lb_config->type != GRPC_JSON_OBJECT) return; - // Find the policy object. - grpc_json* policy = nullptr; - for (grpc_json* field = lb_config->child; field != nullptr; - field = field->next) { - if (field->key == nullptr || strcmp(field->key, "policy") != 0 || - field->type != GRPC_JSON_OBJECT) { - return; - } - if (policy != nullptr) return; // Duplicate. - policy = field; - } - // Find the specific policy content since the policy object is of type - // "oneof". - grpc_json* policy_content = nullptr; - for (grpc_json* field = policy->child; field != nullptr; - field = field->next) { - if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) return; - if (policy_content != nullptr) return; // Violate "oneof" type. - policy_content = field; - } - // If we support this policy, then select it. - if (grpc_core::LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( - policy_content->key)) { - lb_policy_name_.reset(gpr_strdup(policy_content->key)); - lb_policy_config_ = policy_content->child; - return; - } + const grpc_json* policy = + LoadBalancingPolicy::ParseLoadBalancingConfig(field); + if (policy != nullptr) { + lb_policy_name_.reset(gpr_strdup(policy->key)); + lb_policy_config_ = policy->child; } } From 4dcb14ec9e6f926ed24f51464955ce6e147e3e05 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 24 Jan 2019 13:05:05 -0800 Subject: [PATCH 155/814] Fix codegen_test_minimal --- include/grpcpp/impl/codegen/call_op_set.h | 2 +- include/grpcpp/impl/codegen/completion_queue.h | 7 ++++++- include/grpcpp/impl/codegen/core_codegen.h | 3 ++- include/grpcpp/impl/codegen/core_codegen_interface.h | 1 + src/cpp/common/completion_queue_cc.cc | 10 +--------- src/cpp/common/core_codegen.cc | 6 +++++- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 521cafe439b..feef745701f 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -1,6 +1,6 @@ /* * - * Copyright 2018 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 6d0d56cef5a..4812f0253d4 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -367,7 +367,12 @@ class CompletionQueue : private GrpcLibraryCodegen { gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, static_cast(1)); } - void CompleteAvalanching(); + void CompleteAvalanching() { + if (gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, + static_cast(-1)) == 1) { + g_core_codegen_interface->grpc_completion_queue_shutdown(cq_); + } + } grpc_completion_queue* cq_; // owned diff --git a/include/grpcpp/impl/codegen/core_codegen.h b/include/grpcpp/impl/codegen/core_codegen.h index 6ef184d01ab..6230555e1a7 100644 --- a/include/grpcpp/impl/codegen/core_codegen.h +++ b/include/grpcpp/impl/codegen/core_codegen.h @@ -1,6 +1,6 @@ /* * - * Copyright 2016 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +42,7 @@ class CoreCodegen final : public CoreCodegenInterface { void* reserved) override; grpc_completion_queue* grpc_completion_queue_create_for_pluck( void* reserved) override; + void grpc_completion_queue_shutdown(grpc_completion_queue* cq) override; void grpc_completion_queue_destroy(grpc_completion_queue* cq) override; grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq, void* tag, gpr_timespec deadline, diff --git a/include/grpcpp/impl/codegen/core_codegen_interface.h b/include/grpcpp/impl/codegen/core_codegen_interface.h index 20a5b3300c4..1d92b4f0dff 100644 --- a/include/grpcpp/impl/codegen/core_codegen_interface.h +++ b/include/grpcpp/impl/codegen/core_codegen_interface.h @@ -52,6 +52,7 @@ class CoreCodegenInterface { void* reserved) = 0; virtual grpc_completion_queue* grpc_completion_queue_create_for_pluck( void* reserved) = 0; + virtual void grpc_completion_queue_shutdown(grpc_completion_queue* cq) = 0; virtual void grpc_completion_queue_destroy(grpc_completion_queue* cq) = 0; virtual grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq, void* tag, diff --git a/src/cpp/common/completion_queue_cc.cc b/src/cpp/common/completion_queue_cc.cc index d93a54aed71..3df45128ecb 100644 --- a/src/cpp/common/completion_queue_cc.cc +++ b/src/cpp/common/completion_queue_cc.cc @@ -1,5 +1,5 @@ /* - * Copyright 2015 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,14 +42,6 @@ void CompletionQueue::Shutdown() { CompleteAvalanching(); } -void CompletionQueue::CompleteAvalanching() { - // Check if this was the last avalanching operation - if (gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, - static_cast(-1)) == 1) { - grpc_completion_queue_shutdown(cq_); - } -} - CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal( void** tag, bool* ok, gpr_timespec deadline) { for (;;) { diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc index cfaa2e7b193..986c3df7736 100644 --- a/src/cpp/common/core_codegen.cc +++ b/src/cpp/common/core_codegen.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2016 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,6 +59,10 @@ grpc_completion_queue* CoreCodegen::grpc_completion_queue_create_for_pluck( return ::grpc_completion_queue_create_for_pluck(reserved); } +void CoreCodegen::grpc_completion_queue_shutdown(grpc_completion_queue* cq) { + ::grpc_completion_queue_shutdown(cq); +} + void CoreCodegen::grpc_completion_queue_destroy(grpc_completion_queue* cq) { ::grpc_completion_queue_destroy(cq); } From 222dd9f3402e013aa229b260ccc87d70f7c4831d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 24 Jan 2019 16:05:24 -0500 Subject: [PATCH 156/814] fixes from code review --- src/csharp/Grpc.Core/CallOptions.cs | 2 +- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core/CallOptions.cs b/src/csharp/Grpc.Core/CallOptions.cs index 89fd047a1ea..a92caae917d 100644 --- a/src/csharp/Grpc.Core/CallOptions.cs +++ b/src/csharp/Grpc.Core/CallOptions.cs @@ -238,7 +238,7 @@ namespace Grpc.Core var newOptions = this; // silently ignore the context propagation token if it wasn't produced by "us" var propagationTokenImpl = propagationToken.AsImplOrNull(); - if (propagationToken != null) + if (propagationTokenImpl != null) { if (propagationTokenImpl.Options.IsPropagateDeadline) { diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index f80ac4a2f9d..785081c341a 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -494,7 +494,7 @@ namespace Grpc.Core.Internal return injectedNativeCall; // allows injecting a mock INativeCall in tests. } - var parentCall = details.Options.PropagationToken != null ? details.Options.PropagationToken.AsImplOrNull().ParentCall : CallSafeHandle.NullInstance; + var parentCall = details.Options.PropagationToken.AsImplOrNull()?.ParentCall ?? CallSafeHandle.NullInstance; var credentials = details.Options.Credentials; using (var nativeCredentials = credentials != null ? credentials.ToNativeCredentials() : null) From 7c58a8ae7627d4a39a8db9f578e88f32479c4e31 Mon Sep 17 00:00:00 2001 From: Jerry Date: Thu, 24 Jan 2019 13:09:43 -0800 Subject: [PATCH 157/814] rename valgrind.includ to php_valgrind.include --- .../tools/dockerfile/{valgrind.include => php_valgrind.include} | 0 .../tools/dockerfile/test/php7_jessie_x64/Dockerfile.template | 2 +- .../tools/dockerfile/test/php_jessie_x64/Dockerfile.template | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename templates/tools/dockerfile/{valgrind.include => php_valgrind.include} (100%) diff --git a/templates/tools/dockerfile/valgrind.include b/templates/tools/dockerfile/php_valgrind.include similarity index 100% rename from templates/tools/dockerfile/valgrind.include rename to templates/tools/dockerfile/php_valgrind.include diff --git a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template index f6f52805b8c..0b2290b741c 100644 --- a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template @@ -19,7 +19,7 @@ <%include file="../../php7_deps.include"/> <%include file="../../gcp_api_libraries.include"/> <%include file="../../python_deps.include"/> - <%include file="../../valgrind.include"/> + <%include file="../../php_valgrind.include"/> <%include file="../../run_tests_addons.include"/> # Define the default command. CMD ["bash"] diff --git a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template index 1a07522c011..329205363e3 100644 --- a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template @@ -20,7 +20,7 @@ <%include file="../../gcp_api_libraries.include"/> <%include file="../../python_deps.include"/> <%include file="../../php_deps.include"/> - <%include file="../../valgrind.include"/> + <%include file="../../php_valgrind.include"/> <%include file="../../run_tests_addons.include"/> # Define the default command. CMD ["bash"] From 141e42f9b9309be15338f8def0bc018675960469 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 24 Jan 2019 13:45:07 -0800 Subject: [PATCH 158/814] Revert "Remove the fake package dependency && temporarily skip the Channelz tests" This reverts commit 08a90f03d4d0ac846f517c9aeab7aeb05b1cfdca. --- src/python/grpcio_tests/setup.py | 12 +++--------- .../tests/channelz/_channelz_servicer_test.py | 1 - 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index 800b865da62..f9cb9d0cec9 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -37,19 +37,13 @@ PACKAGE_DIRECTORIES = { } INSTALL_REQUIRES = ( - 'coverage>=4.0', - 'enum34>=1.0.4', + 'coverage>=4.0', 'enum34>=1.0.4', 'grpcio>={version}'.format(version=grpc_version.VERSION), - # TODO(https://github.com/pypa/warehouse/issues/5196) - # Re-enable it once we got the name back - # 'grpcio-channelz>={version}'.format(version=grpc_version.VERSION), + 'grpcio-channelz>={version}'.format(version=grpc_version.VERSION), 'grpcio-status>={version}'.format(version=grpc_version.VERSION), 'grpcio-tools>={version}'.format(version=grpc_version.VERSION), 'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION), - 'oauth2client>=1.4.7', - 'protobuf>=3.6.0', - 'six>=1.10', - 'google-auth>=1.0.0', + 'oauth2client>=1.4.7', 'protobuf>=3.6.0', 'six>=1.10', 'google-auth>=1.0.0', 'requests>=2.14.2') if not PY3: diff --git a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py index c63ff5cd842..5265911a0be 100644 --- a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py +++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py @@ -91,7 +91,6 @@ def _close_channel_server_pairs(pairs): pair.channel.close() -@unittest.skip('https://github.com/pypa/warehouse/issues/5196') class ChannelzServicerTest(unittest.TestCase): def _send_successful_unary_unary(self, idx): From cabbd3501431548d34fc5fb16c11891bad78c6be Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 23 Jan 2019 22:44:41 +0100 Subject: [PATCH 159/814] Reformat. --- include/grpcpp/channel_impl.h | 29 +++++++++--------- include/grpcpp/impl/codegen/client_context.h | 4 +-- .../grpcpp/impl/codegen/client_interceptor.h | 1 - .../grpcpp/impl/codegen/completion_queue.h | 1 - include/grpcpp/security/credentials.h | 1 - src/cpp/client/channel_cc.cc | 30 +++++++++---------- src/cpp/client/client_context.cc | 5 ++-- src/cpp/client/create_channel_internal.cc | 6 ++-- src/cpp/client/create_channel_internal.h | 6 ++-- src/cpp/client/secure_credentials.h | 1 - test/cpp/util/create_test_channel.h | 1 - 11 files changed, 40 insertions(+), 45 deletions(-) diff --git a/include/grpcpp/channel_impl.h b/include/grpcpp/channel_impl.h index 19198655e99..ea90e5b8f7b 100644 --- a/include/grpcpp/channel_impl.h +++ b/include/grpcpp/channel_impl.h @@ -65,33 +65,33 @@ class Channel final : public ::grpc::ChannelInterface, friend void experimental::ChannelResetConnectionBackoff(Channel* channel); friend std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> + std::vector> interceptor_creators); friend class ::grpc::internal::InterceptedChannel; Channel(const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> + std::vector> interceptor_creators); ::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method, - ::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq) override; + ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq) override; void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, ::grpc::internal::Call* call) override; void* RegisterMethod(const char* method) override; void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline, ::grpc::CompletionQueue* cq, - void* tag) override; + gpr_timespec deadline, + ::grpc::CompletionQueue* cq, void* tag) override; bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) override; ::grpc::CompletionQueue* CallbackCQ() override; - ::grpc::internal::Call CreateCallInternal(const ::grpc::internal::RpcMethod& method, - ::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, - size_t interceptor_pos) override; + ::grpc::internal::Call CreateCallInternal( + const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq, size_t interceptor_pos) override; const grpc::string host_; grpc_channel* const c_channel_; // owned @@ -105,10 +105,11 @@ class Channel final : public ::grpc::ChannelInterface, // shutdown callback tag (invoked when the CQ is fully shutdown). ::grpc::CompletionQueue* callback_cq_ = nullptr; - std::vector> + std::vector< + std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators_; }; -} // namespace grpc +} // namespace grpc_impl -#endif // GRPCPP_CHANNEL_H +#endif // GRPCPP_CHANNEL_IMPL_H diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index edb583542dd..e6579b5b7a7 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -59,7 +59,6 @@ struct grpc_call; namespace grpc_impl { class Channel; - } namespace grpc { @@ -428,7 +427,8 @@ class ClientContext { } grpc_call* call() const { return call_; } - void set_call(grpc_call* call, const std::shared_ptr<::grpc_impl::Channel>& channel); + void set_call(grpc_call* call, + const std::shared_ptr<::grpc_impl::Channel>& channel); experimental::ClientRpcInfo* set_client_rpc_info( const char* method, internal::RpcMethod::RpcType type, diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 3e8eced6391..c3bdf2364f0 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -29,7 +29,6 @@ namespace grpc_impl { class Channel; - } namespace grpc { diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 7493aa8ba49..96790eca534 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -44,7 +44,6 @@ struct grpc_completion_queue; namespace grpc_impl { class Channel; - } namespace grpc { diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 551d9d1576f..8f090da070f 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -35,7 +35,6 @@ struct grpc_call; namespace grpc_impl { class Channel; - } namespace grpc { diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 9724dcad08d..182eb2115bc 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -49,18 +49,18 @@ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/surface/completion_queue.h" -void grpc::experimental::ChannelResetConnectionBackoff(::grpc::Channel* channel) { +void grpc::experimental::ChannelResetConnectionBackoff( + ::grpc::Channel* channel) { ChannelResetConnectionBackoff(channel); } namespace grpc_impl { static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; -Channel::Channel( - const grpc::string& host, grpc_channel* channel, - std::vector< - std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> - interceptor_creators) +Channel::Channel(const grpc::string& host, grpc_channel* channel, + std::vector> + interceptor_creators) : host_(host), c_channel_(channel) { interceptor_creators_ = std::move(interceptor_creators); g_gli_initializer.summon(); @@ -76,7 +76,8 @@ Channel::~Channel() { namespace { inline grpc_slice SliceFromArray(const char* arr, size_t len) { - return ::grpc::g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); + return ::grpc::g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, + len); } grpc::string GetChannelInfoField(grpc_channel* channel, @@ -114,10 +115,9 @@ void ChannelResetConnectionBackoff(Channel* channel) { } // namespace experimental -::grpc::internal::Call Channel::CreateCallInternal(const ::grpc::internal::RpcMethod& method, - ::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq, - size_t interceptor_pos) { +::grpc::internal::Call Channel::CreateCallInternal( + const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq, size_t interceptor_pos) { const bool kRegistered = method.channel_tag() && context->authority().empty(); grpc_call* c_call = nullptr; if (kRegistered) { @@ -161,9 +161,9 @@ void ChannelResetConnectionBackoff(Channel* channel) { return ::grpc::internal::Call(c_call, this, cq, info); } -::grpc::internal::Call Channel::CreateCall(const ::grpc::internal::RpcMethod& method, - ::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq) { +::grpc::internal::Call Channel::CreateCall( + const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, + ::grpc::CompletionQueue* cq) { return CreateCallInternal(method, context, cq, 0); } @@ -256,4 +256,4 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { return callback_cq_; } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index c30011c2625..b3c52acd5f6 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -33,7 +33,6 @@ namespace grpc_impl { class Channel; - } namespace grpc { @@ -88,8 +87,8 @@ void ClientContext::AddMetadata(const grpc::string& meta_key, send_initial_metadata_.insert(std::make_pair(meta_key, meta_value)); } -void ClientContext::set_call(grpc_call* call, - const std::shared_ptr<::grpc_impl::Channel>& channel) { +void ClientContext::set_call( + grpc_call* call, const std::shared_ptr<::grpc_impl::Channel>& channel) { std::unique_lock lock(mu_); GPR_ASSERT(call_ == nullptr); call_ = call; diff --git a/src/cpp/client/create_channel_internal.cc b/src/cpp/client/create_channel_internal.cc index 1aceee9d37b..77fd00fb3fe 100644 --- a/src/cpp/client/create_channel_internal.cc +++ b/src/cpp/client/create_channel_internal.cc @@ -26,11 +26,11 @@ namespace grpc_impl { std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> + std::vector> interceptor_creators) { return std::shared_ptr( new Channel(host, c_channel, std::move(interceptor_creators))); } -} +} // namespace grpc_impl diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h index caa8c5363fb..7dab6473a9c 100644 --- a/src/cpp/client/create_channel_internal.h +++ b/src/cpp/client/create_channel_internal.h @@ -32,10 +32,10 @@ class Channel; std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::vector< - std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> + std::vector> interceptor_creators); -} // namespace grpc +} // namespace grpc_impl #endif // GRPC_INTERNAL_CPP_CLIENT_CREATE_CHANNEL_INTERNAL_H diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 04ef0b5e617..5db4af143b4 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -30,7 +30,6 @@ namespace grpc_impl { class Channel; - } namespace grpc { diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index 9e8169f3304..f94f0ac30a2 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -26,7 +26,6 @@ namespace grpc_impl { class Channel; - } namespace grpc { From 9dd8a13439d02e2cb586032234c989816ce7eb8b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 24 Jan 2019 19:03:55 -0800 Subject: [PATCH 160/814] Restructure code to handle cases exposed by the callback api --- include/grpcpp/impl/codegen/call_op_set.h | 13 ++++++---- .../grpcpp/impl/codegen/interceptor_common.h | 26 ++++++++++++++++--- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index feef745701f..03a32b9815d 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -871,9 +871,6 @@ class CallOpSet : public CallOpSetInterface, if (RunInterceptors()) { ContinueFillOpsAfterInterception(); } else { - // This call is going to go through interceptors and would need to - // schedule new batches, so delay completion queue shutdown - call_.cq()->RegisterAvalanching(); // After the interceptors are run, ContinueFillOpsAfterInterception will // be run } @@ -881,6 +878,8 @@ class CallOpSet : public CallOpSetInterface, bool FinalizeResult(void** tag, bool* status) override { if (done_intercepting_) { + // Complete the avalanching since we are done with this batch of ops + call_.cq()->CompleteAvalanching(); // We have already finished intercepting and filling in the results. This // round trip from the core needed to be made because interceptors were // run @@ -951,8 +950,6 @@ class CallOpSet : public CallOpSetInterface, GPR_CODEGEN_ASSERT(GRPC_CALL_OK == g_core_codegen_interface->grpc_call_start_batch( call_.call(), nullptr, 0, core_cq_tag(), nullptr)); - // Complete the avalanching since we are done with this batch of ops - call_.cq()->CompleteAvalanching(); } private: @@ -967,6 +964,12 @@ class CallOpSet : public CallOpSetInterface, this->Op4::SetInterceptionHookPoint(&interceptor_methods_); this->Op5::SetInterceptionHookPoint(&interceptor_methods_); this->Op6::SetInterceptionHookPoint(&interceptor_methods_); + if (interceptor_methods_.InterceptorsListEmpty()) { + return true; + } + // This call will go through interceptors and would need to + // schedule new batches, so delay completion queue shutdown + call_.cq()->RegisterAvalanching(); return interceptor_methods_.RunInterceptors(); } // Returns true if no interceptors need to be run diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 09721343ffa..6c4847509e0 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -219,10 +219,28 @@ class InterceptorBatchMethodsImpl // Alternatively, RunInterceptors(std::function f) can be used. void SetCallOpSetInterface(CallOpSetInterface* ops) { ops_ = ops; } - // Returns true if no interceptors are run. This should be used only by - // subclasses of CallOpSetInterface. SetCall and SetCallOpSetInterface should - // have been called before this. After all the interceptors are done running, - // either ContinueFillOpsAfterInterception or + // Returns true if the interceptors list is empty + bool InterceptorsListEmpty() { + auto* client_rpc_info = call_->client_rpc_info(); + if (client_rpc_info != nullptr) { + if (client_rpc_info->interceptors_.size() == 0) { + return true; + } else { + return false; + } + } + + auto* server_rpc_info = call_->server_rpc_info(); + if (server_rpc_info == nullptr || + server_rpc_info->interceptors_.size() == 0) { + return true; + } + return false; + } + + // This should be used only by subclasses of CallOpSetInterface. SetCall and + // SetCallOpSetInterface should have been called before this. After all the + // interceptors are done running, either ContinueFillOpsAfterInterception or // ContinueFinalizeOpsAfterInterception will be called. Note that neither of // them is invoked if there were no interceptors registered. bool RunInterceptors() { From a682c75f6f7a33fa7ebf41fa7fa0f782a9d74c79 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 25 Jan 2019 03:50:45 -0500 Subject: [PATCH 161/814] add tests for foreign context propagation token --- .../Grpc.Core.Tests/ContextPropagationTest.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs index 9a878bde436..4158579194f 100644 --- a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs +++ b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs @@ -154,5 +154,28 @@ namespace Grpc.Core.Tests await call.RequestStream.CompleteAsync(); Assert.AreEqual("PASS", await call); } + + [Test] + public void ForeignPropagationTokenInterpretedAsNull() + { + Assert.IsNull(new ForeignContextPropagationToken().AsImplOrNull()); + } + + [Test] + public async Task ForeignPropagationTokenIsIgnored() + { + helper.UnaryHandler = new UnaryServerMethod((request, context) => + { + return Task.FromResult("PASS"); + }); + + var callOptions = new CallOptions(propagationToken: new ForeignContextPropagationToken()); + await Calls.AsyncUnaryCall(helper.CreateUnaryCall(callOptions), "xyz"); + } + + // For testing, represents context propagation token that's not generated by Grpc.Core + private class ForeignContextPropagationToken : ContextPropagationToken + { + } } } From 27009f256bb0a3ca0c35cb9aa23e2c6704f77ec7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Jan 2019 19:25:53 +0100 Subject: [PATCH 162/814] add Grpc.Core.Api scaffolding --- src/csharp/Grpc.Core.Api/.gitignore | 2 + src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/csharp/Grpc.Core.Api/.gitignore create mode 100755 src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj diff --git a/src/csharp/Grpc.Core.Api/.gitignore b/src/csharp/Grpc.Core.Api/.gitignore new file mode 100644 index 00000000000..1746e3269ed --- /dev/null +++ b/src/csharp/Grpc.Core.Api/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj new file mode 100755 index 00000000000..3ba3762676b --- /dev/null +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -0,0 +1,38 @@ + + + + + + + Copyright 2015, Google Inc. + gRPC C# Surface API + $(GrpcCsharpVersion) + Google Inc. + net45;netstandard1.5 + Grpc.Core.Api + Grpc.Core.Api + gRPC RPC Protocol HTTP/2 + https://github.com/grpc/grpc + https://github.com/grpc/grpc/blob/master/LICENSE + true + true + + + + + + + + + + + + + + + + + + + + From 6382ca10e0f0841ef39daf6557646f3a4fe814bb Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Jan 2019 19:30:54 +0100 Subject: [PATCH 163/814] add Grpc.Core.Api to the solution --- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 6 ------ src/csharp/Grpc.sln | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index 3ba3762676b..6ad1ac85ffc 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -29,10 +29,4 @@ - - - - - - diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln index 6c1b2e99980..25030cc110e 100644 --- a/src/csharp/Grpc.sln +++ b/src/csharp/Grpc.sln @@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26430.4 MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Core.Api", "Grpc.Core.Api\Grpc.Core.Api.csproj", "{63FCEA50-1505-11E9-B56E-0800200C9A66}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Core", "Grpc.Core\Grpc.Core.csproj", "{BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.Auth", "Grpc.Auth\Grpc.Auth.csproj", "{2A16007A-5D67-4C53-BEC8-51E5064D18BF}" @@ -49,6 +51,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {63FCEA50-1505-11E9-B56E-0800200C9A66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63FCEA50-1505-11E9-B56E-0800200C9A66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63FCEA50-1505-11E9-B56E-0800200C9A66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63FCEA50-1505-11E9-B56E-0800200C9A66}.Release|Any CPU.Build.0 = Release|Any CPU {BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}.Debug|Any CPU.Build.0 = Debug|Any CPU {BD878CB3-BDB4-46AB-84EF-C3B4729F56BC}.Release|Any CPU.ActiveCfg = Release|Any CPU From 3fda664d39c0658d19f6c8b156b32fc2423ef10f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Jan 2019 19:33:29 +0100 Subject: [PATCH 164/814] Grpc.Core depends on Grpc.Core.Api --- src/csharp/Grpc.Core/Grpc.Core.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index dc5683c9753..b99c23ae131 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -80,6 +80,10 @@ + + + + From 55b9e5e3990d5c6e6ae5abdecfafb1370af68378 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Jan 2019 20:12:44 +0100 Subject: [PATCH 165/814] move most of serverside API types to Grpc.Core.Api --- .../AuthContext.cs | 1 - .../AuthProperty.cs | 5 +- .../ContextPropagationOptions.cs | 0 .../ContextPropagationToken.cs | 0 .../DeserializationContext.cs | 0 .../IAsyncStreamReader.cs | 0 .../IAsyncStreamWriter.cs | 0 .../IServerStreamWriter.cs | 0 .../Logging/ILogger.cs | 0 .../Logging/LogLevel.cs | 0 .../Marshaller.cs | 0 .../{Grpc.Core => Grpc.Core.Api}/Metadata.cs | 18 +++--- .../{Grpc.Core => Grpc.Core.Api}/Method.cs | 0 .../Grpc.Core.Api/Properties/AssemblyInfo.cs | 63 +++++++++++++++++++ .../RpcException.cs | 0 .../SerializationContext.cs | 0 .../ServerCallContext.cs | 0 .../ServerMethods.cs | 0 .../{Grpc.Core => Grpc.Core.Api}/Status.cs | 4 +- .../StatusCode.cs | 0 .../Utils/GrpcPreconditions.cs | 0 .../WriteOptions.cs | 2 +- src/csharp/Grpc.Core/ForwardedTypes.cs | 56 +++++++++++++++++ 23 files changed, 133 insertions(+), 16 deletions(-) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/AuthContext.cs (99%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/AuthProperty.cs (94%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/ContextPropagationOptions.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/ContextPropagationToken.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/DeserializationContext.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/IAsyncStreamReader.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/IAsyncStreamWriter.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/IServerStreamWriter.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Logging/ILogger.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Logging/LogLevel.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Marshaller.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Metadata.cs (97%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Method.cs (100%) create mode 100644 src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs rename src/csharp/{Grpc.Core => Grpc.Core.Api}/RpcException.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/SerializationContext.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/ServerCallContext.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/ServerMethods.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Status.cs (97%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/StatusCode.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Utils/GrpcPreconditions.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/WriteOptions.cs (99%) create mode 100644 src/csharp/Grpc.Core/ForwardedTypes.cs diff --git a/src/csharp/Grpc.Core/AuthContext.cs b/src/csharp/Grpc.Core.Api/AuthContext.cs similarity index 99% rename from src/csharp/Grpc.Core/AuthContext.cs rename to src/csharp/Grpc.Core.Api/AuthContext.cs index f2354310486..90887887f2d 100644 --- a/src/csharp/Grpc.Core/AuthContext.cs +++ b/src/csharp/Grpc.Core.Api/AuthContext.cs @@ -19,7 +19,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Grpc.Core.Internal; using Grpc.Core.Utils; namespace Grpc.Core diff --git a/src/csharp/Grpc.Core/AuthProperty.cs b/src/csharp/Grpc.Core.Api/AuthProperty.cs similarity index 94% rename from src/csharp/Grpc.Core/AuthProperty.cs rename to src/csharp/Grpc.Core.Api/AuthProperty.cs index 49765da6396..0907edba84d 100644 --- a/src/csharp/Grpc.Core/AuthProperty.cs +++ b/src/csharp/Grpc.Core.Api/AuthProperty.cs @@ -19,7 +19,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Grpc.Core.Internal; +using System.Text; using Grpc.Core.Utils; namespace Grpc.Core @@ -30,6 +30,7 @@ namespace Grpc.Core /// public class AuthProperty { + static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8; string name; byte[] valueBytes; Lazy value; @@ -38,7 +39,7 @@ namespace Grpc.Core { this.name = GrpcPreconditions.CheckNotNull(name); this.valueBytes = GrpcPreconditions.CheckNotNull(valueBytes); - this.value = new Lazy(() => MarshalUtils.GetStringUTF8(this.valueBytes)); + this.value = new Lazy(() => EncodingUTF8.GetString(this.valueBytes)); } /// diff --git a/src/csharp/Grpc.Core/ContextPropagationOptions.cs b/src/csharp/Grpc.Core.Api/ContextPropagationOptions.cs similarity index 100% rename from src/csharp/Grpc.Core/ContextPropagationOptions.cs rename to src/csharp/Grpc.Core.Api/ContextPropagationOptions.cs diff --git a/src/csharp/Grpc.Core/ContextPropagationToken.cs b/src/csharp/Grpc.Core.Api/ContextPropagationToken.cs similarity index 100% rename from src/csharp/Grpc.Core/ContextPropagationToken.cs rename to src/csharp/Grpc.Core.Api/ContextPropagationToken.cs diff --git a/src/csharp/Grpc.Core/DeserializationContext.cs b/src/csharp/Grpc.Core.Api/DeserializationContext.cs similarity index 100% rename from src/csharp/Grpc.Core/DeserializationContext.cs rename to src/csharp/Grpc.Core.Api/DeserializationContext.cs diff --git a/src/csharp/Grpc.Core/IAsyncStreamReader.cs b/src/csharp/Grpc.Core.Api/IAsyncStreamReader.cs similarity index 100% rename from src/csharp/Grpc.Core/IAsyncStreamReader.cs rename to src/csharp/Grpc.Core.Api/IAsyncStreamReader.cs diff --git a/src/csharp/Grpc.Core/IAsyncStreamWriter.cs b/src/csharp/Grpc.Core.Api/IAsyncStreamWriter.cs similarity index 100% rename from src/csharp/Grpc.Core/IAsyncStreamWriter.cs rename to src/csharp/Grpc.Core.Api/IAsyncStreamWriter.cs diff --git a/src/csharp/Grpc.Core/IServerStreamWriter.cs b/src/csharp/Grpc.Core.Api/IServerStreamWriter.cs similarity index 100% rename from src/csharp/Grpc.Core/IServerStreamWriter.cs rename to src/csharp/Grpc.Core.Api/IServerStreamWriter.cs diff --git a/src/csharp/Grpc.Core/Logging/ILogger.cs b/src/csharp/Grpc.Core.Api/Logging/ILogger.cs similarity index 100% rename from src/csharp/Grpc.Core/Logging/ILogger.cs rename to src/csharp/Grpc.Core.Api/Logging/ILogger.cs diff --git a/src/csharp/Grpc.Core/Logging/LogLevel.cs b/src/csharp/Grpc.Core.Api/Logging/LogLevel.cs similarity index 100% rename from src/csharp/Grpc.Core/Logging/LogLevel.cs rename to src/csharp/Grpc.Core.Api/Logging/LogLevel.cs diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core.Api/Marshaller.cs similarity index 100% rename from src/csharp/Grpc.Core/Marshaller.cs rename to src/csharp/Grpc.Core.Api/Marshaller.cs diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core.Api/Metadata.cs similarity index 97% rename from src/csharp/Grpc.Core/Metadata.cs rename to src/csharp/Grpc.Core.Api/Metadata.cs index bc263c34696..27e72fbfa8b 100644 --- a/src/csharp/Grpc.Core/Metadata.cs +++ b/src/csharp/Grpc.Core.Api/Metadata.cs @@ -20,7 +20,6 @@ using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; -using Grpc.Core.Internal; using Grpc.Core.Utils; namespace Grpc.Core @@ -52,6 +51,7 @@ namespace Grpc.Core /// feature and is not part of public API. /// internal const string CompressionRequestAlgorithmMetadataKey = "grpc-internal-encoding-request"; + static readonly Encoding EncodingASCII = System.Text.Encoding.ASCII; readonly List entries; bool readOnly; @@ -286,7 +286,7 @@ namespace Grpc.Core { if (valueBytes == null) { - return MarshalUtils.GetBytesASCII(value); + return EncodingASCII.GetBytes(value); } // defensive copy to guarantee immutability @@ -304,7 +304,7 @@ namespace Grpc.Core get { GrpcPreconditions.CheckState(!IsBinary, "Cannot access string value of a binary metadata entry"); - return value ?? MarshalUtils.GetStringASCII(valueBytes); + return value ?? EncodingASCII.GetString(valueBytes); } } @@ -328,7 +328,7 @@ namespace Grpc.Core { return string.Format("[Entry: key={0}, valueBytes={1}]", key, valueBytes); } - + return string.Format("[Entry: key={0}, value={1}]", key, value); } @@ -338,7 +338,7 @@ namespace Grpc.Core /// internal byte[] GetSerializedValueUnsafe() { - return valueBytes ?? MarshalUtils.GetBytesASCII(value); + return valueBytes ?? EncodingASCII.GetBytes(value); } /// @@ -351,21 +351,21 @@ namespace Grpc.Core { return new Entry(key, null, valueBytes); } - return new Entry(key, MarshalUtils.GetStringASCII(valueBytes), null); + return new Entry(key, EncodingASCII.GetString(valueBytes), null); } private static string NormalizeKey(string key) { GrpcPreconditions.CheckNotNull(key, "key"); - GrpcPreconditions.CheckArgument(IsValidKey(key, out bool isLowercase), + GrpcPreconditions.CheckArgument(IsValidKey(key, out bool isLowercase), "Metadata entry key not valid. Keys can only contain lowercase alphanumeric characters, underscores, hyphens and dots."); if (isLowercase) { // save allocation of a new string if already lowercase return key; } - + return key.ToLowerInvariant(); } @@ -378,7 +378,7 @@ namespace Grpc.Core if ('a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '.' || - c == '_' || + c == '_' || c == '-' ) continue; diff --git a/src/csharp/Grpc.Core/Method.cs b/src/csharp/Grpc.Core.Api/Method.cs similarity index 100% rename from src/csharp/Grpc.Core/Method.cs rename to src/csharp/Grpc.Core.Api/Method.cs diff --git a/src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..fa04d9328d4 --- /dev/null +++ b/src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs @@ -0,0 +1,63 @@ +#region Copyright notice and license + +// Copyright 2018 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyTitle("Grpc.Core.Api")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Google Inc. All rights reserved.")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +#if SIGNED +[assembly: InternalsVisibleTo("Grpc.Core,PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + + "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + + "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + + "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] +[assembly: InternalsVisibleTo("Grpc.Core.Tests,PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + + "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + + "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + + "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] +[assembly: InternalsVisibleTo("Grpc.Core.Testing,PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + + "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + + "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + + "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] +[assembly: InternalsVisibleTo("Grpc.IntegrationTesting,PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + + "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + + "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + + "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] +[assembly: InternalsVisibleTo("Grpc.Microbenchmarks,PublicKey=" + + "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" + + "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" + + "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" + + "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")] +#else +[assembly: InternalsVisibleTo("Grpc.Core")] +[assembly: InternalsVisibleTo("Grpc.Core.Tests")] +[assembly: InternalsVisibleTo("Grpc.Core.Testing")] +[assembly: InternalsVisibleTo("Grpc.IntegrationTesting")] +[assembly: InternalsVisibleTo("Grpc.Microbenchmarks")] +#endif diff --git a/src/csharp/Grpc.Core/RpcException.cs b/src/csharp/Grpc.Core.Api/RpcException.cs similarity index 100% rename from src/csharp/Grpc.Core/RpcException.cs rename to src/csharp/Grpc.Core.Api/RpcException.cs diff --git a/src/csharp/Grpc.Core/SerializationContext.cs b/src/csharp/Grpc.Core.Api/SerializationContext.cs similarity index 100% rename from src/csharp/Grpc.Core/SerializationContext.cs rename to src/csharp/Grpc.Core.Api/SerializationContext.cs diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core.Api/ServerCallContext.cs similarity index 100% rename from src/csharp/Grpc.Core/ServerCallContext.cs rename to src/csharp/Grpc.Core.Api/ServerCallContext.cs diff --git a/src/csharp/Grpc.Core/ServerMethods.cs b/src/csharp/Grpc.Core.Api/ServerMethods.cs similarity index 100% rename from src/csharp/Grpc.Core/ServerMethods.cs rename to src/csharp/Grpc.Core.Api/ServerMethods.cs diff --git a/src/csharp/Grpc.Core/Status.cs b/src/csharp/Grpc.Core.Api/Status.cs similarity index 97% rename from src/csharp/Grpc.Core/Status.cs rename to src/csharp/Grpc.Core.Api/Status.cs index 170a5b68c3e..b1a030b2d1f 100644 --- a/src/csharp/Grpc.Core/Status.cs +++ b/src/csharp/Grpc.Core.Api/Status.cs @@ -14,12 +14,10 @@ // limitations under the License. #endregion -using Grpc.Core.Utils; - namespace Grpc.Core { /// - /// Represents RPC result, which consists of and an optional detail string. + /// Represents RPC result, which consists of and an optional detail string. /// public struct Status { diff --git a/src/csharp/Grpc.Core/StatusCode.cs b/src/csharp/Grpc.Core.Api/StatusCode.cs similarity index 100% rename from src/csharp/Grpc.Core/StatusCode.cs rename to src/csharp/Grpc.Core.Api/StatusCode.cs diff --git a/src/csharp/Grpc.Core/Utils/GrpcPreconditions.cs b/src/csharp/Grpc.Core.Api/Utils/GrpcPreconditions.cs similarity index 100% rename from src/csharp/Grpc.Core/Utils/GrpcPreconditions.cs rename to src/csharp/Grpc.Core.Api/Utils/GrpcPreconditions.cs diff --git a/src/csharp/Grpc.Core/WriteOptions.cs b/src/csharp/Grpc.Core.Api/WriteOptions.cs similarity index 99% rename from src/csharp/Grpc.Core/WriteOptions.cs rename to src/csharp/Grpc.Core.Api/WriteOptions.cs index f99a6a0631e..cbb866b0a90 100644 --- a/src/csharp/Grpc.Core/WriteOptions.cs +++ b/src/csharp/Grpc.Core.Api/WriteOptions.cs @@ -48,7 +48,7 @@ namespace Grpc.Core /// Default write options. /// public static readonly WriteOptions Default = new WriteOptions(); - + private readonly WriteFlags flags; /// diff --git a/src/csharp/Grpc.Core/ForwardedTypes.cs b/src/csharp/Grpc.Core/ForwardedTypes.cs new file mode 100644 index 00000000000..8e104fd410d --- /dev/null +++ b/src/csharp/Grpc.Core/ForwardedTypes.cs @@ -0,0 +1,56 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System.Runtime.CompilerServices; +using Grpc.Core; +using Grpc.Core.Logging; +using Grpc.Core.Utils; + +// API types that used to be in Grpc.Core package, but were moved to Grpc.Core.Api +// https://docs.microsoft.com/en-us/dotnet/framework/app-domains/type-forwarding-in-the-common-language-runtime + +// TODO(jtattermusch): move types needed for implementing a client +// TODO(jtattermusch): ServerServiceDefinition depends on IServerCallHandler (which depends on other stuff) + +[assembly:TypeForwardedToAttribute(typeof(ILogger))] +[assembly:TypeForwardedToAttribute(typeof(LogLevel))] +[assembly:TypeForwardedToAttribute(typeof(GrpcPreconditions))] +[assembly:TypeForwardedToAttribute(typeof(AuthContext))] +[assembly:TypeForwardedToAttribute(typeof(ContextPropagationOptions))] +[assembly:TypeForwardedToAttribute(typeof(ContextPropagationToken))] +[assembly:TypeForwardedToAttribute(typeof(DeserializationContext))] +[assembly:TypeForwardedToAttribute(typeof(IAsyncStreamReader<>))] +[assembly:TypeForwardedToAttribute(typeof(IAsyncStreamWriter<>))] +[assembly:TypeForwardedToAttribute(typeof(IServerStreamWriter<>))] +[assembly:TypeForwardedToAttribute(typeof(Marshaller<>))] +[assembly:TypeForwardedToAttribute(typeof(Marshallers))] +[assembly:TypeForwardedToAttribute(typeof(Metadata))] +[assembly:TypeForwardedToAttribute(typeof(MethodType))] +[assembly:TypeForwardedToAttribute(typeof(IMethod))] +[assembly:TypeForwardedToAttribute(typeof(Method<,>))] +[assembly:TypeForwardedToAttribute(typeof(RpcException))] +[assembly:TypeForwardedToAttribute(typeof(SerializationContext))] +[assembly:TypeForwardedToAttribute(typeof(ServerCallContext))] +[assembly:TypeForwardedToAttribute(typeof(UnaryServerMethod<,>))] +[assembly:TypeForwardedToAttribute(typeof(ClientStreamingServerMethod<,>))] +[assembly:TypeForwardedToAttribute(typeof(ServerStreamingServerMethod<,>))] +[assembly:TypeForwardedToAttribute(typeof(DuplexStreamingServerMethod<,>))] +[assembly:TypeForwardedToAttribute(typeof(Status))] +[assembly:TypeForwardedToAttribute(typeof(StatusCode))] +[assembly:TypeForwardedToAttribute(typeof(WriteOptions))] +[assembly:TypeForwardedToAttribute(typeof(WriteFlags))] From 0f59ff7b4d5c3784ddea590d28c5df412fd56098 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 21 Jan 2019 15:43:09 +0100 Subject: [PATCH 166/814] remove unused methods from MarshalUtils --- src/csharp/Grpc.Core/Internal/MarshalUtils.cs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs index 09ded1a0363..e3e41617955 100644 --- a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs +++ b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs @@ -28,7 +28,6 @@ namespace Grpc.Core.Internal internal static class MarshalUtils { static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8; - static readonly Encoding EncodingASCII = System.Text.Encoding.ASCII; /// /// Converts IntPtr pointing to a UTF-8 encoded byte array to string. @@ -62,21 +61,5 @@ namespace Grpc.Core.Internal { return EncodingUTF8.GetString(bytes); } - - /// - /// Returns byte array containing ASCII encoding of given string. - /// - public static byte[] GetBytesASCII(string str) - { - return EncodingASCII.GetBytes(str); - } - - /// - /// Get string from an ASCII encoded byte array. - /// - public static string GetStringASCII(byte[] bytes) - { - return EncodingASCII.GetString(bytes); - } } } From 140d8dcab9ad0bb9a2cb65e062917e206f285c82 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 21 Jan 2019 16:14:52 +0100 Subject: [PATCH 167/814] package build should build Grpc.Core.Api nuget --- src/csharp/build_packages_dotnetcli.bat | 1 + templates/src/csharp/build_packages_dotnetcli.bat.template | 1 + 2 files changed, 2 insertions(+) diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index fef1a43bb88..9fdfbcbd315 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -34,6 +34,7 @@ powershell -Command "cp -r ..\..\input_artifacts\protoc_* protoc_plugins" @rem To be able to build, we also need to put grpc_csharp_ext to its normal location xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\build\x64\Release\ +%DOTNET% pack --configuration Release Grpc.Core.Api --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Core --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Core.Testing --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Auth --output ..\..\..\artifacts || goto :error diff --git a/templates/src/csharp/build_packages_dotnetcli.bat.template b/templates/src/csharp/build_packages_dotnetcli.bat.template index 877899c7bd9..aa35ae1e6fc 100755 --- a/templates/src/csharp/build_packages_dotnetcli.bat.template +++ b/templates/src/csharp/build_packages_dotnetcli.bat.template @@ -36,6 +36,7 @@ @rem To be able to build, we also need to put grpc_csharp_ext to its normal location xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\build\x64\Release${"\\"} + %%DOTNET% pack --configuration Release Grpc.Core.Api --output ..\..\..\artifacts || goto :error %%DOTNET% pack --configuration Release Grpc.Core --output ..\..\..\artifacts || goto :error %%DOTNET% pack --configuration Release Grpc.Core.Testing --output ..\..\..\artifacts || goto :error %%DOTNET% pack --configuration Release Grpc.Auth --output ..\..\..\artifacts || goto :error From fbb04abd028d85aeb65af4abb2aad37640faf5af Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 25 Jan 2019 05:49:02 -0500 Subject: [PATCH 168/814] fix C# net45 distribtests --- test/distrib/csharp/DistribTest/DistribTest.csproj | 3 +++ test/distrib/csharp/DistribTest/packages.config | 1 + 2 files changed, 4 insertions(+) diff --git a/test/distrib/csharp/DistribTest/DistribTest.csproj b/test/distrib/csharp/DistribTest/DistribTest.csproj index 0bff9ff3e0b..d18bb05be68 100644 --- a/test/distrib/csharp/DistribTest/DistribTest.csproj +++ b/test/distrib/csharp/DistribTest/DistribTest.csproj @@ -62,6 +62,9 @@ ..\packages\Grpc.Core.__GRPC_NUGET_VERSION__\lib\net45\Grpc.Core.dll + + ..\packages\Grpc.Core.Api.__GRPC_NUGET_VERSION__\lib\net45\Grpc.Core.Api.dll + diff --git a/test/distrib/csharp/DistribTest/packages.config b/test/distrib/csharp/DistribTest/packages.config index 3cb2c46bcf0..134add7504d 100644 --- a/test/distrib/csharp/DistribTest/packages.config +++ b/test/distrib/csharp/DistribTest/packages.config @@ -6,6 +6,7 @@ + From 5e8608a97f95ba90e4591d4e270a9e95b1929bef Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 25 Jan 2019 06:19:54 -0500 Subject: [PATCH 169/814] update unity package build --- src/csharp/build_unitypackage.bat | 3 +++ templates/src/csharp/build_unitypackage.bat.template | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 6b66b941a8d..e304c6e4cf1 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -40,6 +40,9 @@ xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\bu @rem copy Grpc assemblies to the unity package skeleton @rem TODO(jtattermusch): Add Grpc.Auth assembly and its dependencies +copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.dll || goto :error +copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.pdb unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.pdb || goto :error +copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.xml unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.xml || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.dll || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.pdb unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.pdb || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.xml unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.xml || goto :error diff --git a/templates/src/csharp/build_unitypackage.bat.template b/templates/src/csharp/build_unitypackage.bat.template index 76ec10dbd90..d6f2e3c7f0d 100755 --- a/templates/src/csharp/build_unitypackage.bat.template +++ b/templates/src/csharp/build_unitypackage.bat.template @@ -42,6 +42,9 @@ @rem copy Grpc assemblies to the unity package skeleton @rem TODO(jtattermusch): Add Grpc.Auth assembly and its dependencies + copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.dll || goto :error + copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.pdb unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.pdb || goto :error + copy /Y Grpc.Core.Api\bin\Release\net45\Grpc.Core.Api.xml unitypackage\unitypackage_skeleton\Plugins\Grpc.Core.Api\lib\net45\Grpc.Core.Api.xml || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.dll || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.pdb unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.pdb || goto :error copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.xml unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.xml || goto :error From c09423f8c19705a7357460edb07f44de68518f00 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 25 Jan 2019 12:48:08 +0100 Subject: [PATCH 170/814] add unity package skeleton for Grpc.Core.Api --- .../Plugins/Grpc.Core.Api.meta | 10 ++++++ .../Plugins/Grpc.Core.Api/lib.meta | 10 ++++++ .../Plugins/Grpc.Core.Api/lib/net45.meta | 10 ++++++ .../lib/net45/Grpc.Core.Api.dll.meta | 32 +++++++++++++++++++ .../lib/net45/Grpc.Core.Api.pdb.meta | 9 ++++++ .../lib/net45/Grpc.Core.Api.xml.meta | 9 ++++++ 6 files changed, 80 insertions(+) create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.dll.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.pdb.meta create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.xml.meta diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api.meta new file mode 100644 index 00000000000..f5d5149c2a5 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9b4ba511bab164bf9a5d0db8bb681b05 +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib.meta new file mode 100644 index 00000000000..88c1aedbae1 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 21a3894045fc74e85a09ab84c0e35c3a +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45.meta new file mode 100644 index 00000000000..8012e3d581b --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 9fd1c7cd7b6ed4d5285de90a332fb93e +folderAsset: yes +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.dll.meta new file mode 100644 index 00000000000..7b939f861c8 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.dll.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: c9bf7237d50ec4e99ba7d2c153b80e8f +timeCreated: 1531219386 +licenseType: Free +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.pdb.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.pdb.meta new file mode 100644 index 00000000000..48019325cdc --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.pdb.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bf384c9cae7a648c488af0193b3e74c0 +timeCreated: 1531219385 +licenseType: Free +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.xml.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.xml.meta new file mode 100644 index 00000000000..e3814dc5850 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.Api/lib/net45/Grpc.Core.Api.xml.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0a4fb8823a783423880c9d8c9d3b5cf4 +timeCreated: 1531219386 +licenseType: Free +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From ae7254aa79b2ba5941b9bd95287958b4703748bc Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 25 Jan 2019 10:04:16 -0800 Subject: [PATCH 171/814] adding ptrace to asan --- third_party/toolchains/BUILD | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD index 04fd795b566..943690a2efd 100644 --- a/third_party/toolchains/BUILD +++ b/third_party/toolchains/BUILD @@ -56,6 +56,14 @@ platform( name: "dockerNetwork" value: "off" } + properties: { + name: "dockerAddCapabilities" + value: "SYS_PTRACE" + } + properties: { + name: "dockerPrivileged" + value: "true" + } """, ) @@ -87,6 +95,14 @@ platform( name: "dockerNetwork" value: "off" } + properties: { + name: "dockerAddCapabilities" + value: "SYS_PTRACE" + } + properties: { + name: "dockerPrivileged" + value: "true" + } """, ) From 59004219ff3781fc8b231cfa845e09c8df1c2521 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 25 Jan 2019 10:07:49 -0800 Subject: [PATCH 172/814] removed override argument for asan --- tools/remote_build/rbe_common.bazelrc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc index 9a86713f505..3438b1873d5 100644 --- a/tools/remote_build/rbe_common.bazelrc +++ b/tools/remote_build/rbe_common.bazelrc @@ -54,12 +54,6 @@ build:asan --copt=-gmlt # TODO(jtattermusch): use more reasonable test timeout build:asan --test_timeout=3600 build:asan --test_tag_filters=-qps_json_driver -build:asan --host_platform_remote_properties_override=''' - properties: { - name: "dockerDropCapabilities" - value: "" - } -''' # memory sanitizer: most settings are already in %workspace%/.bazelrc # we only need a few additional ones that are Foundry specific From 6d569523216d9f03d7c4816e2ad55e5140854a23 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 24 Jan 2019 14:32:40 -0800 Subject: [PATCH 173/814] Reuse subchannel's mu --- src/core/ext/filters/client_channel/subchannel.cc | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 8708cf21c3b..7f15cb416b9 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -202,7 +202,6 @@ class ConnectedSubchannelStateWatcher // Must be instantiated while holding c->mu. explicit ConnectedSubchannelStateWatcher(grpc_subchannel* c) : subchannel_(c) { - gpr_mu_init(&mu_); // Steal subchannel ref for connecting. GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "state_watcher"); GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "connecting"); @@ -235,13 +234,10 @@ class ConnectedSubchannelStateWatcher ~ConnectedSubchannelStateWatcher() { GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "state_watcher"); - gpr_mu_destroy(&mu_); } - void Orphan() override { - MutexLock lock(&mu_); - health_check_client_.reset(); - } + // Must be called while holding subchannel_->mu. + void Orphan() override { health_check_client_.reset(); } private: static void OnConnectivityChanged(void* arg, grpc_error* error) { @@ -307,13 +303,12 @@ class ConnectedSubchannelStateWatcher static void OnHealthChanged(void* arg, grpc_error* error) { auto* self = static_cast(arg); - MutexLock health_state_lock(&self->mu_); + grpc_subchannel* c = self->subchannel_; + MutexLock lock(&c->mu); if (self->health_state_ == GRPC_CHANNEL_SHUTDOWN) { self->Unref(); return; } - grpc_subchannel* c = self->subchannel_; - MutexLock lock(&c->mu); if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) { grpc_connectivity_state_set(&c->state_and_health_tracker, self->health_state_, GRPC_ERROR_REF(error), @@ -330,8 +325,6 @@ class ConnectedSubchannelStateWatcher grpc_core::OrphanablePtr health_check_client_; grpc_closure on_health_changed_; grpc_connectivity_state health_state_ = GRPC_CHANNEL_CONNECTING; - // Ensure atomic change to health_check_client_ and health_state_. - gpr_mu mu_; }; } // namespace grpc_core From 16dcc172fe25ba4b8aedfc501e8763d92a1a7290 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 25 Jan 2019 10:21:24 -0800 Subject: [PATCH 174/814] putting a retry on apt-get jq --- .../helper_scripts/prepare_build_linux_perf_rc | 8 +++++++- tools/internal_ci/linux/grpc_run_tests_matrix.sh | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc index ff5593e031a..b66ac38942f 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc @@ -21,7 +21,13 @@ ulimit -c unlimited # Performance PR testing needs GH API key and PR metadata to comment results if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - sudo apt-get install -y jq + retry=0 + until [ $retry -ge 3 ] + do + sudo apt-get install -y jq && break + retry=$[$retry+1] + sleep 5 + done export ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) fi diff --git a/tools/internal_ci/linux/grpc_run_tests_matrix.sh b/tools/internal_ci/linux/grpc_run_tests_matrix.sh index f9acd814ae8..f8fd963ccf3 100755 --- a/tools/internal_ci/linux/grpc_run_tests_matrix.sh +++ b/tools/internal_ci/linux/grpc_run_tests_matrix.sh @@ -23,7 +23,13 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ] && [ -n "$RUN_TESTS_FLAGS" ]; then sudo apt-get update - sudo apt-get install -y jq + retry=0 + until [ $retry -ge 3 ] + do + sudo apt-get install -y jq && break + retry=$[$retry+1] + sleep 5 + done ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch" fi From 7a164229dbbb0944eb9410b15415d626d44937c3 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 25 Jan 2019 10:25:08 -0800 Subject: [PATCH 175/814] Address reviewer comments --- include/grpcpp/server.h | 23 +++++++++++------------ src/core/lib/iomgr/executor.cc | 10 +++++----- src/cpp/server/server_cc.cc | 17 ++++++++--------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 5bbbd704a02..df68cf31441 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -248,11 +248,11 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { /// the \a sync_server_cqs) std::vector> sync_req_mgrs_; - // Outstanding callback requests. The vector is indexed by method with a - // list per method. Each element should store its own iterator - // in the list and should erase it when the request is actually bound to - // an RPC. Synchronize this list with its own mu_ (not the server mu_) since - // these must be active at Shutdown when the server mu_ is locked + // Outstanding callback requests. The vector is indexed by method with a list + // per method. Each element should store its own iterator in the list and + // should erase it when the request is actually bound to an RPC. Synchronize + // this list with its own mu_ (not the server mu_) since these must be active + // at Shutdown when the server mu_ is locked. // TODO(vjpai): Merge with the core request matcher to avoid duplicate work struct MethodReqList { std::mutex reqs_mu; @@ -274,13 +274,12 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { std::condition_variable shutdown_cv_; // It is ok (but not required) to nest callback_reqs_mu_ under mu_ . - // Incrementing callback_reqs_outstanding_ is ok without a lock - // but it should only be decremented under the lock in case it is the - // last request and enables the server shutdown. The increment is - // performance-critical since it happens during periods of increasing - // load; the decrement happens only when memory is maxed out, during server - // shutdown, or (possibly in a future version) during decreasing load, so - // it is less performance-critical. + // Incrementing callback_reqs_outstanding_ is ok without a lock but it must be + // decremented under the lock in case it is the last request and enables the + // server shutdown. The increment is performance-critical since it happens + // during periods of increasing load; the decrement happens only when memory + // is maxed out, during server shutdown, or (possibly in a future version) + // during decreasing load, so it is less performance-critical. std::mutex callback_reqs_mu_; std::condition_variable callback_reqs_done_cv_; std::atomic_int callback_reqs_outstanding_{0}; diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index 34683273cf6..1e7c6a907a2 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -111,11 +111,11 @@ size_t Executor::RunClosures(const char* executor_name, grpc_closure_list list) { size_t n = 0; - // In the executor, the ExecCtx for the thread is declared - // in the executor thread itself, but this is the point where we - // could start seeing application-level callbacks. No need to - // create a new ExecCtx, though, since there already is one and it is - // flushed (but not destructed) in this function itself + // In the executor, the ExecCtx for the thread is declared in the executor + // thread itself, but this is the point where we could start seeing + // application-level callbacks. No need to create a new ExecCtx, though, + // since there already is one and it is flushed (but not destructed) in this + // function itself. grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_closure* c = list.head; diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 12aa52ef704..1e642681467 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -62,11 +62,11 @@ namespace { #define DEFAULT_CALLBACK_REQS_PER_METHOD 512 // What is the (soft) limit for outstanding requests in the server -#define MAXIMUM_CALLBACK_REQS_OUTSTANDING 30000 +#define SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING 30000 -// If the number of unmatched requests for a method drops below this amount, -// try to allocate extra unless it pushes the total number of callbacks above -// the soft maximum +// If the number of unmatched requests for a method drops below this amount, try +// to allocate extra unless it pushes the total number of callbacks above the +// soft maximum #define SOFT_MINIMUM_SPARE_CALLBACK_REQS_PER_METHOD 128 class DefaultGlobalCallbacks final : public Server::GlobalCallbacks { @@ -185,11 +185,10 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { GPR_ASSERT(cq_ && !in_flight_); in_flight_ = true; if (method_tag_) { - if (GRPC_CALL_OK != - grpc_server_request_registered_call( + if (grpc_server_request_registered_call( server, method_tag_, &call_, &deadline_, &request_metadata_, has_request_payload_ ? &request_payload_ : nullptr, cq_, - notify_cq, this)) { + notify_cq, this) != GRPC_CALL_OK) { TeardownRequest(); return; } @@ -452,7 +451,7 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { (req_->req_list_->reqs_list_sz < SOFT_MINIMUM_SPARE_CALLBACK_REQS_PER_METHOD && req_->server_->callback_reqs_outstanding_ < - MAXIMUM_CALLBACK_REQS_OUTSTANDING)) { + SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING)) { spawn_new = true; } } @@ -528,7 +527,7 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { // load no longer justifies it. Consider measuring // dynamic load and setting a target accordingly. if (req_->server_->callback_reqs_outstanding_ < - MAXIMUM_CALLBACK_REQS_OUTSTANDING) { + SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING) { req_->Clear(); req_->Setup(); } else { From bd19173114eb71c288890e52e874f0c9d8f8015d Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 25 Jan 2019 10:29:39 -0800 Subject: [PATCH 176/814] Collect timestamps for all data written for a stream instead of just data frames --- src/core/ext/transport/chttp2/transport/writing.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 265d3365d3c..cf77ddc8278 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -363,7 +363,6 @@ class DataSendContext { grpc_chttp2_encode_data(s_->id, &s_->compressed_data_buffer, send_bytes, is_last_frame_, &s_->stats.outgoing, &t_->outbuf); s_->flow_control->SentData(send_bytes); - s_->byte_counter += send_bytes; if (s_->compressed_data_buffer.length == 0) { s_->sending_bytes += s_->uncompressed_data_size; } @@ -498,9 +497,6 @@ class StreamWriteContext { data_send_context.CompressMoreBytes(); } } - if (s_->traced && grpc_endpoint_can_track_err(t_->ep)) { - grpc_core::ContextList::Append(&t_->cl, s_); - } write_context_->ResetPingClock(); if (data_send_context.is_last_frame()) { SentLastFrame(); @@ -610,11 +606,18 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( (according to available window sizes) and add to the output buffer */ while (grpc_chttp2_stream* s = ctx.NextStream()) { StreamWriteContext stream_ctx(&ctx, s); + size_t orig_len = t->outbuf.length; stream_ctx.FlushInitialMetadata(); stream_ctx.FlushWindowUpdates(); stream_ctx.FlushData(); stream_ctx.FlushTrailingMetadata(); - + if (t->outbuf.length > orig_len) { + /* Add this stream to the list of the contexts to be traced at TCP */ + s->byte_counter += t->outbuf.length - orig_len; + if (s->traced && grpc_endpoint_can_track_err(t->ep)) { + grpc_core::ContextList::Append(&t->cl, s); + } + } if (stream_ctx.stream_became_writable()) { if (!grpc_chttp2_list_add_writing_stream(t, s)) { /* already in writing list: drop ref */ From d098a0dabc1be2ed0a89359ed6fcca62b430b332 Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 25 Jan 2019 12:12:39 -0800 Subject: [PATCH 177/814] fixed small issue in run_tests.sh and remove duplicate in CallTest.php --- src/php/bin/run_tests.sh | 9 ++++----- src/php/tests/unit_tests/CallTest.php | 10 ---------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh index cfe16ee3e85..2f9c9f636ec 100755 --- a/src/php/bin/run_tests.sh +++ b/src/php/bin/run_tests.sh @@ -32,9 +32,8 @@ php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ export ZEND_DONT_UNLOAD_MODULES=1 export USE_ZEND_ALLOC=0 # Detect whether valgrind is executable -if ! [ -x "$(command -v valgrind)" ]; then - echo 'Error: valgrind is not installed and is not executable' >&2 - exit 1 -fi -valgrind --error-exitcode=10 --leak-check=yes php $extension_dir -d max_execution_time=300 \ +if [ -x "$(command -v valgrind)" ]; then + valgrind --error-exitcode=10 --leak-check=yes php $extension_dir -d max_execution_time=300 \ ../tests/MemoryLeakTest/MemoryLeakTest.php + exit 0 +fi diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php index 20c35299cb0..28098c4016e 100644 --- a/src/php/tests/unit_tests/CallTest.php +++ b/src/php/tests/unit_tests/CallTest.php @@ -96,16 +96,6 @@ class CallTest extends PHPUnit_Framework_TestCase $this->assertTrue($result->send_metadata); } - public function testAddMultiAndMultiValueMetadata() - { - $batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1', 'value2'], - 'key2' => ['value3', 'value4'],], - ]; - $result = $this->call->startBatch($batch); - $this->assertTrue($result->send_metadata); - } - public function testGetPeer() { $this->assertTrue(is_string($this->call->getPeer())); From ca30b2240f6f8e86b51452097c3cb43c5d4f7117 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 25 Jan 2019 13:29:58 -0800 Subject: [PATCH 178/814] Revert c-ares as the default resolvre --- .../client_channel/resolver/dns/c_ares/dns_resolver_ares.cc | 3 +-- .../test/cpp/naming/resolver_component_tests_defs.include | 1 + test/core/client_channel/resolvers/dns_resolver_test.cc | 2 +- test/cpp/naming/resolver_component_tests_runner.py | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index bf8b0ea5f62..fe245bfef09 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -478,8 +478,7 @@ static grpc_address_resolver_vtable ares_resolver = { grpc_resolve_address_ares, blocking_resolve_address_ares}; static bool should_use_ares(const char* resolver_env) { - return resolver_env == nullptr || strlen(resolver_env) == 0 || - gpr_stricmp(resolver_env, "ares") == 0; + return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0; } void grpc_resolver_dns_ares_init() { diff --git a/templates/test/cpp/naming/resolver_component_tests_defs.include b/templates/test/cpp/naming/resolver_component_tests_defs.include index d38316cbe68..b34845e01a3 100644 --- a/templates/test/cpp/naming/resolver_component_tests_defs.include +++ b/templates/test/cpp/naming/resolver_component_tests_defs.include @@ -55,6 +55,7 @@ if cur_resolver and cur_resolver != 'ares': 'needs to use GRPC_DNS_RESOLVER=ares.')) test_runner_log('Exit 1 without running tests.') sys.exit(1) +os.environ.update({'GRPC_DNS_RESOLVER': 'ares'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index 6f153cc9bf6..f426eab9592 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -75,7 +75,7 @@ int main(int argc, char** argv) { test_succeeds(dns, "dns:www.google.com"); test_succeeds(dns, "dns:///www.google.com"); char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) { + if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { test_fails(dns, "dns://8.8.8.8/8.8.8.8:8888"); } else { test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888"); diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index a4438cb100e..8a5b1f53dcf 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -55,6 +55,7 @@ if cur_resolver and cur_resolver != 'ares': 'needs to use GRPC_DNS_RESOLVER=ares.')) test_runner_log('Exit 1 without running tests.') sys.exit(1) +os.environ.update({'GRPC_DNS_RESOLVER': 'ares'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, From f817d49e478fc8ae28ee8999d3195c759ed12e3a Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 25 Jan 2019 14:03:37 -0800 Subject: [PATCH 179/814] Update the README.md --- src/python/grpcio_tests/tests/qps/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/python/grpcio_tests/tests/qps/README.md b/src/python/grpcio_tests/tests/qps/README.md index f5149509ce3..8ae155a5b4b 100644 --- a/src/python/grpcio_tests/tests/qps/README.md +++ b/src/python/grpcio_tests/tests/qps/README.md @@ -15,13 +15,15 @@ All Python related benchmark scenarios are: * python_protobuf_sync_streaming_qps_unconstrained * python_protobuf_sync_unary_ping_pong_1MB -Here I picked the top 2 most representative scenarios of them, and reduce their benchmark duration from 30 seconds to 10 seconds: +Here we picked a small but representative subset, and reduce their benchmark duration from 30 seconds to 10 seconds: * python_protobuf_async_unary_ping_pong * python_protobuf_sync_streaming_ping_pong ## Why keep the scenario file if it can be generated? -Well... The `tools/run_tests/performance/scenario_config.py` is 1274 lines long. The intention of building these benchmark tools is reducing the complexity of existing infrastructure code. So, instead of calling layers of abstraction to generate the scenario file, keeping a valid static copy is more preferable. +Well... The `tools/run_tests/performance/scenario_config.py` is 1274 lines long. The intention of building these benchmark tools is reducing the complexity of existing infrastructure code. So, instead of calling layers of abstraction to generate the scenario file, keeping a valid static copy is preferable. + +Also, if the use case for this tool grows beyond simple static scenarios, we can incorporate automatic generation and selection of scenarios into the tool. ## How to run it? @@ -29,7 +31,7 @@ Well... The `tools/run_tests/performance/scenario_config.py` is 1274 lines long. bazel test --test_output=streamed src/python/grpcio_tests/tests/qps:basic_benchmark_test ``` -## How is the output look like? +## What does the output look like? ``` RUNNING SCENARIO: python_protobuf_async_unary_ping_pong From bf098ed49b6a0c24f8b3fba50bb9c581513bf593 Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 25 Jan 2019 15:13:40 -0800 Subject: [PATCH 180/814] remove exit status --- src/php/bin/run_tests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh index 2f9c9f636ec..861ce433c4e 100755 --- a/src/php/bin/run_tests.sh +++ b/src/php/bin/run_tests.sh @@ -35,5 +35,4 @@ export USE_ZEND_ALLOC=0 if [ -x "$(command -v valgrind)" ]; then valgrind --error-exitcode=10 --leak-check=yes php $extension_dir -d max_execution_time=300 \ ../tests/MemoryLeakTest/MemoryLeakTest.php - exit 0 fi From 08e06da780d3794e8b457f762179abe08fbd220f Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 25 Jan 2019 15:25:34 -0800 Subject: [PATCH 181/814] explicitly lengthened timeout --- test/cpp/end2end/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 4c28eee4d15..c061947e1cb 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -223,6 +223,7 @@ grpc_cc_test( ":end2end_test_lib", ], size = "large", # with poll-cv this takes long, see #17493 + timeout = "long", ) grpc_cc_test( From dd5ead2ac1ef1a442289b911f6e6602b4c808a82 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 25 Jan 2019 18:41:06 -0800 Subject: [PATCH 182/814] Extra argument for grpc_endpoint_write --- test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm index fbc34c74d66..528f4b1cdad 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm @@ -167,7 +167,7 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize); grpc_slice_buffer_add(&write_slices, slice); init_event_closure(&write_done, &write); - grpc_endpoint_write(ep_, &write_slices, &write_done); + grpc_endpoint_write(ep_, &write_slices, &write_done, nullptr); XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES); XCTAssertEqual(reinterpret_cast(write), GRPC_ERROR_NONE); @@ -224,7 +224,7 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize); grpc_slice_buffer_add(&write_slices, slice); init_event_closure(&write_done, &write); - grpc_endpoint_write(ep_, &write_slices, &write_done); + grpc_endpoint_write(ep_, &write_slices, &write_done, nullptr); XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES); XCTAssertEqual(reinterpret_cast(write), GRPC_ERROR_NONE); @@ -273,7 +273,7 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize); grpc_slice_buffer_add(&write_slices, slice); init_event_closure(&write_done, &write); - grpc_endpoint_write(ep_, &write_slices, &write_done); + grpc_endpoint_write(ep_, &write_slices, &write_done, nullptr); XCTAssertEqual([self waitForEvent:&write timeout:kWriteTimeout], YES); XCTAssertEqual(reinterpret_cast(write), GRPC_ERROR_NONE); From 564be999dea89dd88ff4cc4619ff3ea289da21e9 Mon Sep 17 00:00:00 2001 From: Kumar Akshay Date: Mon, 14 Jan 2019 00:19:03 +0530 Subject: [PATCH 183/814] Fix warning Fix clang format --- .../server/load_reporter/load_reporter_async_service_impl.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/server/load_reporter/load_reporter_async_service_impl.cc b/src/cpp/server/load_reporter/load_reporter_async_service_impl.cc index d001199b8c5..859ad9946c8 100644 --- a/src/cpp/server/load_reporter/load_reporter_async_service_impl.cc +++ b/src/cpp/server/load_reporter/load_reporter_async_service_impl.cc @@ -211,8 +211,8 @@ void LoadReporterAsyncServiceImpl::ReportLoadHandler::OnReadDone( load_key_); const auto& load_report_interval = initial_request.load_report_interval(); load_report_interval_ms_ = - static_cast(load_report_interval.seconds() * 1000 + - load_report_interval.nanos() / 1000); + static_cast(load_report_interval.seconds() * 1000 + + load_report_interval.nanos() / 1000); gpr_log( GPR_INFO, "[LRS %p] Initial request received. Start load reporting (load " From cc6ef78972f7d8c745c11915dfac1475a82e0c24 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 28 Jan 2019 09:13:57 -0500 Subject: [PATCH 184/814] Use test timeout implied by test size (unless overridden). Currently, grpc_cc_test with size="large" will still have timeout="moderate" (which corresponds to medium size test) because the timeout will be overriden by the default arg. Fixing as this behavior is very counterintuitive. --- bazel/grpc_build_system.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index caeafc76b69..be85bc87324 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -132,7 +132,7 @@ def grpc_proto_library( generate_mocks = generate_mocks, ) -def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = "moderate", tags = [], exec_compatible_with = []): +def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = None, tags = [], exec_compatible_with = []): copts = [] if language.upper() == "C": copts = if_not_windows(["-std=c99"]) From baaf93b830d9af858f7315875c7342fadd9dcf7d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 28 Jan 2019 09:19:28 -0500 Subject: [PATCH 185/814] revert no-longer-needed hotfix from #17820 --- test/cpp/end2end/BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index c061947e1cb..4c28eee4d15 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -223,7 +223,6 @@ grpc_cc_test( ":end2end_test_lib", ], size = "large", # with poll-cv this takes long, see #17493 - timeout = "long", ) grpc_cc_test( From d4f58b0f226c0008ed5e21b1f4b76c48ad5bea5b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 28 Jan 2019 16:05:12 +0100 Subject: [PATCH 186/814] Revert "Collect timestamps for all data written for a stream instead of just data frames" --- src/core/ext/transport/chttp2/transport/writing.cc | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index cf77ddc8278..265d3365d3c 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -363,6 +363,7 @@ class DataSendContext { grpc_chttp2_encode_data(s_->id, &s_->compressed_data_buffer, send_bytes, is_last_frame_, &s_->stats.outgoing, &t_->outbuf); s_->flow_control->SentData(send_bytes); + s_->byte_counter += send_bytes; if (s_->compressed_data_buffer.length == 0) { s_->sending_bytes += s_->uncompressed_data_size; } @@ -497,6 +498,9 @@ class StreamWriteContext { data_send_context.CompressMoreBytes(); } } + if (s_->traced && grpc_endpoint_can_track_err(t_->ep)) { + grpc_core::ContextList::Append(&t_->cl, s_); + } write_context_->ResetPingClock(); if (data_send_context.is_last_frame()) { SentLastFrame(); @@ -606,18 +610,11 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( (according to available window sizes) and add to the output buffer */ while (grpc_chttp2_stream* s = ctx.NextStream()) { StreamWriteContext stream_ctx(&ctx, s); - size_t orig_len = t->outbuf.length; stream_ctx.FlushInitialMetadata(); stream_ctx.FlushWindowUpdates(); stream_ctx.FlushData(); stream_ctx.FlushTrailingMetadata(); - if (t->outbuf.length > orig_len) { - /* Add this stream to the list of the contexts to be traced at TCP */ - s->byte_counter += t->outbuf.length - orig_len; - if (s->traced && grpc_endpoint_can_track_err(t->ep)) { - grpc_core::ContextList::Append(&t->cl, s); - } - } + if (stream_ctx.stream_became_writable()) { if (!grpc_chttp2_list_add_writing_stream(t, s)) { /* already in writing list: drop ref */ From ee23fc3d2e1898bb712b67aa5f3f2a891695d444 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 28 Jan 2019 10:47:12 -0800 Subject: [PATCH 187/814] Avoid 'which' failure --- third_party/py/python_configure.bzl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/third_party/py/python_configure.bzl b/third_party/py/python_configure.bzl index 6e25cc493b3..9036a95909b 100644 --- a/third_party/py/python_configure.bzl +++ b/third_party/py/python_configure.bzl @@ -139,7 +139,12 @@ def _symlink_genrule_for_dir(repository_ctx, def _get_python_bin(repository_ctx): """Gets the python bin path.""" python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH, 'python') - python_bin_path = repository_ctx.which(python_bin) + if not '/' in python_bin and not '\\' in python_bin: + # It's a command, use 'which' to find its path. + python_bin_path = repository_ctx.which(python_bin) + else: + # It's a path, use it as it is. + python_bin_path = python_bin if python_bin_path != None: return str(python_bin_path) _fail("Cannot find python in PATH, please make sure " + From 7e90dad67543d393379a15b9c1cb7674d64b7d05 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 28 Jan 2019 10:55:19 -0800 Subject: [PATCH 188/814] Adopt reviewer's advices --- src/python/grpcio_tests/tests/BUILD.bazel | 10 +++++----- ...{bazel_patch.py => bazel_namespace_package_hack.py} | 2 +- src/python/grpcio_tests/tests/interop/BUILD.bazel | 2 +- src/python/grpcio_tests/tests/interop/methods.py | 4 ++-- src/python/grpcio_tests/tests/status/BUILD.bazel | 2 +- .../grpcio_tests/tests/status/_grpc_status_test.py | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) rename src/python/grpcio_tests/tests/{bazel_patch.py => bazel_namespace_package_hack.py} (97%) diff --git a/src/python/grpcio_tests/tests/BUILD.bazel b/src/python/grpcio_tests/tests/BUILD.bazel index 118cd0ea0dd..b908ab85173 100644 --- a/src/python/grpcio_tests/tests/BUILD.bazel +++ b/src/python/grpcio_tests/tests/BUILD.bazel @@ -1,8 +1,8 @@ py_library( - name = "bazel_patch", - srcs = ["bazel_patch.py"], - visibility = ["//visibility:public"], - data=[ - "//src/python/grpcio_tests/tests/unit/credentials", + name = "bazel_namespace_package_hack", + srcs = ["bazel_namespace_package_hack.py"], + visibility = [ + "//src/python/grpcio_tests/tests/status:__subpackages__", + "//src/python/grpcio_tests/tests/interop:__subpackages__", ], ) diff --git a/src/python/grpcio_tests/tests/bazel_patch.py b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py similarity index 97% rename from src/python/grpcio_tests/tests/bazel_patch.py rename to src/python/grpcio_tests/tests/bazel_namespace_package_hack.py index af48697de30..c6b72c327b1 100644 --- a/src/python/grpcio_tests/tests/bazel_patch.py +++ b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py @@ -22,7 +22,7 @@ import sys # Python process to parse the .pth file in the sys.path to resolve namespace # package in the right place. # Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 -def bazel_patch(): +def sys_path_to_site_dir_hack(): """Add valid sys.path item to site directory to parse the .pth files.""" for item in sys.path: if os.path.exists(item): diff --git a/src/python/grpcio_tests/tests/interop/BUILD.bazel b/src/python/grpcio_tests/tests/interop/BUILD.bazel index bb5f0f344e2..770b1f78a70 100644 --- a/src/python/grpcio_tests/tests/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests/interop/BUILD.bazel @@ -29,7 +29,7 @@ py_library( srcs = ["methods.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests:bazel_patch", + "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing:py_messages_proto", "//src/proto/grpc/testing:py_test_proto", diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index e037046691b..e16966e3918 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -13,8 +13,8 @@ # limitations under the License. """Implementations of interoperability test methods.""" -from tests.bazel_patch import bazel_patch -bazel_patch() +from tests import bazel_namespace_package_hack +bazel_namespace_package_hack.sys_path_to_site_dir_hack() import enum import json diff --git a/src/python/grpcio_tests/tests/status/BUILD.bazel b/src/python/grpcio_tests/tests/status/BUILD.bazel index 21dea5a76dc..b163fe3975e 100644 --- a/src/python/grpcio_tests/tests/status/BUILD.bazel +++ b/src/python/grpcio_tests/tests/status/BUILD.bazel @@ -10,7 +10,7 @@ py_test( deps = [ "//src/python/grpcio/grpc:grpcio", "//src/python/grpcio_status/grpc_status:grpc_status", - "//src/python/grpcio_tests/tests:bazel_patch", + "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", "//src/python/grpcio_tests/tests/unit:test_common", "//src/python/grpcio_tests/tests/unit/framework/common:common", requirement('protobuf'), diff --git a/src/python/grpcio_tests/tests/status/_grpc_status_test.py b/src/python/grpcio_tests/tests/status/_grpc_status_test.py index 67b1785becb..77f5fb283d1 100644 --- a/src/python/grpcio_tests/tests/status/_grpc_status_test.py +++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py @@ -13,8 +13,8 @@ # limitations under the License. """Tests of grpc_status.""" -from tests.bazel_patch import bazel_patch -bazel_patch() +from tests import bazel_namespace_package_hack +bazel_namespace_package_hack.sys_path_to_site_dir_hack() import unittest From 062e2bcadea19e3a0fb3a518207d91109828c97b Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 28 Jan 2019 11:22:20 -0800 Subject: [PATCH 189/814] added retry statements to jq installation commands --- .../helper_scripts/prepare_build_linux_perf_rc | 8 +++++++- tools/internal_ci/linux/grpc_run_tests_matrix.sh | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc index ff5593e031a..b66ac38942f 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc @@ -21,7 +21,13 @@ ulimit -c unlimited # Performance PR testing needs GH API key and PR metadata to comment results if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - sudo apt-get install -y jq + retry=0 + until [ $retry -ge 3 ] + do + sudo apt-get install -y jq && break + retry=$[$retry+1] + sleep 5 + done export ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) fi diff --git a/tools/internal_ci/linux/grpc_run_tests_matrix.sh b/tools/internal_ci/linux/grpc_run_tests_matrix.sh index f9acd814ae8..f8fd963ccf3 100755 --- a/tools/internal_ci/linux/grpc_run_tests_matrix.sh +++ b/tools/internal_ci/linux/grpc_run_tests_matrix.sh @@ -23,7 +23,13 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ] && [ -n "$RUN_TESTS_FLAGS" ]; then sudo apt-get update - sudo apt-get install -y jq + retry=0 + until [ $retry -ge 3 ] + do + sudo apt-get install -y jq && break + retry=$[$retry+1] + sleep 5 + done ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch" fi From 1a688982a424b849c7fb5702a3357d9789cbaa54 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 28 Jan 2019 11:33:19 -0800 Subject: [PATCH 190/814] Cast the str type if it is unicode --- src/python/grpcio/_parallel_compile_patch.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/python/grpcio/_parallel_compile_patch.py b/src/python/grpcio/_parallel_compile_patch.py index 4d03ef49ba0..de48a4099b5 100644 --- a/src/python/grpcio/_parallel_compile_patch.py +++ b/src/python/grpcio/_parallel_compile_patch.py @@ -19,6 +19,7 @@ Enabling parallel build helps a lot. import distutils.ccompiler import os +import six try: BUILD_EXT_COMPILER_JOBS = int( @@ -37,6 +38,8 @@ def _parallel_compile(self, extra_preargs=None, extra_postargs=None, depends=None): + if isinstance(output_dir, six.text_type): + output_dir = str(output_dir) # setup the same way as distutils.ccompiler.CCompiler # https://github.com/python/cpython/blob/31368a4f0e531c19affe2a1becd25fc316bc7501/Lib/distutils/ccompiler.py#L564 macros, objects, extra_postargs, pp_opts, build = self._setup_compile( From 91fde06b12c0bda8da88141f5ae756b526e039ee Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 28 Jan 2019 12:12:06 -0800 Subject: [PATCH 191/814] Remove the dependency of 'six' --- src/python/grpcio/_parallel_compile_patch.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/python/grpcio/_parallel_compile_patch.py b/src/python/grpcio/_parallel_compile_patch.py index de48a4099b5..b34aa17fd0b 100644 --- a/src/python/grpcio/_parallel_compile_patch.py +++ b/src/python/grpcio/_parallel_compile_patch.py @@ -19,7 +19,6 @@ Enabling parallel build helps a lot. import distutils.ccompiler import os -import six try: BUILD_EXT_COMPILER_JOBS = int( @@ -38,12 +37,10 @@ def _parallel_compile(self, extra_preargs=None, extra_postargs=None, depends=None): - if isinstance(output_dir, six.text_type): - output_dir = str(output_dir) # setup the same way as distutils.ccompiler.CCompiler # https://github.com/python/cpython/blob/31368a4f0e531c19affe2a1becd25fc316bc7501/Lib/distutils/ccompiler.py#L564 macros, objects, extra_postargs, pp_opts, build = self._setup_compile( - output_dir, macros, include_dirs, sources, depends, extra_postargs) + str(output_dir), macros, include_dirs, sources, depends, extra_postargs) cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) def _compile_single_file(obj): From abd75e04aadb4681b768c029dc0d7372c789da93 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 28 Jan 2019 13:36:26 -0800 Subject: [PATCH 192/814] Remove unneeded header --- src/core/lib/iomgr/exec_ctx.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index 36c1a907cbc..c6c30d3129e 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -28,7 +28,6 @@ #include "src/core/lib/gpr/tls.h" #include "src/core/lib/gprpp/fork.h" -#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/closure.h" typedef int64_t grpc_millis; From d98de1facf4680fb5b03b8bec94aaffd8a664d7e Mon Sep 17 00:00:00 2001 From: John Luo Date: Tue, 22 Jan 2019 09:17:19 -0800 Subject: [PATCH 193/814] Add new overload to BindService that doesn't require an implementation --- src/compiler/csharp_generator.cc | 31 +++++++++++++++ src/csharp/Grpc.Core/ServiceBinderBase.cs | 14 +++++++ src/csharp/Grpc.Examples/MathGrpc.cs | 17 +++++++-- src/csharp/Grpc.HealthCheck/HealthGrpc.cs | 15 ++++++-- .../BenchmarkServiceGrpc.cs | 18 +++++++-- src/csharp/Grpc.IntegrationTesting/Control.cs | 10 +++-- src/csharp/Grpc.IntegrationTesting/Empty.cs | 1 + .../EmptyServiceGrpc.cs | 13 +++++-- .../Grpc.IntegrationTesting/MetricsGrpc.cs | 17 +++++++-- .../ReportQpsScenarioServiceGrpc.cs | 14 +++++-- .../Grpc.IntegrationTesting/TestGrpc.cs | 38 +++++++++++++++++-- .../WorkerServiceGrpc.cs | 17 +++++++-- src/csharp/Grpc.Reflection/ReflectionGrpc.cs | 14 +++++-- 13 files changed, 187 insertions(+), 32 deletions(-) diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 59ddbd82f61..c1eaf971483 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -645,6 +645,36 @@ void GenerateBindServiceWithBinderMethod(Printer* out, out->Print("\n"); } +void GenerateBindServiceWithBinderMethodWithoutImplementation( + Printer* out, const ServiceDescriptor* service) { + out->Print( + "/// Register service method with a service " + "binder without implementation. Useful when customizing the service " + "binding logic.\n" + "/// Note: this method is part of an experimental API that can change or " + "be " + "removed without any prior notice.\n"); + out->Print( + "/// Service methods will be bound by " + "calling AddMethod on this object." + "\n"); + out->Print( + "public static void BindService(grpc::ServiceBinderBase " + "serviceBinder)\n"); + out->Print("{\n"); + out->Indent(); + + for (int i = 0; i < service->method_count(); i++) { + const MethodDescriptor* method = service->method(i); + out->Print("serviceBinder.AddMethod($methodfield$);\n", "methodfield", + GetMethodFieldName(method)); + } + + out->Outdent(); + out->Print("}\n"); + out->Print("\n"); +} + void GenerateService(Printer* out, const ServiceDescriptor* service, bool generate_client, bool generate_server, bool internal_access) { @@ -674,6 +704,7 @@ void GenerateService(Printer* out, const ServiceDescriptor* service, if (generate_server) { GenerateBindServiceMethod(out, service); GenerateBindServiceWithBinderMethod(out, service); + GenerateBindServiceWithBinderMethodWithoutImplementation(out, service); } out->Outdent(); diff --git a/src/csharp/Grpc.Core/ServiceBinderBase.cs b/src/csharp/Grpc.Core/ServiceBinderBase.cs index d4909f4a269..79267d8f3d1 100644 --- a/src/csharp/Grpc.Core/ServiceBinderBase.cs +++ b/src/csharp/Grpc.Core/ServiceBinderBase.cs @@ -97,5 +97,19 @@ namespace Grpc.Core { throw new NotImplementedException(); } + + /// + /// Adds a method without a handler. + /// + /// The request message class. + /// The response message class. + /// The method. + public virtual void AddMethod( + Method method) + where TRequest : class + where TResponse : class + { + throw new NotImplementedException(); + } } } diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs index e5be387e67e..717f3fab5ea 100644 --- a/src/csharp/Grpc.Examples/MathGrpc.cs +++ b/src/csharp/Grpc.Examples/MathGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -299,6 +299,17 @@ namespace Math { serviceBinder.AddMethod(__Method_Sum, serviceImpl.Sum); } + /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// Service methods will be bound by calling AddMethod on this object. + public static void BindService(grpc::ServiceBinderBase serviceBinder) + { + serviceBinder.AddMethod(__Method_Div); + serviceBinder.AddMethod(__Method_DivMany); + serviceBinder.AddMethod(__Method_Fib); + serviceBinder.AddMethod(__Method_Sum); + } + } } #endregion diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs index 51956f2f234..f7002328acd 100644 --- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs +++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015 The gRPC Authors -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -243,6 +243,15 @@ namespace Grpc.Health.V1 { serviceBinder.AddMethod(__Method_Watch, serviceImpl.Watch); } + /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// Service methods will be bound by calling AddMethod on this object. + public static void BindService(grpc::ServiceBinderBase serviceBinder) + { + serviceBinder.AddMethod(__Method_Check); + serviceBinder.AddMethod(__Method_Watch); + } + } } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs index 3431b5fa181..39a48f2bb38 100644 --- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -337,6 +337,18 @@ namespace Grpc.Testing { serviceBinder.AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays); } + /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// Service methods will be bound by calling AddMethod on this object. + public static void BindService(grpc::ServiceBinderBase serviceBinder) + { + serviceBinder.AddMethod(__Method_UnaryCall); + serviceBinder.AddMethod(__Method_StreamingCall); + serviceBinder.AddMethod(__Method_StreamingFromClient); + serviceBinder.AddMethod(__Method_StreamingFromServer); + serviceBinder.AddMethod(__Method_StreamingBothWays); + } + } } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs index 368b86659a5..2e80dac074c 100644 --- a/src/csharp/Grpc.IntegrationTesting/Control.cs +++ b/src/csharp/Grpc.IntegrationTesting/Control.cs @@ -96,12 +96,13 @@ namespace Grpc.Testing { "GAcgAygIEhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVlc3RfcmVz", "dWx0cxgJIAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0Q291bnQq", "VgoKQ2xpZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5DX0NMSUVO", - "VBABEhAKDE9USEVSX0NMSUVOVBACEhMKD0NBTExCQUNLX0NMSUVOVBADKlsK", + "VBABEhAKDE9USEVSX0NMSUVOVBACEhMKD0NBTExCQUNLX0NMSUVOVBADKnAK", "ClNlcnZlclR5cGUSDwoLU1lOQ19TRVJWRVIQABIQCgxBU1lOQ19TRVJWRVIQ", "ARIYChRBU1lOQ19HRU5FUklDX1NFUlZFUhACEhAKDE9USEVSX1NFUlZFUhAD", - "KnIKB1JwY1R5cGUSCQoFVU5BUlkQABINCglTVFJFQU1JTkcQARIZChVTVFJF", - "QU1JTkdfRlJPTV9DTElFTlQQAhIZChVTVFJFQU1JTkdfRlJPTV9TRVJWRVIQ", - "AxIXChNTVFJFQU1JTkdfQk9USF9XQVlTEARiBnByb3RvMw==")); + "EhMKD0NBTExCQUNLX1NFUlZFUhAEKnIKB1JwY1R5cGUSCQoFVU5BUlkQABIN", + "CglTVFJFQU1JTkcQARIZChVTVFJFQU1JTkdfRlJPTV9DTElFTlQQAhIZChVT", + "VFJFQU1JTkdfRlJPTV9TRVJWRVIQAxIXChNTVFJFQU1JTkdfQk9USF9XQVlT", + "EARiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedClrTypeInfo[] { @@ -152,6 +153,7 @@ namespace Grpc.Testing { /// used for some language-specific variants /// [pbr::OriginalName("OTHER_SERVER")] OtherServer = 3, + [pbr::OriginalName("CALLBACK_SERVER")] CallbackServer = 4, } public enum RpcType { diff --git a/src/csharp/Grpc.IntegrationTesting/Empty.cs b/src/csharp/Grpc.IntegrationTesting/Empty.cs index 0d4c28bf7fc..389fe433755 100644 --- a/src/csharp/Grpc.IntegrationTesting/Empty.cs +++ b/src/csharp/Grpc.IntegrationTesting/Empty.cs @@ -44,6 +44,7 @@ namespace Grpc.Testing { /// service Foo { /// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { }; /// }; + /// /// public sealed partial class Empty : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Empty()); diff --git a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs index 7e77f8d1141..965d08d8a36 100644 --- a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2018 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -88,6 +88,13 @@ namespace Grpc.Testing { { } + /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// Service methods will be bound by calling AddMethod on this object. + public static void BindService(grpc::ServiceBinderBase serviceBinder) + { + } + } } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs index c66a9a9161e..64db5b3ad08 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015-2016 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,7 @@ // // Contains the definitions for a metrics service and the type of metrics // exposed by the service. -// +// // Currently, 'Gauge' (i.e a metric that represents the measured value of // something at an instant of time) is the only metric type supported by the // service. @@ -203,6 +203,15 @@ namespace Grpc.Testing { serviceBinder.AddMethod(__Method_GetGauge, serviceImpl.GetGauge); } + /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// Service methods will be bound by calling AddMethod on this object. + public static void BindService(grpc::ServiceBinderBase serviceBinder) + { + serviceBinder.AddMethod(__Method_GetAllGauges); + serviceBinder.AddMethod(__Method_GetGauge); + } + } } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs index 954c1722723..81787892c32 100644 --- a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -152,6 +152,14 @@ namespace Grpc.Testing { serviceBinder.AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario); } + /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// Service methods will be bound by calling AddMethod on this object. + public static void BindService(grpc::ServiceBinderBase serviceBinder) + { + serviceBinder.AddMethod(__Method_ReportScenario); + } + } } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs index d125fd5627b..049cb65d7de 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015-2016 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -555,6 +555,21 @@ namespace Grpc.Testing { serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall); } + /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// Service methods will be bound by calling AddMethod on this object. + public static void BindService(grpc::ServiceBinderBase serviceBinder) + { + serviceBinder.AddMethod(__Method_EmptyCall); + serviceBinder.AddMethod(__Method_UnaryCall); + serviceBinder.AddMethod(__Method_CacheableUnaryCall); + serviceBinder.AddMethod(__Method_StreamingOutputCall); + serviceBinder.AddMethod(__Method_StreamingInputCall); + serviceBinder.AddMethod(__Method_FullDuplexCall); + serviceBinder.AddMethod(__Method_HalfDuplexCall); + serviceBinder.AddMethod(__Method_UnimplementedCall); + } + } /// /// A simple service NOT implemented at servers so clients can test for @@ -686,6 +701,14 @@ namespace Grpc.Testing { serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall); } + /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// Service methods will be bound by calling AddMethod on this object. + public static void BindService(grpc::ServiceBinderBase serviceBinder) + { + serviceBinder.AddMethod(__Method_UnimplementedCall); + } + } /// /// A service used to control reconnect server. @@ -814,6 +837,15 @@ namespace Grpc.Testing { serviceBinder.AddMethod(__Method_Stop, serviceImpl.Stop); } + /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// Service methods will be bound by calling AddMethod on this object. + public static void BindService(grpc::ServiceBinderBase serviceBinder) + { + serviceBinder.AddMethod(__Method_Start); + serviceBinder.AddMethod(__Method_Stop); + } + } } #endregion diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs index 5b22337d533..b58d71a784d 100644 --- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -333,6 +333,17 @@ namespace Grpc.Testing { serviceBinder.AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker); } + /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// Service methods will be bound by calling AddMethod on this object. + public static void BindService(grpc::ServiceBinderBase serviceBinder) + { + serviceBinder.AddMethod(__Method_RunServer); + serviceBinder.AddMethod(__Method_RunClient); + serviceBinder.AddMethod(__Method_CoreCount); + serviceBinder.AddMethod(__Method_QuitWorker); + } + } } #endregion diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs index ed55c2f584f..51ef8ace5cc 100644 --- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs +++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2016 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -132,6 +132,14 @@ namespace Grpc.Reflection.V1Alpha { serviceBinder.AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo); } + /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Note: this method is part of an experimental API that can change or be removed without any prior notice. + /// Service methods will be bound by calling AddMethod on this object. + public static void BindService(grpc::ServiceBinderBase serviceBinder) + { + serviceBinder.AddMethod(__Method_ServerReflectionInfo); + } + } } #endregion From ac61379b1eaa929bc9120401608e5c1fd5f474c4 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 28 Jan 2019 14:44:15 -0800 Subject: [PATCH 194/814] Add alignment to size calculation --- src/core/ext/filters/client_channel/subchannel.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 7f15cb416b9..60e408e8c98 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -1004,7 +1004,8 @@ grpc_subchannel_get_connected_subchannel(grpc_subchannel* c) { void* grpc_connected_subchannel_call_get_parent_data( grpc_subchannel_call* subchannel_call) { grpc_channel_stack* chanstk = subchannel_call->connection->channel_stack(); - return (char*)subchannel_call + sizeof(grpc_subchannel_call) + + return (char*)subchannel_call + + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)) + chanstk->call_stack_size; } From fcbb126bafe5f791965c094d1bda881237f13924 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 28 Jan 2019 14:56:52 -0800 Subject: [PATCH 195/814] Point the hack of proto message comparison to new issue --- .../tests/reflection/_reflection_servicer_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py index 0ee40e6f2da..c0d0e7cf34e 100644 --- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py +++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py @@ -50,10 +50,10 @@ def _file_descriptor_to_proto(descriptor): class ReflectionServicerTest(unittest.TestCase): - # NOTE(lidiz) Bazel + Python 3 will result in creating two different - # instance of DESCRIPTOR for each message. So, the equal comparision - # between protobuf returned by stub and manually crafted protobuf will - # always fail. + # TODO(https://github.com/grpc/grpc/issues/17844) + # Bazel + Python 3 will result in creating two different instance of + # DESCRIPTOR for each message. So, the equal comparision between protobuf + # returned by stub and manually crafted protobuf will always fail. def _assert_sequence_of_proto_equal(self, x, y): self.assertSequenceEqual( list(map(lambda x: x.SerializeToString(), x)), From 6cdbd8a49a87c33b26b9dc5d980d2479b482ee06 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 28 Jan 2019 15:02:00 -0800 Subject: [PATCH 196/814] Another alignment --- src/core/ext/filters/client_channel/subchannel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 60e408e8c98..d77bb3c286b 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -1006,7 +1006,7 @@ void* grpc_connected_subchannel_call_get_parent_data( grpc_channel_stack* chanstk = subchannel_call->connection->channel_stack(); return (char*)subchannel_call + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)) + - chanstk->call_stack_size; + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(chanstk->call_stack_size); } grpc_call_stack* grpc_subchannel_call_get_call_stack( From 5b7f0532ac6fba1366ee7ddfa83d83894650503d Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 28 Jan 2019 11:32:32 -0800 Subject: [PATCH 197/814] Properly init TLS for callback exec context --- src/core/lib/iomgr/exec_ctx.h | 6 ++++++ src/core/lib/surface/init.cc | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index c6c30d3129e..16ac14ba6c5 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -271,6 +271,12 @@ class ApplicationCallbackExecCtx { ctx->tail_ = functor; } + /** Global initialization for ApplicationCallbackExecCtx. Called by init. */ + static void GlobalInit(void) { gpr_tls_init(&callback_exec_ctx_); } + + /** Global shutdown for ApplicationCallbackExecCtx. Called by init. */ + static void GlobalShutdown(void) { gpr_tls_destroy(&callback_exec_ctx_); } + private: grpc_experimental_completion_queue_functor* head_{nullptr}; grpc_experimental_completion_queue_functor* tail_{nullptr}; diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 60f506ef5e2..f704a64b1c9 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -130,6 +130,7 @@ void grpc_init(void) { grpc_channel_init_init(); grpc_core::channelz::ChannelzRegistry::Init(); grpc_security_pre_init(); + grpc_core::ApplicationCallbackExecCtx::GlobalInit(); grpc_core::ExecCtx::GlobalInit(); grpc_iomgr_init(); gpr_timers_global_init(); @@ -183,6 +184,7 @@ void grpc_shutdown(void) { grpc_core::Fork::GlobalShutdown(); } grpc_core::ExecCtx::GlobalShutdown(); + grpc_core::ApplicationCallbackExecCtx::GlobalShutdown(); } gpr_mu_unlock(&g_init_mu); } From 3a2cfe50ec768dd83eefd5e29da567c1c98db298 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 28 Jan 2019 16:18:49 -0800 Subject: [PATCH 198/814] Rever copyright changes --- include/grpcpp/impl/codegen/call_op_set.h | 2 +- include/grpcpp/impl/codegen/core_codegen.h | 2 +- src/cpp/common/completion_queue_cc.cc | 2 +- src/cpp/common/core_codegen.cc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h index 03a32b9815d..4ca87a99fca 100644 --- a/include/grpcpp/impl/codegen/call_op_set.h +++ b/include/grpcpp/impl/codegen/call_op_set.h @@ -1,6 +1,6 @@ /* * - * Copyright 2019 gRPC authors. + * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/include/grpcpp/impl/codegen/core_codegen.h b/include/grpcpp/impl/codegen/core_codegen.h index 6230555e1a7..b7ddb0c791c 100644 --- a/include/grpcpp/impl/codegen/core_codegen.h +++ b/include/grpcpp/impl/codegen/core_codegen.h @@ -1,6 +1,6 @@ /* * - * Copyright 2019 gRPC authors. + * Copyright 2016 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/common/completion_queue_cc.cc b/src/cpp/common/completion_queue_cc.cc index 3df45128ecb..4bb3bcbd8b6 100644 --- a/src/cpp/common/completion_queue_cc.cc +++ b/src/cpp/common/completion_queue_cc.cc @@ -1,5 +1,5 @@ /* - * Copyright 2019 gRPC authors. + * Copyright 2015 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc index 986c3df7736..9430dcc9881 100644 --- a/src/cpp/common/core_codegen.cc +++ b/src/cpp/common/core_codegen.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2019 gRPC authors. + * Copyright 2016 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 5e2e61b6e57e6ae1682fe461f8cbaba5603e9ae4 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 28 Jan 2019 16:37:02 -0800 Subject: [PATCH 199/814] Note on conditions of usage --- include/grpcpp/impl/codegen/interceptor_common.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 6c4847509e0..8ed84230911 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -219,6 +219,7 @@ class InterceptorBatchMethodsImpl // Alternatively, RunInterceptors(std::function f) can be used. void SetCallOpSetInterface(CallOpSetInterface* ops) { ops_ = ops; } + // SetCall should have been called before this. // Returns true if the interceptors list is empty bool InterceptorsListEmpty() { auto* client_rpc_info = call_->client_rpc_info(); From a7899511817c18b95e8449ed8ebbe3ccb4ec07e0 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 28 Jan 2019 19:22:57 -0800 Subject: [PATCH 200/814] Revert "Revert "Collect timestamps for all data written for a stream instead of just data frames"" --- src/core/ext/transport/chttp2/transport/writing.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 265d3365d3c..cf77ddc8278 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -363,7 +363,6 @@ class DataSendContext { grpc_chttp2_encode_data(s_->id, &s_->compressed_data_buffer, send_bytes, is_last_frame_, &s_->stats.outgoing, &t_->outbuf); s_->flow_control->SentData(send_bytes); - s_->byte_counter += send_bytes; if (s_->compressed_data_buffer.length == 0) { s_->sending_bytes += s_->uncompressed_data_size; } @@ -498,9 +497,6 @@ class StreamWriteContext { data_send_context.CompressMoreBytes(); } } - if (s_->traced && grpc_endpoint_can_track_err(t_->ep)) { - grpc_core::ContextList::Append(&t_->cl, s_); - } write_context_->ResetPingClock(); if (data_send_context.is_last_frame()) { SentLastFrame(); @@ -610,11 +606,18 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write( (according to available window sizes) and add to the output buffer */ while (grpc_chttp2_stream* s = ctx.NextStream()) { StreamWriteContext stream_ctx(&ctx, s); + size_t orig_len = t->outbuf.length; stream_ctx.FlushInitialMetadata(); stream_ctx.FlushWindowUpdates(); stream_ctx.FlushData(); stream_ctx.FlushTrailingMetadata(); - + if (t->outbuf.length > orig_len) { + /* Add this stream to the list of the contexts to be traced at TCP */ + s->byte_counter += t->outbuf.length - orig_len; + if (s->traced && grpc_endpoint_can_track_err(t->ep)) { + grpc_core::ContextList::Append(&t->cl, s); + } + } if (stream_ctx.stream_became_writable()) { if (!grpc_chttp2_list_add_writing_stream(t, s)) { /* already in writing list: drop ref */ From dc2c81a78a87cde4e3996604e118f55d739e38cd Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Mon, 28 Jan 2019 20:15:16 -0800 Subject: [PATCH 201/814] Copy edit keepalive documentation * Copy edits * Add additional blank lines before bulleted lists, which some Markdown parsers require. --- doc/keepalive.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/doc/keepalive.md b/doc/keepalive.md index 2f9c8bfc9e4..20449fc273b 100644 --- a/doc/keepalive.md +++ b/doc/keepalive.md @@ -5,12 +5,14 @@ The keepalive ping is a way to check if a channel is currently working by sendin This guide documents the knobs within gRPC core to control the current behavior of the keepalive ping. The keepalive ping is controlled by two important channel arguments - + * **GRPC_ARG_KEEPALIVE_TIME_MS** * This channel argument controls the period (in milliseconds) after which a keepalive ping is sent on the transport. * **GRPC_ARG_KEEPALIVE_TIMEOUT_MS** - * This channel argument controls the amount of time (in milliseconds), the sender of the keepalive ping waits for an acknowledgement. If it does not receive an acknowledgement within this time, it will close the connection. + * This channel argument controls the amount of time (in milliseconds) the sender of the keepalive ping waits for an acknowledgement. If it does not receive an acknowledgment within this time, it will close the connection. The above two channel arguments should be sufficient for most users, but the following arguments can also be useful in certain use cases. + * **GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS** * This channel argument if set to 1 (0 : false; 1 : true), allows keepalive pings to be sent even if there are no calls in flight. * **GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA** @@ -39,12 +41,12 @@ GRPC_ARG_HTTP2_MAX_PING_STRIKES|N/A|2 * When is the keepalive timer started? * The keepalive timer is started when a transport is done connecting (after handshake). * What happens when the keepalive timer fires? - * When the keepalive timer fires, gRPC Core would try to send a keepalive ping on the transport. This ping can be blocked if - + * When the keepalive timer fires, gRPC Core will try to send a keepalive ping on the transport. This ping can be blocked if - * there is no active call on that transport and GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS is false. * the number of pings already sent on the transport without any data has already exceeded GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA. - * the time expired since the previous ping is less than GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS. - * If a keepalive ping is not blocked and is sent on the transport, then the keepalive watchdog timer is started which would close the transport if the ping is not acknowledged before it fires. + * the time elapsed since the previous ping is less than GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS. + * If a keepalive ping is not blocked and is sent on the transport, then the keepalive watchdog timer is started which will close the transport if the ping is not acknowledged before it fires. * Why am I receiving a GOAWAY with error code ENHANCE_YOUR_CALM? * A server sends a GOAWAY with ENHANCE_YOUR_CALM if the client sends too many misbehaving pings. For example - - * if a server has GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS set to false, and the client sends pings without there being any call in flight. + * if a server has GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS set to false and the client sends pings without there being any call in flight. * if the client's GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS setting is lower than the server's GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS. From b099ca217e95234781d70c873af6696cd2fe6ef0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 28 Jan 2019 23:09:49 -0800 Subject: [PATCH 202/814] Revert "Memory leak test for PHP unit tests" --- src/php/bin/run_tests.sh | 8 - .../tests/MemoryLeakTest/MemoryLeakTest.php | 2310 ----------------- src/php/tests/unit_tests/CallTest.php | 10 - .../tools/dockerfile/php_valgrind.include | 7 - .../test/php7_jessie_x64/Dockerfile.template | 1 - .../test/php_jessie_x64/Dockerfile.template | 1 - .../test/php7_jessie_x64/Dockerfile | 8 - .../dockerfile/test/php_jessie_x64/Dockerfile | 8 - 8 files changed, 2353 deletions(-) delete mode 100644 src/php/tests/MemoryLeakTest/MemoryLeakTest.php delete mode 100644 templates/tools/dockerfile/php_valgrind.include diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh index 861ce433c4e..295bcb2430c 100755 --- a/src/php/bin/run_tests.sh +++ b/src/php/bin/run_tests.sh @@ -22,17 +22,9 @@ cd src/php/bin source ./determine_extension_dir.sh # in some jenkins macos machine, somehow the PHP build script can't find libgrpc.dylib export DYLD_LIBRARY_PATH=$root/libs/$CONFIG - php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ --exclude-group persistent_list_bound_tests ../tests/unit_tests php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ ../tests/unit_tests/PersistentChannelTests -export ZEND_DONT_UNLOAD_MODULES=1 -export USE_ZEND_ALLOC=0 -# Detect whether valgrind is executable -if [ -x "$(command -v valgrind)" ]; then - valgrind --error-exitcode=10 --leak-check=yes php $extension_dir -d max_execution_time=300 \ - ../tests/MemoryLeakTest/MemoryLeakTest.php -fi diff --git a/src/php/tests/MemoryLeakTest/MemoryLeakTest.php b/src/php/tests/MemoryLeakTest/MemoryLeakTest.php deleted file mode 100644 index 6b5fcb1ec78..00000000000 --- a/src/php/tests/MemoryLeakTest/MemoryLeakTest.php +++ /dev/null @@ -1,2310 +0,0 @@ - "v1"]; -} - -function assertConnecting($state) -{ - assert(($state == GRPC\CHANNEL_CONNECTING || $state == GRPC\CHANNEL_TRANSIENT_FAILURE) == true); -} - -function waitUntilNotIdle($channel) { - for ($i = 0; $i < 10; $i++) { - $now = Grpc\Timeval::now(); - $deadline = $now->add(new Grpc\Timeval(10000)); - if ($channel->watchConnectivityState(GRPC\CHANNEL_IDLE, - $deadline)) { - return true; - } - } - assert(true == false); -} - -// Set up -$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); - -// Test InsecureCredentials -assert('Grpc\Channel' == get_class($channel)); - -// Test ConnectivityState -$state = $channel->getConnectivityState(); -assert(0 == $state); - -// Test GetConnectivityStateWithInt -$state = $channel->getConnectivityState(123); -assert(0 == $state); - -// Test GetConnectivityStateWithString -$state = $channel->getConnectivityState('hello'); -assert(0 == $state); - -// Test GetConnectivityStateWithBool -$state = $channel->getConnectivityState(true); -assert(0 == $state); - -$channel->close(); - -// Test GetTarget -$channel = new Grpc\Channel('localhost:8888', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); -$target = $channel->getTarget(); -assert(is_string($target) == true); -$channel->close(); - -// Test WatchConnectivityState -$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); -$now = Grpc\Timeval::now(); -$deadline = $now->add(new Grpc\Timeval(100*1000)); - -$state = $channel->watchConnectivityState(1, $deadline); -assert($state == true); - -unset($now); -unset($deadline); - -$channel->close(); - -// Test InvalidConstructorWithNull -try { - $channel = new Grpc\Channel(); - assert($channel == NULL); -} -catch (\Exception $e) { -} - -// Test InvalidConstructorWith -try { - $channel = new Grpc\Channel('localhost:0', 'invalid'); - assert($channel == NULL); -} -catch (\Exception $e) { -} - -// Test InvalideCredentials -try { - $channel = new Grpc\Channel('localhost:0', ['credentials' => new Grpc\Timeval(100)]); -} -catch (\Exception $e) { -} - -// Test InvalidOptionsArrray -try { - $channel = new Grpc\Channel('localhost:0', ['abc' => []]); -} -catch (\Exception $e) { -} - -// Test InvalidGetConnectivityStateWithArray -$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); -try { - $channel->getConnectivityState([]); -} -catch (\Exception $e) { -} - -// Test InvalidWatchConnectivityState -try { - $channel->watchConnectivityState([]); -} -catch (\Exception $e) { -} - -// Test InvalidWatchConnectivityState2 -try { - $channel->watchConnectivityState(1, 'hi'); -} -catch (\Exception $e) { -} - -$channel->close(); - -// Test PersistentChannelSameHost -$channel1 = new Grpc\Channel('localhost:1', []); -$channel2 = new Grpc\Channel('localhost:1', []); -$state = $channel1->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelDifferentHost -$channel1 = new Grpc\Channel('localhost:1', ["grpc_target_persist_bound" => 3,]); -$channel2 = new Grpc\Channel('localhost:2', []); -$state = $channel1->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelSameArgs -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 3, - "abc" => "def", - ]); -$channel2 = new Grpc\Channel('localhost:1', ["abc" => "def"]); -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelDifferentArgs -$channel1 = new Grpc\Channel('localhost:1', []); -$channel2 = new Grpc\Channel('localhost:1', ["abc" => "def"]); -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelSameChannelCredentials -$creds1 = Grpc\ChannelCredentials::createSsl(); -$creds2 = Grpc\ChannelCredentials::createSsl(); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => $creds1, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => $creds2]); - -$state = $channel1->getConnectivityState(true); -print "state: ".$state."......................"; -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelDifferentChannelCredentials -$creds1 = Grpc\ChannelCredentials::createSsl(); -$creds2 = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => $creds1, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => $creds2]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - - -// Test PersistentChannelSameChannelCredentialsRootCerts -$creds1 = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); -$creds2 = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => $creds1, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => $creds2]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelDifferentSecureChannelCredentials -$creds1 = Grpc\ChannelCredentials::createSsl(); -$creds2 = Grpc\ChannelCredentials::createInsecure(); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => $creds1, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => $creds2]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelSharedChannelClose1 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 3, -]); -$channel2 = new Grpc\Channel('localhost:1', []); - -$channel1->close(); - -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$channel2->close(); - -// Test PersistentChannelSharedChannelClose2 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 3, -]); -$channel2 = new Grpc\Channel('localhost:1', []); - -$channel1->close(); - -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -try{ - $state = $channel1->getConnectivityState(); -} -catch(\Exception $e){ -} - -$channel2->close(); - -//Test PersistentChannelCreateAfterClose -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 3, -]); - -$channel1->close(); - -$channel2 = new Grpc\Channel('localhost:1', []); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel2->close(); - -//Test PersistentChannelSharedMoreThanTwo -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 3, -]); -$channel2 = new Grpc\Channel('localhost:1', []); -$channel3 = new Grpc\Channel('localhost:1', []); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); -$state = $channel3->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); - -//Test PersistentChannelWithCallCredentials -$creds = Grpc\ChannelCredentials::createSsl(); -$callCreds = Grpc\CallCredentials::createFromPlugin( - 'callbackFunc'); -$credsWithCallCreds = Grpc\ChannelCredentials::createComposite( - $creds, $callCreds); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => - $credsWithCallCreds, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => - $credsWithCallCreds]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelWithDifferentCallCredentials -$callCreds1 = Grpc\CallCredentials::createFromPlugin('callbackFunc'); -$callCreds2 = Grpc\CallCredentials::createFromPlugin('callbackFunc2'); - -$creds1 = Grpc\ChannelCredentials::createSsl(); -$creds2 = Grpc\ChannelCredentials::createComposite( - $creds1, $callCreds1); -$creds3 = Grpc\ChannelCredentials::createComposite( - $creds1, $callCreds2); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => $creds1, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => $creds2]); -$channel3 = new Grpc\Channel('localhost:1', - ["credentials" => $creds3]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$state = $channel3->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); -$channel3->close(); - -// Test PersistentChannelForceNew -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', - ["force_new" => true]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelForceNewOldChannelIdle1 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', - ["force_new" => true]); -$channel3 = new Grpc\Channel('localhost:1', []); - -$state = $channel2->getConnectivityState(true); -waitUntilNotIdle($channel2); -$state = $channel1->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); -$state = $channel3->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelForceNewOldChannelIdle2 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', []); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel2); -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelForceNewOldChannelClose1 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', - ["force_new" => true]); -$channel3 = new Grpc\Channel('localhost:1', []); - -$channel1->close(); - -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$state = $channel3->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel2->close(); -$channel3->close(); - -// Test PersistentChannelForceNewOldChannelClose2 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', - ["force_new" => true]); -// channel3 shares with channel1 -$channel3 = new Grpc\Channel('localhost:1', []); - -$channel1->close(); - -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -// channel3 is still usable -$state = $channel3->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -// channel 1 is closed -try{ - $channel1->getConnectivityState(); -} -catch(\Exception $e){ -} - -$channel2->close(); -$channel3->close(); - -// Test PersistentChannelForceNewNewChannelClose -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', - ["force_new" => true]); -$channel3 = new Grpc\Channel('localhost:1', []); - -$channel2->close(); - -$state = $channel1->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -// can still connect on channel1 -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); - -//============== Call Test ==================== -$server = new Grpc\Server([]); -$port = $server->addHttp2Port('0.0.0.0:53000'); -$channel = new Grpc\Channel('localhost:'.$port, []); -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); - -// Test AddEmptyMetadata -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => [], -]; -$result = $call->startBatch($batch); -assert($result->send_metadata == true); - -// Test testAddSingleMetadata -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value']], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -$result = $call->startBatch($batch); -assert($result->send_metadata == true); - -// Test AddMultiValue -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value1', 'value2']], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -$result = $call->startBatch($batch); -assert($result->send_metadata == true); - -// Test AddSingleAndMultiValueMetadata -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], - 'key2' => ['value2', - 'value3', ], ], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -$result = $call->startBatch($batch); -assert($result->send_metadata == true); - -// Test AddMultiAndMultiValueMetadata -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], - 'key2' => ['value2', - 'value3', ], ], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -$result = $call->startBatch($batch); -assert($result->send_metadata == true); - -// Test GetPeer -assert(is_string($call->getPeer()) == true); - -// Test Cancel -assert($call->cancel == NULL); - -// Test InvalidStartBatchKey -$batch = [ - 'invalid' => ['key1' => 'value1'], -]; -try{ - $result = $call->startBatch($batch); -} -catch(\Exception $e){ -} - -// Test InvalideMetadataStrKey -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['Key' => ['value1', 'value2']], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -try{ - $result = $call->startBatch($batch); -} -catch(\Exception $e){ -} - -// Test InvalidMetadataIntKey -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => [1 => ['value1', 'value2']], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -try{ - $result = $call->startBatch($batch); -} -catch(\Exception $e){ -} - -// Test InvalidMetadataInnerValue -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key1' => 'value1'], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -try{ - $result = $call->startBatch($batch); -} -catch(\Exception $e){ -} - -// Test InvalidConstuctor -try { - $call = new Grpc\Call(); -} catch (\Exception $e) {} - -// Test InvalidConstuctor2 -try { - $call = new Grpc\Call('hi', 'hi', 'hi'); -} catch (\Exception $e) {} - -// Test InvalidSetCredentials -try{ - $call->setCredentials('hi'); -} -catch(\Exception $e){ -} - -// Test InvalidSetCredentials2 -try { - $call->setCredentials([]); -} catch (\Exception $e) {} - - -//============== CallCredentials Test 2 ==================== -// Set Up -$credentials = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); -$server_credentials = Grpc\ServerCredentials::createSsl( - null, - file_get_contents(dirname(__FILE__).'/../data/server1.key'), - file_get_contents(dirname(__FILE__).'/../data/server1.pem')); -$server = new Grpc\Server(); -$port = $server->addSecureHttp2Port('0.0.0.0:0', - $server_credentials); -$server->start(); -$host_override = 'foo.test.google.fr'; -$channel = new Grpc\Channel( - 'localhost:'.$port, - [ - 'grpc.ssl_target_name_override' => $host_override, - 'grpc.default_authority' => $host_override, - 'credentials' => $credentials, - ] -); -function callCredscallbackFunc($context) -{ - is_string($context->service_url); - is_string($context->method_name); - return ['k1' => ['v1'], 'k2' => ['v2']]; -} - -// Test CreateFromPlugin -$deadline = Grpc\Timeval::infFuture(); -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - '/abc/dummy_method', - $deadline, - $host_override); - $call_credentials = Grpc\CallCredentials::createFromPlugin( - 'callCredscallbackFunc'); -$call->setCredentials($call_credentials); - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); - -$event = $server->requestCall(); -assert(is_array($event->metadata) == true); - -$metadata = $event->metadata; -assert(array_key_exists('k1', $metadata) == true); -assert(array_key_exists('k2', $metadata) == true); -assert($metadata['k1'] == ['v1']); -assert($metadata['k2'] == ['v2']); -assert('/abc/dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert($event->send_metadata == true); -assert($event->send_status == true); -assert($event->cancelled == false); - -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert([] == $event->metadata); - -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -function invalidKeyCallbackFunc($context) -{ - is_string($context->service_url); - is_string($context->method_name); - return ['K1' => ['v1']]; -} - -// Test CallbackWithInvalidKey -$deadline = Grpc\Timeval::infFuture(); -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - '/abc/dummy_method', - $deadline, - $host_override); - $call_credentials = Grpc\CallCredentials::createFromPlugin( - 'invalidKeyCallbackFunc'); -$call->setCredentials($call_credentials); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); -assert(($event->status->code == Grpc\STATUS_UNAVAILABLE) == true); - -function invalidReturnCallbackFunc($context) -{ - is_string($context->service_url); - is_string($context->method_name); - return 'a string'; -} - -// Test CallbackWithInvalidReturnValue -$deadline = Grpc\Timeval::infFuture(); -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - '/abc/dummy_method', - $deadline, - $host_override); - $call_credentials = Grpc\CallCredentials::createFromPlugin( - 'invalidReturnCallbackFunc'); -$call->setCredentials($call_credentials); - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); - -assert($event->send_metadata == true); -assert($event->send_close == true); -assert(($event->status->code == Grpc\STATUS_UNAVAILABLE) == true); - -unset($channel); -unset($server); - -//============== CallCredentials Test ==================== -//Set Up -$credentials = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); -$call_credentials = Grpc\CallCredentials::createFromPlugin('callbackFunc'); -$credentials = Grpc\ChannelCredentials::createComposite( - $credentials, - $call_credentials -); -$server_credentials = Grpc\ServerCredentials::createSsl( - null, - file_get_contents(dirname(__FILE__).'/../data/server1.key'), - file_get_contents(dirname(__FILE__).'/../data/server1.pem')); -$server = new Grpc\Server(); -$port = $server->addSecureHttp2Port('0.0.0.0:0', - $server_credentials); -$server->start(); -$host_override = 'foo.test.google.fr'; -$channel = new Grpc\Channel( - 'localhost:'.$port, - [ - 'grpc.ssl_target_name_override' => $host_override, - 'grpc.default_authority' => $host_override, - 'credentials' => $credentials, - ] -); - -// Test CreateComposite -$call_credentials2 = Grpc\CallCredentials::createFromPlugin('callbackFunc'); -$call_credentials3 = Grpc\CallCredentials::createComposite( - $call_credentials, - $call_credentials2 -); -assert('Grpc\CallCredentials' == get_class($call_credentials3)); - -// Test CreateFromPluginInvalidParam -try{ - $call_credentials = Grpc\CallCredentials::createFromPlugin( - 'callbackFunc' - ); -} -catch(\Exception $e){} - -// Test CreateCompositeInvalidParam -try{ - $call_credentials3 = Grpc\CallCredentials::createComposite( - $call_credentials, - $credentials - ); -} -catch(\Exception $e){} - -unset($channel); -unset($server); - - -//============== EndToEnd Test ==================== -// Set Up -$server = new Grpc\Server([]); -$port = $server->addHttp2Port('0.0.0.0:0'); -$channel = new Grpc\Channel('localhost:'.$port, []); -$server->start(); - -// Test SimpleRequestBody -$deadline = Grpc\Timeval::infFuture(); -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert($event->send_metadata == true); -assert($event->send_status == true); -assert($event->cancelled == false) -; - $event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -// Test MessageWriteFlags -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'message_write_flags_test'; -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $req_text, - 'flags' => Grpc\WRITE_NO_COMPRESS, ], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], -]); -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -$status = $event->status; - -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -// Test ClientServerFullRequestResponse -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -assert($event->send_metadata == true); -assert($event->send_close == true); -assert($event->send_message == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); -$server_call = $event->call; - -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert($event->send_metadata == true); -assert($event->send_status == true); -assert($event->send_message == true); -assert($event->cancelled == false); -assert($req_text == $event->message); - -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert([] == $event->metadata); -assert($reply_text == $event->message); -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -// Test InvalidClientMessageArray -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -try { - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => 'invalid', - ]); -} catch (\Exception $e) {} - -// Test InvalidClientMessageString -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -try{ - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => 0], - ]); -} catch (\Exception $e) {} - -// Test InvalidClientMessageFlags -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -try{ - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => 'abc', - 'flags' => 'invalid', - ], - ]); -} catch (\Exception $e) {} - -// Test InvalidServerStatusMetadata -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -assert($event->send_metadata == true); -assert($event->send_close == true); -assert($event->send_message == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); -$server_call = $event->call; -try { - $event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => 'invalid', - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, - ]); -} catch (\Exception $e) {} - -// Test InvalidServerStatusCode -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -assert($event->send_metadata == true); -assert($event->send_close == true); -assert($event->send_message == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); -$server_call = $event->call; -try { - $event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => 'invalid', - 'details' => $status_text, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, - ]); -} catch (\Exception $e) {} - -// Test MissingServerStatusCode -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -$event = $server->requestCall(); -$server_call = $event->call; -try { - $event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'details' => $status_text, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, - ]); -} catch (\Exception $e) {} - -// Test InvalidServerStatusDetails -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -$event = $server->requestCall(); -$server_call = $event->call; -try { - $event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => 0, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, - ]); -} catch (\Exception $e) {} - -// Test MissingServerStatusDetails -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -$event = $server->requestCall(); -$server_call = $event->call; -try { - $event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, - ]); -} catch (\Exception $e) {} - -// Test InvalidStartBatchKey -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -try { - $event = $call->startBatch([ - 9999999 => [], - ]); -} catch (\Exception $e) {} - -// Test InvalidStartBatch -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -try { - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => 'abc', - ], - ]); -} catch (\Exception $e) {} - -// Test GetTarget -assert(is_string($channel->getTarget()) == true); - -// Test GetConnectivityState -assert(($channel->getConnectivityState() == - Grpc\CHANNEL_IDLE) == true); - -// Test WatchConnectivityStateFailed -$idle_state = $channel->getConnectivityState(); -assert(($idle_state == Grpc\CHANNEL_IDLE) == true); - -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(50000); // should timeout -$deadline = $now->add($delta); -assert($channel->watchConnectivityState( - $idle_state, $deadline) == false); - -// Test WatchConnectivityStateSuccess() -$idle_state = $channel->getConnectivityState(true); -assert(($idle_state == Grpc\CHANNEL_IDLE) == true); - -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(3000000); // should finish well before -$deadline = $now->add($delta); -$new_state = $channel->getConnectivityState(); -assert($new_state != $idle_state); - -// Test WatchConnectivityStateDoNothing -$idle_state = $channel->getConnectivityState(); -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(50000); -$deadline = $now->add($delta); -assert(!$channel->watchConnectivityState( - $idle_state, $deadline)); - -$new_state = $channel->getConnectivityState(); -assert($new_state == Grpc\CHANNEL_IDLE); - -// Test GetConnectivityStateInvalidParam -try { - $channel->getConnectivityState(new Grpc\Timeval()); -} catch (\Exception $e) {} -// Test WatchConnectivityStateInvalidParam -try { - $channel->watchConnectivityState(0, 1000); -} catch (\Exception $e) {} -// Test ChannelConstructorInvalidParam -try { - $channel = new Grpc\Channel('localhost:'.$port, null); -} catch (\Exception $e) {} -// testClose() -$channel->close(); - - -//============== SecureEndToEnd Test ==================== -// Set Up - -$credentials = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); -$server_credentials = Grpc\ServerCredentials::createSsl( - null, - file_get_contents(dirname(__FILE__).'/../data/server1.key'), - file_get_contents(dirname(__FILE__).'/../data/server1.pem')); -$server = new Grpc\Server(); -$port = $server->addSecureHttp2Port('0.0.0.0:0', - $server_credentials); -$server->start(); -$host_override = 'foo.test.google.fr'; -$channel = new Grpc\Channel( - 'localhost:'.$port, - [ - 'grpc.ssl_target_name_override' => $host_override, - 'grpc.default_authority' => $host_override, - 'credentials' => $credentials, - ] -); - -// Test SimpleRequestBody -$deadline = Grpc\Timeval::infFuture(); -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline, - $host_override); - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert($event->send_metadata == true); -assert($event->send_status == true); -assert($event->cancelled == false); - -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert([] == $event->metadata); -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -// Test MessageWriteFlags -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'message_write_flags_test'; -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline, - $host_override); - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $req_text, - 'flags' => Grpc\WRITE_NO_COMPRESS, ], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], -]); -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert([] == $event->metadata); -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details);unset($call); - -unset($call); -unset($server_call); - -// Test ClientServerFullRequestResponse -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline, - $host_override); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -assert($event->send_metadata == true); -assert($event->send_close == true); -assert($event->send_message == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert($event->send_metadata); -assert($event->send_status); -assert($event->send_message); -assert(!$event->cancelled); -assert($req_text == $event->message); - -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert([] == $event->metadata); -assert($reply_text == $event->message); -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -$channel->close(); - - -//============== Timeval Test ==================== -// Test ConstructorWithInt -$time = new Grpc\Timeval(1234); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test ConstructorWithNegative -$time = new Grpc\Timeval(-123); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test ConstructorWithZero -$time = new Grpc\Timeval(0); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test ConstructorWithOct -$time = new Grpc\Timeval(0123); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test ConstructorWithHex -$time = new Grpc\Timeval(0x1A); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test ConstructorWithFloat -$time = new Grpc\Timeval(123.456); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test CompareSame -$zero = Grpc\Timeval::zero(); -assert(0 == Grpc\Timeval::compare($zero, $zero)); - -// Test PastIsLessThanZero -$zero = Grpc\Timeval::zero(); -$past = Grpc\Timeval::infPast(); -assert(0 > Grpc\Timeval::compare($past, $zero)); -assert(0 < Grpc\Timeval::compare($zero, $past)); - -// Test FutureIsGreaterThanZero -$zero = Grpc\Timeval::zero(); -$future = Grpc\Timeval::infFuture(); -assert(0 > Grpc\Timeval::compare($zero, $future)); -assert(0 < Grpc\Timeval::compare($future, $zero)); - -// Test NowIsBetweenZeroAndFuture -$zero = Grpc\Timeval::zero(); -$future = Grpc\Timeval::infFuture(); -$now = Grpc\Timeval::now(); -assert(0 > Grpc\Timeval::compare($zero, $now)); -assert(0 > Grpc\Timeval::compare($now, $future)); - -// Test NowAndAdd -$now = Grpc\Timeval::now(); -assert($now != NULL); -$delta = new Grpc\Timeval(1000); -$deadline = $now->add($delta); -assert(0 < Grpc\Timeval::compare($deadline, $now)); - -// Test NowAndSubtract -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(1000); -$deadline = $now->subtract($delta); -assert(0 > Grpc\Timeval::compare($deadline, $now)); - -// Test AddAndSubtract -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(1000); -$deadline = $now->add($delta); -$back_to_now = $deadline->subtract($delta); -assert(0 == Grpc\Timeval::compare($back_to_now, $now)); - -// Test Similar -$a = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(1000); -$b = $a->add($delta); -$thresh = new Grpc\Timeval(1100); -assert(Grpc\Timeval::similar($a, $b, $thresh)); -$thresh = new Grpc\Timeval(900); -assert(!Grpc\Timeval::similar($a, $b, $thresh)); - -// Test SleepUntil -$curr_microtime = microtime(true); -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(1000); -$deadline = $now->add($delta); -$deadline->sleepUntil(); -$done_microtime = microtime(true); -assert(($done_microtime - $curr_microtime) > 0.0009); - -// Test ConstructorInvalidParam -try { - $delta = new Grpc\Timeval('abc'); -} catch (\Exception $e) {} -// Test AddInvalidParam -$a = Grpc\Timeval::now(); -try { - $a->add(1000); -} catch (\Exception $e) {} -// Test SubtractInvalidParam -$a = Grpc\Timeval::now(); -try { - $a->subtract(1000); -} catch (\Exception $e) {} -// Test CompareInvalidParam -try { - $a = Grpc\Timeval::compare(1000, 1100); -} catch (\Exception $e) {} -// Test SimilarInvalidParam -try { - $a = Grpc\Timeval::similar(1000, 1100, 1200); -} catch (\Exception $e) {} - unset($time); - - //============== Server Test ==================== - //Set Up - $server = NULL; - - // Test ConstructorWithNull -$server = new Grpc\Server(); -assert($server != NULL); - -// Test ConstructorWithNullArray -$server = new Grpc\Server([]); -assert($server != NULL); - -// Test ConstructorWithArray -$server = new Grpc\Server(['ip' => '127.0.0.1', - 'port' => '8080', ]); -assert($server != NULL); - -// Test RequestCall -$server = new Grpc\Server(); -$port = $server->addHttp2Port('0.0.0.0:0'); -$server->start(); -$channel = new Grpc\Channel('localhost:'.$port, - [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure() - ]); - -$deadline = Grpc\Timeval::infFuture(); -$call = new Grpc\Call($channel, 'dummy_method', $deadline); - -$event = $call->startBatch([Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - ]); - -$c = $server->requestCall(); -assert('dummy_method' == $c->method); -assert(is_string($c->host)); - -unset($call); -unset($channel); - -// Test InvalidConstructorWithNumKeyOfArray -try{ - $server = new Grpc\Server([10 => '127.0.0.1', - 20 => '8080', ]); -} -catch(\Exception $e){} - -// Test Invalid ArgumentException -try{ - $server = new Grpc\Server(['127.0.0.1', '8080']); -} -catch(\Exception $e){} - -// Test InvalidAddHttp2Port -$server = new Grpc\Server([]); -try{ - $port = $server->addHttp2Port(['0.0.0.0:0']); -} -catch(\Exception $e){} - -// Test InvalidAddSecureHttp2Port -$server = new Grpc\Server([]); -try{ - $port = $server->addSecureHttp2Port(['0.0.0.0:0']); -} -catch(\Exception $e){} - -// Test InvalidAddSecureHttp2Port2 -$server = new Grpc\Server(); -try{ - $port = $server->addSecureHttp2Port('0.0.0.0:0'); -} -catch(\Exception $e){} - -// Test InvalidAddSecureHttp2Port3 -$server = new Grpc\Server(); -try{ - $port = $server->addSecureHttp2Port('0.0.0.0:0', 'invalid'); -} -catch(\Exception $e){} -unset($server); - - -//============== ChannelCredential Test ==================== -// Test CreateSslWith3Null -$channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, - null); -assert($channel_credentials != NULL); - -// Test CreateSslWith3NullString -$channel_credentials = Grpc\ChannelCredentials::createSsl('', '', ''); -assert($channel_credentials != NULL); - -// Test CreateInsecure -$channel_credentials = Grpc\ChannelCredentials::createInsecure(); -assert($channel_credentials == NULL); - -// Test InvalidCreateSsl() -try { - $channel_credentials = Grpc\ChannelCredentials::createSsl([]); -} -catch (\Exception $e) { -} -try { - $channel_credentials = Grpc\ChannelCredentials::createComposite( - 'something', 'something'); -} -catch (\Exception $e) { -} - -//============== Interceptor Test ==================== -require_once(dirname(__FILE__).'/../../lib/Grpc/BaseStub.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/AbstractCall.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/CallInvoker.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/DefaultCallInvoker.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php'); - -class SimpleRequest -{ - private $data; - public function __construct($data) - { - $this->data = $data; - } - public function setData($data) - { - $this->data = $data; - } - public function serializeToString() - { - return $this->data; - } -} - -class InterceptorClient extends Grpc\BaseStub -{ - - /** - * @param string $hostname hostname - * @param array $opts channel options - * @param Channel|InterceptorChannel $channel (optional) re-use channel object - */ - public function __construct($hostname, $opts, $channel = null) - { - parent::__construct($hostname, $opts, $channel); - } - - /** - * A simple RPC. - * @param SimpleRequest $argument input argument - * @param array $metadata metadata - * @param array $options call options - */ - public function UnaryCall( - SimpleRequest $argument, - $metadata = [], - $options = [] - ) { - return $this->_simpleRequest( - '/dummy_method', - $argument, - [], - $metadata, - $options - ); - } - - /** - * A client-to-server streaming RPC. - * @param array $metadata metadata - * @param array $options call options - */ - public function StreamCall( - $metadata = [], - $options = [] - ) { - return $this->_clientStreamRequest('/dummy_method', [], $metadata, $options); - } -} - -class ChangeMetadataInterceptor extends Grpc\Interceptor -{ - public function interceptUnaryUnary($method, - $argument, - $deserialize, - array $metadata = [], - array $options = [], - $continuation) - { - $metadata["foo"] = array('interceptor_from_unary_request'); - return $continuation($method, $argument, $deserialize, $metadata, $options); - } - public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) - { - $metadata["foo"] = array('interceptor_from_stream_request'); - return $continuation($method, $deserialize, $metadata, $options); - } -} - -class ChangeMetadataInterceptor2 extends Grpc\Interceptor -{ - public function interceptUnaryUnary($method, - $argument, - $deserialize, - array $metadata = [], - array $options = [], - $continuation) - { - if (array_key_exists('foo', $metadata)) { - $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first'); - } else { - $metadata["bar"] = array('interceptor_from_unary_request'); - } - return $continuation($method, $argument, $deserialize, $metadata, $options); - } - public function interceptStreamUnary($method, - $deserialize, - array $metadata = [], - array $options = [], - $continuation) - { - if (array_key_exists('foo', $metadata)) { - $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first'); - } else { - $metadata["bar"] = array('interceptor_from_stream_request'); - } - return $continuation($method, $deserialize, $metadata, $options); - } -} - -class ChangeRequestCall -{ - private $call; - - public function __construct($call) - { - $this->call = $call; - } - public function getCall() - { - return $this->call; - } - - public function write($request) - { - $request->setData('intercepted_stream_request'); - $this->getCall()->write($request); - } - - public function wait() - { - return $this->getCall()->wait(); - } -} - -class ChangeRequestInterceptor extends Grpc\Interceptor -{ - public function interceptUnaryUnary($method, - $argument, - $deserialize, - array $metadata = [], - array $options = [], - $continuation) - { - $argument->setData('intercepted_unary_request'); - return $continuation($method, $argument, $deserialize, $metadata, $options); - } - public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) - { - return new ChangeRequestCall( - $continuation($method, $deserialize, $metadata, $options) - ); - } -} - -class StopCallInterceptor extends Grpc\Interceptor -{ - public function interceptUnaryUnary($method, - $argument, - array $metadata = [], - array $options = [], - $continuation) - { - $metadata["foo"] = array('interceptor_from_request_response'); - } - public function interceptStreamUnary($method, - array $metadata = [], - array $options = [], - $continuation) - { - $metadata["foo"] = array('interceptor_from_request_response'); - } -} - -// Set Up -$server = new Grpc\Server([]); -$port = $server->addHttp2Port('0.0.0.0:0'); -$channel = new Grpc\Channel('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure()]); -$server->start(); - -// Test ClientChangeMetadataOneInterceptor -$req_text = 'client_request'; -$channel_matadata_interceptor = new ChangeMetadataInterceptor(); -$intercept_channel = Grpc\Interceptor::intercept($channel, $channel_matadata_interceptor); -$client = new InterceptorClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), -], $intercept_channel); -$req = new SimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_unary_request'] == $event->metadata['foo']); - -$stream_call = $client->StreamCall(); -$stream_call->write($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_stream_request'] == $event->metadata['foo']); - -unset($unary_call); -unset($stream_call); -unset($server_call); - -// Test ClientChangeMetadataTwoInterceptor -$req_text = 'client_request'; -$channel_matadata_interceptor = new ChangeMetadataInterceptor(); -$channel_matadata_intercepto2 = new ChangeMetadataInterceptor2(); -// test intercept separately. -$intercept_channel1 = Grpc\Interceptor::intercept($channel, $channel_matadata_interceptor); -$intercept_channel2 = Grpc\Interceptor::intercept($intercept_channel1, $channel_matadata_intercepto2); -$client = new InterceptorClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), -], $intercept_channel2); - -$req = new SimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_unary_request'] == $event->metadata['foo']); -assert(['interceptor_from_unary_request'] == $event->metadata['bar']); - -$stream_call = $client->StreamCall(); -$stream_call->write($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_stream_request'] == $event->metadata['foo']); -assert(['interceptor_from_stream_request'] == $event->metadata['bar']); - -unset($unary_call); -unset($stream_call); -unset($server_call); - -// test intercept by array. -$intercept_channel3 = Grpc\Interceptor::intercept($channel, - [$channel_matadata_intercepto2, $channel_matadata_interceptor]); -$client = new InterceptorClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), -], $intercept_channel3); - -$req = new SimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_unary_request'] == $event->metadata['foo']); -assert(['interceptor_from_unary_request'] == $event->metadata['bar']); - -$stream_call = $client->StreamCall(); -$stream_call->write($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_stream_request'] == $event->metadata['foo']); -assert(['interceptor_from_stream_request'] == $event->metadata['bar']); - -unset($unary_call); -unset($stream_call); -unset($server_call); - - -// Test ClientChangeRequestInterceptor -$req_text = 'client_request'; -$change_request_interceptor = new ChangeRequestInterceptor(); -$intercept_channel = Grpc\Interceptor::intercept($channel, - $change_request_interceptor); -$client = new InterceptorClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), -], $intercept_channel); - -$req = new SimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); - -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => '', - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert('intercepted_unary_request' == $event->message); - -$stream_call = $client->StreamCall(); -$stream_call->write($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => '', - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert('intercepted_stream_request' == $event->message); - -unset($unary_call); -unset($stream_call); -unset($server_call); - -// Test ClientChangeStopCallInterceptor -$req_text = 'client_request'; -$channel_request_interceptor = new StopCallInterceptor(); -$intercept_channel = Grpc\Interceptor::intercept($channel, - $channel_request_interceptor); -$client = new InterceptorClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), -], $intercept_channel); - -$req = new SimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); -assert($unary_call == NULL); - - -$stream_call = $client->StreamCall(); -assert($stream_call == NULL); - -unset($unary_call); -unset($stream_call); -unset($server_call); - -// Test GetInterceptorChannelConnectivityState -$channel = new Grpc\Channel( - 'localhost:0', - [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure() - ] -); -$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); -$state = $interceptor_channel->getConnectivityState(); -assert(0 == $state); -$channel->close(); - -// Test InterceptorChannelWatchConnectivityState -$channel = new Grpc\Channel( - 'localhost:0', - [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure() - ] -); -$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); -$now = Grpc\Timeval::now(); -$deadline = $now->add(new Grpc\Timeval(100*1000)); -$state = $interceptor_channel->watchConnectivityState(1, $deadline); -assert($state); -unset($time); -unset($deadline); -$channel->close(); - -// Test InterceptorChannelClose -$channel = new Grpc\Channel( - 'localhost:0', - [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure() - ] -); -$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); -assert($interceptor_channel != NULL); -$channel->close(); - -// Test InterceptorChannelGetTarget -$channel = new Grpc\Channel( - 'localhost:8888', - [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure() - ] -); -$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); -$target = $interceptor_channel->getTarget(); -assert(is_string($target)); - -$channel->close(); -unset($server); - - -//============== CallInvoker Test ==================== -class CallInvokerSimpleRequest -{ - private $data; - public function __construct($data) - { - $this->data = $data; - } - public function setData($data) - { - $this->data = $data; - } - public function serializeToString() - { - return $this->data; - } -} - -class CallInvokerClient extends Grpc\BaseStub -{ - - /** - * @param string $hostname hostname - * @param array $opts channel options - * @param Channel|InterceptorChannel $channel (optional) re-use channel object - */ - public function __construct($hostname, $opts, $channel = null) - { - parent::__construct($hostname, $opts, $channel); - } - - /** - * A simple RPC. - * @param SimpleRequest $argument input argument - * @param array $metadata metadata - * @param array $options call options - */ - public function UnaryCall( - CallInvokerSimpleRequest $argument, - $metadata = [], - $options = [] - ) { - return $this->_simpleRequest( - '/dummy_method', - $argument, - [], - $metadata, - $options - ); - } -} - -class CallInvokerUpdateChannel implements \Grpc\CallInvoker -{ - private $channel; - - public function getChannel() { - return $this->channel; - } - - public function createChannelFactory($hostname, $opts) { - $this->channel = new \Grpc\Channel('localhost:50050', $opts); - return $this->channel; - } - - public function UnaryCall($channel, $method, $deserialize, $options) { - return new UnaryCall($channel, $method, $deserialize, $options); - } - - public function ClientStreamingCall($channel, $method, $deserialize, $options) { - return new ClientStreamingCall($channel, $method, $deserialize, $options); - } - - public function ServerStreamingCall($channel, $method, $deserialize, $options) { - return new ServerStreamingCall($channel, $method, $deserialize, $options); - } - - public function BidiStreamingCall($channel, $method, $deserialize, $options) { - return new BidiStreamingCall($channel, $method, $deserialize, $options); - } -} - -class CallInvokerChangeRequest implements \Grpc\CallInvoker -{ - private $channel; - - public function getChannel() { - return $this->channel; - } - public function createChannelFactory($hostname, $opts) { - $this->channel = new \Grpc\Channel($hostname, $opts); - return $this->channel; - } - - public function UnaryCall($channel, $method, $deserialize, $options) { - return new CallInvokerChangeRequestCall($channel, $method, $deserialize, $options); - } - - public function ClientStreamingCall($channel, $method, $deserialize, $options) { - return new ClientStreamingCall($channel, $method, $deserialize, $options); - } - - public function ServerStreamingCall($channel, $method, $deserialize, $options) { - return new ServerStreamingCall($channel, $method, $deserialize, $options); - } - - public function BidiStreamingCall($channel, $method, $deserialize, $options) { - return new BidiStreamingCall($channel, $method, $deserialize, $options); - } -} - -class CallInvokerChangeRequestCall -{ - private $call; - - public function __construct($channel, $method, $deserialize, $options) - { - $this->call = new \Grpc\UnaryCall($channel, $method, $deserialize, $options); - } - - public function start($argument, $metadata, $options) { - $argument->setData('intercepted_unary_request'); - $this->call->start($argument, $metadata, $options); - } - - public function wait() - { - return $this->call->wait(); - } -} - -// Set Up -$server = new Grpc\Server([]); -$port = $server->addHttp2Port('0.0.0.0:0'); -$server->start(); - -// Test CreateDefaultCallInvoker -$call_invoker = new \Grpc\DefaultCallInvoker(); - -// Test CreateCallInvoker -$call_invoker = new CallInvokerUpdateChannel(); - -// Test CallInvokerAccessChannel -$call_invoker = new CallInvokerUpdateChannel(); -$stub = new \Grpc\BaseStub('localhost:50051', - ['credentials' => \Grpc\ChannelCredentials::createInsecure(), - 'grpc_call_invoker' => $call_invoker]); -assert($call_invoker->getChannel()->getTarget() == 'localhost:50050'); -$call_invoker->getChannel()->close(); - -// Test ClientChangeRequestCallInvoker -$req_text = 'client_request'; -$call_invoker = new CallInvokerChangeRequest(); -$client = new CallInvokerClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), - 'grpc_call_invoker' => $call_invoker, -]); - -$req = new CallInvokerSimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); - -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => '', - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert('intercepted_unary_request' == $event->message); -$call_invoker->getChannel()->close(); -unset($unary_call); -unset($server_call); - -unset($server); - -<<<<<<< HEAD -<<<<<<< HEAD -echo "Went Through All Unit Tests..............\r\n"; -======= -echo "Went Through All Unit Tests.............."; ->>>>>>> add MemoryLeakTest -======= -echo "Went Through All Unit Tests..............\r\n"; ->>>>>>> complete memory leak test - - diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php index 28098c4016e..be1d77fe7ad 100644 --- a/src/php/tests/unit_tests/CallTest.php +++ b/src/php/tests/unit_tests/CallTest.php @@ -86,16 +86,6 @@ class CallTest extends PHPUnit_Framework_TestCase $this->assertTrue($result->send_metadata); } - public function testAddMultiAndMultiValueMetadata() - { - $batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1', 'value2'], - 'key2' => ['value3', 'value4'],], - ]; - $result = $this->call->startBatch($batch); - $this->assertTrue($result->send_metadata); - } - public function testGetPeer() { $this->assertTrue(is_string($this->call->getPeer())); diff --git a/templates/tools/dockerfile/php_valgrind.include b/templates/tools/dockerfile/php_valgrind.include deleted file mode 100644 index f1f3b67d826..00000000000 --- a/templates/tools/dockerfile/php_valgrind.include +++ /dev/null @@ -1,7 +0,0 @@ -#================= -# PHP Test dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y ${'\\'} - valgrind diff --git a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template index 0b2290b741c..e7b6c0d5f9c 100644 --- a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template @@ -19,7 +19,6 @@ <%include file="../../php7_deps.include"/> <%include file="../../gcp_api_libraries.include"/> <%include file="../../python_deps.include"/> - <%include file="../../php_valgrind.include"/> <%include file="../../run_tests_addons.include"/> # Define the default command. CMD ["bash"] diff --git a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template index 329205363e3..fdbad53c391 100644 --- a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template @@ -20,7 +20,6 @@ <%include file="../../gcp_api_libraries.include"/> <%include file="../../python_deps.include"/> <%include file="../../php_deps.include"/> - <%include file="../../php_valgrind.include"/> <%include file="../../run_tests_addons.include"/> # Define the default command. CMD ["bash"] diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile index 529ebb9127b..0dff8399047 100644 --- a/tools/dockerfile/test/php7_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile @@ -79,14 +79,6 @@ RUN pip install --upgrade pip==10.0.1 RUN pip install virtualenv RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 -#================= -# PHP Test dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - valgrind - RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile index f69f7e65a20..ed59e569956 100644 --- a/tools/dockerfile/test/php_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php_jessie_x64/Dockerfile @@ -76,14 +76,6 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t RUN apt-get update && apt-get install -y \ git php5 php5-dev phpunit unzip -#================= -# PHP Test dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - valgrind - RUN mkdir /var/local/jenkins From 5198ccd89cf3d1d7970e6e5176cc308bf0c85ed1 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 29 Jan 2019 00:40:01 -0800 Subject: [PATCH 203/814] Revert "Add basic benchmark test for Python" --- src/proto/grpc/core/BUILD | 18 +-- src/proto/grpc/testing/BUILD | 98 +++-------------- src/python/grpcio_tests/tests/qps/BUILD | 103 ------------------ src/python/grpcio_tests/tests/qps/README.md | 102 ----------------- .../tests/qps/basic_benchmark_test.sh | 45 -------- .../grpcio_tests/tests/qps/scenarios.json | 96 ---------------- test/cpp/qps/BUILD | 6 +- 7 files changed, 22 insertions(+), 446 deletions(-) delete mode 100644 src/python/grpcio_tests/tests/qps/BUILD delete mode 100644 src/python/grpcio_tests/tests/qps/README.md delete mode 100755 src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh delete mode 100644 src/python/grpcio_tests/tests/qps/scenarios.json diff --git a/src/proto/grpc/core/BUILD b/src/proto/grpc/core/BUILD index 2543027821c..46de9fae187 100644 --- a/src/proto/grpc/core/BUILD +++ b/src/proto/grpc/core/BUILD @@ -14,25 +14,11 @@ licenses(["notice"]) # Apache v2 -load("//bazel:grpc_build_system.bzl", "grpc_package", "grpc_proto_library") -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") +load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_package") -grpc_package( - name = "core", - visibility = "public", -) +grpc_package(name = "core", visibility = "public") grpc_proto_library( name = "stats_proto", srcs = ["stats.proto"], ) - -py_proto_library( - name = "py_stats_proto", - protos = ["stats.proto"], - with_grpc = True, - deps = [ - requirement("protobuf"), - ], -) diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD index 0c658967942..9876d5160a1 100644 --- a/src/proto/grpc/testing/BUILD +++ b/src/proto/grpc/testing/BUILD @@ -14,14 +14,11 @@ licenses(["notice"]) # Apache v2 -load("//bazel:grpc_build_system.bzl", "grpc_package", "grpc_proto_library") +load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_package") load("@grpc_python_dependencies//:requirements.bzl", "requirement") load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") -grpc_package( - name = "testing", - visibility = "public", -) +grpc_package(name = "testing", visibility = "public") exports_files([ "echo.proto", @@ -53,11 +50,9 @@ grpc_proto_library( grpc_proto_library( name = "echo_proto", srcs = ["echo.proto"], + deps = ["echo_messages_proto", + "simple_messages_proto"], generate_mocks = True, - deps = [ - "echo_messages_proto", - "simple_messages_proto", - ], ) grpc_proto_library( @@ -68,10 +63,10 @@ grpc_proto_library( py_proto_library( name = "py_empty_proto", - protos = ["empty.proto"], + protos = ["empty.proto",], with_grpc = True, deps = [ - requirement("protobuf"), + requirement('protobuf'), ], ) @@ -83,10 +78,10 @@ grpc_proto_library( py_proto_library( name = "py_messages_proto", - protos = ["messages.proto"], + protos = ["messages.proto",], with_grpc = True, deps = [ - requirement("protobuf"), + requirement('protobuf'), ], ) @@ -105,7 +100,7 @@ grpc_proto_library( name = "benchmark_service_proto", srcs = ["benchmark_service.proto"], deps = [ - "messages_proto", + "messages_proto", ], ) @@ -113,7 +108,7 @@ grpc_proto_library( name = "report_qps_scenario_service_proto", srcs = ["report_qps_scenario_service.proto"], deps = [ - "control_proto", + "control_proto", ], ) @@ -121,7 +116,7 @@ grpc_proto_library( name = "worker_service_proto", srcs = ["worker_service.proto"], deps = [ - "control_proto", + "control_proto", ], ) @@ -137,7 +132,7 @@ grpc_proto_library( has_services = False, deps = [ "//src/proto/grpc/core:stats_proto", - ], + ] ) grpc_proto_library( @@ -151,71 +146,14 @@ grpc_proto_library( py_proto_library( name = "py_test_proto", + protos = ["test.proto",], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], proto_deps = [ ":py_empty_proto", ":py_messages_proto", - ], - protos = ["test.proto"], - with_grpc = True, - deps = [ - requirement("protobuf"), - ], + ] ) -py_proto_library( - name = "py_benchmark_service_proto", - proto_deps = [ - ":py_messages_proto", - ], - protos = ["benchmark_service.proto"], - with_grpc = True, - deps = [ - requirement("protobuf"), - ], -) - -py_proto_library( - name = "py_payloads_proto", - protos = ["payloads.proto"], - with_grpc = True, - deps = [ - requirement("protobuf"), - ], -) - -py_proto_library( - name = "py_stats_proto", - proto_deps = [ - "//src/proto/grpc/core:py_stats_proto", - ], - protos = ["stats.proto"], - with_grpc = True, - deps = [ - requirement("protobuf"), - ], -) - -py_proto_library( - name = "py_control_proto", - proto_deps = [ - ":py_payloads_proto", - ":py_stats_proto", - ], - protos = ["control.proto"], - with_grpc = True, - deps = [ - requirement("protobuf"), - ], -) - -py_proto_library( - name = "py_worker_service_proto", - proto_deps = [ - ":py_control_proto", - ], - protos = ["worker_service.proto"], - with_grpc = True, - deps = [ - requirement("protobuf"), - ], -) diff --git a/src/python/grpcio_tests/tests/qps/BUILD b/src/python/grpcio_tests/tests/qps/BUILD deleted file mode 100644 index e1c7d138ef3..00000000000 --- a/src/python/grpcio_tests/tests/qps/BUILD +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright 2019 The gRPC Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -package(default_visibility = ["//visibility:public"]) - -load("@grpc_python_dependencies//:requirements.bzl", "requirement") - -py_library( - name = "benchmark_client", - srcs = ["benchmark_client.py"], - imports = ["../../"], - deps = [ - requirement("six"), - "//src/proto/grpc/testing:py_benchmark_service_proto", - "//src/proto/grpc/testing:py_messages_proto", - "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests/unit:resources", - "//src/python/grpcio_tests/tests/unit:test_common", - ], -) - -py_library( - name = "benchmark_server", - srcs = ["benchmark_server.py"], - imports = ["../../"], - deps = [ - "//src/proto/grpc/testing:py_benchmark_service_proto", - "//src/proto/grpc/testing:py_messages_proto", - ], -) - -py_library( - name = "client_runner", - srcs = ["client_runner.py"], - imports = ["../../"], -) - -py_library( - name = "histogram", - srcs = ["histogram.py"], - imports = ["../../"], - deps = [ - "//src/proto/grpc/testing:py_stats_proto", - ], -) - -py_library( - name = "worker_server", - srcs = ["worker_server.py"], - imports = ["../../"], - deps = [ - ":benchmark_client", - ":benchmark_server", - ":client_runner", - ":histogram", - "//src/proto/grpc/testing:py_benchmark_service_proto", - "//src/proto/grpc/testing:py_control_proto", - "//src/proto/grpc/testing:py_stats_proto", - "//src/proto/grpc/testing:py_worker_service_proto", - "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests/unit:resources", - "//src/python/grpcio_tests/tests/unit:test_common", - ], -) - -py_binary( - name = "qps_worker", - srcs = ["qps_worker.py"], - imports = ["../../"], - main = "qps_worker.py", - deps = [ - ":worker_server", - "//src/proto/grpc/testing:py_worker_service_proto", - "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests/unit:test_common", - ], -) - -filegroup( - name = "scenarios", - srcs = ["scenarios.json"], -) - -sh_test( - name = "basic_benchmark_test", - srcs = ["basic_benchmark_test.sh"], - data = [ - ":qps_worker", - ":scenarios", - "//test/cpp/qps:qps_json_driver", - ], -) diff --git a/src/python/grpcio_tests/tests/qps/README.md b/src/python/grpcio_tests/tests/qps/README.md deleted file mode 100644 index 8ae155a5b4b..00000000000 --- a/src/python/grpcio_tests/tests/qps/README.md +++ /dev/null @@ -1,102 +0,0 @@ -# Python Benchmark Tools - -## Scenarios - -In `src/proto/grpc/testing/control.proto`, it defines the fields of a scenario. -In `tools/run_tests/performance/scenario_config.py`, the script generates actual scenario content that usually in json format, or piped to another script. - -All Python related benchmark scenarios are: -* netperf -* python_generic_sync_streaming_ping_pong -* python_protobuf_sync_streaming_ping_pong -* python_protobuf_async_unary_ping_pong -* python_protobuf_sync_unary_ping_pong -* python_protobuf_sync_unary_qps_unconstrained -* python_protobuf_sync_streaming_qps_unconstrained -* python_protobuf_sync_unary_ping_pong_1MB - -Here we picked a small but representative subset, and reduce their benchmark duration from 30 seconds to 10 seconds: -* python_protobuf_async_unary_ping_pong -* python_protobuf_sync_streaming_ping_pong - -## Why keep the scenario file if it can be generated? - -Well... The `tools/run_tests/performance/scenario_config.py` is 1274 lines long. The intention of building these benchmark tools is reducing the complexity of existing infrastructure code. So, instead of calling layers of abstraction to generate the scenario file, keeping a valid static copy is preferable. - -Also, if the use case for this tool grows beyond simple static scenarios, we can incorporate automatic generation and selection of scenarios into the tool. - -## How to run it? - -```shell -bazel test --test_output=streamed src/python/grpcio_tests/tests/qps:basic_benchmark_test -``` - -## What does the output look like? - -``` -RUNNING SCENARIO: python_protobuf_async_unary_ping_pong -I0123 00:26:04.746195000 140736237159296 driver.cc:288] Starting server on localhost:10086 (worker #0) -D0123 00:26:04.747190000 140736237159296 ev_posix.cc:170] Using polling engine: poll -D0123 00:26:04.747264000 140736237159296 dns_resolver_ares.cc:488] Using ares dns resolver -I0123 00:26:04.748445000 140736237159296 subchannel.cc:869] Connect failed: {"created":"@1548203164.748403000","description":"Failed to connect to remote host: Connection refused","errno":61,"file":"src/core/lib/iomgr/tcp_client_posix.cc","file_line":207,"os_error":"Connection refused","syscall":"connect","target_address":"ipv6:[::1]:10086"} -I0123 00:26:04.748585000 140736237159296 subchannel.cc:869] Connect failed: {"created":"@1548203164.748564000","description":"Failed to connect to remote host: Connection refused","errno":61,"file":"src/core/lib/iomgr/tcp_client_posix.cc","file_line":207,"os_error":"Connection refused","syscall":"connect","target_address":"ipv4:127.0.0.1:10086"} -I0123 00:26:04.748596000 140736237159296 subchannel.cc:751] Subchannel 0x7fca43c19360: Retry in 999 milliseconds -I0123 00:26:05.751251000 123145571299328 subchannel.cc:710] Failed to connect to channel, retrying -I0123 00:26:05.752209000 140736237159296 subchannel.cc:832] New connected subchannel at 0x7fca45000060 for subchannel 0x7fca43c19360 -I0123 00:26:05.772291000 140736237159296 driver.cc:349] Starting client on localhost:10087 (worker #1) -D0123 00:26:05.772384000 140736237159296 driver.cc:373] Client 0 gets 1 channels -I0123 00:26:05.773286000 140736237159296 subchannel.cc:832] New connected subchannel at 0x7fca45004a80 for subchannel 0x7fca451034b0 -I0123 00:26:05.789797000 140736237159296 driver.cc:394] Initiating -I0123 00:26:05.790858000 140736237159296 driver.cc:415] Warming up -I0123 00:26:07.791078000 140736237159296 driver.cc:421] Starting -I0123 00:26:07.791860000 140736237159296 driver.cc:448] Running -I0123 00:26:17.790915000 140736237159296 driver.cc:462] Finishing clients -I0123 00:26:17.791821000 140736237159296 driver.cc:476] Received final status from client 0 -I0123 00:26:17.792148000 140736237159296 driver.cc:508] Finishing servers -I0123 00:26:17.792493000 140736237159296 driver.cc:522] Received final status from server 0 -I0123 00:26:17.795786000 140736237159296 report.cc:82] QPS: 2066.6 -I0123 00:26:17.795799000 140736237159296 report.cc:122] QPS: 2066.6 (258.3/server core) -I0123 00:26:17.795805000 140736237159296 report.cc:127] Latencies (50/90/95/99/99.9%-ile): 467.9/504.8/539.0/653.3/890.4 us -I0123 00:26:17.795811000 140736237159296 report.cc:137] Server system time: 100.00% -I0123 00:26:17.795815000 140736237159296 report.cc:139] Server user time: 100.00% -I0123 00:26:17.795818000 140736237159296 report.cc:141] Client system time: 100.00% -I0123 00:26:17.795821000 140736237159296 report.cc:143] Client user time: 100.00% -I0123 00:26:17.795825000 140736237159296 report.cc:148] Server CPU usage: 0.00% -I0123 00:26:17.795828000 140736237159296 report.cc:153] Client Polls per Request: 0.00 -I0123 00:26:17.795831000 140736237159296 report.cc:155] Server Polls per Request: 0.00 -I0123 00:26:17.795834000 140736237159296 report.cc:160] Server Queries/CPU-sec: 1033.19 -I0123 00:26:17.795837000 140736237159296 report.cc:162] Client Queries/CPU-sec: 1033.32 -RUNNING SCENARIO: python_protobuf_sync_streaming_ping_pong -I0123 00:26:17.795888000 140736237159296 driver.cc:288] Starting server on localhost:10086 (worker #0) -D0123 00:26:17.795964000 140736237159296 ev_posix.cc:170] Using polling engine: poll -D0123 00:26:17.795978000 140736237159296 dns_resolver_ares.cc:488] Using ares dns resolver -I0123 00:26:17.796613000 140736237159296 subchannel.cc:832] New connected subchannel at 0x7fca43c15820 for subchannel 0x7fca43d12140 -I0123 00:26:17.810911000 140736237159296 driver.cc:349] Starting client on localhost:10087 (worker #1) -D0123 00:26:17.811037000 140736237159296 driver.cc:373] Client 0 gets 1 channels -I0123 00:26:17.811892000 140736237159296 subchannel.cc:832] New connected subchannel at 0x7fca43d18f40 for subchannel 0x7fca43d16b80 -I0123 00:26:17.818902000 140736237159296 driver.cc:394] Initiating -I0123 00:26:17.820776000 140736237159296 driver.cc:415] Warming up -I0123 00:26:19.824685000 140736237159296 driver.cc:421] Starting -I0123 00:26:19.825970000 140736237159296 driver.cc:448] Running -I0123 00:26:29.821866000 140736237159296 driver.cc:462] Finishing clients -I0123 00:26:29.823259000 140736237159296 driver.cc:476] Received final status from client 0 -I0123 00:26:29.827195000 140736237159296 driver.cc:508] Finishing servers -I0123 00:26:29.827599000 140736237159296 driver.cc:522] Received final status from server 0 -I0123 00:26:29.828739000 140736237159296 report.cc:82] QPS: 619.5 -I0123 00:26:29.828752000 140736237159296 report.cc:122] QPS: 619.5 (77.4/server core) -I0123 00:26:29.828760000 140736237159296 report.cc:127] Latencies (50/90/95/99/99.9%-ile): 1589.8/1854.3/1920.4/2015.8/2204.8 us -I0123 00:26:29.828765000 140736237159296 report.cc:137] Server system time: 100.00% -I0123 00:26:29.828769000 140736237159296 report.cc:139] Server user time: 100.00% -I0123 00:26:29.828772000 140736237159296 report.cc:141] Client system time: 100.00% -I0123 00:26:29.828776000 140736237159296 report.cc:143] Client user time: 100.00% -I0123 00:26:29.828780000 140736237159296 report.cc:148] Server CPU usage: 0.00% -I0123 00:26:29.828784000 140736237159296 report.cc:153] Client Polls per Request: 0.00 -I0123 00:26:29.828788000 140736237159296 report.cc:155] Server Polls per Request: 0.00 -I0123 00:26:29.828792000 140736237159296 report.cc:160] Server Queries/CPU-sec: 309.58 -I0123 00:26:29.828795000 140736237159296 report.cc:162] Client Queries/CPU-sec: 309.75 -``` - -## Future Works (TODOs) - -1. Generate a target for each scenario. -2. Simplify the main entrance of our benchmark related code, or make it depends on Bazel. diff --git a/src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh b/src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh deleted file mode 100755 index fecb528396a..00000000000 --- a/src/python/grpcio_tests/tests/qps/basic_benchmark_test.sh +++ /dev/null @@ -1,45 +0,0 @@ -#! /bin/bash -# Copyright 2019 The gRPC Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This test benchmarks Python client/server. -set -ex - -declare -a DRIVER_PORTS=("10086" "10087") -SCENARIOS_FILE=src/python/grpcio_tests/tests/qps/scenarios.json - -function join { local IFS="$1"; shift; echo "$*"; } - -if [[ -e "${SCENARIOS_FILE}" ]]; then - echo "Running against ${SCENARIOS_FILE}:" - cat "${SCENARIOS_FILE}" -else - echo "Failed to find ${SCENARIOS_FILE}!" - exit 1 -fi - -echo "Starting Python qps workers..." -qps_workers=() -for DRIVER_PORT in "${DRIVER_PORTS[@]}" -do - echo -e "\tRunning Python qps worker listening at localhost:${DRIVER_PORT}..." - src/python/grpcio_tests/tests/qps/qps_worker \ - --driver_port="${DRIVER_PORT}" & - qps_workers+=("localhost:${DRIVER_PORT}") -done - -echo "Running qps json driver..." -QPS_WORKERS=$(join , ${qps_workers[@]}) -export QPS_WORKERS -test/cpp/qps/qps_json_driver --scenarios_file="${SCENARIOS_FILE}" diff --git a/src/python/grpcio_tests/tests/qps/scenarios.json b/src/python/grpcio_tests/tests/qps/scenarios.json deleted file mode 100644 index 03c91be1e71..00000000000 --- a/src/python/grpcio_tests/tests/qps/scenarios.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "scenarios": [ - { - "name": "python_protobuf_async_unary_ping_pong", - "clientConfig": { - "clientType": "ASYNC_CLIENT", - "securityParams": { - "useTestCa": true, - "serverHostOverride": "foo.test.google.fr" - }, - "outstandingRpcsPerChannel": 1, - "clientChannels": 1, - "asyncClientThreads": 1, - "loadParams": { - "closedLoop": {} - }, - "payloadConfig": { - "simpleParams": {} - }, - "histogramParams": { - "resolution": 0.01, - "maxPossible": 60000000000 - }, - "channelArgs": [ - { - "name": "grpc.optimization_target", - "strValue": "latency" - } - ] - }, - "numClients": 1, - "serverConfig": { - "serverType": "ASYNC_SERVER", - "securityParams": { - "useTestCa": true, - "serverHostOverride": "foo.test.google.fr" - }, - "channelArgs": [ - { - "name": "grpc.optimization_target", - "strValue": "latency" - } - ] - }, - "numServers": 1, - "warmupSeconds": 2, - "benchmarkSeconds": 10 - }, - { - "name": "python_protobuf_sync_streaming_ping_pong", - "clientConfig": { - "securityParams": { - "useTestCa": true, - "serverHostOverride": "foo.test.google.fr" - }, - "outstandingRpcsPerChannel": 1, - "clientChannels": 1, - "asyncClientThreads": 1, - "rpcType": "STREAMING", - "loadParams": { - "closedLoop": {} - }, - "payloadConfig": { - "simpleParams": {} - }, - "histogramParams": { - "resolution": 0.01, - "maxPossible": 60000000000 - }, - "channelArgs": [ - { - "name": "grpc.optimization_target", - "strValue": "latency" - } - ] - }, - "numClients": 1, - "serverConfig": { - "serverType": "ASYNC_SERVER", - "securityParams": { - "useTestCa": true, - "serverHostOverride": "foo.test.google.fr" - }, - "channelArgs": [ - { - "name": "grpc.optimization_target", - "strValue": "latency" - } - ] - }, - "numServers": 1, - "warmupSeconds": 2, - "benchmarkSeconds": 10 - } - ] -} diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index 41ae5d41e0c..8855a1c155d 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -14,10 +14,8 @@ licenses(["notice"]) # Apache v2 -package(default_visibility = ["//visibility:public"]) - -load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library", "grpc_cc_test", "grpc_package") -load("//test/cpp/qps:qps_benchmark_script.bzl", "json_run_localhost_batch", "qps_json_driver_batch") +load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_library", "grpc_cc_binary", "grpc_package") +load("//test/cpp/qps:qps_benchmark_script.bzl", "qps_json_driver_batch", "json_run_localhost_batch") grpc_package(name = "test/cpp/qps") From a3d997cbdc4dcf8f4aff7e380f9efdd041cf09d0 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Tue, 29 Jan 2019 10:04:28 -0800 Subject: [PATCH 204/814] Add a TLS credential surface API (experimental) --- BUILD | 2 + CMakeLists.txt | 2 + Makefile | 3 + build.yaml | 2 + config.m4 | 2 + config.w32 | 2 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 + grpc.def | 9 + grpc.gemspec | 2 + grpc.gyp | 1 + include/grpc/grpc_security.h | 195 ++++++++++++++++ package.xml | 2 + .../tls/grpc_tls_credentials_options.cc | 192 ++++++++++++++++ .../tls/grpc_tls_credentials_options.h | 213 ++++++++++++++++++ .../security/security_connector/ssl_utils.h | 33 +++ src/python/grpcio/grpc_core_dependencies.py | 1 + src/ruby/ext/grpc/rb_grpc_imports.generated.c | 18 ++ src/ruby/ext/grpc/rb_grpc_imports.generated.h | 27 +++ .../core/surface/public_headers_must_be_c89.c | 9 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 3 + 22 files changed, 724 insertions(+) create mode 100644 src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc create mode 100644 src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h diff --git a/BUILD b/BUILD index 81272e27e97..ff066edaeaf 100644 --- a/BUILD +++ b/BUILD @@ -1614,6 +1614,7 @@ grpc_cc_library( "src/core/lib/security/credentials/oauth2/oauth2_credentials.cc", "src/core/lib/security/credentials/plugin/plugin_credentials.cc", "src/core/lib/security/credentials/ssl/ssl_credentials.cc", + "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc", "src/core/lib/security/security_connector/alts/alts_security_connector.cc", "src/core/lib/security/security_connector/fake/fake_security_connector.cc", "src/core/lib/security/security_connector/load_system_roots_fallback.cc", @@ -1648,6 +1649,7 @@ grpc_cc_library( "src/core/lib/security/credentials/oauth2/oauth2_credentials.h", "src/core/lib/security/credentials/plugin/plugin_credentials.h", "src/core/lib/security/credentials/ssl/ssl_credentials.h", + "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h", "src/core/lib/security/security_connector/alts/alts_security_connector.h", "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index a36d06a703c..9813eec7062 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1151,6 +1151,7 @@ add_library(grpc src/core/lib/security/credentials/oauth2/oauth2_credentials.cc src/core/lib/security/credentials/plugin/plugin_credentials.cc src/core/lib/security/credentials/ssl/ssl_credentials.cc + src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc src/core/lib/security/security_connector/alts/alts_security_connector.cc src/core/lib/security/security_connector/fake/fake_security_connector.cc src/core/lib/security/security_connector/load_system_roots_fallback.cc @@ -1609,6 +1610,7 @@ add_library(grpc_cronet src/core/lib/security/credentials/oauth2/oauth2_credentials.cc src/core/lib/security/credentials/plugin/plugin_credentials.cc src/core/lib/security/credentials/ssl/ssl_credentials.cc + src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc src/core/lib/security/security_connector/alts/alts_security_connector.cc src/core/lib/security/security_connector/fake/fake_security_connector.cc src/core/lib/security/security_connector/load_system_roots_fallback.cc diff --git a/Makefile b/Makefile index fd76e8b7d72..b9b7ab4c254 100644 --- a/Makefile +++ b/Makefile @@ -3672,6 +3672,7 @@ LIBGRPC_SRC = \ src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ + src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ @@ -4124,6 +4125,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ + src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ @@ -25370,6 +25372,7 @@ src/core/lib/security/credentials/local/local_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/oauth2/oauth2_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/plugin/plugin_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/ssl/ssl_credentials.cc: $(OPENSSL_DEP) +src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/alts/alts_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/fake/fake_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/load_system_roots_fallback.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 3afe4a3e9ce..0946e853d1b 100644 --- a/build.yaml +++ b/build.yaml @@ -837,6 +837,7 @@ filegroups: - src/core/lib/security/credentials/oauth2/oauth2_credentials.h - src/core/lib/security/credentials/plugin/plugin_credentials.h - src/core/lib/security/credentials/ssl/ssl_credentials.h + - src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h - src/core/lib/security/security_connector/alts/alts_security_connector.h - src/core/lib/security/security_connector/fake/fake_security_connector.h - src/core/lib/security/security_connector/load_system_roots.h @@ -869,6 +870,7 @@ filegroups: - src/core/lib/security/credentials/oauth2/oauth2_credentials.cc - src/core/lib/security/credentials/plugin/plugin_credentials.cc - src/core/lib/security/credentials/ssl/ssl_credentials.cc + - src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc - src/core/lib/security/security_connector/alts/alts_security_connector.cc - src/core/lib/security/security_connector/fake/fake_security_connector.cc - src/core/lib/security/security_connector/load_system_roots_fallback.cc diff --git a/config.m4 b/config.m4 index 46597e6f0e3..1874f3ba1b0 100644 --- a/config.m4 +++ b/config.m4 @@ -283,6 +283,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ + src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ @@ -728,6 +729,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/oauth2) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/plugin) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/ssl) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/tls) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/alts) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/fake) diff --git a/config.w32 b/config.w32 index 00b92e88a05..452e8fd18b1 100644 --- a/config.w32 +++ b/config.w32 @@ -258,6 +258,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\security\\credentials\\oauth2\\oauth2_credentials.cc " + "src\\core\\lib\\security\\credentials\\plugin\\plugin_credentials.cc " + "src\\core\\lib\\security\\credentials\\ssl\\ssl_credentials.cc " + + "src\\core\\lib\\security\\credentials\\tls\\grpc_tls_credentials_options.cc " + "src\\core\\lib\\security\\security_connector\\alts\\alts_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\fake\\fake_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\load_system_roots_fallback.cc " + @@ -743,6 +744,7 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\oauth2"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\plugin"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\ssl"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\tls"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\alts"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\fake"); diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index d0544011e6e..e1b1cf1564e 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -300,6 +300,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/oauth2/oauth2_credentials.h', 'src/core/lib/security/credentials/plugin/plugin_credentials.h', 'src/core/lib/security/credentials/ssl/ssl_credentials.h', + 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h', 'src/core/lib/security/security_connector/alts/alts_security_connector.h', 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index a13612250fa..da48fe7e953 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -294,6 +294,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/oauth2/oauth2_credentials.h', 'src/core/lib/security/credentials/plugin/plugin_credentials.h', 'src/core/lib/security/credentials/ssl/ssl_credentials.h', + 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h', 'src/core/lib/security/security_connector/alts/alts_security_connector.h', 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', @@ -731,6 +732,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', + 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc', 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', @@ -923,6 +925,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/oauth2/oauth2_credentials.h', 'src/core/lib/security/credentials/plugin/plugin_credentials.h', 'src/core/lib/security/credentials/ssl/ssl_credentials.h', + 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h', 'src/core/lib/security/security_connector/alts/alts_security_connector.h', 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', diff --git a/grpc.def b/grpc.def index b3466c004d8..59e29e0d168 100644 --- a/grpc.def +++ b/grpc.def @@ -131,6 +131,15 @@ EXPORTS grpc_alts_server_credentials_create grpc_local_credentials_create grpc_local_server_credentials_create + grpc_tls_credentials_options_create + grpc_tls_credentials_options_set_cert_request_type + grpc_tls_credentials_options_set_key_materials_config + grpc_tls_credentials_options_set_credential_reload_config + grpc_tls_credentials_options_set_server_authorization_check_config + grpc_tls_key_materials_config_create + grpc_tls_key_materials_config_set_key_materials + grpc_tls_credential_reload_config_create + grpc_tls_server_authorization_check_config_create grpc_raw_byte_buffer_create grpc_raw_compressed_byte_buffer_create grpc_byte_buffer_copy diff --git a/grpc.gemspec b/grpc.gemspec index 5cefb524333..9a3c657cc85 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -224,6 +224,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.h ) s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h ) s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h ) + s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h ) s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/fake/fake_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/load_system_roots.h ) @@ -665,6 +666,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.cc ) s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.cc ) s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.cc ) + s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc ) s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/fake/fake_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/load_system_roots_fallback.cc ) diff --git a/grpc.gyp b/grpc.gyp index b925d63fbdf..6a0a2718c8e 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -465,6 +465,7 @@ 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', + 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc', 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index de90971cc55..f0323eb16a1 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -609,6 +609,201 @@ GRPCAPI grpc_channel_credentials* grpc_local_credentials_create( GRPCAPI grpc_server_credentials* grpc_local_server_credentials_create( grpc_local_connect_type type); +/** --- SPIFFE and HTTPS-based TLS channel/server credentials --- + * It is used for experimental purpose for now and subject to change. */ + +/** Config for TLS key materials. It is used for + * experimental purpose for now and subject to change. */ +typedef struct grpc_tls_key_materials_config grpc_tls_key_materials_config; + +/** Config for TLS credential reload. It is used for + * experimental purpose for now and subject to change. */ +typedef struct grpc_tls_credential_reload_config + grpc_tls_credential_reload_config; + +/** Config for TLS server authorization check. It is used for + * experimental purpose for now and subject to change. */ +typedef struct grpc_tls_server_authorization_check_config + grpc_tls_server_authorization_check_config; + +/** TLS credentials options. It is used for + * experimental purpose for now and subject to change. */ +typedef struct grpc_tls_credentials_options grpc_tls_credentials_options; + +/** Create an empty TLS credentials options. It is used for + * experimental purpose for now and subject to change. */ +GRPCAPI grpc_tls_credentials_options* grpc_tls_credentials_options_create(); + +/** Set grpc_ssl_client_certificate_request_type field in credentials options + with the provided type. options should not be NULL. + It returns 1 on success and 0 on failure. It is used for + experimental purpose for now and subject to change. */ +GRPCAPI int grpc_tls_credentials_options_set_cert_request_type( + grpc_tls_credentials_options* options, + grpc_ssl_client_certificate_request_type type); + +/** Set grpc_tls_key_materials_config field in credentials options + with the provided config struct whose ownership is transferred. + Both parameters should not be NULL. + It returns 1 on success and 0 on failure. It is used for + experimental purpose for now and subject to change. */ +GRPCAPI int grpc_tls_credentials_options_set_key_materials_config( + grpc_tls_credentials_options* options, + grpc_tls_key_materials_config* config); + +/** Set grpc_tls_credential_reload_config field in credentials options + with the provided config struct whose ownership is transferred. + Both parameters should not be NULL. + It returns 1 on success and 0 on failure. It is used for + experimental purpose for now and subject to change. */ +GRPCAPI int grpc_tls_credentials_options_set_credential_reload_config( + grpc_tls_credentials_options* options, + grpc_tls_credential_reload_config* config); + +/** Set grpc_tls_server_authorization_check_config field in credentials options + with the provided config struct whose ownership is transferred. + Both parameters should not be NULL. + It returns 1 on success and 0 on failure. It is used for + experimental purpose for now and subject to change. */ +GRPCAPI int grpc_tls_credentials_options_set_server_authorization_check_config( + grpc_tls_credentials_options* options, + grpc_tls_server_authorization_check_config* config); + +/** --- TLS key materials config. --- + It is used for experimental purpose for now and subject to change. */ + +/** Create an empty grpc_tls_key_materials_config instance. + * It is used for experimental purpose for now and subject to change. */ +GRPCAPI grpc_tls_key_materials_config* grpc_tls_key_materials_config_create(); + +/** Set grpc_tls_key_materials_config instance with provided a TLS certificate. + config will take the ownership of pem_root_certs and pem_key_cert_pairs. + It's valid for the caller to provide nullptr pem_root_certs, in which case + the gRPC-provided root cert will be used. pem_key_cert_pairs should not be + NULL. It returns 1 on success and 0 on failure. It is used for + experimental purpose for now and subject to change. + */ +GRPCAPI int grpc_tls_key_materials_config_set_key_materials( + grpc_tls_key_materials_config* config, const char* pem_root_certs, + const grpc_ssl_pem_key_cert_pair** pem_key_cert_pairs, + size_t num_key_cert_pairs); + +/** --- TLS credential reload config. --- + It is used for experimental purpose for now and subject to change.*/ + +typedef struct grpc_tls_credential_reload_arg grpc_tls_credential_reload_arg; + +/** A callback function provided by gRPC to handle the result of credential + reload. It is used when schedule API is implemented asynchronously and + serves to bring the control back to grpc C core. It is used for + experimental purpose for now and subject to change. */ +typedef void (*grpc_tls_on_credential_reload_done_cb)( + grpc_tls_credential_reload_arg* arg); + +/** A struct containing all information necessary to schedule/cancel + a credential reload request. cb and cb_user_data represent a gRPC-provided + callback and an argument passed to it. key_materials is an in/output + parameter containing currently used/newly reloaded credentials. status and + error_details are used to hold information about errors occurred when a + credential reload request is scheduled/cancelled. It is used for + experimental purpose for now and subject to change. */ +struct grpc_tls_credential_reload_arg { + grpc_tls_on_credential_reload_done_cb cb; + void* cb_user_data; + grpc_tls_key_materials_config* key_materials_config; + grpc_status_code status; + const char* error_details; +}; + +/** Create a grpc_tls_credential_reload_config instance. + - config_user_data is config-specific, read-only user data + that works for all channels created with a credential using the config. + - schedule is a pointer to an application-provided callback used to invoke + credential reload API. The implementation of this method has to be + non-blocking, but can be performed synchronously or asynchronously. + 1) If processing occurs synchronously, it populates arg->key_materials, + arg->status, and arg->error_details and returns zero. + 2) If processing occurs asynchronously, it returns a non-zero value. + The application then invokes arg->cb when processing is completed. Note + that arg->cb cannot be invoked before schedule API returns. + - cancel is a pointer to an application-provided callback used to cancel + a credential reload request scheduled via an asynchronous schedule API. + arg is used to pinpoint an exact reloading request to be cancelled. + The operation may not have any effect if the request has already been + processed. + - destruct is a pointer to an application-provided callback used to clean up + any data associated with the config. + It is used for experimental purpose for now and subject to change. +*/ +GRPCAPI grpc_tls_credential_reload_config* +grpc_tls_credential_reload_config_create( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_credential_reload_arg* arg), + void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg), + void (*destruct)(void* config_user_data)); + +/** --- TLS server authorization check config. --- + * It is used for experimental purpose for now and subject to change. */ + +typedef struct grpc_tls_server_authorization_check_arg + grpc_tls_server_authorization_check_arg; + +/** callback function provided by gRPC used to handle the result of server + authorization check. It is used when schedule API is implemented + asynchronously, and serves to bring the control back to gRPC C core. It is + used for experimental purpose for now and subject to change. */ +typedef void (*grpc_tls_on_server_authorization_check_done_cb)( + grpc_tls_server_authorization_check_arg* arg); + +/** A struct containing all information necessary to schedule/cancel a server + authorization check request. cb and cb_user_data represent a gRPC-provided + callback and an argument passed to it. result will store the result of + server authorization check. target_name is the name of an endpoint the + channel is connecting to and certificate represents a complete certificate + chain including both signing and leaf certificates. status and error_details + contain information about errors occurred when a server authorization check + request is scheduled/cancelled. It is used for experimental purpose for now + and subject to change.*/ +struct grpc_tls_server_authorization_check_arg { + grpc_tls_on_server_authorization_check_done_cb cb; + void* cb_user_data; + int result; + const char* target_name; + const char* peer_cert; + grpc_status_code status; + const char* error_details; +}; + +/** Create a grpc_tls_server_authorization_check_config instance. + - config_user_data is config-specific, read-only user data + that works for all channels created with a credential using the config. + - schedule is a pointer to an application-provided callback used to invoke + server authorization check API. The implementation of this method has to + be non-blocking, but can be performed synchronously or asynchronously. + 1)If processing occurs synchronously, it populates arg->result, + arg->status, and arg->error_details and returns zero. + 2) If processing occurs asynchronously, it returns a non-zero value. The + application then invokes arg->cb when processing is completed. Note that + arg->cb cannot be invoked before schedule API returns. + - cancel is a pointer to an application-provided callback used to cancel a + server authorization check request scheduled via an asynchronous schedule + API. arg is used to pinpoint an exact check request to be cancelled. The + operation may not have any effect if the request has already been + processed. + - destruct is a pointer to an application-provided callback used to clean up + any data associated with the config. + It is used for experimental purpose for now and subject to change. +*/ +GRPCAPI grpc_tls_server_authorization_check_config* +grpc_tls_server_authorization_check_config_create( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*cancel)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*destruct)(void* config_user_data)); + #ifdef __cplusplus } #endif diff --git a/package.xml b/package.xml index cb036c81daf..69b6fdfa671 100644 --- a/package.xml +++ b/package.xml @@ -229,6 +229,7 @@ + @@ -670,6 +671,7 @@ + diff --git a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc new file mode 100644 index 00000000000..a6169a1b586 --- /dev/null +++ b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc @@ -0,0 +1,192 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" + +#include +#include + +#include +#include +#include + +/** -- gRPC TLS key materials config API implementation. -- **/ +void grpc_tls_key_materials_config::set_key_materials( + grpc_core::UniquePtr pem_root_certs, + PemKeyCertPairList pem_key_cert_pair_list) { + pem_key_cert_pair_list_ = std::move(pem_key_cert_pair_list); + pem_root_certs_ = std::move(pem_root_certs); +} + +/** -- gRPC TLS credential reload config API implementation. -- **/ +grpc_tls_credential_reload_config::grpc_tls_credential_reload_config( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_credential_reload_arg* arg), + void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg), + void (*destruct)(void* config_user_data)) + : config_user_data_(const_cast(config_user_data)), + schedule_(schedule), + cancel_(cancel), + destruct_(destruct) {} + +grpc_tls_credential_reload_config::~grpc_tls_credential_reload_config() { + if (destruct_ != nullptr) { + destruct_((void*)config_user_data_); + } +} + +/** -- gRPC TLS server authorization check API implementation. -- **/ +grpc_tls_server_authorization_check_config:: + grpc_tls_server_authorization_check_config( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*cancel)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*destruct)(void* config_user_data)) + : config_user_data_(const_cast(config_user_data)), + schedule_(schedule), + cancel_(cancel), + destruct_(destruct) {} + +grpc_tls_server_authorization_check_config:: + ~grpc_tls_server_authorization_check_config() { + if (destruct_ != nullptr) { + destruct_((void*)config_user_data_); + } +} + +/** -- Wrapper APIs declared in grpc_security.h -- **/ +grpc_tls_credentials_options* grpc_tls_credentials_options_create() { + return grpc_core::New(); +} + +int grpc_tls_credentials_options_set_cert_request_type( + grpc_tls_credentials_options* options, + grpc_ssl_client_certificate_request_type type) { + if (options == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_tls_credentials_options_set_cert_request_type()"); + return 0; + } + options->set_cert_request_type(type); + return 1; +} + +int grpc_tls_credentials_options_set_key_materials_config( + grpc_tls_credentials_options* options, + grpc_tls_key_materials_config* config) { + if (options == nullptr || config == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_tls_credentials_options_set_key_materials_config()"); + return 0; + } + options->set_key_materials_config(config->Ref()); + return 1; +} + +int grpc_tls_credentials_options_set_credential_reload_config( + grpc_tls_credentials_options* options, + grpc_tls_credential_reload_config* config) { + if (options == nullptr || config == nullptr) { + gpr_log(GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_tls_credentials_options_set_credential_reload_config()"); + return 0; + } + options->set_credential_reload_config(config->Ref()); + return 1; +} + +int grpc_tls_credentials_options_set_server_authorization_check_config( + grpc_tls_credentials_options* options, + grpc_tls_server_authorization_check_config* config) { + if (options == nullptr || config == nullptr) { + gpr_log( + GPR_ERROR, + "Invalid nullptr arguments to " + "grpc_tls_credentials_options_set_server_authorization_check_config()"); + return 0; + } + options->set_server_authorization_check_config(config->Ref()); + return 1; +} + +grpc_tls_key_materials_config* grpc_tls_key_materials_config_create() { + return grpc_core::New(); +} + +int grpc_tls_key_materials_config_set_key_materials( + grpc_tls_key_materials_config* config, const char* root_certs, + const grpc_ssl_pem_key_cert_pair** key_cert_pairs, size_t num) { + if (config == nullptr || key_cert_pairs == nullptr || num == 0) { + gpr_log(GPR_ERROR, + "Invalid arguments to " + "grpc_tls_key_materials_config_set_key_materials()"); + return 0; + } + grpc_core::UniquePtr pem_root(const_cast(root_certs)); + grpc_tls_key_materials_config::PemKeyCertPairList cert_pair_list; + for (size_t i = 0; i < num; i++) { + grpc_core::PemKeyCertPair key_cert_pair( + const_cast(key_cert_pairs[i])); + cert_pair_list.emplace_back(std::move(key_cert_pair)); + } + config->set_key_materials(std::move(pem_root), std::move(cert_pair_list)); + gpr_free(key_cert_pairs); + return 1; +} + +grpc_tls_credential_reload_config* grpc_tls_credential_reload_config_create( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_credential_reload_arg* arg), + void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg), + void (*destruct)(void* config_user_data)) { + if (schedule == nullptr) { + gpr_log( + GPR_ERROR, + "Schedule API is nullptr in creating TLS credential reload config."); + return nullptr; + } + return grpc_core::New( + config_user_data, schedule, cancel, destruct); +} + +grpc_tls_server_authorization_check_config* +grpc_tls_server_authorization_check_config_create( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*cancel)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*destruct)(void* config_user_data)) { + if (schedule == nullptr) { + gpr_log(GPR_ERROR, + "Schedule API is nullptr in creating TLS server authorization " + "check config."); + return nullptr; + } + return grpc_core::New( + config_user_data, schedule, cancel, destruct); +} diff --git a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h new file mode 100644 index 00000000000..71410d20a8f --- /dev/null +++ b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h @@ -0,0 +1,213 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CREDENTIALS_OPTIONS_H +#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CREDENTIALS_OPTIONS_H + +#include + +#include + +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/ref_counted.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" + +/** TLS key materials config. **/ +struct grpc_tls_key_materials_config + : public grpc_core::RefCounted { + public: + typedef grpc_core::InlinedVector + PemKeyCertPairList; + + /** Getters for member fields. **/ + const char* pem_root_certs() const { return pem_root_certs_.get(); } + const PemKeyCertPairList& pem_key_cert_pair_list() const { + return pem_key_cert_pair_list_; + } + + /** Setters for member fields. **/ + void set_key_materials(grpc_core::UniquePtr pem_root_certs, + PemKeyCertPairList pem_key_cert_pair_list); + + private: + PemKeyCertPairList pem_key_cert_pair_list_; + grpc_core::UniquePtr pem_root_certs_; +}; + +/** TLS credential reload config. **/ +struct grpc_tls_credential_reload_config + : public grpc_core::RefCounted { + public: + grpc_tls_credential_reload_config( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_credential_reload_arg* arg), + void (*cancel)(void* config_user_data, + grpc_tls_credential_reload_arg* arg), + void (*destruct)(void* config_user_data)); + ~grpc_tls_credential_reload_config(); + + int Schedule(grpc_tls_credential_reload_arg* arg) const { + return schedule_(config_user_data_, arg); + } + void Cancel(grpc_tls_credential_reload_arg* arg) const { + if (cancel_ == nullptr) { + gpr_log(GPR_ERROR, "cancel API is nullptr."); + return; + } + cancel_(config_user_data_, arg); + } + + private: + /** config-specific, read-only user data that works for all channels created + with a credential using the config. */ + void* config_user_data_; + /** callback function for invoking credential reload API. The implementation + of this method has to be non-blocking, but can be performed synchronously + or asynchronously. + If processing occurs synchronously, it populates \a arg->key_materials, \a + arg->status, and \a arg->error_details and returns zero. + If processing occurs asynchronously, it returns a non-zero value. + Application then invokes \a arg->cb when processing is completed. Note that + \a arg->cb cannot be invoked before \a schedule returns. + */ + int (*schedule_)(void* config_user_data, grpc_tls_credential_reload_arg* arg); + /** callback function for cancelling a credential reload request scheduled via + an asynchronous \a schedule. \a arg is used to pinpoint an exact reloading + request to be cancelled, and the operation may not have any effect if the + request has already been processed. */ + void (*cancel_)(void* config_user_data, grpc_tls_credential_reload_arg* arg); + /** callback function for cleaning up any data associated with credential + reload config. */ + void (*destruct_)(void* config_user_data); +}; + +/** TLS server authorization check config. **/ +struct grpc_tls_server_authorization_check_config + : public grpc_core::RefCounted { + public: + grpc_tls_server_authorization_check_config( + const void* config_user_data, + int (*schedule)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*cancel)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg), + void (*destruct)(void* config_user_data)); + ~grpc_tls_server_authorization_check_config(); + + int Schedule(grpc_tls_server_authorization_check_arg* arg) const { + return schedule_(config_user_data_, arg); + } + void Cancel(grpc_tls_server_authorization_check_arg* arg) const { + if (cancel_ == nullptr) { + gpr_log(GPR_ERROR, "cancel API is nullptr."); + return; + } + cancel_(config_user_data_, arg); + } + + private: + /** config-specific, read-only user data that works for all channels created + with a Credential using the config. */ + void* config_user_data_; + + /** callback function for invoking server authorization check. The + implementation of this method has to be non-blocking, but can be performed + synchronously or asynchronously. + If processing occurs synchronously, it populates \a arg->result, \a + arg->status, and \a arg->error_details, and returns zero. + If processing occurs asynchronously, it returns a non-zero value. + Application then invokes \a arg->cb when processing is completed. Note that + \a arg->cb cannot be invoked before \a schedule() returns. + */ + int (*schedule_)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg); + + /** callback function for canceling a server authorization check request. */ + void (*cancel_)(void* config_user_data, + grpc_tls_server_authorization_check_arg* arg); + + /** callback function for cleaning up any data associated with server + authorization check config. */ + void (*destruct_)(void* config_user_data); +}; + +/* TLS credentials options. */ +struct grpc_tls_credentials_options + : public grpc_core::RefCounted { + public: + ~grpc_tls_credentials_options() { + if (key_materials_config_.get() != nullptr) { + key_materials_config_.get()->Unref(); + } + if (credential_reload_config_.get() != nullptr) { + credential_reload_config_.get()->Unref(); + } + if (server_authorization_check_config_.get() != nullptr) { + server_authorization_check_config_.get()->Unref(); + } + } + + /* Getters for member fields. */ + grpc_ssl_client_certificate_request_type cert_request_type() const { + return cert_request_type_; + } + const grpc_tls_key_materials_config* key_materials_config() const { + return key_materials_config_.get(); + } + const grpc_tls_credential_reload_config* credential_reload_config() const { + return credential_reload_config_.get(); + } + const grpc_tls_server_authorization_check_config* + server_authorization_check_config() const { + return server_authorization_check_config_.get(); + } + grpc_tls_key_materials_config* mutable_key_materials_config() { + return key_materials_config_.get(); + } + + /* Setters for member fields. */ + void set_cert_request_type( + const grpc_ssl_client_certificate_request_type type) { + cert_request_type_ = type; + } + void set_key_materials_config( + grpc_core::RefCountedPtr config) { + key_materials_config_ = std::move(config); + } + void set_credential_reload_config( + grpc_core::RefCountedPtr config) { + credential_reload_config_ = std::move(config); + } + void set_server_authorization_check_config( + grpc_core::RefCountedPtr + config) { + server_authorization_check_config_ = std::move(config); + } + + private: + grpc_ssl_client_certificate_request_type cert_request_type_; + grpc_core::RefCountedPtr key_materials_config_; + grpc_core::RefCountedPtr + credential_reload_config_; + grpc_core::RefCountedPtr + server_authorization_check_config_; +}; + +#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_GRPC_TLS_CREDENTIALS_OPTIONS_H \ + */ diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index c9cd1a1d9c5..972ca439dea 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -89,6 +89,39 @@ class DefaultSslRootStore { static grpc_slice default_pem_root_certs_; }; +class PemKeyCertPair { + public: + // Construct from the C struct. We steal its members and then immediately + // free it. + explicit PemKeyCertPair(grpc_ssl_pem_key_cert_pair* pair) + : private_key_(const_cast(pair->private_key)), + cert_chain_(const_cast(pair->cert_chain)) { + gpr_free(pair); + } + + // Movable. + PemKeyCertPair(PemKeyCertPair&& other) { + private_key_ = std::move(other.private_key_); + cert_chain_ = std::move(other.cert_chain_); + } + PemKeyCertPair& operator=(PemKeyCertPair&& other) { + private_key_ = std::move(other.private_key_); + cert_chain_ = std::move(other.cert_chain_); + return *this; + } + + // Not copyable. + PemKeyCertPair(const PemKeyCertPair&) = delete; + PemKeyCertPair& operator=(const PemKeyCertPair&) = delete; + + char* private_key() const { return private_key_.get(); } + char* cert_chain() const { return cert_chain_.get(); } + + private: + grpc_core::UniquePtr private_key_; + grpc_core::UniquePtr cert_chain_; +}; + } // namespace grpc_core #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_UTILS_H \ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 0272aae690d..19d27412205 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -257,6 +257,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', + 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc', 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 18245e91073..47250ec7141 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -154,6 +154,15 @@ grpc_alts_credentials_create_type grpc_alts_credentials_create_import; grpc_alts_server_credentials_create_type grpc_alts_server_credentials_create_import; grpc_local_credentials_create_type grpc_local_credentials_create_import; grpc_local_server_credentials_create_type grpc_local_server_credentials_create_import; +grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import; +grpc_tls_credentials_options_set_cert_request_type_type grpc_tls_credentials_options_set_cert_request_type_import; +grpc_tls_credentials_options_set_key_materials_config_type grpc_tls_credentials_options_set_key_materials_config_import; +grpc_tls_credentials_options_set_credential_reload_config_type grpc_tls_credentials_options_set_credential_reload_config_import; +grpc_tls_credentials_options_set_server_authorization_check_config_type grpc_tls_credentials_options_set_server_authorization_check_config_import; +grpc_tls_key_materials_config_create_type grpc_tls_key_materials_config_create_import; +grpc_tls_key_materials_config_set_key_materials_type grpc_tls_key_materials_config_set_key_materials_import; +grpc_tls_credential_reload_config_create_type grpc_tls_credential_reload_config_create_import; +grpc_tls_server_authorization_check_config_create_type grpc_tls_server_authorization_check_config_create_import; grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import; grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import; grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import; @@ -412,6 +421,15 @@ void grpc_rb_load_imports(HMODULE library) { grpc_alts_server_credentials_create_import = (grpc_alts_server_credentials_create_type) GetProcAddress(library, "grpc_alts_server_credentials_create"); grpc_local_credentials_create_import = (grpc_local_credentials_create_type) GetProcAddress(library, "grpc_local_credentials_create"); grpc_local_server_credentials_create_import = (grpc_local_server_credentials_create_type) GetProcAddress(library, "grpc_local_server_credentials_create"); + grpc_tls_credentials_options_create_import = (grpc_tls_credentials_options_create_type) GetProcAddress(library, "grpc_tls_credentials_options_create"); + grpc_tls_credentials_options_set_cert_request_type_import = (grpc_tls_credentials_options_set_cert_request_type_type) GetProcAddress(library, "grpc_tls_credentials_options_set_cert_request_type"); + grpc_tls_credentials_options_set_key_materials_config_import = (grpc_tls_credentials_options_set_key_materials_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_key_materials_config"); + grpc_tls_credentials_options_set_credential_reload_config_import = (grpc_tls_credentials_options_set_credential_reload_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_credential_reload_config"); + grpc_tls_credentials_options_set_server_authorization_check_config_import = (grpc_tls_credentials_options_set_server_authorization_check_config_type) GetProcAddress(library, "grpc_tls_credentials_options_set_server_authorization_check_config"); + grpc_tls_key_materials_config_create_import = (grpc_tls_key_materials_config_create_type) GetProcAddress(library, "grpc_tls_key_materials_config_create"); + grpc_tls_key_materials_config_set_key_materials_import = (grpc_tls_key_materials_config_set_key_materials_type) GetProcAddress(library, "grpc_tls_key_materials_config_set_key_materials"); + grpc_tls_credential_reload_config_create_import = (grpc_tls_credential_reload_config_create_type) GetProcAddress(library, "grpc_tls_credential_reload_config_create"); + grpc_tls_server_authorization_check_config_create_import = (grpc_tls_server_authorization_check_config_create_type) GetProcAddress(library, "grpc_tls_server_authorization_check_config_create"); grpc_raw_byte_buffer_create_import = (grpc_raw_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_byte_buffer_create"); grpc_raw_compressed_byte_buffer_create_import = (grpc_raw_compressed_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_compressed_byte_buffer_create"); grpc_byte_buffer_copy_import = (grpc_byte_buffer_copy_type) GetProcAddress(library, "grpc_byte_buffer_copy"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index e61a35d09fa..9437f6d3918 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -437,6 +437,33 @@ extern grpc_local_credentials_create_type grpc_local_credentials_create_import; typedef grpc_server_credentials*(*grpc_local_server_credentials_create_type)(grpc_local_connect_type type); extern grpc_local_server_credentials_create_type grpc_local_server_credentials_create_import; #define grpc_local_server_credentials_create grpc_local_server_credentials_create_import +typedef grpc_tls_credentials_options*(*grpc_tls_credentials_options_create_type)(); +extern grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import; +#define grpc_tls_credentials_options_create grpc_tls_credentials_options_create_import +typedef int(*grpc_tls_credentials_options_set_cert_request_type_type)(grpc_tls_credentials_options* options, grpc_ssl_client_certificate_request_type type); +extern grpc_tls_credentials_options_set_cert_request_type_type grpc_tls_credentials_options_set_cert_request_type_import; +#define grpc_tls_credentials_options_set_cert_request_type grpc_tls_credentials_options_set_cert_request_type_import +typedef int(*grpc_tls_credentials_options_set_key_materials_config_type)(grpc_tls_credentials_options* options, grpc_tls_key_materials_config* config); +extern grpc_tls_credentials_options_set_key_materials_config_type grpc_tls_credentials_options_set_key_materials_config_import; +#define grpc_tls_credentials_options_set_key_materials_config grpc_tls_credentials_options_set_key_materials_config_import +typedef int(*grpc_tls_credentials_options_set_credential_reload_config_type)(grpc_tls_credentials_options* options, grpc_tls_credential_reload_config* config); +extern grpc_tls_credentials_options_set_credential_reload_config_type grpc_tls_credentials_options_set_credential_reload_config_import; +#define grpc_tls_credentials_options_set_credential_reload_config grpc_tls_credentials_options_set_credential_reload_config_import +typedef int(*grpc_tls_credentials_options_set_server_authorization_check_config_type)(grpc_tls_credentials_options* options, grpc_tls_server_authorization_check_config* config); +extern grpc_tls_credentials_options_set_server_authorization_check_config_type grpc_tls_credentials_options_set_server_authorization_check_config_import; +#define grpc_tls_credentials_options_set_server_authorization_check_config grpc_tls_credentials_options_set_server_authorization_check_config_import +typedef grpc_tls_key_materials_config*(*grpc_tls_key_materials_config_create_type)(); +extern grpc_tls_key_materials_config_create_type grpc_tls_key_materials_config_create_import; +#define grpc_tls_key_materials_config_create grpc_tls_key_materials_config_create_import +typedef int(*grpc_tls_key_materials_config_set_key_materials_type)(grpc_tls_key_materials_config* config, const char* pem_root_certs, const grpc_ssl_pem_key_cert_pair** pem_key_cert_pairs, size_t num_key_cert_pairs); +extern grpc_tls_key_materials_config_set_key_materials_type grpc_tls_key_materials_config_set_key_materials_import; +#define grpc_tls_key_materials_config_set_key_materials grpc_tls_key_materials_config_set_key_materials_import +typedef grpc_tls_credential_reload_config*(*grpc_tls_credential_reload_config_create_type)(const void* config_user_data, int (*schedule)(void* config_user_data, grpc_tls_credential_reload_arg* arg), void (*cancel)(void* config_user_data, grpc_tls_credential_reload_arg* arg), void (*destruct)(void* config_user_data)); +extern grpc_tls_credential_reload_config_create_type grpc_tls_credential_reload_config_create_import; +#define grpc_tls_credential_reload_config_create grpc_tls_credential_reload_config_create_import +typedef grpc_tls_server_authorization_check_config*(*grpc_tls_server_authorization_check_config_create_type)(const void* config_user_data, int (*schedule)(void* config_user_data, grpc_tls_server_authorization_check_arg* arg), void (*cancel)(void* config_user_data, grpc_tls_server_authorization_check_arg* arg), void (*destruct)(void* config_user_data)); +extern grpc_tls_server_authorization_check_config_create_type grpc_tls_server_authorization_check_config_create_import; +#define grpc_tls_server_authorization_check_config_create grpc_tls_server_authorization_check_config_create_import typedef grpc_byte_buffer*(*grpc_raw_byte_buffer_create_type)(grpc_slice* slices, size_t nslices); extern grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import; #define grpc_raw_byte_buffer_create grpc_raw_byte_buffer_create_import diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 426ef1e8b13..1c9b67027c5 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -191,6 +191,15 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_alts_server_credentials_create); printf("%lx", (unsigned long) grpc_local_credentials_create); printf("%lx", (unsigned long) grpc_local_server_credentials_create); + printf("%lx", (unsigned long) grpc_tls_credentials_options_create); + printf("%lx", (unsigned long) grpc_tls_credentials_options_set_cert_request_type); + printf("%lx", (unsigned long) grpc_tls_credentials_options_set_key_materials_config); + printf("%lx", (unsigned long) grpc_tls_credentials_options_set_credential_reload_config); + printf("%lx", (unsigned long) grpc_tls_credentials_options_set_server_authorization_check_config); + printf("%lx", (unsigned long) grpc_tls_key_materials_config_create); + printf("%lx", (unsigned long) grpc_tls_key_materials_config_set_key_materials); + printf("%lx", (unsigned long) grpc_tls_credential_reload_config_create); + printf("%lx", (unsigned long) grpc_tls_server_authorization_check_config_create); printf("%lx", (unsigned long) grpc_raw_byte_buffer_create); printf("%lx", (unsigned long) grpc_raw_compressed_byte_buffer_create); printf("%lx", (unsigned long) grpc_byte_buffer_copy); diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 041c7382be5..2aced414218 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1384,6 +1384,8 @@ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.h \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.h \ +src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \ +src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.h \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index b5992c219d9..9e07c548b69 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10381,6 +10381,7 @@ "src/core/lib/security/credentials/oauth2/oauth2_credentials.h", "src/core/lib/security/credentials/plugin/plugin_credentials.h", "src/core/lib/security/credentials/ssl/ssl_credentials.h", + "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h", "src/core/lib/security/security_connector/alts/alts_security_connector.h", "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", @@ -10434,6 +10435,8 @@ "src/core/lib/security/credentials/plugin/plugin_credentials.h", "src/core/lib/security/credentials/ssl/ssl_credentials.cc", "src/core/lib/security/credentials/ssl/ssl_credentials.h", + "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc", + "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h", "src/core/lib/security/security_connector/alts/alts_security_connector.cc", "src/core/lib/security/security_connector/alts/alts_security_connector.h", "src/core/lib/security/security_connector/fake/fake_security_connector.cc", From 8fb2f4abea2b16a9c813a7ab4d87c9fb5dd42ce8 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 29 Jan 2019 10:04:43 -0800 Subject: [PATCH 205/814] Fix a common typo --- .../grpcio_tests/tests/reflection/_reflection_servicer_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py index c0d0e7cf34e..37a66ad52bb 100644 --- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py +++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py @@ -52,7 +52,7 @@ class ReflectionServicerTest(unittest.TestCase): # TODO(https://github.com/grpc/grpc/issues/17844) # Bazel + Python 3 will result in creating two different instance of - # DESCRIPTOR for each message. So, the equal comparision between protobuf + # DESCRIPTOR for each message. So, the equal comparison between protobuf # returned by stub and manually crafted protobuf will always fail. def _assert_sequence_of_proto_equal(self, x, y): self.assertSequenceEqual( From 80a0488d3398f6761f1a915f4204bb63893075d2 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 29 Jan 2019 10:29:14 -0800 Subject: [PATCH 206/814] Make declaration match definition --- test/cpp/interop/interop_client.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index 8644844d952..22df688468b 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -89,8 +89,8 @@ class InteropClient { const grpc::string& oauth_scope); // username is a string containing the user email bool DoPerRpcCreds(const grpc::string& json_key); - // username is the GCE default service account email - bool DoGoogleDefaultCredentials(const grpc::string& username); + // default_service_account is the GCE default service account email + bool DoGoogleDefaultCredentials(const grpc::string& default_service_account); private: class ServiceStub { From 1d8f7647b00403c826bd1c2fa95bfd3fd6470144 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 29 Jan 2019 10:43:06 -0800 Subject: [PATCH 207/814] Fix broken mac to prod interop --- .../internal_ci/macos/grpc_interop_toprod.sh | 3 +- tools/run_tests/run_interop_tests.py | 32 ++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/tools/internal_ci/macos/grpc_interop_toprod.sh b/tools/internal_ci/macos/grpc_interop_toprod.sh index d1ab54fe01e..daca88c5c51 100755 --- a/tools/internal_ci/macos/grpc_interop_toprod.sh +++ b/tools/internal_ci/macos/grpc_interop_toprod.sh @@ -30,7 +30,8 @@ export GRPC_DEFAULT_SSL_ROOTS_FILE_PATH="$(pwd)/etc/roots.pem" # building all languages in the same working copy can also lead to conflicts # due to different compilation flags tools/run_tests/run_interop_tests.py -l c++ \ - --cloud_to_prod --cloud_to_prod_auth --on_gce=false \ + --cloud_to_prod --cloud_to_prod_auth \ + --google_default_creds_use_key_file=true \ --prod_servers default gateway_v4 \ --service_account_key_file="${KOKORO_GFILE_DIR}/GrpcTesting-726eb1347f15.json" \ --skip_compute_engine_creds --internal_ci -t -j 4 || FAILED="true" diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 782393be1aa..603977545ce 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -723,7 +723,10 @@ def compute_engine_creds_required(language, test_case): return False -def auth_options(language, test_case, on_gce, service_account_key_file=None): +def auth_options(language, + test_case, + google_default_creds_use_key_file, + service_account_key_file=None): """Returns (cmdline, env) tuple with cloud_to_prod_auth test options.""" language = str(language) @@ -757,7 +760,7 @@ def auth_options(language, test_case, on_gce, service_account_key_file=None): cmdargs += [oauth_scope_arg, default_account_arg] if test_case == _GOOGLE_DEFAULT_CREDS_TEST_CASE: - if not on_gce: + if google_default_creds_use_key_file: env['GOOGLE_APPLICATION_CREDENTIALS'] = service_account_key_file cmdargs += [default_account_arg] @@ -778,7 +781,7 @@ def cloud_to_prod_jobspec(language, test_case, server_host_nickname, server_host, - on_gce, + google_default_creds_use_key_file, docker_image=None, auth=False, manual_cmd_log=None, @@ -804,7 +807,8 @@ def cloud_to_prod_jobspec(language, cmdargs = cmdargs + transport_security_options environ = dict(language.cloud_to_prod_env(), **language.global_env()) if auth: - auth_cmdargs, auth_env = auth_options(language, test_case, on_gce, + auth_cmdargs, auth_env = auth_options(language, test_case, + google_default_creds_use_key_file, service_account_key_file) cmdargs += auth_cmdargs environ.update(auth_env) @@ -1083,11 +1087,13 @@ argp.add_argument( const=True, help='Run cloud_to_prod_auth tests.') argp.add_argument( - '--on_gce', - default=True, + '--google_default_creds_use_key_file', + default=False, action='store_const', const=True, - help='Whether or not this test script is running on GCE.') + help=('Whether or not we should use a key file for the ' + 'google_default_credentials test case, e.g. by ' + 'setting env var GOOGLE_APPLICATION_CREDENTIALS.')) argp.add_argument( '--prod_servers', choices=prod_servers.keys(), @@ -1343,7 +1349,8 @@ try: test_case, server_host_nickname, prod_servers[server_host_nickname], - on_gce=args.on_gce, + google_default_creds_use_key_file=args. + google_default_creds_use_key_file, docker_image=docker_images.get(str(language)), manual_cmd_log=client_manual_cmd_log, service_account_key_file=args. @@ -1358,7 +1365,8 @@ try: test_case, server_host_nickname, prod_servers[server_host_nickname], - on_gce=args.on_gce, + google_default_creds_use_key_file=args. + google_default_creds_use_key_file, docker_image=docker_images.get( str(language)), manual_cmd_log=client_manual_cmd_log, @@ -1375,7 +1383,8 @@ try: test_case, server_host_nickname, prod_servers[server_host_nickname], - on_gce=args.on_gce, + google_default_creds_use_key_file=args. + google_default_creds_use_key_file, docker_image=docker_images.get(str(http2Interop)), manual_cmd_log=client_manual_cmd_log, service_account_key_file=args.service_account_key_file, @@ -1402,7 +1411,8 @@ try: test_case, server_host_nickname, prod_servers[server_host_nickname], - on_gce=args.on_gce, + google_default_creds_use_key_file=args. + google_default_creds_use_key_file, docker_image=docker_images.get(str(language)), auth=True, manual_cmd_log=client_manual_cmd_log, From b9804c30feb7b8e24b63e0e62de7568163bc6143 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 29 Jan 2019 11:04:37 -0800 Subject: [PATCH 208/814] Only log data at TCP level if flag is DEBUG --- src/core/lib/iomgr/tcp_posix.cc | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index e0b999ecea9..792ffd27385 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -408,13 +408,15 @@ static void call_read_cb(grpc_tcp* tcp, grpc_error* error) { gpr_log(GPR_INFO, "TCP:%p call_cb %p %p:%p", tcp, cb, cb->cb, cb->cb_arg); size_t i; const char* str = grpc_error_string(error); - gpr_log(GPR_INFO, "read: error=%s", str); + gpr_log(GPR_INFO, "READ %p (peer=%s) error=%s", tcp, tcp->peer_string, str); - for (i = 0; i < tcp->incoming_buffer->count; i++) { - char* dump = grpc_dump_slice(tcp->incoming_buffer->slices[i], - GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_INFO, "READ %p (peer=%s): %s", tcp, tcp->peer_string, dump); - gpr_free(dump); + if (gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { + for (i = 0; i < tcp->incoming_buffer->count; i++) { + char* dump = grpc_dump_slice(tcp->incoming_buffer->slices[i], + GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "DATA: %s", dump); + gpr_free(dump); + } } } @@ -976,10 +978,13 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, size_t i; for (i = 0; i < buf->count; i++) { - char* data = - grpc_dump_slice(buf->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_INFO, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data); - gpr_free(data); + gpr_log(GPR_INFO, "WRITE %p (peer=%s)", tcp, tcp->peer_string); + if (gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { + char* data = + grpc_dump_slice(buf->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "DATA: %s", data); + gpr_free(data); + } } } From bf0d1d6bfc934d61af93d6a4d9458dd41e6522ec Mon Sep 17 00:00:00 2001 From: = Date: Tue, 29 Jan 2019 11:34:36 -0800 Subject: [PATCH 209/814] Remove previous BindService implementation --- src/compiler/csharp_generator.cc | 39 +---------- src/csharp/Grpc.Core/ServiceBinderBase.cs | 64 ------------------- src/csharp/Grpc.Examples/MathGrpc.cs | 12 ---- src/csharp/Grpc.HealthCheck/HealthGrpc.cs | 10 --- .../BenchmarkServiceGrpc.cs | 13 ---- .../EmptyServiceGrpc.cs | 8 --- .../Grpc.IntegrationTesting/MetricsGrpc.cs | 10 --- .../ReportQpsScenarioServiceGrpc.cs | 9 --- .../Grpc.IntegrationTesting/TestGrpc.cs | 35 ---------- .../WorkerServiceGrpc.cs | 12 ---- src/csharp/Grpc.Reflection/ReflectionGrpc.cs | 9 --- 11 files changed, 1 insertion(+), 220 deletions(-) diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index c1eaf971483..14ee535d071 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -609,43 +609,7 @@ void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor* service) { out->Print("\n"); } -void GenerateBindServiceWithBinderMethod(Printer* out, - const ServiceDescriptor* service) { - out->Print( - "/// Register service method implementations with a service " - "binder. Useful when customizing the service binding logic.\n" - "/// Note: this method is part of an experimental API that can change or " - "be " - "removed without any prior notice.\n"); - out->Print( - "/// Service methods will be bound by " - "calling AddMethod on this object." - "\n"); - out->Print( - "/// An object implementing the server-side" - " handling logic.\n"); - out->Print( - "public static void BindService(grpc::ServiceBinderBase serviceBinder, " - "$implclass$ " - "serviceImpl)\n", - "implclass", GetServerClassName(service)); - out->Print("{\n"); - out->Indent(); - - for (int i = 0; i < service->method_count(); i++) { - const MethodDescriptor* method = service->method(i); - out->Print( - "serviceBinder.AddMethod($methodfield$, serviceImpl.$methodname$);\n", - "methodfield", GetMethodFieldName(method), "methodname", - method->name()); - } - - out->Outdent(); - out->Print("}\n"); - out->Print("\n"); -} - -void GenerateBindServiceWithBinderMethodWithoutImplementation( +void GenerateBindServiceWithBinderMethod( Printer* out, const ServiceDescriptor* service) { out->Print( "/// Register service method with a service " @@ -704,7 +668,6 @@ void GenerateService(Printer* out, const ServiceDescriptor* service, if (generate_server) { GenerateBindServiceMethod(out, service); GenerateBindServiceWithBinderMethod(out, service); - GenerateBindServiceWithBinderMethodWithoutImplementation(out, service); } out->Outdent(); diff --git a/src/csharp/Grpc.Core/ServiceBinderBase.cs b/src/csharp/Grpc.Core/ServiceBinderBase.cs index 79267d8f3d1..318892cc5fb 100644 --- a/src/csharp/Grpc.Core/ServiceBinderBase.cs +++ b/src/csharp/Grpc.Core/ServiceBinderBase.cs @@ -34,70 +34,6 @@ namespace Grpc.Core /// public class ServiceBinderBase { - /// - /// Adds a definition for a single request - single response method. - /// - /// The request message class. - /// The response message class. - /// The method. - /// The method handler. - public virtual void AddMethod( - Method method, - UnaryServerMethod handler) - where TRequest : class - where TResponse : class - { - throw new NotImplementedException(); - } - - /// - /// Adds a definition for a client streaming method. - /// - /// The request message class. - /// The response message class. - /// The method. - /// The method handler. - public virtual void AddMethod( - Method method, - ClientStreamingServerMethod handler) - where TRequest : class - where TResponse : class - { - throw new NotImplementedException(); - } - - /// - /// Adds a definition for a server streaming method. - /// - /// The request message class. - /// The response message class. - /// The method. - /// The method handler. - public virtual void AddMethod( - Method method, - ServerStreamingServerMethod handler) - where TRequest : class - where TResponse : class - { - throw new NotImplementedException(); - } - - /// - /// Adds a definition for a bidirectional streaming method. - /// - /// The request message class. - /// The response message class. - /// The method. - /// The method handler. - public virtual void AddMethod( - Method method, - DuplexStreamingServerMethod handler) - where TRequest : class - where TResponse : class - { - throw new NotImplementedException(); - } - /// /// Adds a method without a handler. /// diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs index 717f3fab5ea..85436ddc232 100644 --- a/src/csharp/Grpc.Examples/MathGrpc.cs +++ b/src/csharp/Grpc.Examples/MathGrpc.cs @@ -287,18 +287,6 @@ namespace Math { .AddMethod(__Method_Sum, serviceImpl.Sum).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. - /// Note: this method is part of an experimental API that can change or be removed without any prior notice. - /// Service methods will be bound by calling AddMethod on this object. - /// An object implementing the server-side handling logic. - public static void BindService(grpc::ServiceBinderBase serviceBinder, MathBase serviceImpl) - { - serviceBinder.AddMethod(__Method_Div, serviceImpl.Div); - serviceBinder.AddMethod(__Method_DivMany, serviceImpl.DivMany); - serviceBinder.AddMethod(__Method_Fib, serviceImpl.Fib); - serviceBinder.AddMethod(__Method_Sum, serviceImpl.Sum); - } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs index f7002328acd..5492600da9b 100644 --- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs +++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs @@ -233,16 +233,6 @@ namespace Grpc.Health.V1 { .AddMethod(__Method_Watch, serviceImpl.Watch).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. - /// Note: this method is part of an experimental API that can change or be removed without any prior notice. - /// Service methods will be bound by calling AddMethod on this object. - /// An object implementing the server-side handling logic. - public static void BindService(grpc::ServiceBinderBase serviceBinder, HealthBase serviceImpl) - { - serviceBinder.AddMethod(__Method_Check, serviceImpl.Check); - serviceBinder.AddMethod(__Method_Watch, serviceImpl.Watch); - } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs index 39a48f2bb38..fcd0e3f89b3 100644 --- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs @@ -324,19 +324,6 @@ namespace Grpc.Testing { .AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. - /// Note: this method is part of an experimental API that can change or be removed without any prior notice. - /// Service methods will be bound by calling AddMethod on this object. - /// An object implementing the server-side handling logic. - public static void BindService(grpc::ServiceBinderBase serviceBinder, BenchmarkServiceBase serviceImpl) - { - serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall); - serviceBinder.AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall); - serviceBinder.AddMethod(__Method_StreamingFromClient, serviceImpl.StreamingFromClient); - serviceBinder.AddMethod(__Method_StreamingFromServer, serviceImpl.StreamingFromServer); - serviceBinder.AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays); - } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. diff --git a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs index 965d08d8a36..ba74c3a6016 100644 --- a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs @@ -80,14 +80,6 @@ namespace Grpc.Testing { return grpc::ServerServiceDefinition.CreateBuilder().Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. - /// Note: this method is part of an experimental API that can change or be removed without any prior notice. - /// Service methods will be bound by calling AddMethod on this object. - /// An object implementing the server-side handling logic. - public static void BindService(grpc::ServiceBinderBase serviceBinder, EmptyServiceBase serviceImpl) - { - } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs index 64db5b3ad08..bc6ddf21f70 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs @@ -193,16 +193,6 @@ namespace Grpc.Testing { .AddMethod(__Method_GetGauge, serviceImpl.GetGauge).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. - /// Note: this method is part of an experimental API that can change or be removed without any prior notice. - /// Service methods will be bound by calling AddMethod on this object. - /// An object implementing the server-side handling logic. - public static void BindService(grpc::ServiceBinderBase serviceBinder, MetricsServiceBase serviceImpl) - { - serviceBinder.AddMethod(__Method_GetAllGauges, serviceImpl.GetAllGauges); - serviceBinder.AddMethod(__Method_GetGauge, serviceImpl.GetGauge); - } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs index 81787892c32..096eb7e1d4b 100644 --- a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs @@ -143,15 +143,6 @@ namespace Grpc.Testing { .AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. - /// Note: this method is part of an experimental API that can change or be removed without any prior notice. - /// Service methods will be bound by calling AddMethod on this object. - /// An object implementing the server-side handling logic. - public static void BindService(grpc::ServiceBinderBase serviceBinder, ReportQpsScenarioServiceBase serviceImpl) - { - serviceBinder.AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario); - } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs index 049cb65d7de..c8760583177 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs @@ -539,22 +539,6 @@ namespace Grpc.Testing { .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. - /// Note: this method is part of an experimental API that can change or be removed without any prior notice. - /// Service methods will be bound by calling AddMethod on this object. - /// An object implementing the server-side handling logic. - public static void BindService(grpc::ServiceBinderBase serviceBinder, TestServiceBase serviceImpl) - { - serviceBinder.AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall); - serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall); - serviceBinder.AddMethod(__Method_CacheableUnaryCall, serviceImpl.CacheableUnaryCall); - serviceBinder.AddMethod(__Method_StreamingOutputCall, serviceImpl.StreamingOutputCall); - serviceBinder.AddMethod(__Method_StreamingInputCall, serviceImpl.StreamingInputCall); - serviceBinder.AddMethod(__Method_FullDuplexCall, serviceImpl.FullDuplexCall); - serviceBinder.AddMethod(__Method_HalfDuplexCall, serviceImpl.HalfDuplexCall); - serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall); - } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. @@ -692,15 +676,6 @@ namespace Grpc.Testing { .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. - /// Note: this method is part of an experimental API that can change or be removed without any prior notice. - /// Service methods will be bound by calling AddMethod on this object. - /// An object implementing the server-side handling logic. - public static void BindService(grpc::ServiceBinderBase serviceBinder, UnimplementedServiceBase serviceImpl) - { - serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall); - } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. @@ -827,16 +802,6 @@ namespace Grpc.Testing { .AddMethod(__Method_Stop, serviceImpl.Stop).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. - /// Note: this method is part of an experimental API that can change or be removed without any prior notice. - /// Service methods will be bound by calling AddMethod on this object. - /// An object implementing the server-side handling logic. - public static void BindService(grpc::ServiceBinderBase serviceBinder, ReconnectServiceBase serviceImpl) - { - serviceBinder.AddMethod(__Method_Start, serviceImpl.Start); - serviceBinder.AddMethod(__Method_Stop, serviceImpl.Stop); - } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs index b58d71a784d..7b2a9e8d481 100644 --- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs @@ -321,18 +321,6 @@ namespace Grpc.Testing { .AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. - /// Note: this method is part of an experimental API that can change or be removed without any prior notice. - /// Service methods will be bound by calling AddMethod on this object. - /// An object implementing the server-side handling logic. - public static void BindService(grpc::ServiceBinderBase serviceBinder, WorkerServiceBase serviceImpl) - { - serviceBinder.AddMethod(__Method_RunServer, serviceImpl.RunServer); - serviceBinder.AddMethod(__Method_RunClient, serviceImpl.RunClient); - serviceBinder.AddMethod(__Method_CoreCount, serviceImpl.CoreCount); - serviceBinder.AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker); - } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs index 51ef8ace5cc..6c391361bc5 100644 --- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs +++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs @@ -123,15 +123,6 @@ namespace Grpc.Reflection.V1Alpha { .AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo).Build(); } - /// Register service method implementations with a service binder. Useful when customizing the service binding logic. - /// Note: this method is part of an experimental API that can change or be removed without any prior notice. - /// Service methods will be bound by calling AddMethod on this object. - /// An object implementing the server-side handling logic. - public static void BindService(grpc::ServiceBinderBase serviceBinder, ServerReflectionBase serviceImpl) - { - serviceBinder.AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo); - } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. From 25dc2ffed69f62823bc1f8a19a22971cf53ab357 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 29 Jan 2019 11:21:51 -0800 Subject: [PATCH 210/814] C++-ify subchannel --- .../filters/client_channel/client_channel.cc | 114 +- .../filters/client_channel/client_channel.h | 4 +- .../client_channel/client_channel_channelz.cc | 11 +- .../client_channel/client_channel_channelz.h | 9 +- .../client_channel/client_channel_factory.cc | 2 +- .../client_channel/client_channel_factory.h | 6 +- .../client_channel/global_subchannel_pool.cc | 19 +- .../client_channel/global_subchannel_pool.h | 6 +- .../health/health_check_client.cc | 18 +- .../health/health_check_client.h | 2 +- .../lb_policy/pick_first/pick_first.cc | 2 +- .../lb_policy/round_robin/round_robin.cc | 2 +- .../lb_policy/subchannel_list.h | 37 +- .../client_channel/local_subchannel_pool.cc | 14 +- .../client_channel/local_subchannel_pool.h | 6 +- .../ext/filters/client_channel/subchannel.cc | 1506 ++++++++--------- .../ext/filters/client_channel/subchannel.h | 331 ++-- .../subchannel_pool_interface.h | 10 +- .../chttp2/client/chttp2_connector.cc | 3 +- .../chttp2/client/insecure/channel_create.cc | 4 +- .../client/secure/secure_channel_create.cc | 7 +- test/core/util/debugger_macros.cc | 5 +- test/cpp/microbenchmarks/bm_call_create.cc | 4 +- 23 files changed, 1060 insertions(+), 1062 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 35c3efab6aa..38525dbf97e 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -394,7 +394,7 @@ struct subchannel_batch_data { gpr_refcount refs; grpc_call_element* elem; - grpc_subchannel_call* subchannel_call; // Holds a ref. + grpc_core::RefCountedPtr subchannel_call; // The batch to use in the subchannel call. // Its payload field points to subchannel_call_retry_state.batch_payload. grpc_transport_stream_op_batch batch; @@ -478,7 +478,7 @@ struct pending_batch { bool send_ops_cached; }; -/** Call data. Holds a pointer to grpc_subchannel_call and the +/** Call data. Holds a pointer to SubchannelCall and the associated machinery to create such a pointer. Handles queueing of stream ops until a call object is ready, waiting for initial metadata before trying to create a call object, @@ -504,10 +504,6 @@ struct call_data { last_attempt_got_server_pushback(false) {} ~call_data() { - if (GPR_LIKELY(subchannel_call != nullptr)) { - GRPC_SUBCHANNEL_CALL_UNREF(subchannel_call, - "client_channel_destroy_call"); - } grpc_slice_unref_internal(path); GRPC_ERROR_UNREF(cancel_error); for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches); ++i) { @@ -536,7 +532,7 @@ struct call_data { grpc_core::RefCountedPtr retry_throttle_data; grpc_core::RefCountedPtr method_params; - grpc_subchannel_call* subchannel_call = nullptr; + grpc_core::RefCountedPtr subchannel_call; // Set when we get a cancel_stream op. grpc_error* cancel_error = GRPC_ERROR_NONE; @@ -807,8 +803,8 @@ static void pending_batches_add(grpc_call_element* elem, calld->subchannel_call == nullptr ? nullptr : static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); + + calld->subchannel_call->GetParentData()); retry_commit(elem, retry_state); // If we are not going to retry and have not yet started, pretend // retries are disabled so that we don't bother with retry overhead. @@ -896,10 +892,10 @@ static void resume_pending_batch_in_call_combiner(void* arg, grpc_error* ignored) { grpc_transport_stream_op_batch* batch = static_cast(arg); - grpc_subchannel_call* subchannel_call = - static_cast(batch->handler_private.extra_arg); + grpc_core::SubchannelCall* subchannel_call = + static_cast(batch->handler_private.extra_arg); // Note: This will release the call combiner. - grpc_subchannel_call_process_op(subchannel_call, batch); + subchannel_call->StartTransportStreamOpBatch(batch); } // This is called via the call combiner, so access to calld is synchronized. @@ -919,7 +915,7 @@ static void pending_batches_resume(grpc_call_element* elem) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting %" PRIuPTR " pending batches on subchannel_call=%p", - chand, calld, num_batches, calld->subchannel_call); + chand, calld, num_batches, calld->subchannel_call.get()); } grpc_core::CallCombinerClosureList closures; for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { @@ -930,7 +926,7 @@ static void pending_batches_resume(grpc_call_element* elem) { maybe_inject_recv_trailing_metadata_ready_for_lb( *calld->request->pick(), batch); } - batch->handler_private.extra_arg = calld->subchannel_call; + batch->handler_private.extra_arg = calld->subchannel_call.get(); GRPC_CLOSURE_INIT(&batch->handler_private.closure, resume_pending_batch_in_call_combiner, batch, grpc_schedule_on_exec_ctx); @@ -1019,12 +1015,7 @@ static void do_retry(grpc_call_element* elem, const ClientChannelMethodParams::RetryPolicy* retry_policy = calld->method_params->retry_policy(); GPR_ASSERT(retry_policy != nullptr); - // Reset subchannel call and connected subchannel. - if (calld->subchannel_call != nullptr) { - GRPC_SUBCHANNEL_CALL_UNREF(calld->subchannel_call, - "client_channel_call_retry"); - calld->subchannel_call = nullptr; - } + calld->subchannel_call.reset(); if (calld->have_request) { calld->have_request = false; calld->request.Destroy(); @@ -1078,8 +1069,7 @@ static bool maybe_retry(grpc_call_element* elem, subchannel_call_retry_state* retry_state = nullptr; if (batch_data != nullptr) { retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); if (retry_state->retry_dispatched) { if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: retry already dispatched", chand, @@ -1180,13 +1170,10 @@ namespace { subchannel_batch_data::subchannel_batch_data(grpc_call_element* elem, call_data* calld, int refcount, bool set_on_complete) - : elem(elem), - subchannel_call(GRPC_SUBCHANNEL_CALL_REF(calld->subchannel_call, - "batch_data_create")) { + : elem(elem), subchannel_call(calld->subchannel_call) { subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); + calld->subchannel_call->GetParentData()); batch.payload = &retry_state->batch_payload; gpr_ref_init(&refs, refcount); if (set_on_complete) { @@ -1200,7 +1187,7 @@ subchannel_batch_data::subchannel_batch_data(grpc_call_element* elem, void subchannel_batch_data::destroy() { subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data(subchannel_call)); + subchannel_call->GetParentData()); if (batch.send_initial_metadata) { grpc_metadata_batch_destroy(&retry_state->send_initial_metadata); } @@ -1213,7 +1200,7 @@ void subchannel_batch_data::destroy() { if (batch.recv_trailing_metadata) { grpc_metadata_batch_destroy(&retry_state->recv_trailing_metadata); } - GRPC_SUBCHANNEL_CALL_UNREF(subchannel_call, "batch_data_unref"); + subchannel_call.reset(); call_data* calld = static_cast(elem->call_data); GRPC_CALL_STACK_UNREF(calld->owning_call, "batch_data"); } @@ -1260,8 +1247,7 @@ static void invoke_recv_initial_metadata_callback(void* arg, // Return metadata. subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); grpc_metadata_batch_move( &retry_state->recv_initial_metadata, pending->batch->payload->recv_initial_metadata.recv_initial_metadata); @@ -1293,8 +1279,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); retry_state->completed_recv_initial_metadata = true; // If a retry was already dispatched, then we're not going to use the // result of this recv_initial_metadata op, so do nothing. @@ -1355,8 +1340,7 @@ static void invoke_recv_message_callback(void* arg, grpc_error* error) { // Return payload. subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); *pending->batch->payload->recv_message.recv_message = std::move(retry_state->recv_message); // Update bookkeeping. @@ -1384,8 +1368,7 @@ static void recv_message_ready(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); ++retry_state->completed_recv_message_count; // If a retry was already dispatched, then we're not going to use the // result of this recv_message op, so do nothing. @@ -1473,8 +1456,7 @@ static void add_closure_for_recv_trailing_metadata_ready( // Return metadata. subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); grpc_metadata_batch_move( &retry_state->recv_trailing_metadata, pending->batch->payload->recv_trailing_metadata.recv_trailing_metadata); @@ -1576,8 +1558,7 @@ static void run_closures_for_completed_call(subchannel_batch_data* batch_data, call_data* calld = static_cast(elem->call_data); subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); // Construct list of closures to execute. grpc_core::CallCombinerClosureList closures; // First, add closure for recv_trailing_metadata_ready. @@ -1611,8 +1592,7 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); retry_state->completed_recv_trailing_metadata = true; // Get the call's status and check for server pushback metadata. grpc_status_code status = GRPC_STATUS_OK; @@ -1735,8 +1715,7 @@ static void on_complete(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); // Update bookkeeping in retry_state. if (batch_data->batch.send_initial_metadata) { retry_state->completed_send_initial_metadata = true; @@ -1792,10 +1771,10 @@ static void on_complete(void* arg, grpc_error* error) { static void start_batch_in_call_combiner(void* arg, grpc_error* ignored) { grpc_transport_stream_op_batch* batch = static_cast(arg); - grpc_subchannel_call* subchannel_call = - static_cast(batch->handler_private.extra_arg); + grpc_core::SubchannelCall* subchannel_call = + static_cast(batch->handler_private.extra_arg); // Note: This will release the call combiner. - grpc_subchannel_call_process_op(subchannel_call, batch); + subchannel_call->StartTransportStreamOpBatch(batch); } // Adds a closure to closures that will execute batch in the call combiner. @@ -1804,7 +1783,7 @@ static void add_closure_for_subchannel_batch( grpc_core::CallCombinerClosureList* closures) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - batch->handler_private.extra_arg = calld->subchannel_call; + batch->handler_private.extra_arg = calld->subchannel_call.get(); GRPC_CLOSURE_INIT(&batch->handler_private.closure, start_batch_in_call_combiner, batch, grpc_schedule_on_exec_ctx); @@ -1978,8 +1957,7 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); + calld->subchannel_call->GetParentData()); // Create batch_data with 2 refs, since this batch will be unreffed twice: // once for the recv_trailing_metadata_ready callback when the subchannel // batch returns, and again when we actually get a recv_trailing_metadata @@ -1989,7 +1967,7 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem) { add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data); retry_state->recv_trailing_metadata_internal_batch = batch_data; // Note: This will release the call combiner. - grpc_subchannel_call_process_op(calld->subchannel_call, &batch_data->batch); + calld->subchannel_call->StartTransportStreamOpBatch(&batch_data->batch); } // If there are any cached send ops that need to be replayed on the @@ -2196,8 +2174,7 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); + calld->subchannel_call->GetParentData()); // Construct list of closures to execute, one for each pending batch. grpc_core::CallCombinerClosureList closures; // Replay previously-returned send_* ops if needed. @@ -2220,7 +2197,7 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting %" PRIuPTR " retriable batches on subchannel_call=%p", - chand, calld, closures.size(), calld->subchannel_call); + chand, calld, closures.size(), calld->subchannel_call.get()); } // Note: This will yield the call combiner. closures.RunClosures(calld->call_combiner); @@ -2245,22 +2222,22 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { calld->call_combiner, // call_combiner parent_data_size // parent_data_size }; - grpc_error* new_error = - calld->request->pick()->connected_subchannel->CreateCall( - call_args, &calld->subchannel_call); + grpc_error* new_error = GRPC_ERROR_NONE; + calld->subchannel_call = + calld->request->pick()->connected_subchannel->CreateCall(call_args, + &new_error); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", - chand, calld, calld->subchannel_call, grpc_error_string(new_error)); + chand, calld, calld->subchannel_call.get(), + grpc_error_string(new_error)); } if (GPR_UNLIKELY(new_error != GRPC_ERROR_NONE)) { new_error = grpc_error_add_child(new_error, error); pending_batches_fail(elem, new_error, true /* yield_call_combiner */); } else { if (parent_data_size > 0) { - new (grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)) - subchannel_call_retry_state( - calld->request->pick()->subchannel_call_context); + new (calld->subchannel_call->GetParentData()) subchannel_call_retry_state( + calld->request->pick()->subchannel_call_context); } pending_batches_resume(elem); } @@ -2488,7 +2465,7 @@ static void cc_start_transport_stream_op_batch( batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner); } else { // Note: This will release the call combiner. - grpc_subchannel_call_process_op(calld->subchannel_call, batch); + calld->subchannel_call->StartTransportStreamOpBatch(batch); } return; } @@ -2502,7 +2479,7 @@ static void cc_start_transport_stream_op_batch( if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting batch on subchannel_call=%p", chand, - calld, calld->subchannel_call); + calld, calld->subchannel_call.get()); } pending_batches_resume(elem); return; @@ -2545,8 +2522,7 @@ static void cc_destroy_call_elem(grpc_call_element* elem, grpc_closure* then_schedule_closure) { call_data* calld = static_cast(elem->call_data); if (GPR_LIKELY(calld->subchannel_call != nullptr)) { - grpc_subchannel_call_set_cleanup_closure(calld->subchannel_call, - then_schedule_closure); + calld->subchannel_call->SetAfterCallStackDestroy(then_schedule_closure); then_schedule_closure = nullptr; } calld->~call_data(); @@ -2752,8 +2728,8 @@ void grpc_client_channel_watch_connectivity_state( GRPC_ERROR_NONE); } -grpc_subchannel_call* grpc_client_channel_get_subchannel_call( - grpc_call_element* elem) { +grpc_core::RefCountedPtr +grpc_client_channel_get_subchannel_call(grpc_call_element* elem) { call_data* calld = static_cast(elem->call_data); return calld->subchannel_call; } diff --git a/src/core/ext/filters/client_channel/client_channel.h b/src/core/ext/filters/client_channel/client_channel.h index 4935fd24d87..5bfff4df9cd 100644 --- a/src/core/ext/filters/client_channel/client_channel.h +++ b/src/core/ext/filters/client_channel/client_channel.h @@ -60,7 +60,7 @@ void grpc_client_channel_watch_connectivity_state( grpc_closure* watcher_timer_init); /* Debug helper: pull the subchannel call from a call stack element */ -grpc_subchannel_call* grpc_client_channel_get_subchannel_call( - grpc_call_element* elem); +grpc_core::RefCountedPtr +grpc_client_channel_get_subchannel_call(grpc_call_element* elem); #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H */ diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 8e5426081c4..76c5a786240 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -113,12 +113,11 @@ RefCountedPtr ClientChannelNode::MakeClientChannelNode( is_top_level_channel); } -SubchannelNode::SubchannelNode(grpc_subchannel* subchannel, +SubchannelNode::SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes) : BaseNode(EntityType::kSubchannel), subchannel_(subchannel), - target_( - UniquePtr(gpr_strdup(grpc_subchannel_get_target(subchannel_)))), + target_(UniquePtr(gpr_strdup(subchannel_->GetTargetAddress()))), trace_(channel_tracer_max_nodes) {} SubchannelNode::~SubchannelNode() {} @@ -128,8 +127,8 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) { if (subchannel_ == nullptr) { state = GRPC_CHANNEL_SHUTDOWN; } else { - state = grpc_subchannel_check_connectivity( - subchannel_, nullptr, true /* inhibit_health_checking */); + state = subchannel_->CheckConnectivity(nullptr, + true /* inhibit_health_checking */); } json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); @@ -170,7 +169,7 @@ grpc_json* SubchannelNode::RenderJson() { call_counter_.PopulateCallCounts(json); json = top_level_json; // populate the child socket. - intptr_t socket_uuid = grpc_subchannel_get_child_socket_uuid(subchannel_); + intptr_t socket_uuid = subchannel_->GetChildSocketUuid(); if (socket_uuid != 0) { grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 8a5c3e7e5e5..1dc1bf595be 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -26,9 +26,10 @@ #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" -typedef struct grpc_subchannel grpc_subchannel; - namespace grpc_core { + +class Subchannel; + namespace channelz { // Subtype of ChannelNode that overrides and provides client_channel specific @@ -59,7 +60,7 @@ class ClientChannelNode : public ChannelNode { // Handles channelz bookkeeping for sockets class SubchannelNode : public BaseNode { public: - SubchannelNode(grpc_subchannel* subchannel, size_t channel_tracer_max_nodes); + SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes); ~SubchannelNode() override; void MarkSubchannelDestroyed() { @@ -84,7 +85,7 @@ class SubchannelNode : public BaseNode { void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } private: - grpc_subchannel* subchannel_; + Subchannel* subchannel_; UniquePtr target_; CallCountingHelper call_counter_; ChannelTrace trace_; diff --git a/src/core/ext/filters/client_channel/client_channel_factory.cc b/src/core/ext/filters/client_channel/client_channel_factory.cc index 130bbe04180..8c558382fdf 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.cc +++ b/src/core/ext/filters/client_channel/client_channel_factory.cc @@ -29,7 +29,7 @@ void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory) { factory->vtable->unref(factory); } -grpc_subchannel* grpc_client_channel_factory_create_subchannel( +grpc_core::Subchannel* grpc_client_channel_factory_create_subchannel( grpc_client_channel_factory* factory, const grpc_channel_args* args) { return factory->vtable->create_subchannel(factory, args); } diff --git a/src/core/ext/filters/client_channel/client_channel_factory.h b/src/core/ext/filters/client_channel/client_channel_factory.h index 91dec12282f..4b72aa46499 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -48,8 +48,8 @@ struct grpc_client_channel_factory { struct grpc_client_channel_factory_vtable { void (*ref)(grpc_client_channel_factory* factory); void (*unref)(grpc_client_channel_factory* factory); - grpc_subchannel* (*create_subchannel)(grpc_client_channel_factory* factory, - const grpc_channel_args* args); + grpc_core::Subchannel* (*create_subchannel)( + grpc_client_channel_factory* factory, const grpc_channel_args* args); grpc_channel* (*create_client_channel)(grpc_client_channel_factory* factory, const char* target, grpc_client_channel_type type, @@ -60,7 +60,7 @@ void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory); void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory); /** Create a new grpc_subchannel */ -grpc_subchannel* grpc_client_channel_factory_create_subchannel( +grpc_core::Subchannel* grpc_client_channel_factory_create_subchannel( grpc_client_channel_factory* factory, const grpc_channel_args* args); /** Create a new grpc_channel */ diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.cc b/src/core/ext/filters/client_channel/global_subchannel_pool.cc index a41d993fe66..ee6e58159a0 100644 --- a/src/core/ext/filters/client_channel/global_subchannel_pool.cc +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.cc @@ -54,9 +54,9 @@ RefCountedPtr GlobalSubchannelPool::instance() { return *instance_; } -grpc_subchannel* GlobalSubchannelPool::RegisterSubchannel( - SubchannelKey* key, grpc_subchannel* constructed) { - grpc_subchannel* c = nullptr; +Subchannel* GlobalSubchannelPool::RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) { + Subchannel* c = nullptr; // Compare and swap (CAS) loop: while (c == nullptr) { // Ref the shared map to have a local copy. @@ -64,7 +64,7 @@ grpc_subchannel* GlobalSubchannelPool::RegisterSubchannel( grpc_avl old_map = grpc_avl_ref(subchannel_map_, nullptr); gpr_mu_unlock(&mu_); // Check to see if a subchannel already exists. - c = static_cast(grpc_avl_get(old_map, key, nullptr)); + c = static_cast(grpc_avl_get(old_map, key, nullptr)); if (c != nullptr) { // The subchannel already exists. Reuse it. c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "subchannel_register+reuse"); @@ -121,15 +121,14 @@ void GlobalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { } } -grpc_subchannel* GlobalSubchannelPool::FindSubchannel(SubchannelKey* key) { +Subchannel* GlobalSubchannelPool::FindSubchannel(SubchannelKey* key) { // Lock, and take a reference to the subchannel map. // We don't need to do the search under a lock as AVL's are immutable. gpr_mu_lock(&mu_); grpc_avl index = grpc_avl_ref(subchannel_map_, nullptr); gpr_mu_unlock(&mu_); - grpc_subchannel* c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF( - static_cast(grpc_avl_get(index, key, nullptr)), - "found_from_pool"); + Subchannel* c = static_cast(grpc_avl_get(index, key, nullptr)); + if (c != nullptr) GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "found_from_pool"); grpc_avl_unref(index, nullptr); return c; } @@ -156,11 +155,11 @@ long sck_avl_compare(void* a, void* b, void* unused) { } void scv_avl_destroy(void* p, void* user_data) { - GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "global_subchannel_pool"); + GRPC_SUBCHANNEL_WEAK_UNREF((Subchannel*)p, "global_subchannel_pool"); } void* scv_avl_copy(void* p, void* unused) { - GRPC_SUBCHANNEL_WEAK_REF((grpc_subchannel*)p, "global_subchannel_pool"); + GRPC_SUBCHANNEL_WEAK_REF((Subchannel*)p, "global_subchannel_pool"); return p; } diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.h b/src/core/ext/filters/client_channel/global_subchannel_pool.h index 0deb3769360..96dc8d7b3a4 100644 --- a/src/core/ext/filters/client_channel/global_subchannel_pool.h +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.h @@ -45,10 +45,10 @@ class GlobalSubchannelPool final : public SubchannelPoolInterface { static RefCountedPtr instance(); // Implements interface methods. - grpc_subchannel* RegisterSubchannel(SubchannelKey* key, - grpc_subchannel* constructed) override; + Subchannel* RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) override; void UnregisterSubchannel(SubchannelKey* key) override; - grpc_subchannel* FindSubchannel(SubchannelKey* key) override; + Subchannel* FindSubchannel(SubchannelKey* key) override; private: // The singleton instance. (It's a pointer to RefCountedPtr so that this diff --git a/src/core/ext/filters/client_channel/health/health_check_client.cc b/src/core/ext/filters/client_channel/health/health_check_client.cc index 2232c57120e..e845d63d295 100644 --- a/src/core/ext/filters/client_channel/health/health_check_client.cc +++ b/src/core/ext/filters/client_channel/health/health_check_client.cc @@ -295,7 +295,9 @@ HealthCheckClient::CallState::~CallState() { gpr_log(GPR_INFO, "HealthCheckClient %p: destroying CallState %p", health_check_client_.get(), this); } - if (call_ != nullptr) GRPC_SUBCHANNEL_CALL_UNREF(call_, "call_ended"); + // The subchannel call is in the arena, so reset the pointer before we destroy + // the arena. + call_.reset(); for (size_t i = 0; i < GRPC_CONTEXT_COUNT; i++) { if (context_[i].destroy != nullptr) { context_[i].destroy(context_[i].value); @@ -329,8 +331,8 @@ void HealthCheckClient::CallState::StartCall() { &call_combiner_, 0, // parent_data_size }; - grpc_error* error = - health_check_client_->connected_subchannel_->CreateCall(args, &call_); + grpc_error* error = GRPC_ERROR_NONE; + call_ = health_check_client_->connected_subchannel_->CreateCall(args, &error); if (error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "HealthCheckClient %p CallState %p: error creating health " @@ -423,14 +425,14 @@ void HealthCheckClient::CallState::StartBatchInCallCombiner(void* arg, grpc_error* error) { grpc_transport_stream_op_batch* batch = static_cast(arg); - grpc_subchannel_call* call = - static_cast(batch->handler_private.extra_arg); - grpc_subchannel_call_process_op(call, batch); + SubchannelCall* call = + static_cast(batch->handler_private.extra_arg); + call->StartTransportStreamOpBatch(batch); } void HealthCheckClient::CallState::StartBatch( grpc_transport_stream_op_batch* batch) { - batch->handler_private.extra_arg = call_; + batch->handler_private.extra_arg = call_.get(); GRPC_CLOSURE_INIT(&batch->handler_private.closure, StartBatchInCallCombiner, batch, grpc_schedule_on_exec_ctx); GRPC_CALL_COMBINER_START(&call_combiner_, &batch->handler_private.closure, @@ -452,7 +454,7 @@ void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) { GRPC_CLOSURE_CREATE(OnCancelComplete, self, grpc_schedule_on_exec_ctx)); batch->cancel_stream = true; batch->payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED; - grpc_subchannel_call_process_op(self->call_, batch); + self->call_->StartTransportStreamOpBatch(batch); } void HealthCheckClient::CallState::Cancel() { diff --git a/src/core/ext/filters/client_channel/health/health_check_client.h b/src/core/ext/filters/client_channel/health/health_check_client.h index 2369b73feac..7af88a54cfc 100644 --- a/src/core/ext/filters/client_channel/health/health_check_client.h +++ b/src/core/ext/filters/client_channel/health/health_check_client.h @@ -99,7 +99,7 @@ class HealthCheckClient : public InternallyRefCounted { grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {}; // The streaming call to the backend. Always non-NULL. - grpc_subchannel_call* call_; + RefCountedPtr call_; grpc_transport_stream_op_batch_payload payload_; grpc_transport_stream_op_batch batch_; diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index ec5c782c469..dc716a6adac 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -79,7 +79,7 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const ServerAddress& address, Subchannel* subchannel, grpc_combiner* combiner) : SubchannelData(subchannel_list, address, subchannel, combiner) {} diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 30316689ea7..aab6dd68216 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -94,7 +94,7 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const ServerAddress& address, Subchannel* subchannel, grpc_combiner* combiner) : SubchannelData(subchannel_list, address, subchannel, combiner) {} diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 2eb92b7ead0..0174a98a73d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -88,7 +88,7 @@ class SubchannelData { } // Returns a pointer to the subchannel. - grpc_subchannel* subchannel() const { return subchannel_; } + Subchannel* subchannel() const { return subchannel_; } // Returns the connected subchannel. Will be null if the subchannel // is not connected. @@ -103,8 +103,8 @@ class SubchannelData { // ProcessConnectivityChangeLocked()). grpc_connectivity_state CheckConnectivityStateLocked(grpc_error** error) { GPR_ASSERT(!connectivity_notification_pending_); - pending_connectivity_state_unsafe_ = grpc_subchannel_check_connectivity( - subchannel(), error, subchannel_list_->inhibit_health_checking()); + pending_connectivity_state_unsafe_ = subchannel()->CheckConnectivity( + error, subchannel_list_->inhibit_health_checking()); UpdateConnectedSubchannelLocked(); return pending_connectivity_state_unsafe_; } @@ -142,7 +142,7 @@ class SubchannelData { protected: SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const ServerAddress& address, Subchannel* subchannel, grpc_combiner* combiner); virtual ~SubchannelData(); @@ -170,7 +170,7 @@ class SubchannelData { SubchannelList* subchannel_list_; // The subchannel and connected subchannel. - grpc_subchannel* subchannel_; + Subchannel* subchannel_; RefCountedPtr connected_subchannel_; // Notification that connectivity has changed on subchannel. @@ -203,7 +203,7 @@ class SubchannelList : public InternallyRefCounted { for (size_t i = 0; i < subchannels_.size(); ++i) { if (subchannels_[i].subchannel() != nullptr) { grpc_core::channelz::SubchannelNode* subchannel_node = - grpc_subchannel_get_channelz_node(subchannels_[i].subchannel()); + subchannels_[i].subchannel()->channelz_node(); if (subchannel_node != nullptr) { refs_list->push_back(subchannel_node->uuid()); } @@ -276,7 +276,7 @@ class SubchannelList : public InternallyRefCounted { template SubchannelData::SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const ServerAddress& address, Subchannel* subchannel, grpc_combiner* combiner) : subchannel_list_(subchannel_list), subchannel_(subchannel), @@ -317,7 +317,7 @@ template void SubchannelData::ResetBackoffLocked() { if (subchannel_ != nullptr) { - grpc_subchannel_reset_backoff(subchannel_); + subchannel_->ResetBackoff(); } } @@ -337,8 +337,8 @@ void SubchannelDataRef(DEBUG_LOCATION, "connectivity_watch").release(); - grpc_subchannel_notify_on_state_change( - subchannel_, subchannel_list_->policy()->interested_parties(), + subchannel_->NotifyOnStateChange( + subchannel_list_->policy()->interested_parties(), &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, subchannel_list_->inhibit_health_checking()); } @@ -357,8 +357,8 @@ void SubchannelDatapolicy()->interested_parties(), + subchannel_->NotifyOnStateChange( + subchannel_list_->policy()->interested_parties(), &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, subchannel_list_->inhibit_health_checking()); } @@ -391,9 +391,9 @@ void SubchannelData:: subchannel_, reason); } GPR_ASSERT(connectivity_notification_pending_); - grpc_subchannel_notify_on_state_change( - subchannel_, nullptr, nullptr, &connectivity_changed_closure_, - subchannel_list_->inhibit_health_checking()); + subchannel_->NotifyOnStateChange(nullptr, nullptr, + &connectivity_changed_closure_, + subchannel_list_->inhibit_health_checking()); } template @@ -401,8 +401,7 @@ bool SubchannelData::UpdateConnectedSubchannelLocked() { // If the subchannel is READY, take a ref to the connected subchannel. if (pending_connectivity_state_unsafe_ == GRPC_CHANNEL_READY) { - connected_subchannel_ = - grpc_subchannel_get_connected_subchannel(subchannel_); + connected_subchannel_ = subchannel_->connected_subchannel(); // If the subchannel became disconnected between the time that READY // was reported and the time we got here (e.g., between when a // notification callback is scheduled and when it was actually run in @@ -518,7 +517,7 @@ SubchannelList::SubchannelList( SubchannelPoolInterface::CreateChannelArg(policy_->subchannel_pool())); const size_t subchannel_address_arg_index = args_to_add.size(); args_to_add.emplace_back( - grpc_create_subchannel_address_arg(&addresses[i].address())); + Subchannel::CreateSubchannelAddressArg(&addresses[i].address())); if (addresses[i].args() != nullptr) { for (size_t j = 0; j < addresses[i].args()->num_args; ++j) { args_to_add.emplace_back(addresses[i].args()->args[j]); @@ -528,7 +527,7 @@ SubchannelList::SubchannelList( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); gpr_free(args_to_add[subchannel_address_arg_index].value.string); - grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( + Subchannel* subchannel = grpc_client_channel_factory_create_subchannel( client_channel_factory, new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) { diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.cc b/src/core/ext/filters/client_channel/local_subchannel_pool.cc index 145fa4e0374..d1c1cacb441 100644 --- a/src/core/ext/filters/client_channel/local_subchannel_pool.cc +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.cc @@ -32,11 +32,11 @@ LocalSubchannelPool::~LocalSubchannelPool() { grpc_avl_unref(subchannel_map_, nullptr); } -grpc_subchannel* LocalSubchannelPool::RegisterSubchannel( - SubchannelKey* key, grpc_subchannel* constructed) { +Subchannel* LocalSubchannelPool::RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) { // Check to see if a subchannel already exists. - grpc_subchannel* c = static_cast( - grpc_avl_get(subchannel_map_, key, nullptr)); + Subchannel* c = + static_cast(grpc_avl_get(subchannel_map_, key, nullptr)); if (c != nullptr) { // The subchannel already exists. Reuse it. c = GRPC_SUBCHANNEL_REF(c, "subchannel_register+reuse"); @@ -54,9 +54,9 @@ void LocalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { subchannel_map_ = grpc_avl_remove(subchannel_map_, key, nullptr); } -grpc_subchannel* LocalSubchannelPool::FindSubchannel(SubchannelKey* key) { - grpc_subchannel* c = static_cast( - grpc_avl_get(subchannel_map_, key, nullptr)); +Subchannel* LocalSubchannelPool::FindSubchannel(SubchannelKey* key) { + Subchannel* c = + static_cast(grpc_avl_get(subchannel_map_, key, nullptr)); return c == nullptr ? c : GRPC_SUBCHANNEL_REF(c, "found_from_pool"); } diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.h b/src/core/ext/filters/client_channel/local_subchannel_pool.h index 9929cdb3627..a6b7e259fbb 100644 --- a/src/core/ext/filters/client_channel/local_subchannel_pool.h +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.h @@ -39,10 +39,10 @@ class LocalSubchannelPool final : public SubchannelPoolInterface { // Implements interface methods. // Thread-unsafe. Intended to be invoked within the client_channel combiner. - grpc_subchannel* RegisterSubchannel(SubchannelKey* key, - grpc_subchannel* constructed) override; + Subchannel* RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) override; void UnregisterSubchannel(SubchannelKey* key) override; - grpc_subchannel* FindSubchannel(SubchannelKey* key) override; + Subchannel* FindSubchannel(SubchannelKey* key) override; private: // The vtable for subchannel operations in an AVL tree. diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index d77bb3c286b..70285659aad 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -44,7 +44,6 @@ #include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr_utils.h" -#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/channel.h" @@ -55,153 +54,256 @@ #include "src/core/lib/transport/status_metadata.h" #include "src/core/lib/uri/uri_parser.h" +// Strong and weak refs. #define INTERNAL_REF_BITS 16 #define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1)) +// Backoff parameters. #define GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS 1 #define GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER 1.6 #define GRPC_SUBCHANNEL_RECONNECT_MIN_TIMEOUT_SECONDS 20 #define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120 #define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2 -typedef struct external_state_watcher { - grpc_subchannel* subchannel; - grpc_pollset_set* pollset_set; - grpc_closure* notify; - grpc_closure closure; - struct external_state_watcher* next; - struct external_state_watcher* prev; -} external_state_watcher; +// Conversion between subchannel call and call stack. +#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ + (grpc_call_stack*)((char*)(call) + \ + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall))) +#define CALL_STACK_TO_SUBCHANNEL_CALL(callstack) \ + (SubchannelCall*)(((char*)(call_stack)) - \ + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall))) namespace grpc_core { -class ConnectedSubchannelStateWatcher; +// +// ConnectedSubchannel +// -} // namespace grpc_core +ConnectedSubchannel::ConnectedSubchannel( + grpc_channel_stack* channel_stack, const grpc_channel_args* args, + RefCountedPtr channelz_subchannel, + intptr_t socket_uuid) + : RefCounted(&grpc_trace_stream_refcount), + channel_stack_(channel_stack), + args_(grpc_channel_args_copy(args)), + channelz_subchannel_(std::move(channelz_subchannel)), + socket_uuid_(socket_uuid) {} -struct grpc_subchannel { - /** The subchannel pool this subchannel is in */ - grpc_core::RefCountedPtr subchannel_pool; - - grpc_connector* connector; - - /** refcount - - lower INTERNAL_REF_BITS bits are for internal references: - these do not keep the subchannel open. - - upper remaining bits are for public references: these do - keep the subchannel open */ - gpr_atm ref_pair; - - /** channel arguments */ - grpc_channel_args* args; - - grpc_core::SubchannelKey* key; - - /** set during connection */ - grpc_connect_out_args connecting_result; - - /** callback for connection finishing */ - grpc_closure on_connected; - - /** callback for our alarm */ - grpc_closure on_alarm; - - /** pollset_set tracking who's interested in a connection - being setup */ - grpc_pollset_set* pollset_set; - - grpc_core::UniquePtr health_check_service_name; - - /** mutex protecting remaining elements */ - gpr_mu mu; - - /** active connection, or null */ - grpc_core::RefCountedPtr connected_subchannel; - grpc_core::OrphanablePtr - connected_subchannel_watcher; - - /** have we seen a disconnection? */ - bool disconnected; - /** are we connecting */ - bool connecting; - - /** connectivity state tracking */ - grpc_connectivity_state_tracker state_tracker; - grpc_connectivity_state_tracker state_and_health_tracker; - - external_state_watcher root_external_state_watcher; - - /** backoff state */ - grpc_core::ManualConstructor backoff; - grpc_millis next_attempt_deadline; - grpc_millis min_connect_timeout_ms; - - /** do we have an active alarm? */ - bool have_alarm; - /** have we started the backoff loop */ - bool backoff_begun; - // reset_backoff() was called while alarm was pending - bool retry_immediately; - /** our alarm */ - grpc_timer alarm; - - grpc_core::RefCountedPtr - channelz_subchannel; -}; - -struct grpc_subchannel_call { - grpc_subchannel_call(grpc_core::ConnectedSubchannel* connection, - const grpc_core::ConnectedSubchannel::CallArgs& args) - : connection(connection), deadline(args.deadline) {} - - grpc_core::ConnectedSubchannel* connection; - grpc_closure* schedule_closure_after_destroy = nullptr; - // state needed to support channelz interception of recv trailing metadata. - grpc_closure recv_trailing_metadata_ready; - grpc_closure* original_recv_trailing_metadata; - grpc_metadata_batch* recv_trailing_metadata = nullptr; - grpc_millis deadline; -}; - -static void maybe_start_connecting_locked(grpc_subchannel* c); - -static const char* subchannel_connectivity_state_change_string( - grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "Subchannel state change to IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "Subchannel state change to CONNECTING"; - case GRPC_CHANNEL_READY: - return "Subchannel state change to READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "Subchannel state change to TRANSIENT_FAILURE"; - case GRPC_CHANNEL_SHUTDOWN: - return "Subchannel state change to SHUTDOWN"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); +ConnectedSubchannel::~ConnectedSubchannel() { + grpc_channel_args_destroy(args_); + GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); } -static void set_subchannel_connectivity_state_locked( - grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error, - const char* reason) { - if (c->channelz_subchannel != nullptr) { - c->channelz_subchannel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - subchannel_connectivity_state_change_string(state))); - } - grpc_connectivity_state_set(&c->state_tracker, state, error, reason); +void ConnectedSubchannel::NotifyOnStateChange( + grpc_pollset_set* interested_parties, grpc_connectivity_state* state, + grpc_closure* closure) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + grpc_channel_element* elem; + op->connectivity_state = state; + op->on_connectivity_state_change = closure; + op->bind_pollset_set = interested_parties; + elem = grpc_channel_stack_element(channel_stack_, 0); + elem->filter->start_transport_op(elem, op); } -namespace grpc_core { +void ConnectedSubchannel::Ping(grpc_closure* on_initiate, + grpc_closure* on_ack) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + grpc_channel_element* elem; + op->send_ping.on_initiate = on_initiate; + op->send_ping.on_ack = on_ack; + elem = grpc_channel_stack_element(channel_stack_, 0); + elem->filter->start_transport_op(elem, op); +} -class ConnectedSubchannelStateWatcher +namespace { + +void SubchannelCallDestroy(void* arg, grpc_error* error) { + GPR_TIMER_SCOPE("subchannel_call_destroy", 0); + SubchannelCall* call = static_cast(arg); + grpc_closure* after_call_stack_destroy = call->after_call_stack_destroy(); + call->~SubchannelCall(); + // This should be the last step to destroy the subchannel call, because + // call->after_call_stack_destroy(), if not null, will free the call arena. + grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(call), nullptr, + after_call_stack_destroy); +} + +} // namespace + +RefCountedPtr ConnectedSubchannel::CreateCall( + const CallArgs& args, grpc_error** error) { + const size_t allocation_size = + GetInitialCallSizeEstimate(args.parent_data_size); + RefCountedPtr call( + new (gpr_arena_alloc(args.arena, allocation_size)) + SubchannelCall(Ref(DEBUG_LOCATION, "subchannel_call"), args)); + grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call.get()); + const grpc_call_element_args call_args = { + callstk, /* call_stack */ + nullptr, /* server_transport_data */ + args.context, /* context */ + args.path, /* path */ + args.start_time, /* start_time */ + args.deadline, /* deadline */ + args.arena, /* arena */ + args.call_combiner /* call_combiner */ + }; + *error = grpc_call_stack_init(channel_stack_, 1, SubchannelCallDestroy, + call.get(), &call_args); + if (GPR_UNLIKELY(*error != GRPC_ERROR_NONE)) { + const char* error_string = grpc_error_string(*error); + gpr_log(GPR_ERROR, "error: %s", error_string); + return call; + } + grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); + if (channelz_subchannel_ != nullptr) { + channelz_subchannel_->RecordCallStarted(); + } + return call; +} + +size_t ConnectedSubchannel::GetInitialCallSizeEstimate( + size_t parent_data_size) const { + size_t allocation_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)); + if (parent_data_size > 0) { + allocation_size += + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + + parent_data_size; + } else { + allocation_size += channel_stack_->call_stack_size; + } + return allocation_size; +} + +// +// SubchannelCall +// + +void SubchannelCall::StartTransportStreamOpBatch( + grpc_transport_stream_op_batch* batch) { + GPR_TIMER_SCOPE("subchannel_call_process_op", 0); + MaybeInterceptRecvTrailingMetadata(batch); + grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(this); + grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0); + GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch); + top_elem->filter->start_transport_stream_op_batch(top_elem, batch); +} + +void* SubchannelCall::GetParentData() { + grpc_channel_stack* chanstk = connected_subchannel_->channel_stack(); + return (char*)this + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)) + + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(chanstk->call_stack_size); +} + +grpc_call_stack* SubchannelCall::GetCallStack() { + return SUBCHANNEL_CALL_TO_CALL_STACK(this); +} + +void SubchannelCall::SetAfterCallStackDestroy(grpc_closure* closure) { + GPR_ASSERT(after_call_stack_destroy_ == nullptr); + GPR_ASSERT(closure != nullptr); + after_call_stack_destroy_ = closure; +} + +RefCountedPtr SubchannelCall::Ref() { + IncrementRefCount(); + return RefCountedPtr(this); +} + +RefCountedPtr SubchannelCall::Ref( + const grpc_core::DebugLocation& location, const char* reason) { + IncrementRefCount(location, reason); + return RefCountedPtr(this); +} + +void SubchannelCall::Unref() { + GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), ""); +} + +void SubchannelCall::Unref(const DebugLocation& location, const char* reason) { + GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason); +} + +void SubchannelCall::MaybeInterceptRecvTrailingMetadata( + grpc_transport_stream_op_batch* batch) { + // only intercept payloads with recv trailing. + if (!batch->recv_trailing_metadata) { + return; + } + // only add interceptor is channelz is enabled. + if (connected_subchannel_->channelz_subchannel() == nullptr) { + return; + } + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, RecvTrailingMetadataReady, + this, grpc_schedule_on_exec_ctx); + // save some state needed for the interception callback. + GPR_ASSERT(recv_trailing_metadata_ == nullptr); + recv_trailing_metadata_ = + batch->payload->recv_trailing_metadata.recv_trailing_metadata; + original_recv_trailing_metadata_ = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &recv_trailing_metadata_ready_; +} + +namespace { + +// Sets *status based on the rest of the parameters. +void GetCallStatus(grpc_status_code* status, grpc_millis deadline, + grpc_metadata_batch* md_batch, grpc_error* error) { + if (error != GRPC_ERROR_NONE) { + grpc_error_get_status(error, deadline, status, nullptr, nullptr, nullptr); + } else { + if (md_batch->idx.named.grpc_status != nullptr) { + *status = grpc_get_status_code_from_metadata( + md_batch->idx.named.grpc_status->md); + } else { + *status = GRPC_STATUS_UNKNOWN; + } + } + GRPC_ERROR_UNREF(error); +} + +} // namespace + +void SubchannelCall::RecvTrailingMetadataReady(void* arg, grpc_error* error) { + SubchannelCall* call = static_cast(arg); + GPR_ASSERT(call->recv_trailing_metadata_ != nullptr); + grpc_status_code status = GRPC_STATUS_OK; + GetCallStatus(&status, call->deadline_, call->recv_trailing_metadata_, + GRPC_ERROR_REF(error)); + channelz::SubchannelNode* channelz_subchannel = + call->connected_subchannel_->channelz_subchannel(); + GPR_ASSERT(channelz_subchannel != nullptr); + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); + } + GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata_, + GRPC_ERROR_REF(error)); +} + +void SubchannelCall::IncrementRefCount() { + GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), ""); +} + +void SubchannelCall::IncrementRefCount(const grpc_core::DebugLocation& location, + const char* reason) { + GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason); +} + +// +// Subchannel::ConnectedSubchannelStateWatcher +// + +class Subchannel::ConnectedSubchannelStateWatcher : public InternallyRefCounted { public: // Must be instantiated while holding c->mu. - explicit ConnectedSubchannelStateWatcher(grpc_subchannel* c) - : subchannel_(c) { + explicit ConnectedSubchannelStateWatcher(Subchannel* c) : subchannel_(c) { // Steal subchannel ref for connecting. GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "state_watcher"); GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "connecting"); @@ -209,15 +311,15 @@ class ConnectedSubchannelStateWatcher // Callback uses initial ref to this. GRPC_CLOSURE_INIT(&on_connectivity_changed_, OnConnectivityChanged, this, grpc_schedule_on_exec_ctx); - c->connected_subchannel->NotifyOnStateChange(c->pollset_set, - &pending_connectivity_state_, - &on_connectivity_changed_); + c->connected_subchannel_->NotifyOnStateChange(c->pollset_set_, + &pending_connectivity_state_, + &on_connectivity_changed_); // Start health check if needed. grpc_connectivity_state health_state = GRPC_CHANNEL_READY; - if (c->health_check_service_name != nullptr) { - health_check_client_ = grpc_core::MakeOrphanable( - c->health_check_service_name.get(), c->connected_subchannel, - c->pollset_set, c->channelz_subchannel); + if (c->health_check_service_name_ != nullptr) { + health_check_client_ = MakeOrphanable( + c->health_check_service_name_.get(), c->connected_subchannel_, + c->pollset_set_, c->channelz_node_); GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this, grpc_schedule_on_exec_ctx); Ref().release(); // Ref for health callback tracked manually. @@ -226,9 +328,9 @@ class ConnectedSubchannelStateWatcher health_state = GRPC_CHANNEL_CONNECTING; } // Report initial state. - set_subchannel_connectivity_state_locked( - c, GRPC_CHANNEL_READY, GRPC_ERROR_NONE, "subchannel_connected"); - grpc_connectivity_state_set(&c->state_and_health_tracker, health_state, + c->SetConnectivityStateLocked(GRPC_CHANNEL_READY, GRPC_ERROR_NONE, + "subchannel_connected"); + grpc_connectivity_state_set(&c->state_and_health_tracker_, health_state, GRPC_ERROR_NONE, "subchannel_connected"); } @@ -242,33 +344,33 @@ class ConnectedSubchannelStateWatcher private: static void OnConnectivityChanged(void* arg, grpc_error* error) { auto* self = static_cast(arg); - grpc_subchannel* c = self->subchannel_; + Subchannel* c = self->subchannel_; { - MutexLock lock(&c->mu); + MutexLock lock(&c->mu_); switch (self->pending_connectivity_state_) { case GRPC_CHANNEL_TRANSIENT_FAILURE: case GRPC_CHANNEL_SHUTDOWN: { - if (!c->disconnected && c->connected_subchannel != nullptr) { + if (!c->disconnected_ && c->connected_subchannel_ != nullptr) { if (grpc_trace_stream_refcount.enabled()) { gpr_log(GPR_INFO, "Connected subchannel %p of subchannel %p has gone into " "%s. Attempting to reconnect.", - c->connected_subchannel.get(), c, + c->connected_subchannel_.get(), c, grpc_connectivity_state_name( self->pending_connectivity_state_)); } - c->connected_subchannel.reset(); - c->connected_subchannel_watcher.reset(); + c->connected_subchannel_.reset(); + c->connected_subchannel_watcher_.reset(); self->last_connectivity_state_ = GRPC_CHANNEL_TRANSIENT_FAILURE; - set_subchannel_connectivity_state_locked( - c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - "reflect_child"); - grpc_connectivity_state_set(&c->state_and_health_tracker, + c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_REF(error), + "reflect_child"); + grpc_connectivity_state_set(&c->state_and_health_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), "reflect_child"); - c->backoff_begun = false; - c->backoff->Reset(); - maybe_start_connecting_locked(c); + c->backoff_begun_ = false; + c->backoff_.Reset(); + c->MaybeStartConnectingLocked(); } else { self->last_connectivity_state_ = GRPC_CHANNEL_SHUTDOWN; } @@ -281,15 +383,14 @@ class ConnectedSubchannelStateWatcher // this watch from. And a connected subchannel should never go // from READY to CONNECTING or IDLE. self->last_connectivity_state_ = self->pending_connectivity_state_; - set_subchannel_connectivity_state_locked( - c, self->pending_connectivity_state_, GRPC_ERROR_REF(error), - "reflect_child"); + c->SetConnectivityStateLocked(self->pending_connectivity_state_, + GRPC_ERROR_REF(error), "reflect_child"); if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) { - grpc_connectivity_state_set(&c->state_and_health_tracker, + grpc_connectivity_state_set(&c->state_and_health_tracker_, self->pending_connectivity_state_, GRPC_ERROR_REF(error), "reflect_child"); } - c->connected_subchannel->NotifyOnStateChange( + c->connected_subchannel_->NotifyOnStateChange( nullptr, &self->pending_connectivity_state_, &self->on_connectivity_changed_); self = nullptr; // So we don't unref below. @@ -303,14 +404,14 @@ class ConnectedSubchannelStateWatcher static void OnHealthChanged(void* arg, grpc_error* error) { auto* self = static_cast(arg); - grpc_subchannel* c = self->subchannel_; - MutexLock lock(&c->mu); + Subchannel* c = self->subchannel_; + MutexLock lock(&c->mu_); if (self->health_state_ == GRPC_CHANNEL_SHUTDOWN) { self->Unref(); return; } if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) { - grpc_connectivity_state_set(&c->state_and_health_tracker, + grpc_connectivity_state_set(&c->state_and_health_tracker_, self->health_state_, GRPC_ERROR_REF(error), "health_changed"); } @@ -318,163 +419,63 @@ class ConnectedSubchannelStateWatcher &self->on_health_changed_); } - grpc_subchannel* subchannel_; + Subchannel* subchannel_; grpc_closure on_connectivity_changed_; grpc_connectivity_state pending_connectivity_state_ = GRPC_CHANNEL_READY; grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_READY; - grpc_core::OrphanablePtr health_check_client_; + OrphanablePtr health_check_client_; grpc_closure on_health_changed_; grpc_connectivity_state health_state_ = GRPC_CHANNEL_CONNECTING; }; -} // namespace grpc_core +// +// Subchannel::ExternalStateWatcher +// -#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ - (grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ - sizeof(grpc_subchannel_call))) -#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \ - (grpc_subchannel_call*)(((char*)(call_stack)) - \ - GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ - sizeof(grpc_subchannel_call))) - -static void on_subchannel_connected(void* subchannel, grpc_error* error); - -#ifndef NDEBUG -#define REF_REASON reason -#define REF_MUTATE_EXTRA_ARGS \ - GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char* purpose -#define REF_MUTATE_PURPOSE(x) , file, line, reason, x -#else -#define REF_REASON "" -#define REF_MUTATE_EXTRA_ARGS -#define REF_MUTATE_PURPOSE(x) -#endif - -/* - * connection implementation - */ - -static void connection_destroy(void* arg, grpc_error* error) { - grpc_channel_stack* stk = static_cast(arg); - grpc_channel_stack_destroy(stk); - gpr_free(stk); -} - -/* - * grpc_subchannel implementation - */ - -static void subchannel_destroy(void* arg, grpc_error* error) { - grpc_subchannel* c = static_cast(arg); - if (c->channelz_subchannel != nullptr) { - c->channelz_subchannel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string("Subchannel destroyed")); - c->channelz_subchannel->MarkSubchannelDestroyed(); - c->channelz_subchannel.reset(); +struct Subchannel::ExternalStateWatcher { + ExternalStateWatcher(Subchannel* subchannel, grpc_pollset_set* pollset_set, + grpc_closure* notify) + : subchannel(subchannel), pollset_set(pollset_set), notify(notify) { + GRPC_SUBCHANNEL_WEAK_REF(subchannel, "external_state_watcher+init"); + GRPC_CLOSURE_INIT(&on_state_changed, OnStateChanged, this, + grpc_schedule_on_exec_ctx); } - c->health_check_service_name.reset(); - grpc_channel_args_destroy(c->args); - grpc_connectivity_state_destroy(&c->state_tracker); - grpc_connectivity_state_destroy(&c->state_and_health_tracker); - grpc_connector_unref(c->connector); - grpc_pollset_set_destroy(c->pollset_set); - grpc_core::Delete(c->key); - gpr_mu_destroy(&c->mu); - gpr_free(c); -} -static gpr_atm ref_mutate(grpc_subchannel* c, gpr_atm delta, - int barrier REF_MUTATE_EXTRA_ARGS) { - gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta) - : gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta); -#ifndef NDEBUG - if (grpc_trace_stream_refcount.enabled()) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", c, - purpose, old_val, old_val + delta, reason); - } -#endif - return old_val; -} - -grpc_subchannel* grpc_subchannel_ref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, (1 << INTERNAL_REF_BITS), - 0 REF_MUTATE_PURPOSE("STRONG_REF")); - GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0); - return c; -} - -grpc_subchannel* grpc_subchannel_weak_ref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, 1, 0 REF_MUTATE_PURPOSE("WEAK_REF")); - GPR_ASSERT(old_refs != 0); - return c; -} - -grpc_subchannel* grpc_subchannel_ref_from_weak_ref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - if (!c) return nullptr; - for (;;) { - gpr_atm old_refs = gpr_atm_acq_load(&c->ref_pair); - if (old_refs >= (1 << INTERNAL_REF_BITS)) { - gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS); - if (gpr_atm_rel_cas(&c->ref_pair, old_refs, new_refs)) { - return c; - } - } else { - return nullptr; + static void OnStateChanged(void* arg, grpc_error* error) { + ExternalStateWatcher* w = static_cast(arg); + grpc_closure* follow_up = w->notify; + if (w->pollset_set != nullptr) { + grpc_pollset_set_del_pollset_set(w->subchannel->pollset_set_, + w->pollset_set); } + gpr_mu_lock(&w->subchannel->mu_); + if (w->subchannel->external_state_watcher_list_ == w) { + w->subchannel->external_state_watcher_list_ = w->next; + } + if (w->next != nullptr) w->next->prev = w->prev; + if (w->prev != nullptr) w->prev->next = w->next; + gpr_mu_unlock(&w->subchannel->mu_); + GRPC_SUBCHANNEL_WEAK_UNREF(w->subchannel, "external_state_watcher+done"); + Delete(w); + GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error)); } -} -static void disconnect(grpc_subchannel* c) { - // The subchannel_pool is only used once here in this subchannel, so the - // access can be outside of the lock. - if (c->subchannel_pool != nullptr) { - c->subchannel_pool->UnregisterSubchannel(c->key); - c->subchannel_pool.reset(); - } - gpr_mu_lock(&c->mu); - GPR_ASSERT(!c->disconnected); - c->disconnected = true; - grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Subchannel disconnected")); - c->connected_subchannel.reset(); - c->connected_subchannel_watcher.reset(); - gpr_mu_unlock(&c->mu); -} + Subchannel* subchannel; + grpc_pollset_set* pollset_set; + grpc_closure* notify; + grpc_closure on_state_changed; + ExternalStateWatcher* next = nullptr; + ExternalStateWatcher* prev = nullptr; +}; -void grpc_subchannel_unref(grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - // add a weak ref and subtract a strong ref (atomically) - old_refs = ref_mutate( - c, static_cast(1) - static_cast(1 << INTERNAL_REF_BITS), - 1 REF_MUTATE_PURPOSE("STRONG_UNREF")); - if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) { - disconnect(c); - } - GRPC_SUBCHANNEL_WEAK_UNREF(c, "strong-unref"); -} +// +// Subchannel +// -void grpc_subchannel_weak_unref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, -static_cast(1), - 1 REF_MUTATE_PURPOSE("WEAK_UNREF")); - if (old_refs == 1) { - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(subchannel_destroy, c, grpc_schedule_on_exec_ctx), - GRPC_ERROR_NONE); - } -} +namespace { -static void parse_args_for_backoff_values( - const grpc_channel_args* args, grpc_core::BackOff::Options* backoff_options, - grpc_millis* min_connect_timeout_ms) { +BackOff::Options ParseArgsForBackoffValues( + const grpc_channel_args* args, grpc_millis* min_connect_timeout_ms) { grpc_millis initial_backoff_ms = GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000; *min_connect_timeout_ms = @@ -511,7 +512,8 @@ static void parse_args_for_backoff_values( } } } - backoff_options->set_initial_backoff(initial_backoff_ms) + return BackOff::Options() + .set_initial_backoff(initial_backoff_ms) .set_multiplier(fixed_reconnect_backoff ? 1.0 : GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER) @@ -520,9 +522,6 @@ static void parse_args_for_backoff_values( .set_max_backoff(max_backoff_ms); } -namespace grpc_core { -namespace { - struct HealthCheckParams { UniquePtr service_name; @@ -543,31 +542,19 @@ struct HealthCheckParams { }; } // namespace -} // namespace grpc_core -grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, - const grpc_channel_args* args) { - grpc_core::SubchannelKey* key = - grpc_core::New(args); - grpc_core::SubchannelPoolInterface* subchannel_pool = - grpc_core::SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs( - args); - GPR_ASSERT(subchannel_pool != nullptr); - grpc_subchannel* c = subchannel_pool->FindSubchannel(key); - if (c != nullptr) { - grpc_core::Delete(key); - return c; - } +Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, + const grpc_channel_args* args) + : key_(key), + connector_(connector), + backoff_(ParseArgsForBackoffValues(args, &min_connect_timeout_ms_)) { GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED(); - c = static_cast(gpr_zalloc(sizeof(*c))); - c->key = key; - gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS); - c->connector = connector; - grpc_connector_ref(c->connector); - c->pollset_set = grpc_pollset_set_create(); + gpr_atm_no_barrier_store(&ref_pair_, 1 << INTERNAL_REF_BITS); + grpc_connector_ref(connector_); + pollset_set_ = grpc_pollset_set_create(); grpc_resolved_address* addr = static_cast(gpr_malloc(sizeof(*addr))); - grpc_get_subchannel_address_arg(args, addr); + GetAddressFromSubchannelAddressArg(args, addr); grpc_resolved_address* new_address = nullptr; grpc_channel_args* new_args = nullptr; if (grpc_proxy_mappers_map_address(addr, args, &new_address, &new_args)) { @@ -576,291 +563,398 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, addr = new_address; } static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS}; - grpc_arg new_arg = grpc_create_subchannel_address_arg(addr); + grpc_arg new_arg = CreateSubchannelAddressArg(addr); gpr_free(addr); - c->args = grpc_channel_args_copy_and_add_and_remove( + args_ = grpc_channel_args_copy_and_add_and_remove( new_args != nullptr ? new_args : args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1); gpr_free(new_arg.value.string); if (new_args != nullptr) grpc_channel_args_destroy(new_args); - c->root_external_state_watcher.next = c->root_external_state_watcher.prev = - &c->root_external_state_watcher; - GRPC_CLOSURE_INIT(&c->on_connected, on_subchannel_connected, c, + GRPC_CLOSURE_INIT(&on_connecting_finished_, OnConnectingFinished, this, grpc_schedule_on_exec_ctx); - grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE, + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "subchannel"); - grpc_connectivity_state_init(&c->state_and_health_tracker, GRPC_CHANNEL_IDLE, + grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE, "subchannel"); - grpc_core::BackOff::Options backoff_options; - parse_args_for_backoff_values(args, &backoff_options, - &c->min_connect_timeout_ms); - c->backoff.Init(backoff_options); - gpr_mu_init(&c->mu); - + gpr_mu_init(&mu_); // Check whether we should enable health checking. const char* service_config_json = grpc_channel_arg_get_string( - grpc_channel_args_find(c->args, GRPC_ARG_SERVICE_CONFIG)); + grpc_channel_args_find(args_, GRPC_ARG_SERVICE_CONFIG)); if (service_config_json != nullptr) { - grpc_core::UniquePtr service_config = - grpc_core::ServiceConfig::Create(service_config_json); + UniquePtr service_config = + ServiceConfig::Create(service_config_json); if (service_config != nullptr) { - grpc_core::HealthCheckParams params; - service_config->ParseGlobalParams(grpc_core::HealthCheckParams::Parse, - ¶ms); - c->health_check_service_name = std::move(params.service_name); + HealthCheckParams params; + service_config->ParseGlobalParams(HealthCheckParams::Parse, ¶ms); + health_check_service_name_ = std::move(params.service_name); } } - - const grpc_arg* arg = - grpc_channel_args_find(c->args, GRPC_ARG_ENABLE_CHANNELZ); - bool channelz_enabled = + const grpc_arg* arg = grpc_channel_args_find(args_, GRPC_ARG_ENABLE_CHANNELZ); + const bool channelz_enabled = grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT); arg = grpc_channel_args_find( - c->args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); + args_, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); const grpc_integer_options options = { GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX}; size_t channel_tracer_max_memory = (size_t)grpc_channel_arg_get_integer(arg, options); if (channelz_enabled) { - c->channelz_subchannel = - grpc_core::MakeRefCounted( - c, channel_tracer_max_memory); - c->channelz_subchannel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string("Subchannel created")); + channelz_node_ = MakeRefCounted( + this, channel_tracer_max_memory); + channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("subchannel created")); } +} + +Subchannel::~Subchannel() { + if (channelz_node_ != nullptr) { + channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("Subchannel destroyed")); + channelz_node_->MarkSubchannelDestroyed(); + } + grpc_channel_args_destroy(args_); + grpc_connectivity_state_destroy(&state_tracker_); + grpc_connectivity_state_destroy(&state_and_health_tracker_); + grpc_connector_unref(connector_); + grpc_pollset_set_destroy(pollset_set_); + Delete(key_); + gpr_mu_destroy(&mu_); +} + +Subchannel* Subchannel::Create(grpc_connector* connector, + const grpc_channel_args* args) { + SubchannelKey* key = New(args); + SubchannelPoolInterface* subchannel_pool = + SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs(args); + GPR_ASSERT(subchannel_pool != nullptr); + Subchannel* c = subchannel_pool->FindSubchannel(key); + if (c != nullptr) { + Delete(key); + return c; + } + c = New(key, connector, args); // Try to register the subchannel before setting the subchannel pool. // Otherwise, in case of a registration race, unreffing c in - // RegisterSubchannel() will cause c to be tried to be unregistered, while its - // key maps to a different subchannel. - grpc_subchannel* registered = subchannel_pool->RegisterSubchannel(key, c); - if (registered == c) c->subchannel_pool = subchannel_pool->Ref(); + // RegisterSubchannel() will cause c to be tried to be unregistered, while + // its key maps to a different subchannel. + Subchannel* registered = subchannel_pool->RegisterSubchannel(key, c); + if (registered == c) c->subchannel_pool_ = subchannel_pool->Ref(); return registered; } -grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( - grpc_subchannel* subchannel) { - return subchannel->channelz_subchannel.get(); +Subchannel* Subchannel::Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = RefMutate((1 << INTERNAL_REF_BITS), + 0 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("STRONG_REF")); + GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0); + return this; } -intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel) { - if (subchannel->connected_subchannel != nullptr) { - return subchannel->connected_subchannel->socket_uuid(); +void Subchannel::Unref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + // add a weak ref and subtract a strong ref (atomically) + old_refs = RefMutate( + static_cast(1) - static_cast(1 << INTERNAL_REF_BITS), + 1 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("STRONG_UNREF")); + if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) { + Disconnect(); + } + GRPC_SUBCHANNEL_WEAK_UNREF(this, "strong-unref"); +} + +Subchannel* Subchannel::WeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = RefMutate(1, 0 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("WEAK_REF")); + GPR_ASSERT(old_refs != 0); + return this; +} + +namespace { + +void subchannel_destroy(void* arg, grpc_error* error) { + Subchannel* self = static_cast(arg); + Delete(self); +} + +} // namespace + +void Subchannel::WeakUnref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = RefMutate(-static_cast(1), + 1 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("WEAK_UNREF")); + if (old_refs == 1) { + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(subchannel_destroy, this, + grpc_schedule_on_exec_ctx), + GRPC_ERROR_NONE); + } +} + +Subchannel* Subchannel::RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + for (;;) { + gpr_atm old_refs = gpr_atm_acq_load(&ref_pair_); + if (old_refs >= (1 << INTERNAL_REF_BITS)) { + gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS); + if (gpr_atm_rel_cas(&ref_pair_, old_refs, new_refs)) { + return this; + } + } else { + return nullptr; + } + } +} + +intptr_t Subchannel::GetChildSocketUuid() { + if (connected_subchannel_ != nullptr) { + return connected_subchannel_->socket_uuid(); } else { return 0; } } -static void continue_connect_locked(grpc_subchannel* c) { - grpc_connect_in_args args; - args.interested_parties = c->pollset_set; - const grpc_millis min_deadline = - c->min_connect_timeout_ms + grpc_core::ExecCtx::Get()->Now(); - c->next_attempt_deadline = c->backoff->NextAttemptTime(); - args.deadline = std::max(c->next_attempt_deadline, min_deadline); - args.channel_args = c->args; - set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_NONE, "connecting"); - grpc_connectivity_state_set(&c->state_and_health_tracker, - GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, - "connecting"); - grpc_connector_connect(c->connector, &args, &c->connecting_result, - &c->on_connected); +const char* Subchannel::GetTargetAddress() { + const grpc_arg* addr_arg = + grpc_channel_args_find(args_, GRPC_ARG_SUBCHANNEL_ADDRESS); + const char* addr_str = grpc_channel_arg_get_string(addr_arg); + GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. + return addr_str; } -grpc_connectivity_state grpc_subchannel_check_connectivity( - grpc_subchannel* c, grpc_error** error, bool inhibit_health_checks) { - gpr_mu_lock(&c->mu); +RefCountedPtr Subchannel::connected_subchannel() { + MutexLock lock(&mu_); + return connected_subchannel_; +} + +channelz::SubchannelNode* Subchannel::channelz_node() { + return channelz_node_.get(); +} + +grpc_connectivity_state Subchannel::CheckConnectivity( + grpc_error** error, bool inhibit_health_checks) { + MutexLock lock(&mu_); grpc_connectivity_state_tracker* tracker = - inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; + inhibit_health_checks ? &state_tracker_ : &state_and_health_tracker_; grpc_connectivity_state state = grpc_connectivity_state_get(tracker, error); - gpr_mu_unlock(&c->mu); return state; } -static void on_external_state_watcher_done(void* arg, grpc_error* error) { - external_state_watcher* w = static_cast(arg); - grpc_closure* follow_up = w->notify; - if (w->pollset_set != nullptr) { - grpc_pollset_set_del_pollset_set(w->subchannel->pollset_set, - w->pollset_set); +void Subchannel::NotifyOnStateChange(grpc_pollset_set* interested_parties, + grpc_connectivity_state* state, + grpc_closure* notify, + bool inhibit_health_checks) { + grpc_connectivity_state_tracker* tracker = + inhibit_health_checks ? &state_tracker_ : &state_and_health_tracker_; + ExternalStateWatcher* w; + if (state == nullptr) { + MutexLock lock(&mu_); + for (w = external_state_watcher_list_; w != nullptr; w = w->next) { + if (w->notify == notify) { + grpc_connectivity_state_notify_on_state_change(tracker, nullptr, + &w->on_state_changed); + } + } + } else { + w = New(this, interested_parties, notify); + if (interested_parties != nullptr) { + grpc_pollset_set_add_pollset_set(pollset_set_, interested_parties); + } + MutexLock lock(&mu_); + if (external_state_watcher_list_ != nullptr) { + w->next = external_state_watcher_list_; + w->next->prev = w; + } + external_state_watcher_list_ = w; + grpc_connectivity_state_notify_on_state_change(tracker, state, + &w->on_state_changed); + MaybeStartConnectingLocked(); } - gpr_mu_lock(&w->subchannel->mu); - w->next->prev = w->prev; - w->prev->next = w->next; - gpr_mu_unlock(&w->subchannel->mu); - GRPC_SUBCHANNEL_WEAK_UNREF(w->subchannel, "external_state_watcher"); - gpr_free(w); - GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error)); } -static void on_alarm(void* arg, grpc_error* error) { - grpc_subchannel* c = static_cast(arg); - gpr_mu_lock(&c->mu); - c->have_alarm = false; - if (c->disconnected) { +void Subchannel::ResetBackoff() { + MutexLock lock(&mu_); + backoff_.Reset(); + if (have_retry_alarm_) { + retry_immediately_ = true; + grpc_timer_cancel(&retry_alarm_); + } else { + backoff_begun_ = false; + MaybeStartConnectingLocked(); + } +} + +grpc_arg Subchannel::CreateSubchannelAddressArg( + const grpc_resolved_address* addr) { + return grpc_channel_arg_string_create( + (char*)GRPC_ARG_SUBCHANNEL_ADDRESS, + addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("")); +} + +const char* Subchannel::GetUriFromSubchannelAddressArg( + const grpc_channel_args* args) { + const grpc_arg* addr_arg = + grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS); + const char* addr_str = grpc_channel_arg_get_string(addr_arg); + GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. + return addr_str; +} + +namespace { + +void UriToSockaddr(const char* uri_str, grpc_resolved_address* addr) { + grpc_uri* uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */); + GPR_ASSERT(uri != nullptr); + if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr)); + grpc_uri_destroy(uri); +} + +} // namespace + +void Subchannel::GetAddressFromSubchannelAddressArg( + const grpc_channel_args* args, grpc_resolved_address* addr) { + const char* addr_uri_str = GetUriFromSubchannelAddressArg(args); + memset(addr, 0, sizeof(*addr)); + if (*addr_uri_str != '\0') { + UriToSockaddr(addr_uri_str, addr); + } +} + +namespace { + +// Returns a string indicating the subchannel's connectivity state change to +// \a state. +const char* SubchannelConnectivityStateChangeString( + grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "Subchannel state change to IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "Subchannel state change to CONNECTING"; + case GRPC_CHANNEL_READY: + return "Subchannel state change to READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "Subchannel state change to TRANSIENT_FAILURE"; + case GRPC_CHANNEL_SHUTDOWN: + return "Subchannel state change to SHUTDOWN"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +} // namespace + +void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state, + grpc_error* error, + const char* reason) { + if (channelz_node_ != nullptr) { + channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + SubchannelConnectivityStateChangeString(state))); + } + grpc_connectivity_state_set(&state_tracker_, state, error, reason); +} + +void Subchannel::MaybeStartConnectingLocked() { + if (disconnected_) { + // Don't try to connect if we're already disconnected. + return; + } + if (connecting_) { + // Already connecting: don't restart. + return; + } + if (connected_subchannel_ != nullptr) { + // Already connected: don't restart. + return; + } + if (!grpc_connectivity_state_has_watchers(&state_tracker_) && + !grpc_connectivity_state_has_watchers(&state_and_health_tracker_)) { + // Nobody is interested in connecting: so don't just yet. + return; + } + connecting_ = true; + GRPC_SUBCHANNEL_WEAK_REF(this, "connecting"); + if (!backoff_begun_) { + backoff_begun_ = true; + ContinueConnectingLocked(); + } else { + GPR_ASSERT(!have_retry_alarm_); + have_retry_alarm_ = true; + const grpc_millis time_til_next = + next_attempt_deadline_ - ExecCtx::Get()->Now(); + if (time_til_next <= 0) { + gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", this); + } else { + gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRId64 " milliseconds", + this, time_til_next); + } + GRPC_CLOSURE_INIT(&on_retry_alarm_, OnRetryAlarm, this, + grpc_schedule_on_exec_ctx); + grpc_timer_init(&retry_alarm_, next_attempt_deadline_, &on_retry_alarm_); + } +} + +void Subchannel::OnRetryAlarm(void* arg, grpc_error* error) { + Subchannel* c = static_cast(arg); + gpr_mu_lock(&c->mu_); + c->have_retry_alarm_ = false; + if (c->disconnected_) { error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected", &error, 1); - } else if (c->retry_immediately) { - c->retry_immediately = false; + } else if (c->retry_immediately_) { + c->retry_immediately_ = false; error = GRPC_ERROR_NONE; } else { GRPC_ERROR_REF(error); } if (error == GRPC_ERROR_NONE) { gpr_log(GPR_INFO, "Failed to connect to channel, retrying"); - continue_connect_locked(c); - gpr_mu_unlock(&c->mu); + c->ContinueConnectingLocked(); + gpr_mu_unlock(&c->mu_); } else { - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&c->mu_); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } GRPC_ERROR_UNREF(error); } -static void maybe_start_connecting_locked(grpc_subchannel* c) { - if (c->disconnected) { - /* Don't try to connect if we're already disconnected */ - return; - } - if (c->connecting) { - /* Already connecting: don't restart */ - return; - } - if (c->connected_subchannel != nullptr) { - /* Already connected: don't restart */ - return; - } - if (!grpc_connectivity_state_has_watchers(&c->state_tracker) && - !grpc_connectivity_state_has_watchers(&c->state_and_health_tracker)) { - /* Nobody is interested in connecting: so don't just yet */ - return; - } - c->connecting = true; - GRPC_SUBCHANNEL_WEAK_REF(c, "connecting"); - if (!c->backoff_begun) { - c->backoff_begun = true; - continue_connect_locked(c); - } else { - GPR_ASSERT(!c->have_alarm); - c->have_alarm = true; - const grpc_millis time_til_next = - c->next_attempt_deadline - grpc_core::ExecCtx::Get()->Now(); - if (time_til_next <= 0) { - gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", c); - } else { - gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRId64 " milliseconds", c, - time_til_next); - } - GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx); - grpc_timer_init(&c->alarm, c->next_attempt_deadline, &c->on_alarm); - } +void Subchannel::ContinueConnectingLocked() { + grpc_connect_in_args args; + args.interested_parties = pollset_set_; + const grpc_millis min_deadline = + min_connect_timeout_ms_ + ExecCtx::Get()->Now(); + next_attempt_deadline_ = backoff_.NextAttemptTime(); + args.deadline = std::max(next_attempt_deadline_, min_deadline); + args.channel_args = args_; + SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + "connecting"); + grpc_connectivity_state_set(&state_and_health_tracker_, + GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + "connecting"); + grpc_connector_connect(connector_, &args, &connecting_result_, + &on_connecting_finished_); } -void grpc_subchannel_notify_on_state_change( - grpc_subchannel* c, grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, grpc_closure* notify, - bool inhibit_health_checks) { - grpc_connectivity_state_tracker* tracker = - inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; - external_state_watcher* w; - if (state == nullptr) { - gpr_mu_lock(&c->mu); - for (w = c->root_external_state_watcher.next; - w != &c->root_external_state_watcher; w = w->next) { - if (w->notify == notify) { - grpc_connectivity_state_notify_on_state_change(tracker, nullptr, - &w->closure); - } - } - gpr_mu_unlock(&c->mu); - } else { - w = static_cast(gpr_malloc(sizeof(*w))); - w->subchannel = c; - w->pollset_set = interested_parties; - w->notify = notify; - GRPC_CLOSURE_INIT(&w->closure, on_external_state_watcher_done, w, - grpc_schedule_on_exec_ctx); - if (interested_parties != nullptr) { - grpc_pollset_set_add_pollset_set(c->pollset_set, interested_parties); - } - GRPC_SUBCHANNEL_WEAK_REF(c, "external_state_watcher"); - gpr_mu_lock(&c->mu); - w->next = &c->root_external_state_watcher; - w->prev = w->next->prev; - w->next->prev = w->prev->next = w; - grpc_connectivity_state_notify_on_state_change(tracker, state, &w->closure); - maybe_start_connecting_locked(c); - gpr_mu_unlock(&c->mu); - } -} - -static bool publish_transport_locked(grpc_subchannel* c) { - /* construct channel stack */ - grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); - grpc_channel_stack_builder_set_channel_arguments( - builder, c->connecting_result.channel_args); - grpc_channel_stack_builder_set_transport(builder, - c->connecting_result.transport); - - if (!grpc_channel_init_create_stack(builder, GRPC_CLIENT_SUBCHANNEL)) { - grpc_channel_stack_builder_destroy(builder); - return false; - } - grpc_channel_stack* stk; - grpc_error* error = grpc_channel_stack_builder_finish( - builder, 0, 1, connection_destroy, nullptr, - reinterpret_cast(&stk)); - if (error != GRPC_ERROR_NONE) { - grpc_transport_destroy(c->connecting_result.transport); - gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", - grpc_error_string(error)); - GRPC_ERROR_UNREF(error); - return false; - } - intptr_t socket_uuid = c->connecting_result.socket_uuid; - memset(&c->connecting_result, 0, sizeof(c->connecting_result)); - - if (c->disconnected) { - grpc_channel_stack_destroy(stk); - gpr_free(stk); - return false; - } - - /* publish */ - c->connected_subchannel.reset(grpc_core::New( - stk, c->args, c->channelz_subchannel, socket_uuid)); - gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", - c->connected_subchannel.get(), c); - - // Instantiate state watcher. Will clean itself up. - c->connected_subchannel_watcher = - grpc_core::MakeOrphanable(c); - - return true; -} - -static void on_subchannel_connected(void* arg, grpc_error* error) { - grpc_subchannel* c = static_cast(arg); - grpc_channel_args* delete_channel_args = c->connecting_result.channel_args; - - GRPC_SUBCHANNEL_WEAK_REF(c, "on_subchannel_connected"); - gpr_mu_lock(&c->mu); - c->connecting = false; - if (c->connecting_result.transport != nullptr && - publish_transport_locked(c)) { - /* do nothing, transport was published */ - } else if (c->disconnected) { +void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) { + auto* c = static_cast(arg); + grpc_channel_args* delete_channel_args = c->connecting_result_.channel_args; + GRPC_SUBCHANNEL_WEAK_REF(c, "on_connecting_finished"); + gpr_mu_lock(&c->mu_); + c->connecting_ = false; + if (c->connecting_result_.transport != nullptr && + c->PublishTransportLocked()) { + // Do nothing, transport was published. + } else if (c->disconnected_) { GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } else { - set_subchannel_connectivity_state_locked( - c, GRPC_CHANNEL_TRANSIENT_FAILURE, + c->SetConnectivityStateLocked( + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Connect Failed", &error, 1), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), "connect_failed"); grpc_connectivity_state_set( - &c->state_and_health_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE, + &c->state_and_health_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Connect Failed", &error, 1), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), @@ -869,276 +963,92 @@ static void on_subchannel_connected(void* arg, grpc_error* error) { const char* errmsg = grpc_error_string(error); gpr_log(GPR_INFO, "Connect failed: %s", errmsg); - maybe_start_connecting_locked(c); + c->MaybeStartConnectingLocked(); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } - gpr_mu_unlock(&c->mu); - GRPC_SUBCHANNEL_WEAK_UNREF(c, "connected"); + gpr_mu_unlock(&c->mu_); + GRPC_SUBCHANNEL_WEAK_UNREF(c, "on_connecting_finished"); grpc_channel_args_destroy(delete_channel_args); } -void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel) { - gpr_mu_lock(&subchannel->mu); - subchannel->backoff->Reset(); - if (subchannel->have_alarm) { - subchannel->retry_immediately = true; - grpc_timer_cancel(&subchannel->alarm); - } else { - subchannel->backoff_begun = false; - maybe_start_connecting_locked(subchannel); +namespace { + +void ConnectionDestroy(void* arg, grpc_error* error) { + grpc_channel_stack* stk = static_cast(arg); + grpc_channel_stack_destroy(stk); + gpr_free(stk); +} + +} // namespace + +bool Subchannel::PublishTransportLocked() { + // Construct channel stack. + grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); + grpc_channel_stack_builder_set_channel_arguments( + builder, connecting_result_.channel_args); + grpc_channel_stack_builder_set_transport(builder, + connecting_result_.transport); + if (!grpc_channel_init_create_stack(builder, GRPC_CLIENT_SUBCHANNEL)) { + grpc_channel_stack_builder_destroy(builder); + return false; } - gpr_mu_unlock(&subchannel->mu); -} - -/* - * grpc_subchannel_call implementation - */ - -static void subchannel_call_destroy(void* call, grpc_error* error) { - GPR_TIMER_SCOPE("grpc_subchannel_call_unref.destroy", 0); - grpc_subchannel_call* c = static_cast(call); - grpc_core::ConnectedSubchannel* connection = c->connection; - grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c), nullptr, - c->schedule_closure_after_destroy); - connection->Unref(DEBUG_LOCATION, "subchannel_call"); - c->~grpc_subchannel_call(); -} - -void grpc_subchannel_call_set_cleanup_closure(grpc_subchannel_call* call, - grpc_closure* closure) { - GPR_ASSERT(call->schedule_closure_after_destroy == nullptr); - GPR_ASSERT(closure != nullptr); - call->schedule_closure_after_destroy = closure; -} - -grpc_subchannel_call* grpc_subchannel_call_ref( - grpc_subchannel_call* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); - return c; -} - -void grpc_subchannel_call_unref( - grpc_subchannel_call* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); -} - -// Sets *status based on md_batch and error. -static void get_call_status(grpc_subchannel_call* call, - grpc_metadata_batch* md_batch, grpc_error* error, - grpc_status_code* status) { + grpc_channel_stack* stk; + grpc_error* error = grpc_channel_stack_builder_finish( + builder, 0, 1, ConnectionDestroy, nullptr, + reinterpret_cast(&stk)); if (error != GRPC_ERROR_NONE) { - grpc_error_get_status(error, call->deadline, status, nullptr, nullptr, - nullptr); - } else { - if (md_batch->idx.named.grpc_status != nullptr) { - *status = grpc_get_status_code_from_metadata( - md_batch->idx.named.grpc_status->md); - } else { - *status = GRPC_STATUS_UNKNOWN; - } + grpc_transport_destroy(connecting_result_.transport); + gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", + grpc_error_string(error)); + GRPC_ERROR_UNREF(error); + return false; } - GRPC_ERROR_UNREF(error); -} - -static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { - grpc_subchannel_call* call = static_cast(arg); - GPR_ASSERT(call->recv_trailing_metadata != nullptr); - grpc_status_code status = GRPC_STATUS_OK; - grpc_metadata_batch* md_batch = call->recv_trailing_metadata; - get_call_status(call, md_batch, GRPC_ERROR_REF(error), &status); - grpc_core::channelz::SubchannelNode* channelz_subchannel = - call->connection->channelz_subchannel(); - GPR_ASSERT(channelz_subchannel != nullptr); - if (status == GRPC_STATUS_OK) { - channelz_subchannel->RecordCallSucceeded(); - } else { - channelz_subchannel->RecordCallFailed(); + intptr_t socket_uuid = connecting_result_.socket_uuid; + memset(&connecting_result_, 0, sizeof(connecting_result_)); + if (disconnected_) { + grpc_channel_stack_destroy(stk); + gpr_free(stk); + return false; } - GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata, - GRPC_ERROR_REF(error)); + // Publish. + connected_subchannel_.reset( + New(stk, args_, channelz_node_, socket_uuid)); + gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", + connected_subchannel_.get(), this); + // Instantiate state watcher. Will clean itself up. + connected_subchannel_watcher_ = + MakeOrphanable(this); + return true; } -// If channelz is enabled, intercept recv_trailing so that we may check the -// status and associate it to a subchannel. -static void maybe_intercept_recv_trailing_metadata( - grpc_subchannel_call* call, grpc_transport_stream_op_batch* batch) { - // only intercept payloads with recv trailing. - if (!batch->recv_trailing_metadata) { - return; +void Subchannel::Disconnect() { + // The subchannel_pool is only used once here in this subchannel, so the + // access can be outside of the lock. + if (subchannel_pool_ != nullptr) { + subchannel_pool_->UnregisterSubchannel(key_); + subchannel_pool_.reset(); } - // only add interceptor is channelz is enabled. - if (call->connection->channelz_subchannel() == nullptr) { - return; + MutexLock lock(&mu_); + GPR_ASSERT(!disconnected_); + disconnected_ = true; + grpc_connector_shutdown(connector_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Subchannel disconnected")); + connected_subchannel_.reset(); + connected_subchannel_watcher_.reset(); +} + +gpr_atm Subchannel::RefMutate( + gpr_atm delta, int barrier GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS) { + gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&ref_pair_, delta) + : gpr_atm_no_barrier_fetch_add(&ref_pair_, delta); +#ifndef NDEBUG + if (grpc_trace_stream_refcount.enabled()) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", this, + purpose, old_val, old_val + delta, reason); } - GRPC_CLOSURE_INIT(&call->recv_trailing_metadata_ready, - recv_trailing_metadata_ready, call, - grpc_schedule_on_exec_ctx); - // save some state needed for the interception callback. - GPR_ASSERT(call->recv_trailing_metadata == nullptr); - call->recv_trailing_metadata = - batch->payload->recv_trailing_metadata.recv_trailing_metadata; - call->original_recv_trailing_metadata = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &call->recv_trailing_metadata_ready; -} - -void grpc_subchannel_call_process_op(grpc_subchannel_call* call, - grpc_transport_stream_op_batch* batch) { - GPR_TIMER_SCOPE("grpc_subchannel_call_process_op", 0); - maybe_intercept_recv_trailing_metadata(call, batch); - grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call); - grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0); - GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch); - top_elem->filter->start_transport_stream_op_batch(top_elem, batch); -} - -grpc_core::RefCountedPtr -grpc_subchannel_get_connected_subchannel(grpc_subchannel* c) { - gpr_mu_lock(&c->mu); - auto copy = c->connected_subchannel; - gpr_mu_unlock(&c->mu); - return copy; -} - -void* grpc_connected_subchannel_call_get_parent_data( - grpc_subchannel_call* subchannel_call) { - grpc_channel_stack* chanstk = subchannel_call->connection->channel_stack(); - return (char*)subchannel_call + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(chanstk->call_stack_size); -} - -grpc_call_stack* grpc_subchannel_call_get_call_stack( - grpc_subchannel_call* subchannel_call) { - return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call); -} - -static void grpc_uri_to_sockaddr(const char* uri_str, - grpc_resolved_address* addr) { - grpc_uri* uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */); - GPR_ASSERT(uri != nullptr); - if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr)); - grpc_uri_destroy(uri); -} - -void grpc_get_subchannel_address_arg(const grpc_channel_args* args, - grpc_resolved_address* addr) { - const char* addr_uri_str = grpc_get_subchannel_address_uri_arg(args); - memset(addr, 0, sizeof(*addr)); - if (*addr_uri_str != '\0') { - grpc_uri_to_sockaddr(addr_uri_str, addr); - } -} - -const char* grpc_subchannel_get_target(grpc_subchannel* subchannel) { - const grpc_arg* addr_arg = - grpc_channel_args_find(subchannel->args, GRPC_ARG_SUBCHANNEL_ADDRESS); - const char* addr_str = grpc_channel_arg_get_string(addr_arg); - GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. - return addr_str; -} - -const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args) { - const grpc_arg* addr_arg = - grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS); - const char* addr_str = grpc_channel_arg_get_string(addr_arg); - GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. - return addr_str; -} - -grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) { - return grpc_channel_arg_string_create( - (char*)GRPC_ARG_SUBCHANNEL_ADDRESS, - addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("")); -} - -namespace grpc_core { - -ConnectedSubchannel::ConnectedSubchannel( - grpc_channel_stack* channel_stack, const grpc_channel_args* args, - grpc_core::RefCountedPtr - channelz_subchannel, - intptr_t socket_uuid) - : RefCounted(&grpc_trace_stream_refcount), - channel_stack_(channel_stack), - args_(grpc_channel_args_copy(args)), - channelz_subchannel_(std::move(channelz_subchannel)), - socket_uuid_(socket_uuid) {} - -ConnectedSubchannel::~ConnectedSubchannel() { - grpc_channel_args_destroy(args_); - GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); -} - -void ConnectedSubchannel::NotifyOnStateChange( - grpc_pollset_set* interested_parties, grpc_connectivity_state* state, - grpc_closure* closure) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - grpc_channel_element* elem; - op->connectivity_state = state; - op->on_connectivity_state_change = closure; - op->bind_pollset_set = interested_parties; - elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} - -void ConnectedSubchannel::Ping(grpc_closure* on_initiate, - grpc_closure* on_ack) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - grpc_channel_element* elem; - op->send_ping.on_initiate = on_initiate; - op->send_ping.on_ack = on_ack; - elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} - -grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, - grpc_subchannel_call** call) { - const size_t allocation_size = - GetInitialCallSizeEstimate(args.parent_data_size); - *call = new (gpr_arena_alloc(args.arena, allocation_size)) - grpc_subchannel_call(this, args); - grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); - RefCountedPtr connection = - Ref(DEBUG_LOCATION, "subchannel_call"); - connection.release(); // Ref is passed to the grpc_subchannel_call object. - const grpc_call_element_args call_args = { - callstk, /* call_stack */ - nullptr, /* server_transport_data */ - args.context, /* context */ - args.path, /* path */ - args.start_time, /* start_time */ - args.deadline, /* deadline */ - args.arena, /* arena */ - args.call_combiner /* call_combiner */ - }; - grpc_error* error = grpc_call_stack_init( - channel_stack_, 1, subchannel_call_destroy, *call, &call_args); - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - const char* error_string = grpc_error_string(error); - gpr_log(GPR_ERROR, "error: %s", error_string); - return error; - } - grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); - if (channelz_subchannel_ != nullptr) { - channelz_subchannel_->RecordCallStarted(); - } - return GRPC_ERROR_NONE; -} - -size_t ConnectedSubchannel::GetInitialCallSizeEstimate( - size_t parent_data_size) const { - size_t allocation_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); - if (parent_data_size > 0) { - allocation_size += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + - parent_data_size; - } else { - allocation_size += channel_stack_->call_stack_size; - } - return allocation_size; +#endif + return old_val; } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index fac515eee5c..88282c9d95e 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -24,53 +24,49 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/connector.h" #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" +#include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/gpr/arena.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/metadata.h" // Channel arg containing a grpc_resolved_address to connect to. #define GRPC_ARG_SUBCHANNEL_ADDRESS "grpc.subchannel_address" -/** A (sub-)channel that knows how to connect to exactly one target - address. Provides a target for load balancing. */ -typedef struct grpc_subchannel grpc_subchannel; -typedef struct grpc_subchannel_call grpc_subchannel_call; - +// For debugging refcounting. #ifndef NDEBUG -#define GRPC_SUBCHANNEL_REF(p, r) \ - grpc_subchannel_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_REF(p, r) (p)->Ref(__FILE__, __LINE__, (r)) #define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ - grpc_subchannel_ref_from_weak_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_UNREF(p, r) \ - grpc_subchannel_unref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_WEAK_REF(p, r) \ - grpc_subchannel_weak_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) \ - grpc_subchannel_weak_unref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_REF(p, r) \ - grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) \ - grpc_subchannel_call_unref((p), __FILE__, __LINE__, (r)) + (p)->RefFromWeakRef(__FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_UNREF(p, r) (p)->Unref(__FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_WEAK_REF(p, r) (p)->WeakRef(__FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) (p)->WeakUnref(__FILE__, __LINE__, (r)) #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS \ - , const char *file, int line, const char *reason + const char *file, int line, const char *reason +#define GRPC_SUBCHANNEL_REF_REASON reason +#define GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS \ + , GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char* purpose +#define GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE(x) , file, line, reason, x #else -#define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p)) -#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ - grpc_subchannel_ref_from_weak_ref((p)) -#define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p)) -#define GRPC_SUBCHANNEL_WEAK_REF(p, r) grpc_subchannel_weak_ref((p)) -#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) grpc_subchannel_weak_unref((p)) -#define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p)) -#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) grpc_subchannel_call_unref((p)) +#define GRPC_SUBCHANNEL_REF(p, r) (p)->Ref() +#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) (p)->RefFromWeakRef() +#define GRPC_SUBCHANNEL_UNREF(p, r) (p)->Unref() +#define GRPC_SUBCHANNEL_WEAK_REF(p, r) (p)->WeakRef() +#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) (p)->WeakUnref() #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS +#define GRPC_SUBCHANNEL_REF_REASON "" +#define GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS +#define GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE(x) #endif namespace grpc_core { +class SubchannelCall; + class ConnectedSubchannel : public RefCounted { public: struct CallArgs { @@ -86,8 +82,7 @@ class ConnectedSubchannel : public RefCounted { ConnectedSubchannel( grpc_channel_stack* channel_stack, const grpc_channel_args* args, - grpc_core::RefCountedPtr - channelz_subchannel, + RefCountedPtr channelz_subchannel, intptr_t socket_uuid); ~ConnectedSubchannel(); @@ -95,7 +90,8 @@ class ConnectedSubchannel : public RefCounted { grpc_connectivity_state* state, grpc_closure* closure); void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); - grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); + RefCountedPtr CreateCall(const CallArgs& args, + grpc_error** error); grpc_channel_stack* channel_stack() const { return channel_stack_; } const grpc_channel_args* args() const { return args_; } @@ -111,91 +107,204 @@ class ConnectedSubchannel : public RefCounted { grpc_channel_args* args_; // ref counted pointer to the channelz node in this connected subchannel's // owning subchannel. - grpc_core::RefCountedPtr - channelz_subchannel_; + RefCountedPtr channelz_subchannel_; // uuid of this subchannel's socket. 0 if this subchannel is not connected. const intptr_t socket_uuid_; }; +// Implements the interface of RefCounted<>. +class SubchannelCall { + public: + SubchannelCall(RefCountedPtr connected_subchannel, + const ConnectedSubchannel::CallArgs& args) + : connected_subchannel_(std::move(connected_subchannel)), + deadline_(args.deadline) {} + + // Continues processing a transport stream op batch. + void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch); + + // Returns a pointer to the parent data associated with the subchannel call. + // The data will be of the size specified in \a parent_data_size field of + // the args passed to \a ConnectedSubchannel::CreateCall(). + void* GetParentData(); + + // Returns the call stack of the subchannel call. + grpc_call_stack* GetCallStack(); + + grpc_closure* after_call_stack_destroy() const { + return after_call_stack_destroy_; + } + + // Sets the 'then_schedule_closure' argument for call stack destruction. + // Must be called once per call. + void SetAfterCallStackDestroy(grpc_closure* closure); + + // Interface of RefCounted<>. + RefCountedPtr Ref() GRPC_MUST_USE_RESULT; + RefCountedPtr Ref(const DebugLocation& location, + const char* reason) GRPC_MUST_USE_RESULT; + // When refcount drops to 0, destroys itself and the associated call stack, + // but does NOT free the memory because it's in the call arena. + void Unref(); + void Unref(const DebugLocation& location, const char* reason); + + private: + // Allow RefCountedPtr<> to access IncrementRefCount(). + template + friend class RefCountedPtr; + + // If channelz is enabled, intercepts recv_trailing so that we may check the + // status and associate it to a subchannel. + void MaybeInterceptRecvTrailingMetadata( + grpc_transport_stream_op_batch* batch); + + static void RecvTrailingMetadataReady(void* arg, grpc_error* error); + + // Interface of RefCounted<>. + void IncrementRefCount(); + void IncrementRefCount(const DebugLocation& location, const char* reason); + + RefCountedPtr connected_subchannel_; + grpc_closure* after_call_stack_destroy_ = nullptr; + // State needed to support channelz interception of recv trailing metadata. + grpc_closure recv_trailing_metadata_ready_; + grpc_closure* original_recv_trailing_metadata_ = nullptr; + grpc_metadata_batch* recv_trailing_metadata_ = nullptr; + grpc_millis deadline_; +}; + +// A subchannel that knows how to connect to exactly one target address. It +// provides a target for load balancing. +class Subchannel { + public: + // The ctor and dtor are not intended to use directly. + Subchannel(SubchannelKey* key, grpc_connector* connector, + const grpc_channel_args* args); + ~Subchannel(); + + // Creates a subchannel given \a connector and \a args. + static Subchannel* Create(grpc_connector* connector, + const grpc_channel_args* args); + + // Strong and weak refcounting. + Subchannel* Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + void Unref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + Subchannel* WeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + void WeakUnref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + Subchannel* RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + + intptr_t GetChildSocketUuid(); + + // Gets the string representing the subchannel address. + // Caller doesn't take ownership. + const char* GetTargetAddress(); + + // Gets the connected subchannel - or nullptr if not connected (which may + // happen before it initially connects or during transient failures). + RefCountedPtr connected_subchannel(); + + channelz::SubchannelNode* channelz_node(); + + // Polls the current connectivity state of the subchannel. + grpc_connectivity_state CheckConnectivity(grpc_error** error, + bool inhibit_health_checking); + + // When the connectivity state of the subchannel changes from \a *state, + // invokes \a notify and updates \a *state with the new state. + void NotifyOnStateChange(grpc_pollset_set* interested_parties, + grpc_connectivity_state* state, grpc_closure* notify, + bool inhibit_health_checks); + + // Resets the connection backoff of the subchannel. + // TODO(roth): Move connection backoff out of subchannels and up into LB + // policy code (probably by adding a SubchannelGroup between + // SubchannelList and SubchannelData), at which point this method can + // go away. + void ResetBackoff(); + + // Returns a new channel arg encoding the subchannel address as a URI + // string. Caller is responsible for freeing the string. + static grpc_arg CreateSubchannelAddressArg(const grpc_resolved_address* addr); + + // Returns the URI string from the subchannel address arg in \a args. + static const char* GetUriFromSubchannelAddressArg( + const grpc_channel_args* args); + + // Sets \a addr from the subchannel address arg in \a args. + static void GetAddressFromSubchannelAddressArg(const grpc_channel_args* args, + grpc_resolved_address* addr); + + private: + struct ExternalStateWatcher; + class ConnectedSubchannelStateWatcher; + + // Sets the subchannel's connectivity state to \a state. + void SetConnectivityStateLocked(grpc_connectivity_state state, + grpc_error* error, const char* reason); + + // Methods for connection. + void MaybeStartConnectingLocked(); + static void OnRetryAlarm(void* arg, grpc_error* error); + void ContinueConnectingLocked(); + static void OnConnectingFinished(void* arg, grpc_error* error); + bool PublishTransportLocked(); + void Disconnect(); + + gpr_atm RefMutate(gpr_atm delta, + int barrier GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS); + + // The subchannel pool this subchannel is in. + RefCountedPtr subchannel_pool_; + // TODO(juanlishen): Consider using args_ as key_ directly. + // Subchannel key that identifies this subchannel in the subchannel pool. + SubchannelKey* key_; + // Channel args. + grpc_channel_args* args_; + // pollset_set tracking who's interested in a connection being setup. + grpc_pollset_set* pollset_set_; + // Protects the other members. + gpr_mu mu_; + // Refcount + // - lower INTERNAL_REF_BITS bits are for internal references: + // these do not keep the subchannel open. + // - upper remaining bits are for public references: these do + // keep the subchannel open + gpr_atm ref_pair_; + + // Connection states. + grpc_connector* connector_ = nullptr; + // Set during connection. + grpc_connect_out_args connecting_result_; + grpc_closure on_connecting_finished_; + // Active connection, or null. + RefCountedPtr connected_subchannel_; + OrphanablePtr connected_subchannel_watcher_; + bool connecting_ = false; + bool disconnected_ = false; + + // Connectivity state tracking. + grpc_connectivity_state_tracker state_tracker_; + grpc_connectivity_state_tracker state_and_health_tracker_; + UniquePtr health_check_service_name_; + ExternalStateWatcher* external_state_watcher_list_ = nullptr; + + // Backoff state. + BackOff backoff_; + grpc_millis next_attempt_deadline_; + grpc_millis min_connect_timeout_ms_; + bool backoff_begun_ = false; + + // Retry alarm. + grpc_timer retry_alarm_; + grpc_closure on_retry_alarm_; + bool have_retry_alarm_ = false; + // reset_backoff() was called while alarm was pending. + bool retry_immediately_ = false; + + // Channelz tracking. + RefCountedPtr channelz_node_; +}; + } // namespace grpc_core -grpc_subchannel* grpc_subchannel_ref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel* grpc_subchannel_ref_from_weak_ref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_unref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel* grpc_subchannel_weak_ref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_weak_unref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel_call* grpc_subchannel_call_ref( - grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_call_unref( - grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); - -grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( - grpc_subchannel* subchannel); - -intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel); - -/** Returns a pointer to the parent data associated with \a subchannel_call. - The data will be of the size specified in \a parent_data_size - field of the args passed to \a grpc_connected_subchannel_create_call(). */ -void* grpc_connected_subchannel_call_get_parent_data( - grpc_subchannel_call* subchannel_call); - -/** poll the current connectivity state of a channel */ -grpc_connectivity_state grpc_subchannel_check_connectivity( - grpc_subchannel* channel, grpc_error** error, bool inhibit_health_checking); - -/** Calls notify when the connectivity state of a channel becomes different - from *state. Updates *state with the new state of the channel. */ -void grpc_subchannel_notify_on_state_change( - grpc_subchannel* channel, grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, grpc_closure* notify, - bool inhibit_health_checks); - -/** retrieve the grpc_core::ConnectedSubchannel - or nullptr if not connected - * (which may happen before it initially connects or during transient failures) - * */ -grpc_core::RefCountedPtr -grpc_subchannel_get_connected_subchannel(grpc_subchannel* c); - -// Resets the connection backoff of the subchannel. -// TODO(roth): Move connection backoff out of subchannels and up into LB -// policy code (probably by adding a SubchannelGroup between -// SubchannelList and SubchannelData), at which point this method can -// go away. -void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel); - -/** continue processing a transport op */ -void grpc_subchannel_call_process_op(grpc_subchannel_call* subchannel_call, - grpc_transport_stream_op_batch* op); - -/** Must be called once per call. Sets the 'then_schedule_closure' argument for - call stack destruction. */ -void grpc_subchannel_call_set_cleanup_closure( - grpc_subchannel_call* subchannel_call, grpc_closure* closure); - -grpc_call_stack* grpc_subchannel_call_get_call_stack( - grpc_subchannel_call* subchannel_call); - -/** create a subchannel given a connector */ -grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, - const grpc_channel_args* args); - -/// Sets \a addr from \a args. -void grpc_get_subchannel_address_arg(const grpc_channel_args* args, - grpc_resolved_address* addr); - -const char* grpc_subchannel_get_target(grpc_subchannel* subchannel); - -/// Returns the URI string for the address to connect to. -const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args); - -/// Returns a new channel arg encoding the subchannel address as a string. -/// Caller is responsible for freeing the string. -grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr); - #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_H */ diff --git a/src/core/ext/filters/client_channel/subchannel_pool_interface.h b/src/core/ext/filters/client_channel/subchannel_pool_interface.h index 21597bf4276..eeb56faf0c0 100644 --- a/src/core/ext/filters/client_channel/subchannel_pool_interface.h +++ b/src/core/ext/filters/client_channel/subchannel_pool_interface.h @@ -26,10 +26,10 @@ #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/ref_counted.h" -struct grpc_subchannel; - namespace grpc_core { +class Subchannel; + extern TraceFlag grpc_subchannel_pool_trace; // A key that can uniquely identify a subchannel. @@ -69,15 +69,15 @@ class SubchannelPoolInterface : public RefCounted { // Registers a subchannel against a key. Returns the subchannel registered // with \a key, which may be different from \a constructed because we reuse // (instead of update) any existing subchannel already registered with \a key. - virtual grpc_subchannel* RegisterSubchannel( - SubchannelKey* key, grpc_subchannel* constructed) GRPC_ABSTRACT; + virtual Subchannel* RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) GRPC_ABSTRACT; // Removes the registered subchannel found by \a key. virtual void UnregisterSubchannel(SubchannelKey* key) GRPC_ABSTRACT; // Finds the subchannel registered for the given subchannel key. Returns NULL // if no such channel exists. Thread-safe. - virtual grpc_subchannel* FindSubchannel(SubchannelKey* key) GRPC_ABSTRACT; + virtual Subchannel* FindSubchannel(SubchannelKey* key) GRPC_ABSTRACT; // Creates a channel arg from \a subchannel pool. static grpc_arg CreateChannelArg(SubchannelPoolInterface* subchannel_pool); diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 42a2e2e896c..1e9a75d0630 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -202,7 +202,8 @@ static void chttp2_connector_connect(grpc_connector* con, grpc_closure* notify) { chttp2_connector* c = reinterpret_cast(con); grpc_resolved_address addr; - grpc_get_subchannel_address_arg(args->channel_args, &addr); + grpc_core::Subchannel::GetAddressFromSubchannelAddressArg(args->channel_args, + &addr); gpr_mu_lock(&c->mu); GPR_ASSERT(c->notify == nullptr); c->notify = notify; diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc index a5bf1bf21d4..8aabcfa2000 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -39,11 +39,11 @@ static void client_channel_factory_ref( static void client_channel_factory_unref( grpc_client_channel_factory* cc_factory) {} -static grpc_subchannel* client_channel_factory_create_subchannel( +static grpc_core::Subchannel* client_channel_factory_create_subchannel( grpc_client_channel_factory* cc_factory, const grpc_channel_args* args) { grpc_channel_args* new_args = grpc_default_authority_add_if_not_present(args); grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_subchannel* s = grpc_subchannel_create(connector, new_args); + grpc_core::Subchannel* s = grpc_core::Subchannel::Create(connector, new_args); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index 5985fa0cbdb..eb2fee2af91 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -76,7 +76,8 @@ static grpc_channel_args* get_secure_naming_channel_args( grpc_core::UniquePtr authority; if (target_authority_table != nullptr) { // Find the authority for the target. - const char* target_uri_str = grpc_get_subchannel_address_uri_arg(args); + const char* target_uri_str = + grpc_core::Subchannel::GetUriFromSubchannelAddressArg(args); grpc_uri* target_uri = grpc_uri_parse(target_uri_str, false /* suppress errors */); GPR_ASSERT(target_uri != nullptr); @@ -138,7 +139,7 @@ static grpc_channel_args* get_secure_naming_channel_args( return new_args; } -static grpc_subchannel* client_channel_factory_create_subchannel( +static grpc_core::Subchannel* client_channel_factory_create_subchannel( grpc_client_channel_factory* cc_factory, const grpc_channel_args* args) { grpc_channel_args* new_args = get_secure_naming_channel_args(args); if (new_args == nullptr) { @@ -147,7 +148,7 @@ static grpc_subchannel* client_channel_factory_create_subchannel( return nullptr; } grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_subchannel* s = grpc_subchannel_create(connector, new_args); + grpc_core::Subchannel* s = grpc_core::Subchannel::Create(connector, new_args); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/test/core/util/debugger_macros.cc b/test/core/util/debugger_macros.cc index 05fb1461733..fed6ad97285 100644 --- a/test/core/util/debugger_macros.cc +++ b/test/core/util/debugger_macros.cc @@ -36,13 +36,14 @@ grpc_stream* grpc_transport_stream_from_call(grpc_call* call) { for (;;) { grpc_call_element* el = grpc_call_stack_element(cs, cs->count - 1); if (el->filter == &grpc_client_channel_filter) { - grpc_subchannel_call* scc = grpc_client_channel_get_subchannel_call(el); + grpc_core::RefCountedPtr scc = + grpc_client_channel_get_subchannel_call(el); if (scc == nullptr) { fprintf(stderr, "No subchannel-call"); fflush(stderr); return nullptr; } - cs = grpc_subchannel_call_get_call_stack(scc); + cs = scc->GetCallStack(); } else if (el->filter == &grpc_connected_filter) { return grpc_connected_channel_get_stream(el); } else { diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 125b1ce5c4e..973f47beaf7 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -325,8 +325,8 @@ class FakeClientChannelFactory : public grpc_client_channel_factory { private: static void NoRef(grpc_client_channel_factory* factory) {} static void NoUnref(grpc_client_channel_factory* factory) {} - static grpc_subchannel* CreateSubchannel(grpc_client_channel_factory* factory, - const grpc_channel_args* args) { + static grpc_core::Subchannel* CreateSubchannel( + grpc_client_channel_factory* factory, const grpc_channel_args* args) { return nullptr; } static grpc_channel* CreateClientChannel(grpc_client_channel_factory* factory, From b20f15892217698f2bb9f9c8ad7bf26607953329 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 29 Jan 2019 12:40:31 -0800 Subject: [PATCH 211/814] Deflake a shared CQ usage --- test/cpp/end2end/generic_end2end_test.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 015862bfe81..8c4b3cf1fd3 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -219,10 +220,11 @@ TEST_F(GenericEnd2endTest, SequentialUnaryRpcs) { // Use the same cq as server so that events can be polled in time. std::unique_ptr call = generic_stub_->PrepareUnaryCall(&cli_ctx, kMethodName, - *cli_send_buffer.get(), srv_cq_.get()); + *cli_send_buffer.get(), &cli_cq_); call->StartCall(); ByteBuffer cli_recv_buffer; call->Finish(&cli_recv_buffer, &recv_status, tag(1)); + std::thread client_check([this] { client_ok(1); }); generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), srv_cq_.get(), tag(4)); @@ -246,7 +248,7 @@ TEST_F(GenericEnd2endTest, SequentialUnaryRpcs) { stream.Finish(Status::OK, tag(7)); server_ok(7); - verify_ok(srv_cq_.get(), 1, true); + client_check.join(); EXPECT_TRUE(ParseFromByteBuffer(&cli_recv_buffer, &recv_response)); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.ok()); From 7da0aacef2886d5556a043fc3b6400db9daa5424 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 29 Jan 2019 13:50:16 -0800 Subject: [PATCH 212/814] Revert "Merge pull request #17644 from lidizheng/bzl-py3" This reverts commit a25828ad784e4302699c00751ebe1191462caee8, reversing changes made to 5176fd80fc160c492cb6529569bde5f36e1ecf44. --- BUILD | 5 --- src/python/grpcio/grpc/BUILD.bazel | 6 ++-- .../grpcio/grpc/framework/common/BUILD.bazel | 14 ++++---- .../grpc/framework/foundation/BUILD.bazel | 13 +++----- .../framework/interfaces/base/BUILD.bazel | 13 +++----- .../framework/interfaces/face/BUILD.bazel | 6 ++-- .../grpcio_status/grpc_status/rpc_status.py | 5 +++ src/python/grpcio_tests/tests/BUILD.bazel | 8 ----- .../tests/bazel_namespace_package_hack.py | 32 ------------------- .../grpcio_tests/tests/interop/BUILD.bazel | 7 ++-- .../grpcio_tests/tests/interop/methods.py | 3 -- .../reflection/_reflection_servicer_test.py | 20 +++--------- .../grpcio_tests/tests/status/BUILD.bazel | 1 - .../tests/status/_grpc_status_test.py | 3 -- third_party/py/python_configure.bzl | 11 +++---- tools/bazel.rc | 4 --- .../linux/grpc_python_bazel_test_in_docker.sh | 2 -- 17 files changed, 36 insertions(+), 117 deletions(-) delete mode 100644 src/python/grpcio_tests/tests/BUILD.bazel delete mode 100644 src/python/grpcio_tests/tests/bazel_namespace_package_hack.py diff --git a/BUILD b/BUILD index ff066edaeaf..3f1e735466d 100644 --- a/BUILD +++ b/BUILD @@ -63,11 +63,6 @@ config_setting( values = {"cpu": "x64_windows_msvc"}, ) -config_setting( - name = "python3", - values = {"python_path": "python3"}, -) - # This should be updated along with build.yaml g_stands_for = "gold" diff --git a/src/python/grpcio/grpc/BUILD.bazel b/src/python/grpcio/grpc/BUILD.bazel index 27d5d2e4bb2..6958ccdfb66 100644 --- a/src/python/grpcio/grpc/BUILD.bazel +++ b/src/python/grpcio/grpc/BUILD.bazel @@ -15,11 +15,9 @@ py_library( "//src/python/grpcio/grpc/_cython:cygrpc", "//src/python/grpcio/grpc/experimental", "//src/python/grpcio/grpc/framework", + requirement('enum34'), requirement('six'), - ] + select({ - "//conditions:default": [requirement('enum34'),], - "//:python3": [], - }), + ], data = [ "//:grpc", ], diff --git a/src/python/grpcio/grpc/framework/common/BUILD.bazel b/src/python/grpcio/grpc/framework/common/BUILD.bazel index 52fbb2b516c..9d9ef682c90 100644 --- a/src/python/grpcio/grpc/framework/common/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/common/BUILD.bazel @@ -13,17 +13,15 @@ py_library( py_library( name = "cardinality", srcs = ["cardinality.py"], - deps = select({ - "//conditions:default": [requirement('enum34'),], - "//:python3": [], - }), + deps = [ + requirement("enum34"), + ], ) py_library( name = "style", srcs = ["style.py"], - deps = select({ - "//conditions:default": [requirement('enum34'),], - "//:python3": [], - }), + deps = [ + requirement("enum34"), + ], ) diff --git a/src/python/grpcio/grpc/framework/foundation/BUILD.bazel b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel index a447ecded49..1287fdd44ed 100644 --- a/src/python/grpcio/grpc/framework/foundation/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel @@ -23,11 +23,9 @@ py_library( name = "callable_util", srcs = ["callable_util.py"], deps = [ + requirement("enum34"), requirement("six"), - ] + select({ - "//conditions:default": [requirement('enum34'),], - "//:python3": [], - }), + ], ) py_library( @@ -41,10 +39,9 @@ py_library( py_library( name = "logging_pool", srcs = ["logging_pool.py"], - deps = select({ - "//conditions:default": [requirement('futures'),], - "//:python3": [], - }), + deps = [ + requirement("futures"), + ], ) py_library( diff --git a/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel b/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel index 35cfe877f34..408a66a6310 100644 --- a/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel @@ -15,18 +15,15 @@ py_library( srcs = ["base.py"], deps = [ "//src/python/grpcio/grpc/framework/foundation:abandonment", + requirement("enum34"), requirement("six"), - ] + select({ - "//conditions:default": [requirement('enum34'),], - "//:python3": [], - }), + ], ) py_library( name = "utilities", srcs = ["utilities.py"], - deps = select({ - "//conditions:default": [requirement('enum34'),], - "//:python3": [], - }), + deps = [ + requirement("enum34"), + ], ) diff --git a/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel b/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel index 83fadb6372e..e683e7cc426 100644 --- a/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel @@ -16,11 +16,9 @@ py_library( deps = [ "//src/python/grpcio/grpc/framework/foundation", "//src/python/grpcio/grpc/framework/common", + requirement("enum34"), requirement("six"), - ] + select({ - "//conditions:default": [requirement('enum34'),], - "//:python3": [], - }), + ], ) py_library( diff --git a/src/python/grpcio_status/grpc_status/rpc_status.py b/src/python/grpcio_status/grpc_status/rpc_status.py index 76891e2422e..87618fa5412 100644 --- a/src/python/grpcio_status/grpc_status/rpc_status.py +++ b/src/python/grpcio_status/grpc_status/rpc_status.py @@ -17,6 +17,11 @@ import collections import grpc +# TODO(https://github.com/bazelbuild/bazel/issues/6844) +# Due to Bazel issue, the namespace packages won't resolve correctly. +# Adding this unused-import as a workaround to avoid module-not-found error +# under Bazel builds. +import google.protobuf # pylint: disable=unused-import from google.rpc import status_pb2 _CODE_TO_GRPC_CODE_MAPPING = {x.value[0]: x for x in grpc.StatusCode} diff --git a/src/python/grpcio_tests/tests/BUILD.bazel b/src/python/grpcio_tests/tests/BUILD.bazel deleted file mode 100644 index b908ab85173..00000000000 --- a/src/python/grpcio_tests/tests/BUILD.bazel +++ /dev/null @@ -1,8 +0,0 @@ -py_library( - name = "bazel_namespace_package_hack", - srcs = ["bazel_namespace_package_hack.py"], - visibility = [ - "//src/python/grpcio_tests/tests/status:__subpackages__", - "//src/python/grpcio_tests/tests/interop:__subpackages__", - ], -) diff --git a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py deleted file mode 100644 index c6b72c327b1..00000000000 --- a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2019 The gRPC Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import site -import sys - - -# TODO(https://github.com/bazelbuild/bazel/issues/6844) Bazel failed to -# interpret namespace packages correctly. This monkey patch will force the -# Python process to parse the .pth file in the sys.path to resolve namespace -# package in the right place. -# Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 -def sys_path_to_site_dir_hack(): - """Add valid sys.path item to site directory to parse the .pth files.""" - for item in sys.path: - if os.path.exists(item): - # The only difference between sys.path and site-directory is - # whether the .pth file will be parsed or not. A site-directory - # will always exist in sys.path, but not another way around. - site.addsitedir(item) diff --git a/src/python/grpcio_tests/tests/interop/BUILD.bazel b/src/python/grpcio_tests/tests/interop/BUILD.bazel index 770b1f78a70..aebdbf67ebf 100644 --- a/src/python/grpcio_tests/tests/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests/interop/BUILD.bazel @@ -29,20 +29,17 @@ py_library( srcs = ["methods.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing:py_messages_proto", "//src/proto/grpc/testing:py_test_proto", requirement('google-auth'), requirement('requests'), + requirement('enum34'), requirement('urllib3'), requirement('chardet'), requirement('certifi'), requirement('idna'), - ] + select({ - "//conditions:default": [requirement('enum34'),], - "//:python3": [], - }), + ], imports=["../../",], ) diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index e16966e3918..c11f6c8fad7 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -13,9 +13,6 @@ # limitations under the License. """Implementations of interoperability test methods.""" -from tests import bazel_namespace_package_hack -bazel_namespace_package_hack.sys_path_to_site_dir_hack() - import enum import json import os diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py index 37a66ad52bb..560f6d3ddb3 100644 --- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py +++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py @@ -50,16 +50,6 @@ def _file_descriptor_to_proto(descriptor): class ReflectionServicerTest(unittest.TestCase): - # TODO(https://github.com/grpc/grpc/issues/17844) - # Bazel + Python 3 will result in creating two different instance of - # DESCRIPTOR for each message. So, the equal comparison between protobuf - # returned by stub and manually crafted protobuf will always fail. - def _assert_sequence_of_proto_equal(self, x, y): - self.assertSequenceEqual( - list(map(lambda x: x.SerializeToString(), x)), - list(map(lambda x: x.SerializeToString(), y)), - ) - def setUp(self): self._server = test_common.test_server() reflection.enable_server_reflection(_SERVICE_NAMES, self._server) @@ -94,7 +84,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self._assert_sequence_of_proto_equal(expected_responses, responses) + self.assertSequenceEqual(expected_responses, responses) def testFileBySymbol(self): requests = ( @@ -118,7 +108,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self._assert_sequence_of_proto_equal(expected_responses, responses) + self.assertSequenceEqual(expected_responses, responses) def testFileContainingExtension(self): requests = ( @@ -147,7 +137,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self._assert_sequence_of_proto_equal(expected_responses, responses) + self.assertSequenceEqual(expected_responses, responses) def testExtensionNumbersOfType(self): requests = ( @@ -172,7 +162,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self._assert_sequence_of_proto_equal(expected_responses, responses) + self.assertSequenceEqual(expected_responses, responses) def testListServices(self): requests = (reflection_pb2.ServerReflectionRequest(list_services='',),) @@ -183,7 +173,7 @@ class ReflectionServicerTest(unittest.TestCase): service=tuple( reflection_pb2.ServiceResponse(name=name) for name in _SERVICE_NAMES))),) - self._assert_sequence_of_proto_equal(expected_responses, responses) + self.assertSequenceEqual(expected_responses, responses) def testReflectionServiceName(self): self.assertEqual(reflection.SERVICE_NAME, diff --git a/src/python/grpcio_tests/tests/status/BUILD.bazel b/src/python/grpcio_tests/tests/status/BUILD.bazel index b163fe3975e..937e50498e0 100644 --- a/src/python/grpcio_tests/tests/status/BUILD.bazel +++ b/src/python/grpcio_tests/tests/status/BUILD.bazel @@ -10,7 +10,6 @@ py_test( deps = [ "//src/python/grpcio/grpc:grpcio", "//src/python/grpcio_status/grpc_status:grpc_status", - "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", "//src/python/grpcio_tests/tests/unit:test_common", "//src/python/grpcio_tests/tests/unit/framework/common:common", requirement('protobuf'), diff --git a/src/python/grpcio_tests/tests/status/_grpc_status_test.py b/src/python/grpcio_tests/tests/status/_grpc_status_test.py index 77f5fb283d1..519c372a960 100644 --- a/src/python/grpcio_tests/tests/status/_grpc_status_test.py +++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py @@ -13,9 +13,6 @@ # limitations under the License. """Tests of grpc_status.""" -from tests import bazel_namespace_package_hack -bazel_namespace_package_hack.sys_path_to_site_dir_hack() - import unittest import logging diff --git a/third_party/py/python_configure.bzl b/third_party/py/python_configure.bzl index 9036a95909b..2ba1e07049c 100644 --- a/third_party/py/python_configure.bzl +++ b/third_party/py/python_configure.bzl @@ -138,13 +138,10 @@ def _symlink_genrule_for_dir(repository_ctx, def _get_python_bin(repository_ctx): """Gets the python bin path.""" - python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH, 'python') - if not '/' in python_bin and not '\\' in python_bin: - # It's a command, use 'which' to find its path. - python_bin_path = repository_ctx.which(python_bin) - else: - # It's a path, use it as it is. - python_bin_path = python_bin + python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH) + if python_bin != None: + return python_bin + python_bin_path = repository_ctx.which("python") if python_bin_path != None: return str(python_bin_path) _fail("Cannot find python in PATH, please make sure " + diff --git a/tools/bazel.rc b/tools/bazel.rc index 99347495361..59e597b4723 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -57,7 +57,3 @@ build:basicprof --copt=-DNDEBUG build:basicprof --copt=-O2 build:basicprof --copt=-DGRPC_BASIC_PROFILER build:basicprof --copt=-DGRPC_TIMERS_RDTSC - -build:python3 --python_path=python3 -build:python3 --force_python=PY3 -build:python3 --action_env=PYTHON_BIN_PATH=python3 diff --git a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh index 14989648a2a..156d65955ad 100755 --- a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh +++ b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh @@ -25,5 +25,3 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc ${name}') cd /var/local/git/grpc/test bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... -bazel clean --expunge -bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... From bbfc024a02e522570e75e6645bd154568aedd022 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 29 Jan 2019 15:23:55 -0800 Subject: [PATCH 213/814] Revert "C++-ify subchannel" --- .../filters/client_channel/client_channel.cc | 114 +- .../filters/client_channel/client_channel.h | 4 +- .../client_channel/client_channel_channelz.cc | 11 +- .../client_channel/client_channel_channelz.h | 9 +- .../client_channel/client_channel_factory.cc | 2 +- .../client_channel/client_channel_factory.h | 6 +- .../client_channel/global_subchannel_pool.cc | 19 +- .../client_channel/global_subchannel_pool.h | 6 +- .../health/health_check_client.cc | 18 +- .../health/health_check_client.h | 2 +- .../lb_policy/pick_first/pick_first.cc | 2 +- .../lb_policy/round_robin/round_robin.cc | 2 +- .../lb_policy/subchannel_list.h | 37 +- .../client_channel/local_subchannel_pool.cc | 14 +- .../client_channel/local_subchannel_pool.h | 6 +- .../ext/filters/client_channel/subchannel.cc | 1490 +++++++++-------- .../ext/filters/client_channel/subchannel.h | 331 ++-- .../subchannel_pool_interface.h | 10 +- .../chttp2/client/chttp2_connector.cc | 3 +- .../chttp2/client/insecure/channel_create.cc | 4 +- .../client/secure/secure_channel_create.cc | 7 +- test/core/util/debugger_macros.cc | 5 +- test/cpp/microbenchmarks/bm_call_create.cc | 4 +- 23 files changed, 1054 insertions(+), 1052 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 38525dbf97e..35c3efab6aa 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -394,7 +394,7 @@ struct subchannel_batch_data { gpr_refcount refs; grpc_call_element* elem; - grpc_core::RefCountedPtr subchannel_call; + grpc_subchannel_call* subchannel_call; // Holds a ref. // The batch to use in the subchannel call. // Its payload field points to subchannel_call_retry_state.batch_payload. grpc_transport_stream_op_batch batch; @@ -478,7 +478,7 @@ struct pending_batch { bool send_ops_cached; }; -/** Call data. Holds a pointer to SubchannelCall and the +/** Call data. Holds a pointer to grpc_subchannel_call and the associated machinery to create such a pointer. Handles queueing of stream ops until a call object is ready, waiting for initial metadata before trying to create a call object, @@ -504,6 +504,10 @@ struct call_data { last_attempt_got_server_pushback(false) {} ~call_data() { + if (GPR_LIKELY(subchannel_call != nullptr)) { + GRPC_SUBCHANNEL_CALL_UNREF(subchannel_call, + "client_channel_destroy_call"); + } grpc_slice_unref_internal(path); GRPC_ERROR_UNREF(cancel_error); for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches); ++i) { @@ -532,7 +536,7 @@ struct call_data { grpc_core::RefCountedPtr retry_throttle_data; grpc_core::RefCountedPtr method_params; - grpc_core::RefCountedPtr subchannel_call; + grpc_subchannel_call* subchannel_call = nullptr; // Set when we get a cancel_stream op. grpc_error* cancel_error = GRPC_ERROR_NONE; @@ -803,8 +807,8 @@ static void pending_batches_add(grpc_call_element* elem, calld->subchannel_call == nullptr ? nullptr : static_cast( - - calld->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + calld->subchannel_call)); retry_commit(elem, retry_state); // If we are not going to retry and have not yet started, pretend // retries are disabled so that we don't bother with retry overhead. @@ -892,10 +896,10 @@ static void resume_pending_batch_in_call_combiner(void* arg, grpc_error* ignored) { grpc_transport_stream_op_batch* batch = static_cast(arg); - grpc_core::SubchannelCall* subchannel_call = - static_cast(batch->handler_private.extra_arg); + grpc_subchannel_call* subchannel_call = + static_cast(batch->handler_private.extra_arg); // Note: This will release the call combiner. - subchannel_call->StartTransportStreamOpBatch(batch); + grpc_subchannel_call_process_op(subchannel_call, batch); } // This is called via the call combiner, so access to calld is synchronized. @@ -915,7 +919,7 @@ static void pending_batches_resume(grpc_call_element* elem) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting %" PRIuPTR " pending batches on subchannel_call=%p", - chand, calld, num_batches, calld->subchannel_call.get()); + chand, calld, num_batches, calld->subchannel_call); } grpc_core::CallCombinerClosureList closures; for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { @@ -926,7 +930,7 @@ static void pending_batches_resume(grpc_call_element* elem) { maybe_inject_recv_trailing_metadata_ready_for_lb( *calld->request->pick(), batch); } - batch->handler_private.extra_arg = calld->subchannel_call.get(); + batch->handler_private.extra_arg = calld->subchannel_call; GRPC_CLOSURE_INIT(&batch->handler_private.closure, resume_pending_batch_in_call_combiner, batch, grpc_schedule_on_exec_ctx); @@ -1015,7 +1019,12 @@ static void do_retry(grpc_call_element* elem, const ClientChannelMethodParams::RetryPolicy* retry_policy = calld->method_params->retry_policy(); GPR_ASSERT(retry_policy != nullptr); - calld->subchannel_call.reset(); + // Reset subchannel call and connected subchannel. + if (calld->subchannel_call != nullptr) { + GRPC_SUBCHANNEL_CALL_UNREF(calld->subchannel_call, + "client_channel_call_retry"); + calld->subchannel_call = nullptr; + } if (calld->have_request) { calld->have_request = false; calld->request.Destroy(); @@ -1069,7 +1078,8 @@ static bool maybe_retry(grpc_call_element* elem, subchannel_call_retry_state* retry_state = nullptr; if (batch_data != nullptr) { retry_state = static_cast( - batch_data->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + batch_data->subchannel_call)); if (retry_state->retry_dispatched) { if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: retry already dispatched", chand, @@ -1170,10 +1180,13 @@ namespace { subchannel_batch_data::subchannel_batch_data(grpc_call_element* elem, call_data* calld, int refcount, bool set_on_complete) - : elem(elem), subchannel_call(calld->subchannel_call) { + : elem(elem), + subchannel_call(GRPC_SUBCHANNEL_CALL_REF(calld->subchannel_call, + "batch_data_create")) { subchannel_call_retry_state* retry_state = static_cast( - calld->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + calld->subchannel_call)); batch.payload = &retry_state->batch_payload; gpr_ref_init(&refs, refcount); if (set_on_complete) { @@ -1187,7 +1200,7 @@ subchannel_batch_data::subchannel_batch_data(grpc_call_element* elem, void subchannel_batch_data::destroy() { subchannel_call_retry_state* retry_state = static_cast( - subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data(subchannel_call)); if (batch.send_initial_metadata) { grpc_metadata_batch_destroy(&retry_state->send_initial_metadata); } @@ -1200,7 +1213,7 @@ void subchannel_batch_data::destroy() { if (batch.recv_trailing_metadata) { grpc_metadata_batch_destroy(&retry_state->recv_trailing_metadata); } - subchannel_call.reset(); + GRPC_SUBCHANNEL_CALL_UNREF(subchannel_call, "batch_data_unref"); call_data* calld = static_cast(elem->call_data); GRPC_CALL_STACK_UNREF(calld->owning_call, "batch_data"); } @@ -1247,7 +1260,8 @@ static void invoke_recv_initial_metadata_callback(void* arg, // Return metadata. subchannel_call_retry_state* retry_state = static_cast( - batch_data->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + batch_data->subchannel_call)); grpc_metadata_batch_move( &retry_state->recv_initial_metadata, pending->batch->payload->recv_initial_metadata.recv_initial_metadata); @@ -1279,7 +1293,8 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - batch_data->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + batch_data->subchannel_call)); retry_state->completed_recv_initial_metadata = true; // If a retry was already dispatched, then we're not going to use the // result of this recv_initial_metadata op, so do nothing. @@ -1340,7 +1355,8 @@ static void invoke_recv_message_callback(void* arg, grpc_error* error) { // Return payload. subchannel_call_retry_state* retry_state = static_cast( - batch_data->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + batch_data->subchannel_call)); *pending->batch->payload->recv_message.recv_message = std::move(retry_state->recv_message); // Update bookkeeping. @@ -1368,7 +1384,8 @@ static void recv_message_ready(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - batch_data->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + batch_data->subchannel_call)); ++retry_state->completed_recv_message_count; // If a retry was already dispatched, then we're not going to use the // result of this recv_message op, so do nothing. @@ -1456,7 +1473,8 @@ static void add_closure_for_recv_trailing_metadata_ready( // Return metadata. subchannel_call_retry_state* retry_state = static_cast( - batch_data->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + batch_data->subchannel_call)); grpc_metadata_batch_move( &retry_state->recv_trailing_metadata, pending->batch->payload->recv_trailing_metadata.recv_trailing_metadata); @@ -1558,7 +1576,8 @@ static void run_closures_for_completed_call(subchannel_batch_data* batch_data, call_data* calld = static_cast(elem->call_data); subchannel_call_retry_state* retry_state = static_cast( - batch_data->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + batch_data->subchannel_call)); // Construct list of closures to execute. grpc_core::CallCombinerClosureList closures; // First, add closure for recv_trailing_metadata_ready. @@ -1592,7 +1611,8 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - batch_data->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + batch_data->subchannel_call)); retry_state->completed_recv_trailing_metadata = true; // Get the call's status and check for server pushback metadata. grpc_status_code status = GRPC_STATUS_OK; @@ -1715,7 +1735,8 @@ static void on_complete(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - batch_data->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + batch_data->subchannel_call)); // Update bookkeeping in retry_state. if (batch_data->batch.send_initial_metadata) { retry_state->completed_send_initial_metadata = true; @@ -1771,10 +1792,10 @@ static void on_complete(void* arg, grpc_error* error) { static void start_batch_in_call_combiner(void* arg, grpc_error* ignored) { grpc_transport_stream_op_batch* batch = static_cast(arg); - grpc_core::SubchannelCall* subchannel_call = - static_cast(batch->handler_private.extra_arg); + grpc_subchannel_call* subchannel_call = + static_cast(batch->handler_private.extra_arg); // Note: This will release the call combiner. - subchannel_call->StartTransportStreamOpBatch(batch); + grpc_subchannel_call_process_op(subchannel_call, batch); } // Adds a closure to closures that will execute batch in the call combiner. @@ -1783,7 +1804,7 @@ static void add_closure_for_subchannel_batch( grpc_core::CallCombinerClosureList* closures) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - batch->handler_private.extra_arg = calld->subchannel_call.get(); + batch->handler_private.extra_arg = calld->subchannel_call; GRPC_CLOSURE_INIT(&batch->handler_private.closure, start_batch_in_call_combiner, batch, grpc_schedule_on_exec_ctx); @@ -1957,7 +1978,8 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem) { } subchannel_call_retry_state* retry_state = static_cast( - calld->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + calld->subchannel_call)); // Create batch_data with 2 refs, since this batch will be unreffed twice: // once for the recv_trailing_metadata_ready callback when the subchannel // batch returns, and again when we actually get a recv_trailing_metadata @@ -1967,7 +1989,7 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem) { add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data); retry_state->recv_trailing_metadata_internal_batch = batch_data; // Note: This will release the call combiner. - calld->subchannel_call->StartTransportStreamOpBatch(&batch_data->batch); + grpc_subchannel_call_process_op(calld->subchannel_call, &batch_data->batch); } // If there are any cached send ops that need to be replayed on the @@ -2174,7 +2196,8 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { } subchannel_call_retry_state* retry_state = static_cast( - calld->subchannel_call->GetParentData()); + grpc_connected_subchannel_call_get_parent_data( + calld->subchannel_call)); // Construct list of closures to execute, one for each pending batch. grpc_core::CallCombinerClosureList closures; // Replay previously-returned send_* ops if needed. @@ -2197,7 +2220,7 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting %" PRIuPTR " retriable batches on subchannel_call=%p", - chand, calld, closures.size(), calld->subchannel_call.get()); + chand, calld, closures.size(), calld->subchannel_call); } // Note: This will yield the call combiner. closures.RunClosures(calld->call_combiner); @@ -2222,22 +2245,22 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { calld->call_combiner, // call_combiner parent_data_size // parent_data_size }; - grpc_error* new_error = GRPC_ERROR_NONE; - calld->subchannel_call = - calld->request->pick()->connected_subchannel->CreateCall(call_args, - &new_error); + grpc_error* new_error = + calld->request->pick()->connected_subchannel->CreateCall( + call_args, &calld->subchannel_call); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", - chand, calld, calld->subchannel_call.get(), - grpc_error_string(new_error)); + chand, calld, calld->subchannel_call, grpc_error_string(new_error)); } if (GPR_UNLIKELY(new_error != GRPC_ERROR_NONE)) { new_error = grpc_error_add_child(new_error, error); pending_batches_fail(elem, new_error, true /* yield_call_combiner */); } else { if (parent_data_size > 0) { - new (calld->subchannel_call->GetParentData()) subchannel_call_retry_state( - calld->request->pick()->subchannel_call_context); + new (grpc_connected_subchannel_call_get_parent_data( + calld->subchannel_call)) + subchannel_call_retry_state( + calld->request->pick()->subchannel_call_context); } pending_batches_resume(elem); } @@ -2465,7 +2488,7 @@ static void cc_start_transport_stream_op_batch( batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner); } else { // Note: This will release the call combiner. - calld->subchannel_call->StartTransportStreamOpBatch(batch); + grpc_subchannel_call_process_op(calld->subchannel_call, batch); } return; } @@ -2479,7 +2502,7 @@ static void cc_start_transport_stream_op_batch( if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting batch on subchannel_call=%p", chand, - calld, calld->subchannel_call.get()); + calld, calld->subchannel_call); } pending_batches_resume(elem); return; @@ -2522,7 +2545,8 @@ static void cc_destroy_call_elem(grpc_call_element* elem, grpc_closure* then_schedule_closure) { call_data* calld = static_cast(elem->call_data); if (GPR_LIKELY(calld->subchannel_call != nullptr)) { - calld->subchannel_call->SetAfterCallStackDestroy(then_schedule_closure); + grpc_subchannel_call_set_cleanup_closure(calld->subchannel_call, + then_schedule_closure); then_schedule_closure = nullptr; } calld->~call_data(); @@ -2728,8 +2752,8 @@ void grpc_client_channel_watch_connectivity_state( GRPC_ERROR_NONE); } -grpc_core::RefCountedPtr -grpc_client_channel_get_subchannel_call(grpc_call_element* elem) { +grpc_subchannel_call* grpc_client_channel_get_subchannel_call( + grpc_call_element* elem) { call_data* calld = static_cast(elem->call_data); return calld->subchannel_call; } diff --git a/src/core/ext/filters/client_channel/client_channel.h b/src/core/ext/filters/client_channel/client_channel.h index 5bfff4df9cd..4935fd24d87 100644 --- a/src/core/ext/filters/client_channel/client_channel.h +++ b/src/core/ext/filters/client_channel/client_channel.h @@ -60,7 +60,7 @@ void grpc_client_channel_watch_connectivity_state( grpc_closure* watcher_timer_init); /* Debug helper: pull the subchannel call from a call stack element */ -grpc_core::RefCountedPtr -grpc_client_channel_get_subchannel_call(grpc_call_element* elem); +grpc_subchannel_call* grpc_client_channel_get_subchannel_call( + grpc_call_element* elem); #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H */ diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 76c5a786240..8e5426081c4 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -113,11 +113,12 @@ RefCountedPtr ClientChannelNode::MakeClientChannelNode( is_top_level_channel); } -SubchannelNode::SubchannelNode(Subchannel* subchannel, +SubchannelNode::SubchannelNode(grpc_subchannel* subchannel, size_t channel_tracer_max_nodes) : BaseNode(EntityType::kSubchannel), subchannel_(subchannel), - target_(UniquePtr(gpr_strdup(subchannel_->GetTargetAddress()))), + target_( + UniquePtr(gpr_strdup(grpc_subchannel_get_target(subchannel_)))), trace_(channel_tracer_max_nodes) {} SubchannelNode::~SubchannelNode() {} @@ -127,8 +128,8 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) { if (subchannel_ == nullptr) { state = GRPC_CHANNEL_SHUTDOWN; } else { - state = subchannel_->CheckConnectivity(nullptr, - true /* inhibit_health_checking */); + state = grpc_subchannel_check_connectivity( + subchannel_, nullptr, true /* inhibit_health_checking */); } json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); @@ -169,7 +170,7 @@ grpc_json* SubchannelNode::RenderJson() { call_counter_.PopulateCallCounts(json); json = top_level_json; // populate the child socket. - intptr_t socket_uuid = subchannel_->GetChildSocketUuid(); + intptr_t socket_uuid = grpc_subchannel_get_child_socket_uuid(subchannel_); if (socket_uuid != 0) { grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 1dc1bf595be..8a5c3e7e5e5 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -26,10 +26,9 @@ #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" +typedef struct grpc_subchannel grpc_subchannel; + namespace grpc_core { - -class Subchannel; - namespace channelz { // Subtype of ChannelNode that overrides and provides client_channel specific @@ -60,7 +59,7 @@ class ClientChannelNode : public ChannelNode { // Handles channelz bookkeeping for sockets class SubchannelNode : public BaseNode { public: - SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes); + SubchannelNode(grpc_subchannel* subchannel, size_t channel_tracer_max_nodes); ~SubchannelNode() override; void MarkSubchannelDestroyed() { @@ -85,7 +84,7 @@ class SubchannelNode : public BaseNode { void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } private: - Subchannel* subchannel_; + grpc_subchannel* subchannel_; UniquePtr target_; CallCountingHelper call_counter_; ChannelTrace trace_; diff --git a/src/core/ext/filters/client_channel/client_channel_factory.cc b/src/core/ext/filters/client_channel/client_channel_factory.cc index 8c558382fdf..130bbe04180 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.cc +++ b/src/core/ext/filters/client_channel/client_channel_factory.cc @@ -29,7 +29,7 @@ void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory) { factory->vtable->unref(factory); } -grpc_core::Subchannel* grpc_client_channel_factory_create_subchannel( +grpc_subchannel* grpc_client_channel_factory_create_subchannel( grpc_client_channel_factory* factory, const grpc_channel_args* args) { return factory->vtable->create_subchannel(factory, args); } diff --git a/src/core/ext/filters/client_channel/client_channel_factory.h b/src/core/ext/filters/client_channel/client_channel_factory.h index 4b72aa46499..91dec12282f 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -48,8 +48,8 @@ struct grpc_client_channel_factory { struct grpc_client_channel_factory_vtable { void (*ref)(grpc_client_channel_factory* factory); void (*unref)(grpc_client_channel_factory* factory); - grpc_core::Subchannel* (*create_subchannel)( - grpc_client_channel_factory* factory, const grpc_channel_args* args); + grpc_subchannel* (*create_subchannel)(grpc_client_channel_factory* factory, + const grpc_channel_args* args); grpc_channel* (*create_client_channel)(grpc_client_channel_factory* factory, const char* target, grpc_client_channel_type type, @@ -60,7 +60,7 @@ void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory); void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory); /** Create a new grpc_subchannel */ -grpc_core::Subchannel* grpc_client_channel_factory_create_subchannel( +grpc_subchannel* grpc_client_channel_factory_create_subchannel( grpc_client_channel_factory* factory, const grpc_channel_args* args); /** Create a new grpc_channel */ diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.cc b/src/core/ext/filters/client_channel/global_subchannel_pool.cc index ee6e58159a0..a41d993fe66 100644 --- a/src/core/ext/filters/client_channel/global_subchannel_pool.cc +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.cc @@ -54,9 +54,9 @@ RefCountedPtr GlobalSubchannelPool::instance() { return *instance_; } -Subchannel* GlobalSubchannelPool::RegisterSubchannel(SubchannelKey* key, - Subchannel* constructed) { - Subchannel* c = nullptr; +grpc_subchannel* GlobalSubchannelPool::RegisterSubchannel( + SubchannelKey* key, grpc_subchannel* constructed) { + grpc_subchannel* c = nullptr; // Compare and swap (CAS) loop: while (c == nullptr) { // Ref the shared map to have a local copy. @@ -64,7 +64,7 @@ Subchannel* GlobalSubchannelPool::RegisterSubchannel(SubchannelKey* key, grpc_avl old_map = grpc_avl_ref(subchannel_map_, nullptr); gpr_mu_unlock(&mu_); // Check to see if a subchannel already exists. - c = static_cast(grpc_avl_get(old_map, key, nullptr)); + c = static_cast(grpc_avl_get(old_map, key, nullptr)); if (c != nullptr) { // The subchannel already exists. Reuse it. c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "subchannel_register+reuse"); @@ -121,14 +121,15 @@ void GlobalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { } } -Subchannel* GlobalSubchannelPool::FindSubchannel(SubchannelKey* key) { +grpc_subchannel* GlobalSubchannelPool::FindSubchannel(SubchannelKey* key) { // Lock, and take a reference to the subchannel map. // We don't need to do the search under a lock as AVL's are immutable. gpr_mu_lock(&mu_); grpc_avl index = grpc_avl_ref(subchannel_map_, nullptr); gpr_mu_unlock(&mu_); - Subchannel* c = static_cast(grpc_avl_get(index, key, nullptr)); - if (c != nullptr) GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "found_from_pool"); + grpc_subchannel* c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF( + static_cast(grpc_avl_get(index, key, nullptr)), + "found_from_pool"); grpc_avl_unref(index, nullptr); return c; } @@ -155,11 +156,11 @@ long sck_avl_compare(void* a, void* b, void* unused) { } void scv_avl_destroy(void* p, void* user_data) { - GRPC_SUBCHANNEL_WEAK_UNREF((Subchannel*)p, "global_subchannel_pool"); + GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "global_subchannel_pool"); } void* scv_avl_copy(void* p, void* unused) { - GRPC_SUBCHANNEL_WEAK_REF((Subchannel*)p, "global_subchannel_pool"); + GRPC_SUBCHANNEL_WEAK_REF((grpc_subchannel*)p, "global_subchannel_pool"); return p; } diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.h b/src/core/ext/filters/client_channel/global_subchannel_pool.h index 96dc8d7b3a4..0deb3769360 100644 --- a/src/core/ext/filters/client_channel/global_subchannel_pool.h +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.h @@ -45,10 +45,10 @@ class GlobalSubchannelPool final : public SubchannelPoolInterface { static RefCountedPtr instance(); // Implements interface methods. - Subchannel* RegisterSubchannel(SubchannelKey* key, - Subchannel* constructed) override; + grpc_subchannel* RegisterSubchannel(SubchannelKey* key, + grpc_subchannel* constructed) override; void UnregisterSubchannel(SubchannelKey* key) override; - Subchannel* FindSubchannel(SubchannelKey* key) override; + grpc_subchannel* FindSubchannel(SubchannelKey* key) override; private: // The singleton instance. (It's a pointer to RefCountedPtr so that this diff --git a/src/core/ext/filters/client_channel/health/health_check_client.cc b/src/core/ext/filters/client_channel/health/health_check_client.cc index e845d63d295..2232c57120e 100644 --- a/src/core/ext/filters/client_channel/health/health_check_client.cc +++ b/src/core/ext/filters/client_channel/health/health_check_client.cc @@ -295,9 +295,7 @@ HealthCheckClient::CallState::~CallState() { gpr_log(GPR_INFO, "HealthCheckClient %p: destroying CallState %p", health_check_client_.get(), this); } - // The subchannel call is in the arena, so reset the pointer before we destroy - // the arena. - call_.reset(); + if (call_ != nullptr) GRPC_SUBCHANNEL_CALL_UNREF(call_, "call_ended"); for (size_t i = 0; i < GRPC_CONTEXT_COUNT; i++) { if (context_[i].destroy != nullptr) { context_[i].destroy(context_[i].value); @@ -331,8 +329,8 @@ void HealthCheckClient::CallState::StartCall() { &call_combiner_, 0, // parent_data_size }; - grpc_error* error = GRPC_ERROR_NONE; - call_ = health_check_client_->connected_subchannel_->CreateCall(args, &error); + grpc_error* error = + health_check_client_->connected_subchannel_->CreateCall(args, &call_); if (error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "HealthCheckClient %p CallState %p: error creating health " @@ -425,14 +423,14 @@ void HealthCheckClient::CallState::StartBatchInCallCombiner(void* arg, grpc_error* error) { grpc_transport_stream_op_batch* batch = static_cast(arg); - SubchannelCall* call = - static_cast(batch->handler_private.extra_arg); - call->StartTransportStreamOpBatch(batch); + grpc_subchannel_call* call = + static_cast(batch->handler_private.extra_arg); + grpc_subchannel_call_process_op(call, batch); } void HealthCheckClient::CallState::StartBatch( grpc_transport_stream_op_batch* batch) { - batch->handler_private.extra_arg = call_.get(); + batch->handler_private.extra_arg = call_; GRPC_CLOSURE_INIT(&batch->handler_private.closure, StartBatchInCallCombiner, batch, grpc_schedule_on_exec_ctx); GRPC_CALL_COMBINER_START(&call_combiner_, &batch->handler_private.closure, @@ -454,7 +452,7 @@ void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) { GRPC_CLOSURE_CREATE(OnCancelComplete, self, grpc_schedule_on_exec_ctx)); batch->cancel_stream = true; batch->payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED; - self->call_->StartTransportStreamOpBatch(batch); + grpc_subchannel_call_process_op(self->call_, batch); } void HealthCheckClient::CallState::Cancel() { diff --git a/src/core/ext/filters/client_channel/health/health_check_client.h b/src/core/ext/filters/client_channel/health/health_check_client.h index 7af88a54cfc..2369b73feac 100644 --- a/src/core/ext/filters/client_channel/health/health_check_client.h +++ b/src/core/ext/filters/client_channel/health/health_check_client.h @@ -99,7 +99,7 @@ class HealthCheckClient : public InternallyRefCounted { grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {}; // The streaming call to the backend. Always non-NULL. - RefCountedPtr call_; + grpc_subchannel_call* call_; grpc_transport_stream_op_batch_payload payload_; grpc_transport_stream_op_batch batch_; diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index dc716a6adac..ec5c782c469 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -79,7 +79,7 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) : SubchannelData(subchannel_list, address, subchannel, combiner) {} diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index aab6dd68216..30316689ea7 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -94,7 +94,7 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) : SubchannelData(subchannel_list, address, subchannel, combiner) {} diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 0174a98a73d..2eb92b7ead0 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -88,7 +88,7 @@ class SubchannelData { } // Returns a pointer to the subchannel. - Subchannel* subchannel() const { return subchannel_; } + grpc_subchannel* subchannel() const { return subchannel_; } // Returns the connected subchannel. Will be null if the subchannel // is not connected. @@ -103,8 +103,8 @@ class SubchannelData { // ProcessConnectivityChangeLocked()). grpc_connectivity_state CheckConnectivityStateLocked(grpc_error** error) { GPR_ASSERT(!connectivity_notification_pending_); - pending_connectivity_state_unsafe_ = subchannel()->CheckConnectivity( - error, subchannel_list_->inhibit_health_checking()); + pending_connectivity_state_unsafe_ = grpc_subchannel_check_connectivity( + subchannel(), error, subchannel_list_->inhibit_health_checking()); UpdateConnectedSubchannelLocked(); return pending_connectivity_state_unsafe_; } @@ -142,7 +142,7 @@ class SubchannelData { protected: SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner); virtual ~SubchannelData(); @@ -170,7 +170,7 @@ class SubchannelData { SubchannelList* subchannel_list_; // The subchannel and connected subchannel. - Subchannel* subchannel_; + grpc_subchannel* subchannel_; RefCountedPtr connected_subchannel_; // Notification that connectivity has changed on subchannel. @@ -203,7 +203,7 @@ class SubchannelList : public InternallyRefCounted { for (size_t i = 0; i < subchannels_.size(); ++i) { if (subchannels_[i].subchannel() != nullptr) { grpc_core::channelz::SubchannelNode* subchannel_node = - subchannels_[i].subchannel()->channelz_node(); + grpc_subchannel_get_channelz_node(subchannels_[i].subchannel()); if (subchannel_node != nullptr) { refs_list->push_back(subchannel_node->uuid()); } @@ -276,7 +276,7 @@ class SubchannelList : public InternallyRefCounted { template SubchannelData::SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, Subchannel* subchannel, + const ServerAddress& address, grpc_subchannel* subchannel, grpc_combiner* combiner) : subchannel_list_(subchannel_list), subchannel_(subchannel), @@ -317,7 +317,7 @@ template void SubchannelData::ResetBackoffLocked() { if (subchannel_ != nullptr) { - subchannel_->ResetBackoff(); + grpc_subchannel_reset_backoff(subchannel_); } } @@ -337,8 +337,8 @@ void SubchannelDataRef(DEBUG_LOCATION, "connectivity_watch").release(); - subchannel_->NotifyOnStateChange( - subchannel_list_->policy()->interested_parties(), + grpc_subchannel_notify_on_state_change( + subchannel_, subchannel_list_->policy()->interested_parties(), &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, subchannel_list_->inhibit_health_checking()); } @@ -357,8 +357,8 @@ void SubchannelDataNotifyOnStateChange( - subchannel_list_->policy()->interested_parties(), + grpc_subchannel_notify_on_state_change( + subchannel_, subchannel_list_->policy()->interested_parties(), &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, subchannel_list_->inhibit_health_checking()); } @@ -391,9 +391,9 @@ void SubchannelData:: subchannel_, reason); } GPR_ASSERT(connectivity_notification_pending_); - subchannel_->NotifyOnStateChange(nullptr, nullptr, - &connectivity_changed_closure_, - subchannel_list_->inhibit_health_checking()); + grpc_subchannel_notify_on_state_change( + subchannel_, nullptr, nullptr, &connectivity_changed_closure_, + subchannel_list_->inhibit_health_checking()); } template @@ -401,7 +401,8 @@ bool SubchannelData::UpdateConnectedSubchannelLocked() { // If the subchannel is READY, take a ref to the connected subchannel. if (pending_connectivity_state_unsafe_ == GRPC_CHANNEL_READY) { - connected_subchannel_ = subchannel_->connected_subchannel(); + connected_subchannel_ = + grpc_subchannel_get_connected_subchannel(subchannel_); // If the subchannel became disconnected between the time that READY // was reported and the time we got here (e.g., between when a // notification callback is scheduled and when it was actually run in @@ -517,7 +518,7 @@ SubchannelList::SubchannelList( SubchannelPoolInterface::CreateChannelArg(policy_->subchannel_pool())); const size_t subchannel_address_arg_index = args_to_add.size(); args_to_add.emplace_back( - Subchannel::CreateSubchannelAddressArg(&addresses[i].address())); + grpc_create_subchannel_address_arg(&addresses[i].address())); if (addresses[i].args() != nullptr) { for (size_t j = 0; j < addresses[i].args()->num_args; ++j) { args_to_add.emplace_back(addresses[i].args()->args[j]); @@ -527,7 +528,7 @@ SubchannelList::SubchannelList( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); gpr_free(args_to_add[subchannel_address_arg_index].value.string); - Subchannel* subchannel = grpc_client_channel_factory_create_subchannel( + grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( client_channel_factory, new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) { diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.cc b/src/core/ext/filters/client_channel/local_subchannel_pool.cc index d1c1cacb441..145fa4e0374 100644 --- a/src/core/ext/filters/client_channel/local_subchannel_pool.cc +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.cc @@ -32,11 +32,11 @@ LocalSubchannelPool::~LocalSubchannelPool() { grpc_avl_unref(subchannel_map_, nullptr); } -Subchannel* LocalSubchannelPool::RegisterSubchannel(SubchannelKey* key, - Subchannel* constructed) { +grpc_subchannel* LocalSubchannelPool::RegisterSubchannel( + SubchannelKey* key, grpc_subchannel* constructed) { // Check to see if a subchannel already exists. - Subchannel* c = - static_cast(grpc_avl_get(subchannel_map_, key, nullptr)); + grpc_subchannel* c = static_cast( + grpc_avl_get(subchannel_map_, key, nullptr)); if (c != nullptr) { // The subchannel already exists. Reuse it. c = GRPC_SUBCHANNEL_REF(c, "subchannel_register+reuse"); @@ -54,9 +54,9 @@ void LocalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { subchannel_map_ = grpc_avl_remove(subchannel_map_, key, nullptr); } -Subchannel* LocalSubchannelPool::FindSubchannel(SubchannelKey* key) { - Subchannel* c = - static_cast(grpc_avl_get(subchannel_map_, key, nullptr)); +grpc_subchannel* LocalSubchannelPool::FindSubchannel(SubchannelKey* key) { + grpc_subchannel* c = static_cast( + grpc_avl_get(subchannel_map_, key, nullptr)); return c == nullptr ? c : GRPC_SUBCHANNEL_REF(c, "found_from_pool"); } diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.h b/src/core/ext/filters/client_channel/local_subchannel_pool.h index a6b7e259fbb..9929cdb3627 100644 --- a/src/core/ext/filters/client_channel/local_subchannel_pool.h +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.h @@ -39,10 +39,10 @@ class LocalSubchannelPool final : public SubchannelPoolInterface { // Implements interface methods. // Thread-unsafe. Intended to be invoked within the client_channel combiner. - Subchannel* RegisterSubchannel(SubchannelKey* key, - Subchannel* constructed) override; + grpc_subchannel* RegisterSubchannel(SubchannelKey* key, + grpc_subchannel* constructed) override; void UnregisterSubchannel(SubchannelKey* key) override; - Subchannel* FindSubchannel(SubchannelKey* key) override; + grpc_subchannel* FindSubchannel(SubchannelKey* key) override; private: // The vtable for subchannel operations in an AVL tree. diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 70285659aad..d77bb3c286b 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -44,6 +44,7 @@ #include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/channel.h" @@ -54,256 +55,153 @@ #include "src/core/lib/transport/status_metadata.h" #include "src/core/lib/uri/uri_parser.h" -// Strong and weak refs. #define INTERNAL_REF_BITS 16 #define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1)) -// Backoff parameters. #define GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS 1 #define GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER 1.6 #define GRPC_SUBCHANNEL_RECONNECT_MIN_TIMEOUT_SECONDS 20 #define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120 #define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2 -// Conversion between subchannel call and call stack. -#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ - (grpc_call_stack*)((char*)(call) + \ - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall))) -#define CALL_STACK_TO_SUBCHANNEL_CALL(callstack) \ - (SubchannelCall*)(((char*)(call_stack)) - \ - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall))) +typedef struct external_state_watcher { + grpc_subchannel* subchannel; + grpc_pollset_set* pollset_set; + grpc_closure* notify; + grpc_closure closure; + struct external_state_watcher* next; + struct external_state_watcher* prev; +} external_state_watcher; namespace grpc_core { -// -// ConnectedSubchannel -// +class ConnectedSubchannelStateWatcher; -ConnectedSubchannel::ConnectedSubchannel( - grpc_channel_stack* channel_stack, const grpc_channel_args* args, - RefCountedPtr channelz_subchannel, - intptr_t socket_uuid) - : RefCounted(&grpc_trace_stream_refcount), - channel_stack_(channel_stack), - args_(grpc_channel_args_copy(args)), - channelz_subchannel_(std::move(channelz_subchannel)), - socket_uuid_(socket_uuid) {} +} // namespace grpc_core -ConnectedSubchannel::~ConnectedSubchannel() { - grpc_channel_args_destroy(args_); - GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); -} +struct grpc_subchannel { + /** The subchannel pool this subchannel is in */ + grpc_core::RefCountedPtr subchannel_pool; -void ConnectedSubchannel::NotifyOnStateChange( - grpc_pollset_set* interested_parties, grpc_connectivity_state* state, - grpc_closure* closure) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - grpc_channel_element* elem; - op->connectivity_state = state; - op->on_connectivity_state_change = closure; - op->bind_pollset_set = interested_parties; - elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} + grpc_connector* connector; -void ConnectedSubchannel::Ping(grpc_closure* on_initiate, - grpc_closure* on_ack) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - grpc_channel_element* elem; - op->send_ping.on_initiate = on_initiate; - op->send_ping.on_ack = on_ack; - elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} + /** refcount + - lower INTERNAL_REF_BITS bits are for internal references: + these do not keep the subchannel open. + - upper remaining bits are for public references: these do + keep the subchannel open */ + gpr_atm ref_pair; -namespace { + /** channel arguments */ + grpc_channel_args* args; -void SubchannelCallDestroy(void* arg, grpc_error* error) { - GPR_TIMER_SCOPE("subchannel_call_destroy", 0); - SubchannelCall* call = static_cast(arg); - grpc_closure* after_call_stack_destroy = call->after_call_stack_destroy(); - call->~SubchannelCall(); - // This should be the last step to destroy the subchannel call, because - // call->after_call_stack_destroy(), if not null, will free the call arena. - grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(call), nullptr, - after_call_stack_destroy); -} + grpc_core::SubchannelKey* key; -} // namespace + /** set during connection */ + grpc_connect_out_args connecting_result; -RefCountedPtr ConnectedSubchannel::CreateCall( - const CallArgs& args, grpc_error** error) { - const size_t allocation_size = - GetInitialCallSizeEstimate(args.parent_data_size); - RefCountedPtr call( - new (gpr_arena_alloc(args.arena, allocation_size)) - SubchannelCall(Ref(DEBUG_LOCATION, "subchannel_call"), args)); - grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call.get()); - const grpc_call_element_args call_args = { - callstk, /* call_stack */ - nullptr, /* server_transport_data */ - args.context, /* context */ - args.path, /* path */ - args.start_time, /* start_time */ - args.deadline, /* deadline */ - args.arena, /* arena */ - args.call_combiner /* call_combiner */ - }; - *error = grpc_call_stack_init(channel_stack_, 1, SubchannelCallDestroy, - call.get(), &call_args); - if (GPR_UNLIKELY(*error != GRPC_ERROR_NONE)) { - const char* error_string = grpc_error_string(*error); - gpr_log(GPR_ERROR, "error: %s", error_string); - return call; + /** callback for connection finishing */ + grpc_closure on_connected; + + /** callback for our alarm */ + grpc_closure on_alarm; + + /** pollset_set tracking who's interested in a connection + being setup */ + grpc_pollset_set* pollset_set; + + grpc_core::UniquePtr health_check_service_name; + + /** mutex protecting remaining elements */ + gpr_mu mu; + + /** active connection, or null */ + grpc_core::RefCountedPtr connected_subchannel; + grpc_core::OrphanablePtr + connected_subchannel_watcher; + + /** have we seen a disconnection? */ + bool disconnected; + /** are we connecting */ + bool connecting; + + /** connectivity state tracking */ + grpc_connectivity_state_tracker state_tracker; + grpc_connectivity_state_tracker state_and_health_tracker; + + external_state_watcher root_external_state_watcher; + + /** backoff state */ + grpc_core::ManualConstructor backoff; + grpc_millis next_attempt_deadline; + grpc_millis min_connect_timeout_ms; + + /** do we have an active alarm? */ + bool have_alarm; + /** have we started the backoff loop */ + bool backoff_begun; + // reset_backoff() was called while alarm was pending + bool retry_immediately; + /** our alarm */ + grpc_timer alarm; + + grpc_core::RefCountedPtr + channelz_subchannel; +}; + +struct grpc_subchannel_call { + grpc_subchannel_call(grpc_core::ConnectedSubchannel* connection, + const grpc_core::ConnectedSubchannel::CallArgs& args) + : connection(connection), deadline(args.deadline) {} + + grpc_core::ConnectedSubchannel* connection; + grpc_closure* schedule_closure_after_destroy = nullptr; + // state needed to support channelz interception of recv trailing metadata. + grpc_closure recv_trailing_metadata_ready; + grpc_closure* original_recv_trailing_metadata; + grpc_metadata_batch* recv_trailing_metadata = nullptr; + grpc_millis deadline; +}; + +static void maybe_start_connecting_locked(grpc_subchannel* c); + +static const char* subchannel_connectivity_state_change_string( + grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "Subchannel state change to IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "Subchannel state change to CONNECTING"; + case GRPC_CHANNEL_READY: + return "Subchannel state change to READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "Subchannel state change to TRANSIENT_FAILURE"; + case GRPC_CHANNEL_SHUTDOWN: + return "Subchannel state change to SHUTDOWN"; } - grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); - if (channelz_subchannel_ != nullptr) { - channelz_subchannel_->RecordCallStarted(); + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +static void set_subchannel_connectivity_state_locked( + grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error, + const char* reason) { + if (c->channelz_subchannel != nullptr) { + c->channelz_subchannel->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + subchannel_connectivity_state_change_string(state))); } - return call; + grpc_connectivity_state_set(&c->state_tracker, state, error, reason); } -size_t ConnectedSubchannel::GetInitialCallSizeEstimate( - size_t parent_data_size) const { - size_t allocation_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)); - if (parent_data_size > 0) { - allocation_size += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + - parent_data_size; - } else { - allocation_size += channel_stack_->call_stack_size; - } - return allocation_size; -} +namespace grpc_core { -// -// SubchannelCall -// - -void SubchannelCall::StartTransportStreamOpBatch( - grpc_transport_stream_op_batch* batch) { - GPR_TIMER_SCOPE("subchannel_call_process_op", 0); - MaybeInterceptRecvTrailingMetadata(batch); - grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(this); - grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0); - GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch); - top_elem->filter->start_transport_stream_op_batch(top_elem, batch); -} - -void* SubchannelCall::GetParentData() { - grpc_channel_stack* chanstk = connected_subchannel_->channel_stack(); - return (char*)this + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(chanstk->call_stack_size); -} - -grpc_call_stack* SubchannelCall::GetCallStack() { - return SUBCHANNEL_CALL_TO_CALL_STACK(this); -} - -void SubchannelCall::SetAfterCallStackDestroy(grpc_closure* closure) { - GPR_ASSERT(after_call_stack_destroy_ == nullptr); - GPR_ASSERT(closure != nullptr); - after_call_stack_destroy_ = closure; -} - -RefCountedPtr SubchannelCall::Ref() { - IncrementRefCount(); - return RefCountedPtr(this); -} - -RefCountedPtr SubchannelCall::Ref( - const grpc_core::DebugLocation& location, const char* reason) { - IncrementRefCount(location, reason); - return RefCountedPtr(this); -} - -void SubchannelCall::Unref() { - GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), ""); -} - -void SubchannelCall::Unref(const DebugLocation& location, const char* reason) { - GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason); -} - -void SubchannelCall::MaybeInterceptRecvTrailingMetadata( - grpc_transport_stream_op_batch* batch) { - // only intercept payloads with recv trailing. - if (!batch->recv_trailing_metadata) { - return; - } - // only add interceptor is channelz is enabled. - if (connected_subchannel_->channelz_subchannel() == nullptr) { - return; - } - GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, RecvTrailingMetadataReady, - this, grpc_schedule_on_exec_ctx); - // save some state needed for the interception callback. - GPR_ASSERT(recv_trailing_metadata_ == nullptr); - recv_trailing_metadata_ = - batch->payload->recv_trailing_metadata.recv_trailing_metadata; - original_recv_trailing_metadata_ = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &recv_trailing_metadata_ready_; -} - -namespace { - -// Sets *status based on the rest of the parameters. -void GetCallStatus(grpc_status_code* status, grpc_millis deadline, - grpc_metadata_batch* md_batch, grpc_error* error) { - if (error != GRPC_ERROR_NONE) { - grpc_error_get_status(error, deadline, status, nullptr, nullptr, nullptr); - } else { - if (md_batch->idx.named.grpc_status != nullptr) { - *status = grpc_get_status_code_from_metadata( - md_batch->idx.named.grpc_status->md); - } else { - *status = GRPC_STATUS_UNKNOWN; - } - } - GRPC_ERROR_UNREF(error); -} - -} // namespace - -void SubchannelCall::RecvTrailingMetadataReady(void* arg, grpc_error* error) { - SubchannelCall* call = static_cast(arg); - GPR_ASSERT(call->recv_trailing_metadata_ != nullptr); - grpc_status_code status = GRPC_STATUS_OK; - GetCallStatus(&status, call->deadline_, call->recv_trailing_metadata_, - GRPC_ERROR_REF(error)); - channelz::SubchannelNode* channelz_subchannel = - call->connected_subchannel_->channelz_subchannel(); - GPR_ASSERT(channelz_subchannel != nullptr); - if (status == GRPC_STATUS_OK) { - channelz_subchannel->RecordCallSucceeded(); - } else { - channelz_subchannel->RecordCallFailed(); - } - GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata_, - GRPC_ERROR_REF(error)); -} - -void SubchannelCall::IncrementRefCount() { - GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), ""); -} - -void SubchannelCall::IncrementRefCount(const grpc_core::DebugLocation& location, - const char* reason) { - GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason); -} - -// -// Subchannel::ConnectedSubchannelStateWatcher -// - -class Subchannel::ConnectedSubchannelStateWatcher +class ConnectedSubchannelStateWatcher : public InternallyRefCounted { public: // Must be instantiated while holding c->mu. - explicit ConnectedSubchannelStateWatcher(Subchannel* c) : subchannel_(c) { + explicit ConnectedSubchannelStateWatcher(grpc_subchannel* c) + : subchannel_(c) { // Steal subchannel ref for connecting. GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "state_watcher"); GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "connecting"); @@ -311,15 +209,15 @@ class Subchannel::ConnectedSubchannelStateWatcher // Callback uses initial ref to this. GRPC_CLOSURE_INIT(&on_connectivity_changed_, OnConnectivityChanged, this, grpc_schedule_on_exec_ctx); - c->connected_subchannel_->NotifyOnStateChange(c->pollset_set_, - &pending_connectivity_state_, - &on_connectivity_changed_); + c->connected_subchannel->NotifyOnStateChange(c->pollset_set, + &pending_connectivity_state_, + &on_connectivity_changed_); // Start health check if needed. grpc_connectivity_state health_state = GRPC_CHANNEL_READY; - if (c->health_check_service_name_ != nullptr) { - health_check_client_ = MakeOrphanable( - c->health_check_service_name_.get(), c->connected_subchannel_, - c->pollset_set_, c->channelz_node_); + if (c->health_check_service_name != nullptr) { + health_check_client_ = grpc_core::MakeOrphanable( + c->health_check_service_name.get(), c->connected_subchannel, + c->pollset_set, c->channelz_subchannel); GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this, grpc_schedule_on_exec_ctx); Ref().release(); // Ref for health callback tracked manually. @@ -328,9 +226,9 @@ class Subchannel::ConnectedSubchannelStateWatcher health_state = GRPC_CHANNEL_CONNECTING; } // Report initial state. - c->SetConnectivityStateLocked(GRPC_CHANNEL_READY, GRPC_ERROR_NONE, - "subchannel_connected"); - grpc_connectivity_state_set(&c->state_and_health_tracker_, health_state, + set_subchannel_connectivity_state_locked( + c, GRPC_CHANNEL_READY, GRPC_ERROR_NONE, "subchannel_connected"); + grpc_connectivity_state_set(&c->state_and_health_tracker, health_state, GRPC_ERROR_NONE, "subchannel_connected"); } @@ -344,33 +242,33 @@ class Subchannel::ConnectedSubchannelStateWatcher private: static void OnConnectivityChanged(void* arg, grpc_error* error) { auto* self = static_cast(arg); - Subchannel* c = self->subchannel_; + grpc_subchannel* c = self->subchannel_; { - MutexLock lock(&c->mu_); + MutexLock lock(&c->mu); switch (self->pending_connectivity_state_) { case GRPC_CHANNEL_TRANSIENT_FAILURE: case GRPC_CHANNEL_SHUTDOWN: { - if (!c->disconnected_ && c->connected_subchannel_ != nullptr) { + if (!c->disconnected && c->connected_subchannel != nullptr) { if (grpc_trace_stream_refcount.enabled()) { gpr_log(GPR_INFO, "Connected subchannel %p of subchannel %p has gone into " "%s. Attempting to reconnect.", - c->connected_subchannel_.get(), c, + c->connected_subchannel.get(), c, grpc_connectivity_state_name( self->pending_connectivity_state_)); } - c->connected_subchannel_.reset(); - c->connected_subchannel_watcher_.reset(); + c->connected_subchannel.reset(); + c->connected_subchannel_watcher.reset(); self->last_connectivity_state_ = GRPC_CHANNEL_TRANSIENT_FAILURE; - c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(error), - "reflect_child"); - grpc_connectivity_state_set(&c->state_and_health_tracker_, + set_subchannel_connectivity_state_locked( + c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + "reflect_child"); + grpc_connectivity_state_set(&c->state_and_health_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), "reflect_child"); - c->backoff_begun_ = false; - c->backoff_.Reset(); - c->MaybeStartConnectingLocked(); + c->backoff_begun = false; + c->backoff->Reset(); + maybe_start_connecting_locked(c); } else { self->last_connectivity_state_ = GRPC_CHANNEL_SHUTDOWN; } @@ -383,14 +281,15 @@ class Subchannel::ConnectedSubchannelStateWatcher // this watch from. And a connected subchannel should never go // from READY to CONNECTING or IDLE. self->last_connectivity_state_ = self->pending_connectivity_state_; - c->SetConnectivityStateLocked(self->pending_connectivity_state_, - GRPC_ERROR_REF(error), "reflect_child"); + set_subchannel_connectivity_state_locked( + c, self->pending_connectivity_state_, GRPC_ERROR_REF(error), + "reflect_child"); if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) { - grpc_connectivity_state_set(&c->state_and_health_tracker_, + grpc_connectivity_state_set(&c->state_and_health_tracker, self->pending_connectivity_state_, GRPC_ERROR_REF(error), "reflect_child"); } - c->connected_subchannel_->NotifyOnStateChange( + c->connected_subchannel->NotifyOnStateChange( nullptr, &self->pending_connectivity_state_, &self->on_connectivity_changed_); self = nullptr; // So we don't unref below. @@ -404,14 +303,14 @@ class Subchannel::ConnectedSubchannelStateWatcher static void OnHealthChanged(void* arg, grpc_error* error) { auto* self = static_cast(arg); - Subchannel* c = self->subchannel_; - MutexLock lock(&c->mu_); + grpc_subchannel* c = self->subchannel_; + MutexLock lock(&c->mu); if (self->health_state_ == GRPC_CHANNEL_SHUTDOWN) { self->Unref(); return; } if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) { - grpc_connectivity_state_set(&c->state_and_health_tracker_, + grpc_connectivity_state_set(&c->state_and_health_tracker, self->health_state_, GRPC_ERROR_REF(error), "health_changed"); } @@ -419,63 +318,163 @@ class Subchannel::ConnectedSubchannelStateWatcher &self->on_health_changed_); } - Subchannel* subchannel_; + grpc_subchannel* subchannel_; grpc_closure on_connectivity_changed_; grpc_connectivity_state pending_connectivity_state_ = GRPC_CHANNEL_READY; grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_READY; - OrphanablePtr health_check_client_; + grpc_core::OrphanablePtr health_check_client_; grpc_closure on_health_changed_; grpc_connectivity_state health_state_ = GRPC_CHANNEL_CONNECTING; }; -// -// Subchannel::ExternalStateWatcher -// +} // namespace grpc_core -struct Subchannel::ExternalStateWatcher { - ExternalStateWatcher(Subchannel* subchannel, grpc_pollset_set* pollset_set, - grpc_closure* notify) - : subchannel(subchannel), pollset_set(pollset_set), notify(notify) { - GRPC_SUBCHANNEL_WEAK_REF(subchannel, "external_state_watcher+init"); - GRPC_CLOSURE_INIT(&on_state_changed, OnStateChanged, this, - grpc_schedule_on_exec_ctx); +#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ + (grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ + sizeof(grpc_subchannel_call))) +#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \ + (grpc_subchannel_call*)(((char*)(call_stack)) - \ + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ + sizeof(grpc_subchannel_call))) + +static void on_subchannel_connected(void* subchannel, grpc_error* error); + +#ifndef NDEBUG +#define REF_REASON reason +#define REF_MUTATE_EXTRA_ARGS \ + GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char* purpose +#define REF_MUTATE_PURPOSE(x) , file, line, reason, x +#else +#define REF_REASON "" +#define REF_MUTATE_EXTRA_ARGS +#define REF_MUTATE_PURPOSE(x) +#endif + +/* + * connection implementation + */ + +static void connection_destroy(void* arg, grpc_error* error) { + grpc_channel_stack* stk = static_cast(arg); + grpc_channel_stack_destroy(stk); + gpr_free(stk); +} + +/* + * grpc_subchannel implementation + */ + +static void subchannel_destroy(void* arg, grpc_error* error) { + grpc_subchannel* c = static_cast(arg); + if (c->channelz_subchannel != nullptr) { + c->channelz_subchannel->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("Subchannel destroyed")); + c->channelz_subchannel->MarkSubchannelDestroyed(); + c->channelz_subchannel.reset(); } + c->health_check_service_name.reset(); + grpc_channel_args_destroy(c->args); + grpc_connectivity_state_destroy(&c->state_tracker); + grpc_connectivity_state_destroy(&c->state_and_health_tracker); + grpc_connector_unref(c->connector); + grpc_pollset_set_destroy(c->pollset_set); + grpc_core::Delete(c->key); + gpr_mu_destroy(&c->mu); + gpr_free(c); +} - static void OnStateChanged(void* arg, grpc_error* error) { - ExternalStateWatcher* w = static_cast(arg); - grpc_closure* follow_up = w->notify; - if (w->pollset_set != nullptr) { - grpc_pollset_set_del_pollset_set(w->subchannel->pollset_set_, - w->pollset_set); - } - gpr_mu_lock(&w->subchannel->mu_); - if (w->subchannel->external_state_watcher_list_ == w) { - w->subchannel->external_state_watcher_list_ = w->next; - } - if (w->next != nullptr) w->next->prev = w->prev; - if (w->prev != nullptr) w->prev->next = w->next; - gpr_mu_unlock(&w->subchannel->mu_); - GRPC_SUBCHANNEL_WEAK_UNREF(w->subchannel, "external_state_watcher+done"); - Delete(w); - GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error)); +static gpr_atm ref_mutate(grpc_subchannel* c, gpr_atm delta, + int barrier REF_MUTATE_EXTRA_ARGS) { + gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta) + : gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta); +#ifndef NDEBUG + if (grpc_trace_stream_refcount.enabled()) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", c, + purpose, old_val, old_val + delta, reason); } +#endif + return old_val; +} - Subchannel* subchannel; - grpc_pollset_set* pollset_set; - grpc_closure* notify; - grpc_closure on_state_changed; - ExternalStateWatcher* next = nullptr; - ExternalStateWatcher* prev = nullptr; -}; +grpc_subchannel* grpc_subchannel_ref( + grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = ref_mutate(c, (1 << INTERNAL_REF_BITS), + 0 REF_MUTATE_PURPOSE("STRONG_REF")); + GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0); + return c; +} -// -// Subchannel -// +grpc_subchannel* grpc_subchannel_weak_ref( + grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = ref_mutate(c, 1, 0 REF_MUTATE_PURPOSE("WEAK_REF")); + GPR_ASSERT(old_refs != 0); + return c; +} -namespace { +grpc_subchannel* grpc_subchannel_ref_from_weak_ref( + grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + if (!c) return nullptr; + for (;;) { + gpr_atm old_refs = gpr_atm_acq_load(&c->ref_pair); + if (old_refs >= (1 << INTERNAL_REF_BITS)) { + gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS); + if (gpr_atm_rel_cas(&c->ref_pair, old_refs, new_refs)) { + return c; + } + } else { + return nullptr; + } + } +} -BackOff::Options ParseArgsForBackoffValues( - const grpc_channel_args* args, grpc_millis* min_connect_timeout_ms) { +static void disconnect(grpc_subchannel* c) { + // The subchannel_pool is only used once here in this subchannel, so the + // access can be outside of the lock. + if (c->subchannel_pool != nullptr) { + c->subchannel_pool->UnregisterSubchannel(c->key); + c->subchannel_pool.reset(); + } + gpr_mu_lock(&c->mu); + GPR_ASSERT(!c->disconnected); + c->disconnected = true; + grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Subchannel disconnected")); + c->connected_subchannel.reset(); + c->connected_subchannel_watcher.reset(); + gpr_mu_unlock(&c->mu); +} + +void grpc_subchannel_unref(grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + // add a weak ref and subtract a strong ref (atomically) + old_refs = ref_mutate( + c, static_cast(1) - static_cast(1 << INTERNAL_REF_BITS), + 1 REF_MUTATE_PURPOSE("STRONG_UNREF")); + if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) { + disconnect(c); + } + GRPC_SUBCHANNEL_WEAK_UNREF(c, "strong-unref"); +} + +void grpc_subchannel_weak_unref( + grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = ref_mutate(c, -static_cast(1), + 1 REF_MUTATE_PURPOSE("WEAK_UNREF")); + if (old_refs == 1) { + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(subchannel_destroy, c, grpc_schedule_on_exec_ctx), + GRPC_ERROR_NONE); + } +} + +static void parse_args_for_backoff_values( + const grpc_channel_args* args, grpc_core::BackOff::Options* backoff_options, + grpc_millis* min_connect_timeout_ms) { grpc_millis initial_backoff_ms = GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000; *min_connect_timeout_ms = @@ -512,8 +511,7 @@ BackOff::Options ParseArgsForBackoffValues( } } } - return BackOff::Options() - .set_initial_backoff(initial_backoff_ms) + backoff_options->set_initial_backoff(initial_backoff_ms) .set_multiplier(fixed_reconnect_backoff ? 1.0 : GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER) @@ -522,6 +520,9 @@ BackOff::Options ParseArgsForBackoffValues( .set_max_backoff(max_backoff_ms); } +namespace grpc_core { +namespace { + struct HealthCheckParams { UniquePtr service_name; @@ -542,19 +543,31 @@ struct HealthCheckParams { }; } // namespace +} // namespace grpc_core -Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, - const grpc_channel_args* args) - : key_(key), - connector_(connector), - backoff_(ParseArgsForBackoffValues(args, &min_connect_timeout_ms_)) { +grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, + const grpc_channel_args* args) { + grpc_core::SubchannelKey* key = + grpc_core::New(args); + grpc_core::SubchannelPoolInterface* subchannel_pool = + grpc_core::SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs( + args); + GPR_ASSERT(subchannel_pool != nullptr); + grpc_subchannel* c = subchannel_pool->FindSubchannel(key); + if (c != nullptr) { + grpc_core::Delete(key); + return c; + } GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED(); - gpr_atm_no_barrier_store(&ref_pair_, 1 << INTERNAL_REF_BITS); - grpc_connector_ref(connector_); - pollset_set_ = grpc_pollset_set_create(); + c = static_cast(gpr_zalloc(sizeof(*c))); + c->key = key; + gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS); + c->connector = connector; + grpc_connector_ref(c->connector); + c->pollset_set = grpc_pollset_set_create(); grpc_resolved_address* addr = static_cast(gpr_malloc(sizeof(*addr))); - GetAddressFromSubchannelAddressArg(args, addr); + grpc_get_subchannel_address_arg(args, addr); grpc_resolved_address* new_address = nullptr; grpc_channel_args* new_args = nullptr; if (grpc_proxy_mappers_map_address(addr, args, &new_address, &new_args)) { @@ -563,398 +576,291 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, addr = new_address; } static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS}; - grpc_arg new_arg = CreateSubchannelAddressArg(addr); + grpc_arg new_arg = grpc_create_subchannel_address_arg(addr); gpr_free(addr); - args_ = grpc_channel_args_copy_and_add_and_remove( + c->args = grpc_channel_args_copy_and_add_and_remove( new_args != nullptr ? new_args : args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1); gpr_free(new_arg.value.string); if (new_args != nullptr) grpc_channel_args_destroy(new_args); - GRPC_CLOSURE_INIT(&on_connecting_finished_, OnConnectingFinished, this, + c->root_external_state_watcher.next = c->root_external_state_watcher.prev = + &c->root_external_state_watcher; + GRPC_CLOSURE_INIT(&c->on_connected, on_subchannel_connected, c, grpc_schedule_on_exec_ctx); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, + grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE, "subchannel"); - grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE, + grpc_connectivity_state_init(&c->state_and_health_tracker, GRPC_CHANNEL_IDLE, "subchannel"); - gpr_mu_init(&mu_); + grpc_core::BackOff::Options backoff_options; + parse_args_for_backoff_values(args, &backoff_options, + &c->min_connect_timeout_ms); + c->backoff.Init(backoff_options); + gpr_mu_init(&c->mu); + // Check whether we should enable health checking. const char* service_config_json = grpc_channel_arg_get_string( - grpc_channel_args_find(args_, GRPC_ARG_SERVICE_CONFIG)); + grpc_channel_args_find(c->args, GRPC_ARG_SERVICE_CONFIG)); if (service_config_json != nullptr) { - UniquePtr service_config = - ServiceConfig::Create(service_config_json); + grpc_core::UniquePtr service_config = + grpc_core::ServiceConfig::Create(service_config_json); if (service_config != nullptr) { - HealthCheckParams params; - service_config->ParseGlobalParams(HealthCheckParams::Parse, ¶ms); - health_check_service_name_ = std::move(params.service_name); + grpc_core::HealthCheckParams params; + service_config->ParseGlobalParams(grpc_core::HealthCheckParams::Parse, + ¶ms); + c->health_check_service_name = std::move(params.service_name); } } - const grpc_arg* arg = grpc_channel_args_find(args_, GRPC_ARG_ENABLE_CHANNELZ); - const bool channelz_enabled = + + const grpc_arg* arg = + grpc_channel_args_find(c->args, GRPC_ARG_ENABLE_CHANNELZ); + bool channelz_enabled = grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT); arg = grpc_channel_args_find( - args_, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); + c->args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); const grpc_integer_options options = { GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX}; size_t channel_tracer_max_memory = (size_t)grpc_channel_arg_get_integer(arg, options); if (channelz_enabled) { - channelz_node_ = MakeRefCounted( - this, channel_tracer_max_memory); - channelz_node_->AddTraceEvent( - channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string("subchannel created")); + c->channelz_subchannel = + grpc_core::MakeRefCounted( + c, channel_tracer_max_memory); + c->channelz_subchannel->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("Subchannel created")); } -} - -Subchannel::~Subchannel() { - if (channelz_node_ != nullptr) { - channelz_node_->AddTraceEvent( - channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string("Subchannel destroyed")); - channelz_node_->MarkSubchannelDestroyed(); - } - grpc_channel_args_destroy(args_); - grpc_connectivity_state_destroy(&state_tracker_); - grpc_connectivity_state_destroy(&state_and_health_tracker_); - grpc_connector_unref(connector_); - grpc_pollset_set_destroy(pollset_set_); - Delete(key_); - gpr_mu_destroy(&mu_); -} - -Subchannel* Subchannel::Create(grpc_connector* connector, - const grpc_channel_args* args) { - SubchannelKey* key = New(args); - SubchannelPoolInterface* subchannel_pool = - SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs(args); - GPR_ASSERT(subchannel_pool != nullptr); - Subchannel* c = subchannel_pool->FindSubchannel(key); - if (c != nullptr) { - Delete(key); - return c; - } - c = New(key, connector, args); // Try to register the subchannel before setting the subchannel pool. // Otherwise, in case of a registration race, unreffing c in - // RegisterSubchannel() will cause c to be tried to be unregistered, while - // its key maps to a different subchannel. - Subchannel* registered = subchannel_pool->RegisterSubchannel(key, c); - if (registered == c) c->subchannel_pool_ = subchannel_pool->Ref(); + // RegisterSubchannel() will cause c to be tried to be unregistered, while its + // key maps to a different subchannel. + grpc_subchannel* registered = subchannel_pool->RegisterSubchannel(key, c); + if (registered == c) c->subchannel_pool = subchannel_pool->Ref(); return registered; } -Subchannel* Subchannel::Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = RefMutate((1 << INTERNAL_REF_BITS), - 0 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("STRONG_REF")); - GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0); - return this; +grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( + grpc_subchannel* subchannel) { + return subchannel->channelz_subchannel.get(); } -void Subchannel::Unref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - // add a weak ref and subtract a strong ref (atomically) - old_refs = RefMutate( - static_cast(1) - static_cast(1 << INTERNAL_REF_BITS), - 1 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("STRONG_UNREF")); - if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) { - Disconnect(); - } - GRPC_SUBCHANNEL_WEAK_UNREF(this, "strong-unref"); -} - -Subchannel* Subchannel::WeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = RefMutate(1, 0 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("WEAK_REF")); - GPR_ASSERT(old_refs != 0); - return this; -} - -namespace { - -void subchannel_destroy(void* arg, grpc_error* error) { - Subchannel* self = static_cast(arg); - Delete(self); -} - -} // namespace - -void Subchannel::WeakUnref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = RefMutate(-static_cast(1), - 1 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("WEAK_UNREF")); - if (old_refs == 1) { - GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(subchannel_destroy, this, - grpc_schedule_on_exec_ctx), - GRPC_ERROR_NONE); - } -} - -Subchannel* Subchannel::RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - for (;;) { - gpr_atm old_refs = gpr_atm_acq_load(&ref_pair_); - if (old_refs >= (1 << INTERNAL_REF_BITS)) { - gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS); - if (gpr_atm_rel_cas(&ref_pair_, old_refs, new_refs)) { - return this; - } - } else { - return nullptr; - } - } -} - -intptr_t Subchannel::GetChildSocketUuid() { - if (connected_subchannel_ != nullptr) { - return connected_subchannel_->socket_uuid(); +intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel) { + if (subchannel->connected_subchannel != nullptr) { + return subchannel->connected_subchannel->socket_uuid(); } else { return 0; } } -const char* Subchannel::GetTargetAddress() { - const grpc_arg* addr_arg = - grpc_channel_args_find(args_, GRPC_ARG_SUBCHANNEL_ADDRESS); - const char* addr_str = grpc_channel_arg_get_string(addr_arg); - GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. - return addr_str; +static void continue_connect_locked(grpc_subchannel* c) { + grpc_connect_in_args args; + args.interested_parties = c->pollset_set; + const grpc_millis min_deadline = + c->min_connect_timeout_ms + grpc_core::ExecCtx::Get()->Now(); + c->next_attempt_deadline = c->backoff->NextAttemptTime(); + args.deadline = std::max(c->next_attempt_deadline, min_deadline); + args.channel_args = c->args; + set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_CONNECTING, + GRPC_ERROR_NONE, "connecting"); + grpc_connectivity_state_set(&c->state_and_health_tracker, + GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + "connecting"); + grpc_connector_connect(c->connector, &args, &c->connecting_result, + &c->on_connected); } -RefCountedPtr Subchannel::connected_subchannel() { - MutexLock lock(&mu_); - return connected_subchannel_; -} - -channelz::SubchannelNode* Subchannel::channelz_node() { - return channelz_node_.get(); -} - -grpc_connectivity_state Subchannel::CheckConnectivity( - grpc_error** error, bool inhibit_health_checks) { - MutexLock lock(&mu_); +grpc_connectivity_state grpc_subchannel_check_connectivity( + grpc_subchannel* c, grpc_error** error, bool inhibit_health_checks) { + gpr_mu_lock(&c->mu); grpc_connectivity_state_tracker* tracker = - inhibit_health_checks ? &state_tracker_ : &state_and_health_tracker_; + inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; grpc_connectivity_state state = grpc_connectivity_state_get(tracker, error); + gpr_mu_unlock(&c->mu); return state; } -void Subchannel::NotifyOnStateChange(grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, - grpc_closure* notify, - bool inhibit_health_checks) { - grpc_connectivity_state_tracker* tracker = - inhibit_health_checks ? &state_tracker_ : &state_and_health_tracker_; - ExternalStateWatcher* w; - if (state == nullptr) { - MutexLock lock(&mu_); - for (w = external_state_watcher_list_; w != nullptr; w = w->next) { - if (w->notify == notify) { - grpc_connectivity_state_notify_on_state_change(tracker, nullptr, - &w->on_state_changed); - } - } - } else { - w = New(this, interested_parties, notify); - if (interested_parties != nullptr) { - grpc_pollset_set_add_pollset_set(pollset_set_, interested_parties); - } - MutexLock lock(&mu_); - if (external_state_watcher_list_ != nullptr) { - w->next = external_state_watcher_list_; - w->next->prev = w; - } - external_state_watcher_list_ = w; - grpc_connectivity_state_notify_on_state_change(tracker, state, - &w->on_state_changed); - MaybeStartConnectingLocked(); +static void on_external_state_watcher_done(void* arg, grpc_error* error) { + external_state_watcher* w = static_cast(arg); + grpc_closure* follow_up = w->notify; + if (w->pollset_set != nullptr) { + grpc_pollset_set_del_pollset_set(w->subchannel->pollset_set, + w->pollset_set); } + gpr_mu_lock(&w->subchannel->mu); + w->next->prev = w->prev; + w->prev->next = w->next; + gpr_mu_unlock(&w->subchannel->mu); + GRPC_SUBCHANNEL_WEAK_UNREF(w->subchannel, "external_state_watcher"); + gpr_free(w); + GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error)); } -void Subchannel::ResetBackoff() { - MutexLock lock(&mu_); - backoff_.Reset(); - if (have_retry_alarm_) { - retry_immediately_ = true; - grpc_timer_cancel(&retry_alarm_); - } else { - backoff_begun_ = false; - MaybeStartConnectingLocked(); - } -} - -grpc_arg Subchannel::CreateSubchannelAddressArg( - const grpc_resolved_address* addr) { - return grpc_channel_arg_string_create( - (char*)GRPC_ARG_SUBCHANNEL_ADDRESS, - addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("")); -} - -const char* Subchannel::GetUriFromSubchannelAddressArg( - const grpc_channel_args* args) { - const grpc_arg* addr_arg = - grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS); - const char* addr_str = grpc_channel_arg_get_string(addr_arg); - GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. - return addr_str; -} - -namespace { - -void UriToSockaddr(const char* uri_str, grpc_resolved_address* addr) { - grpc_uri* uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */); - GPR_ASSERT(uri != nullptr); - if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr)); - grpc_uri_destroy(uri); -} - -} // namespace - -void Subchannel::GetAddressFromSubchannelAddressArg( - const grpc_channel_args* args, grpc_resolved_address* addr) { - const char* addr_uri_str = GetUriFromSubchannelAddressArg(args); - memset(addr, 0, sizeof(*addr)); - if (*addr_uri_str != '\0') { - UriToSockaddr(addr_uri_str, addr); - } -} - -namespace { - -// Returns a string indicating the subchannel's connectivity state change to -// \a state. -const char* SubchannelConnectivityStateChangeString( - grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "Subchannel state change to IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "Subchannel state change to CONNECTING"; - case GRPC_CHANNEL_READY: - return "Subchannel state change to READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "Subchannel state change to TRANSIENT_FAILURE"; - case GRPC_CHANNEL_SHUTDOWN: - return "Subchannel state change to SHUTDOWN"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -} // namespace - -void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state, - grpc_error* error, - const char* reason) { - if (channelz_node_ != nullptr) { - channelz_node_->AddTraceEvent( - channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - SubchannelConnectivityStateChangeString(state))); - } - grpc_connectivity_state_set(&state_tracker_, state, error, reason); -} - -void Subchannel::MaybeStartConnectingLocked() { - if (disconnected_) { - // Don't try to connect if we're already disconnected. - return; - } - if (connecting_) { - // Already connecting: don't restart. - return; - } - if (connected_subchannel_ != nullptr) { - // Already connected: don't restart. - return; - } - if (!grpc_connectivity_state_has_watchers(&state_tracker_) && - !grpc_connectivity_state_has_watchers(&state_and_health_tracker_)) { - // Nobody is interested in connecting: so don't just yet. - return; - } - connecting_ = true; - GRPC_SUBCHANNEL_WEAK_REF(this, "connecting"); - if (!backoff_begun_) { - backoff_begun_ = true; - ContinueConnectingLocked(); - } else { - GPR_ASSERT(!have_retry_alarm_); - have_retry_alarm_ = true; - const grpc_millis time_til_next = - next_attempt_deadline_ - ExecCtx::Get()->Now(); - if (time_til_next <= 0) { - gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", this); - } else { - gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRId64 " milliseconds", - this, time_til_next); - } - GRPC_CLOSURE_INIT(&on_retry_alarm_, OnRetryAlarm, this, - grpc_schedule_on_exec_ctx); - grpc_timer_init(&retry_alarm_, next_attempt_deadline_, &on_retry_alarm_); - } -} - -void Subchannel::OnRetryAlarm(void* arg, grpc_error* error) { - Subchannel* c = static_cast(arg); - gpr_mu_lock(&c->mu_); - c->have_retry_alarm_ = false; - if (c->disconnected_) { +static void on_alarm(void* arg, grpc_error* error) { + grpc_subchannel* c = static_cast(arg); + gpr_mu_lock(&c->mu); + c->have_alarm = false; + if (c->disconnected) { error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected", &error, 1); - } else if (c->retry_immediately_) { - c->retry_immediately_ = false; + } else if (c->retry_immediately) { + c->retry_immediately = false; error = GRPC_ERROR_NONE; } else { GRPC_ERROR_REF(error); } if (error == GRPC_ERROR_NONE) { gpr_log(GPR_INFO, "Failed to connect to channel, retrying"); - c->ContinueConnectingLocked(); - gpr_mu_unlock(&c->mu_); + continue_connect_locked(c); + gpr_mu_unlock(&c->mu); } else { - gpr_mu_unlock(&c->mu_); + gpr_mu_unlock(&c->mu); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } GRPC_ERROR_UNREF(error); } -void Subchannel::ContinueConnectingLocked() { - grpc_connect_in_args args; - args.interested_parties = pollset_set_; - const grpc_millis min_deadline = - min_connect_timeout_ms_ + ExecCtx::Get()->Now(); - next_attempt_deadline_ = backoff_.NextAttemptTime(); - args.deadline = std::max(next_attempt_deadline_, min_deadline); - args.channel_args = args_; - SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, - "connecting"); - grpc_connectivity_state_set(&state_and_health_tracker_, - GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, - "connecting"); - grpc_connector_connect(connector_, &args, &connecting_result_, - &on_connecting_finished_); +static void maybe_start_connecting_locked(grpc_subchannel* c) { + if (c->disconnected) { + /* Don't try to connect if we're already disconnected */ + return; + } + if (c->connecting) { + /* Already connecting: don't restart */ + return; + } + if (c->connected_subchannel != nullptr) { + /* Already connected: don't restart */ + return; + } + if (!grpc_connectivity_state_has_watchers(&c->state_tracker) && + !grpc_connectivity_state_has_watchers(&c->state_and_health_tracker)) { + /* Nobody is interested in connecting: so don't just yet */ + return; + } + c->connecting = true; + GRPC_SUBCHANNEL_WEAK_REF(c, "connecting"); + if (!c->backoff_begun) { + c->backoff_begun = true; + continue_connect_locked(c); + } else { + GPR_ASSERT(!c->have_alarm); + c->have_alarm = true; + const grpc_millis time_til_next = + c->next_attempt_deadline - grpc_core::ExecCtx::Get()->Now(); + if (time_til_next <= 0) { + gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", c); + } else { + gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRId64 " milliseconds", c, + time_til_next); + } + GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx); + grpc_timer_init(&c->alarm, c->next_attempt_deadline, &c->on_alarm); + } } -void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) { - auto* c = static_cast(arg); - grpc_channel_args* delete_channel_args = c->connecting_result_.channel_args; - GRPC_SUBCHANNEL_WEAK_REF(c, "on_connecting_finished"); - gpr_mu_lock(&c->mu_); - c->connecting_ = false; - if (c->connecting_result_.transport != nullptr && - c->PublishTransportLocked()) { - // Do nothing, transport was published. - } else if (c->disconnected_) { +void grpc_subchannel_notify_on_state_change( + grpc_subchannel* c, grpc_pollset_set* interested_parties, + grpc_connectivity_state* state, grpc_closure* notify, + bool inhibit_health_checks) { + grpc_connectivity_state_tracker* tracker = + inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; + external_state_watcher* w; + if (state == nullptr) { + gpr_mu_lock(&c->mu); + for (w = c->root_external_state_watcher.next; + w != &c->root_external_state_watcher; w = w->next) { + if (w->notify == notify) { + grpc_connectivity_state_notify_on_state_change(tracker, nullptr, + &w->closure); + } + } + gpr_mu_unlock(&c->mu); + } else { + w = static_cast(gpr_malloc(sizeof(*w))); + w->subchannel = c; + w->pollset_set = interested_parties; + w->notify = notify; + GRPC_CLOSURE_INIT(&w->closure, on_external_state_watcher_done, w, + grpc_schedule_on_exec_ctx); + if (interested_parties != nullptr) { + grpc_pollset_set_add_pollset_set(c->pollset_set, interested_parties); + } + GRPC_SUBCHANNEL_WEAK_REF(c, "external_state_watcher"); + gpr_mu_lock(&c->mu); + w->next = &c->root_external_state_watcher; + w->prev = w->next->prev; + w->next->prev = w->prev->next = w; + grpc_connectivity_state_notify_on_state_change(tracker, state, &w->closure); + maybe_start_connecting_locked(c); + gpr_mu_unlock(&c->mu); + } +} + +static bool publish_transport_locked(grpc_subchannel* c) { + /* construct channel stack */ + grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); + grpc_channel_stack_builder_set_channel_arguments( + builder, c->connecting_result.channel_args); + grpc_channel_stack_builder_set_transport(builder, + c->connecting_result.transport); + + if (!grpc_channel_init_create_stack(builder, GRPC_CLIENT_SUBCHANNEL)) { + grpc_channel_stack_builder_destroy(builder); + return false; + } + grpc_channel_stack* stk; + grpc_error* error = grpc_channel_stack_builder_finish( + builder, 0, 1, connection_destroy, nullptr, + reinterpret_cast(&stk)); + if (error != GRPC_ERROR_NONE) { + grpc_transport_destroy(c->connecting_result.transport); + gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", + grpc_error_string(error)); + GRPC_ERROR_UNREF(error); + return false; + } + intptr_t socket_uuid = c->connecting_result.socket_uuid; + memset(&c->connecting_result, 0, sizeof(c->connecting_result)); + + if (c->disconnected) { + grpc_channel_stack_destroy(stk); + gpr_free(stk); + return false; + } + + /* publish */ + c->connected_subchannel.reset(grpc_core::New( + stk, c->args, c->channelz_subchannel, socket_uuid)); + gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", + c->connected_subchannel.get(), c); + + // Instantiate state watcher. Will clean itself up. + c->connected_subchannel_watcher = + grpc_core::MakeOrphanable(c); + + return true; +} + +static void on_subchannel_connected(void* arg, grpc_error* error) { + grpc_subchannel* c = static_cast(arg); + grpc_channel_args* delete_channel_args = c->connecting_result.channel_args; + + GRPC_SUBCHANNEL_WEAK_REF(c, "on_subchannel_connected"); + gpr_mu_lock(&c->mu); + c->connecting = false; + if (c->connecting_result.transport != nullptr && + publish_transport_locked(c)) { + /* do nothing, transport was published */ + } else if (c->disconnected) { GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } else { - c->SetConnectivityStateLocked( - GRPC_CHANNEL_TRANSIENT_FAILURE, + set_subchannel_connectivity_state_locked( + c, GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Connect Failed", &error, 1), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), "connect_failed"); grpc_connectivity_state_set( - &c->state_and_health_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, + &c->state_and_health_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Connect Failed", &error, 1), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), @@ -963,92 +869,276 @@ void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) { const char* errmsg = grpc_error_string(error); gpr_log(GPR_INFO, "Connect failed: %s", errmsg); - c->MaybeStartConnectingLocked(); + maybe_start_connecting_locked(c); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } - gpr_mu_unlock(&c->mu_); - GRPC_SUBCHANNEL_WEAK_UNREF(c, "on_connecting_finished"); + gpr_mu_unlock(&c->mu); + GRPC_SUBCHANNEL_WEAK_UNREF(c, "connected"); grpc_channel_args_destroy(delete_channel_args); } -namespace { - -void ConnectionDestroy(void* arg, grpc_error* error) { - grpc_channel_stack* stk = static_cast(arg); - grpc_channel_stack_destroy(stk); - gpr_free(stk); +void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel) { + gpr_mu_lock(&subchannel->mu); + subchannel->backoff->Reset(); + if (subchannel->have_alarm) { + subchannel->retry_immediately = true; + grpc_timer_cancel(&subchannel->alarm); + } else { + subchannel->backoff_begun = false; + maybe_start_connecting_locked(subchannel); + } + gpr_mu_unlock(&subchannel->mu); } -} // namespace +/* + * grpc_subchannel_call implementation + */ -bool Subchannel::PublishTransportLocked() { - // Construct channel stack. - grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); - grpc_channel_stack_builder_set_channel_arguments( - builder, connecting_result_.channel_args); - grpc_channel_stack_builder_set_transport(builder, - connecting_result_.transport); - if (!grpc_channel_init_create_stack(builder, GRPC_CLIENT_SUBCHANNEL)) { - grpc_channel_stack_builder_destroy(builder); - return false; - } - grpc_channel_stack* stk; - grpc_error* error = grpc_channel_stack_builder_finish( - builder, 0, 1, ConnectionDestroy, nullptr, - reinterpret_cast(&stk)); +static void subchannel_call_destroy(void* call, grpc_error* error) { + GPR_TIMER_SCOPE("grpc_subchannel_call_unref.destroy", 0); + grpc_subchannel_call* c = static_cast(call); + grpc_core::ConnectedSubchannel* connection = c->connection; + grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c), nullptr, + c->schedule_closure_after_destroy); + connection->Unref(DEBUG_LOCATION, "subchannel_call"); + c->~grpc_subchannel_call(); +} + +void grpc_subchannel_call_set_cleanup_closure(grpc_subchannel_call* call, + grpc_closure* closure) { + GPR_ASSERT(call->schedule_closure_after_destroy == nullptr); + GPR_ASSERT(closure != nullptr); + call->schedule_closure_after_destroy = closure; +} + +grpc_subchannel_call* grpc_subchannel_call_ref( + grpc_subchannel_call* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); + return c; +} + +void grpc_subchannel_call_unref( + grpc_subchannel_call* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); +} + +// Sets *status based on md_batch and error. +static void get_call_status(grpc_subchannel_call* call, + grpc_metadata_batch* md_batch, grpc_error* error, + grpc_status_code* status) { if (error != GRPC_ERROR_NONE) { - grpc_transport_destroy(connecting_result_.transport); - gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", - grpc_error_string(error)); - GRPC_ERROR_UNREF(error); - return false; + grpc_error_get_status(error, call->deadline, status, nullptr, nullptr, + nullptr); + } else { + if (md_batch->idx.named.grpc_status != nullptr) { + *status = grpc_get_status_code_from_metadata( + md_batch->idx.named.grpc_status->md); + } else { + *status = GRPC_STATUS_UNKNOWN; + } } - intptr_t socket_uuid = connecting_result_.socket_uuid; - memset(&connecting_result_, 0, sizeof(connecting_result_)); - if (disconnected_) { - grpc_channel_stack_destroy(stk); - gpr_free(stk); - return false; - } - // Publish. - connected_subchannel_.reset( - New(stk, args_, channelz_node_, socket_uuid)); - gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", - connected_subchannel_.get(), this); - // Instantiate state watcher. Will clean itself up. - connected_subchannel_watcher_ = - MakeOrphanable(this); - return true; + GRPC_ERROR_UNREF(error); } -void Subchannel::Disconnect() { - // The subchannel_pool is only used once here in this subchannel, so the - // access can be outside of the lock. - if (subchannel_pool_ != nullptr) { - subchannel_pool_->UnregisterSubchannel(key_); - subchannel_pool_.reset(); +static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { + grpc_subchannel_call* call = static_cast(arg); + GPR_ASSERT(call->recv_trailing_metadata != nullptr); + grpc_status_code status = GRPC_STATUS_OK; + grpc_metadata_batch* md_batch = call->recv_trailing_metadata; + get_call_status(call, md_batch, GRPC_ERROR_REF(error), &status); + grpc_core::channelz::SubchannelNode* channelz_subchannel = + call->connection->channelz_subchannel(); + GPR_ASSERT(channelz_subchannel != nullptr); + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); } - MutexLock lock(&mu_); - GPR_ASSERT(!disconnected_); - disconnected_ = true; - grpc_connector_shutdown(connector_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Subchannel disconnected")); - connected_subchannel_.reset(); - connected_subchannel_watcher_.reset(); + GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata, + GRPC_ERROR_REF(error)); } -gpr_atm Subchannel::RefMutate( - gpr_atm delta, int barrier GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS) { - gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&ref_pair_, delta) - : gpr_atm_no_barrier_fetch_add(&ref_pair_, delta); -#ifndef NDEBUG - if (grpc_trace_stream_refcount.enabled()) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", this, - purpose, old_val, old_val + delta, reason); +// If channelz is enabled, intercept recv_trailing so that we may check the +// status and associate it to a subchannel. +static void maybe_intercept_recv_trailing_metadata( + grpc_subchannel_call* call, grpc_transport_stream_op_batch* batch) { + // only intercept payloads with recv trailing. + if (!batch->recv_trailing_metadata) { + return; } -#endif - return old_val; + // only add interceptor is channelz is enabled. + if (call->connection->channelz_subchannel() == nullptr) { + return; + } + GRPC_CLOSURE_INIT(&call->recv_trailing_metadata_ready, + recv_trailing_metadata_ready, call, + grpc_schedule_on_exec_ctx); + // save some state needed for the interception callback. + GPR_ASSERT(call->recv_trailing_metadata == nullptr); + call->recv_trailing_metadata = + batch->payload->recv_trailing_metadata.recv_trailing_metadata; + call->original_recv_trailing_metadata = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &call->recv_trailing_metadata_ready; +} + +void grpc_subchannel_call_process_op(grpc_subchannel_call* call, + grpc_transport_stream_op_batch* batch) { + GPR_TIMER_SCOPE("grpc_subchannel_call_process_op", 0); + maybe_intercept_recv_trailing_metadata(call, batch); + grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call); + grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0); + GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch); + top_elem->filter->start_transport_stream_op_batch(top_elem, batch); +} + +grpc_core::RefCountedPtr +grpc_subchannel_get_connected_subchannel(grpc_subchannel* c) { + gpr_mu_lock(&c->mu); + auto copy = c->connected_subchannel; + gpr_mu_unlock(&c->mu); + return copy; +} + +void* grpc_connected_subchannel_call_get_parent_data( + grpc_subchannel_call* subchannel_call) { + grpc_channel_stack* chanstk = subchannel_call->connection->channel_stack(); + return (char*)subchannel_call + + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)) + + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(chanstk->call_stack_size); +} + +grpc_call_stack* grpc_subchannel_call_get_call_stack( + grpc_subchannel_call* subchannel_call) { + return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call); +} + +static void grpc_uri_to_sockaddr(const char* uri_str, + grpc_resolved_address* addr) { + grpc_uri* uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */); + GPR_ASSERT(uri != nullptr); + if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr)); + grpc_uri_destroy(uri); +} + +void grpc_get_subchannel_address_arg(const grpc_channel_args* args, + grpc_resolved_address* addr) { + const char* addr_uri_str = grpc_get_subchannel_address_uri_arg(args); + memset(addr, 0, sizeof(*addr)); + if (*addr_uri_str != '\0') { + grpc_uri_to_sockaddr(addr_uri_str, addr); + } +} + +const char* grpc_subchannel_get_target(grpc_subchannel* subchannel) { + const grpc_arg* addr_arg = + grpc_channel_args_find(subchannel->args, GRPC_ARG_SUBCHANNEL_ADDRESS); + const char* addr_str = grpc_channel_arg_get_string(addr_arg); + GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. + return addr_str; +} + +const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args) { + const grpc_arg* addr_arg = + grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS); + const char* addr_str = grpc_channel_arg_get_string(addr_arg); + GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. + return addr_str; +} + +grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) { + return grpc_channel_arg_string_create( + (char*)GRPC_ARG_SUBCHANNEL_ADDRESS, + addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("")); +} + +namespace grpc_core { + +ConnectedSubchannel::ConnectedSubchannel( + grpc_channel_stack* channel_stack, const grpc_channel_args* args, + grpc_core::RefCountedPtr + channelz_subchannel, + intptr_t socket_uuid) + : RefCounted(&grpc_trace_stream_refcount), + channel_stack_(channel_stack), + args_(grpc_channel_args_copy(args)), + channelz_subchannel_(std::move(channelz_subchannel)), + socket_uuid_(socket_uuid) {} + +ConnectedSubchannel::~ConnectedSubchannel() { + grpc_channel_args_destroy(args_); + GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); +} + +void ConnectedSubchannel::NotifyOnStateChange( + grpc_pollset_set* interested_parties, grpc_connectivity_state* state, + grpc_closure* closure) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + grpc_channel_element* elem; + op->connectivity_state = state; + op->on_connectivity_state_change = closure; + op->bind_pollset_set = interested_parties; + elem = grpc_channel_stack_element(channel_stack_, 0); + elem->filter->start_transport_op(elem, op); +} + +void ConnectedSubchannel::Ping(grpc_closure* on_initiate, + grpc_closure* on_ack) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + grpc_channel_element* elem; + op->send_ping.on_initiate = on_initiate; + op->send_ping.on_ack = on_ack; + elem = grpc_channel_stack_element(channel_stack_, 0); + elem->filter->start_transport_op(elem, op); +} + +grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, + grpc_subchannel_call** call) { + const size_t allocation_size = + GetInitialCallSizeEstimate(args.parent_data_size); + *call = new (gpr_arena_alloc(args.arena, allocation_size)) + grpc_subchannel_call(this, args); + grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); + RefCountedPtr connection = + Ref(DEBUG_LOCATION, "subchannel_call"); + connection.release(); // Ref is passed to the grpc_subchannel_call object. + const grpc_call_element_args call_args = { + callstk, /* call_stack */ + nullptr, /* server_transport_data */ + args.context, /* context */ + args.path, /* path */ + args.start_time, /* start_time */ + args.deadline, /* deadline */ + args.arena, /* arena */ + args.call_combiner /* call_combiner */ + }; + grpc_error* error = grpc_call_stack_init( + channel_stack_, 1, subchannel_call_destroy, *call, &call_args); + if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { + const char* error_string = grpc_error_string(error); + gpr_log(GPR_ERROR, "error: %s", error_string); + return error; + } + grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); + if (channelz_subchannel_ != nullptr) { + channelz_subchannel_->RecordCallStarted(); + } + return GRPC_ERROR_NONE; +} + +size_t ConnectedSubchannel::GetInitialCallSizeEstimate( + size_t parent_data_size) const { + size_t allocation_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); + if (parent_data_size > 0) { + allocation_size += + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + + parent_data_size; + } else { + allocation_size += channel_stack_->call_stack_size; + } + return allocation_size; } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 88282c9d95e..fac515eee5c 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -24,49 +24,53 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/connector.h" #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" -#include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/gpr/arena.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/polling_entity.h" -#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/metadata.h" // Channel arg containing a grpc_resolved_address to connect to. #define GRPC_ARG_SUBCHANNEL_ADDRESS "grpc.subchannel_address" -// For debugging refcounting. +/** A (sub-)channel that knows how to connect to exactly one target + address. Provides a target for load balancing. */ +typedef struct grpc_subchannel grpc_subchannel; +typedef struct grpc_subchannel_call grpc_subchannel_call; + #ifndef NDEBUG -#define GRPC_SUBCHANNEL_REF(p, r) (p)->Ref(__FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_REF(p, r) \ + grpc_subchannel_ref((p), __FILE__, __LINE__, (r)) #define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ - (p)->RefFromWeakRef(__FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_UNREF(p, r) (p)->Unref(__FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_WEAK_REF(p, r) (p)->WeakRef(__FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) (p)->WeakUnref(__FILE__, __LINE__, (r)) + grpc_subchannel_ref_from_weak_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_UNREF(p, r) \ + grpc_subchannel_unref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_WEAK_REF(p, r) \ + grpc_subchannel_weak_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) \ + grpc_subchannel_weak_unref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_CALL_REF(p, r) \ + grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) \ + grpc_subchannel_call_unref((p), __FILE__, __LINE__, (r)) #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS \ - const char *file, int line, const char *reason -#define GRPC_SUBCHANNEL_REF_REASON reason -#define GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS \ - , GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char* purpose -#define GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE(x) , file, line, reason, x + , const char *file, int line, const char *reason #else -#define GRPC_SUBCHANNEL_REF(p, r) (p)->Ref() -#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) (p)->RefFromWeakRef() -#define GRPC_SUBCHANNEL_UNREF(p, r) (p)->Unref() -#define GRPC_SUBCHANNEL_WEAK_REF(p, r) (p)->WeakRef() -#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) (p)->WeakUnref() +#define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p)) +#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ + grpc_subchannel_ref_from_weak_ref((p)) +#define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p)) +#define GRPC_SUBCHANNEL_WEAK_REF(p, r) grpc_subchannel_weak_ref((p)) +#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) grpc_subchannel_weak_unref((p)) +#define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p)) +#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) grpc_subchannel_call_unref((p)) #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS -#define GRPC_SUBCHANNEL_REF_REASON "" -#define GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS -#define GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE(x) #endif namespace grpc_core { -class SubchannelCall; - class ConnectedSubchannel : public RefCounted { public: struct CallArgs { @@ -82,7 +86,8 @@ class ConnectedSubchannel : public RefCounted { ConnectedSubchannel( grpc_channel_stack* channel_stack, const grpc_channel_args* args, - RefCountedPtr channelz_subchannel, + grpc_core::RefCountedPtr + channelz_subchannel, intptr_t socket_uuid); ~ConnectedSubchannel(); @@ -90,8 +95,7 @@ class ConnectedSubchannel : public RefCounted { grpc_connectivity_state* state, grpc_closure* closure); void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); - RefCountedPtr CreateCall(const CallArgs& args, - grpc_error** error); + grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); grpc_channel_stack* channel_stack() const { return channel_stack_; } const grpc_channel_args* args() const { return args_; } @@ -107,204 +111,91 @@ class ConnectedSubchannel : public RefCounted { grpc_channel_args* args_; // ref counted pointer to the channelz node in this connected subchannel's // owning subchannel. - RefCountedPtr channelz_subchannel_; + grpc_core::RefCountedPtr + channelz_subchannel_; // uuid of this subchannel's socket. 0 if this subchannel is not connected. const intptr_t socket_uuid_; }; -// Implements the interface of RefCounted<>. -class SubchannelCall { - public: - SubchannelCall(RefCountedPtr connected_subchannel, - const ConnectedSubchannel::CallArgs& args) - : connected_subchannel_(std::move(connected_subchannel)), - deadline_(args.deadline) {} - - // Continues processing a transport stream op batch. - void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch); - - // Returns a pointer to the parent data associated with the subchannel call. - // The data will be of the size specified in \a parent_data_size field of - // the args passed to \a ConnectedSubchannel::CreateCall(). - void* GetParentData(); - - // Returns the call stack of the subchannel call. - grpc_call_stack* GetCallStack(); - - grpc_closure* after_call_stack_destroy() const { - return after_call_stack_destroy_; - } - - // Sets the 'then_schedule_closure' argument for call stack destruction. - // Must be called once per call. - void SetAfterCallStackDestroy(grpc_closure* closure); - - // Interface of RefCounted<>. - RefCountedPtr Ref() GRPC_MUST_USE_RESULT; - RefCountedPtr Ref(const DebugLocation& location, - const char* reason) GRPC_MUST_USE_RESULT; - // When refcount drops to 0, destroys itself and the associated call stack, - // but does NOT free the memory because it's in the call arena. - void Unref(); - void Unref(const DebugLocation& location, const char* reason); - - private: - // Allow RefCountedPtr<> to access IncrementRefCount(). - template - friend class RefCountedPtr; - - // If channelz is enabled, intercepts recv_trailing so that we may check the - // status and associate it to a subchannel. - void MaybeInterceptRecvTrailingMetadata( - grpc_transport_stream_op_batch* batch); - - static void RecvTrailingMetadataReady(void* arg, grpc_error* error); - - // Interface of RefCounted<>. - void IncrementRefCount(); - void IncrementRefCount(const DebugLocation& location, const char* reason); - - RefCountedPtr connected_subchannel_; - grpc_closure* after_call_stack_destroy_ = nullptr; - // State needed to support channelz interception of recv trailing metadata. - grpc_closure recv_trailing_metadata_ready_; - grpc_closure* original_recv_trailing_metadata_ = nullptr; - grpc_metadata_batch* recv_trailing_metadata_ = nullptr; - grpc_millis deadline_; -}; - -// A subchannel that knows how to connect to exactly one target address. It -// provides a target for load balancing. -class Subchannel { - public: - // The ctor and dtor are not intended to use directly. - Subchannel(SubchannelKey* key, grpc_connector* connector, - const grpc_channel_args* args); - ~Subchannel(); - - // Creates a subchannel given \a connector and \a args. - static Subchannel* Create(grpc_connector* connector, - const grpc_channel_args* args); - - // Strong and weak refcounting. - Subchannel* Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); - void Unref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); - Subchannel* WeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); - void WeakUnref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); - Subchannel* RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); - - intptr_t GetChildSocketUuid(); - - // Gets the string representing the subchannel address. - // Caller doesn't take ownership. - const char* GetTargetAddress(); - - // Gets the connected subchannel - or nullptr if not connected (which may - // happen before it initially connects or during transient failures). - RefCountedPtr connected_subchannel(); - - channelz::SubchannelNode* channelz_node(); - - // Polls the current connectivity state of the subchannel. - grpc_connectivity_state CheckConnectivity(grpc_error** error, - bool inhibit_health_checking); - - // When the connectivity state of the subchannel changes from \a *state, - // invokes \a notify and updates \a *state with the new state. - void NotifyOnStateChange(grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, grpc_closure* notify, - bool inhibit_health_checks); - - // Resets the connection backoff of the subchannel. - // TODO(roth): Move connection backoff out of subchannels and up into LB - // policy code (probably by adding a SubchannelGroup between - // SubchannelList and SubchannelData), at which point this method can - // go away. - void ResetBackoff(); - - // Returns a new channel arg encoding the subchannel address as a URI - // string. Caller is responsible for freeing the string. - static grpc_arg CreateSubchannelAddressArg(const grpc_resolved_address* addr); - - // Returns the URI string from the subchannel address arg in \a args. - static const char* GetUriFromSubchannelAddressArg( - const grpc_channel_args* args); - - // Sets \a addr from the subchannel address arg in \a args. - static void GetAddressFromSubchannelAddressArg(const grpc_channel_args* args, - grpc_resolved_address* addr); - - private: - struct ExternalStateWatcher; - class ConnectedSubchannelStateWatcher; - - // Sets the subchannel's connectivity state to \a state. - void SetConnectivityStateLocked(grpc_connectivity_state state, - grpc_error* error, const char* reason); - - // Methods for connection. - void MaybeStartConnectingLocked(); - static void OnRetryAlarm(void* arg, grpc_error* error); - void ContinueConnectingLocked(); - static void OnConnectingFinished(void* arg, grpc_error* error); - bool PublishTransportLocked(); - void Disconnect(); - - gpr_atm RefMutate(gpr_atm delta, - int barrier GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS); - - // The subchannel pool this subchannel is in. - RefCountedPtr subchannel_pool_; - // TODO(juanlishen): Consider using args_ as key_ directly. - // Subchannel key that identifies this subchannel in the subchannel pool. - SubchannelKey* key_; - // Channel args. - grpc_channel_args* args_; - // pollset_set tracking who's interested in a connection being setup. - grpc_pollset_set* pollset_set_; - // Protects the other members. - gpr_mu mu_; - // Refcount - // - lower INTERNAL_REF_BITS bits are for internal references: - // these do not keep the subchannel open. - // - upper remaining bits are for public references: these do - // keep the subchannel open - gpr_atm ref_pair_; - - // Connection states. - grpc_connector* connector_ = nullptr; - // Set during connection. - grpc_connect_out_args connecting_result_; - grpc_closure on_connecting_finished_; - // Active connection, or null. - RefCountedPtr connected_subchannel_; - OrphanablePtr connected_subchannel_watcher_; - bool connecting_ = false; - bool disconnected_ = false; - - // Connectivity state tracking. - grpc_connectivity_state_tracker state_tracker_; - grpc_connectivity_state_tracker state_and_health_tracker_; - UniquePtr health_check_service_name_; - ExternalStateWatcher* external_state_watcher_list_ = nullptr; - - // Backoff state. - BackOff backoff_; - grpc_millis next_attempt_deadline_; - grpc_millis min_connect_timeout_ms_; - bool backoff_begun_ = false; - - // Retry alarm. - grpc_timer retry_alarm_; - grpc_closure on_retry_alarm_; - bool have_retry_alarm_ = false; - // reset_backoff() was called while alarm was pending. - bool retry_immediately_ = false; - - // Channelz tracking. - RefCountedPtr channelz_node_; -}; - } // namespace grpc_core +grpc_subchannel* grpc_subchannel_ref( + grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +grpc_subchannel* grpc_subchannel_ref_from_weak_ref( + grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_unref( + grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +grpc_subchannel* grpc_subchannel_weak_ref( + grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_weak_unref( + grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +grpc_subchannel_call* grpc_subchannel_call_ref( + grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_call_unref( + grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + +grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( + grpc_subchannel* subchannel); + +intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel); + +/** Returns a pointer to the parent data associated with \a subchannel_call. + The data will be of the size specified in \a parent_data_size + field of the args passed to \a grpc_connected_subchannel_create_call(). */ +void* grpc_connected_subchannel_call_get_parent_data( + grpc_subchannel_call* subchannel_call); + +/** poll the current connectivity state of a channel */ +grpc_connectivity_state grpc_subchannel_check_connectivity( + grpc_subchannel* channel, grpc_error** error, bool inhibit_health_checking); + +/** Calls notify when the connectivity state of a channel becomes different + from *state. Updates *state with the new state of the channel. */ +void grpc_subchannel_notify_on_state_change( + grpc_subchannel* channel, grpc_pollset_set* interested_parties, + grpc_connectivity_state* state, grpc_closure* notify, + bool inhibit_health_checks); + +/** retrieve the grpc_core::ConnectedSubchannel - or nullptr if not connected + * (which may happen before it initially connects or during transient failures) + * */ +grpc_core::RefCountedPtr +grpc_subchannel_get_connected_subchannel(grpc_subchannel* c); + +// Resets the connection backoff of the subchannel. +// TODO(roth): Move connection backoff out of subchannels and up into LB +// policy code (probably by adding a SubchannelGroup between +// SubchannelList and SubchannelData), at which point this method can +// go away. +void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel); + +/** continue processing a transport op */ +void grpc_subchannel_call_process_op(grpc_subchannel_call* subchannel_call, + grpc_transport_stream_op_batch* op); + +/** Must be called once per call. Sets the 'then_schedule_closure' argument for + call stack destruction. */ +void grpc_subchannel_call_set_cleanup_closure( + grpc_subchannel_call* subchannel_call, grpc_closure* closure); + +grpc_call_stack* grpc_subchannel_call_get_call_stack( + grpc_subchannel_call* subchannel_call); + +/** create a subchannel given a connector */ +grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, + const grpc_channel_args* args); + +/// Sets \a addr from \a args. +void grpc_get_subchannel_address_arg(const grpc_channel_args* args, + grpc_resolved_address* addr); + +const char* grpc_subchannel_get_target(grpc_subchannel* subchannel); + +/// Returns the URI string for the address to connect to. +const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args); + +/// Returns a new channel arg encoding the subchannel address as a string. +/// Caller is responsible for freeing the string. +grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr); + #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_H */ diff --git a/src/core/ext/filters/client_channel/subchannel_pool_interface.h b/src/core/ext/filters/client_channel/subchannel_pool_interface.h index eeb56faf0c0..21597bf4276 100644 --- a/src/core/ext/filters/client_channel/subchannel_pool_interface.h +++ b/src/core/ext/filters/client_channel/subchannel_pool_interface.h @@ -26,9 +26,9 @@ #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/ref_counted.h" -namespace grpc_core { +struct grpc_subchannel; -class Subchannel; +namespace grpc_core { extern TraceFlag grpc_subchannel_pool_trace; @@ -69,15 +69,15 @@ class SubchannelPoolInterface : public RefCounted { // Registers a subchannel against a key. Returns the subchannel registered // with \a key, which may be different from \a constructed because we reuse // (instead of update) any existing subchannel already registered with \a key. - virtual Subchannel* RegisterSubchannel(SubchannelKey* key, - Subchannel* constructed) GRPC_ABSTRACT; + virtual grpc_subchannel* RegisterSubchannel( + SubchannelKey* key, grpc_subchannel* constructed) GRPC_ABSTRACT; // Removes the registered subchannel found by \a key. virtual void UnregisterSubchannel(SubchannelKey* key) GRPC_ABSTRACT; // Finds the subchannel registered for the given subchannel key. Returns NULL // if no such channel exists. Thread-safe. - virtual Subchannel* FindSubchannel(SubchannelKey* key) GRPC_ABSTRACT; + virtual grpc_subchannel* FindSubchannel(SubchannelKey* key) GRPC_ABSTRACT; // Creates a channel arg from \a subchannel pool. static grpc_arg CreateChannelArg(SubchannelPoolInterface* subchannel_pool); diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 1e9a75d0630..42a2e2e896c 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -202,8 +202,7 @@ static void chttp2_connector_connect(grpc_connector* con, grpc_closure* notify) { chttp2_connector* c = reinterpret_cast(con); grpc_resolved_address addr; - grpc_core::Subchannel::GetAddressFromSubchannelAddressArg(args->channel_args, - &addr); + grpc_get_subchannel_address_arg(args->channel_args, &addr); gpr_mu_lock(&c->mu); GPR_ASSERT(c->notify == nullptr); c->notify = notify; diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc index 8aabcfa2000..a5bf1bf21d4 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -39,11 +39,11 @@ static void client_channel_factory_ref( static void client_channel_factory_unref( grpc_client_channel_factory* cc_factory) {} -static grpc_core::Subchannel* client_channel_factory_create_subchannel( +static grpc_subchannel* client_channel_factory_create_subchannel( grpc_client_channel_factory* cc_factory, const grpc_channel_args* args) { grpc_channel_args* new_args = grpc_default_authority_add_if_not_present(args); grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_core::Subchannel* s = grpc_core::Subchannel::Create(connector, new_args); + grpc_subchannel* s = grpc_subchannel_create(connector, new_args); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index eb2fee2af91..5985fa0cbdb 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -76,8 +76,7 @@ static grpc_channel_args* get_secure_naming_channel_args( grpc_core::UniquePtr authority; if (target_authority_table != nullptr) { // Find the authority for the target. - const char* target_uri_str = - grpc_core::Subchannel::GetUriFromSubchannelAddressArg(args); + const char* target_uri_str = grpc_get_subchannel_address_uri_arg(args); grpc_uri* target_uri = grpc_uri_parse(target_uri_str, false /* suppress errors */); GPR_ASSERT(target_uri != nullptr); @@ -139,7 +138,7 @@ static grpc_channel_args* get_secure_naming_channel_args( return new_args; } -static grpc_core::Subchannel* client_channel_factory_create_subchannel( +static grpc_subchannel* client_channel_factory_create_subchannel( grpc_client_channel_factory* cc_factory, const grpc_channel_args* args) { grpc_channel_args* new_args = get_secure_naming_channel_args(args); if (new_args == nullptr) { @@ -148,7 +147,7 @@ static grpc_core::Subchannel* client_channel_factory_create_subchannel( return nullptr; } grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_core::Subchannel* s = grpc_core::Subchannel::Create(connector, new_args); + grpc_subchannel* s = grpc_subchannel_create(connector, new_args); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/test/core/util/debugger_macros.cc b/test/core/util/debugger_macros.cc index fed6ad97285..05fb1461733 100644 --- a/test/core/util/debugger_macros.cc +++ b/test/core/util/debugger_macros.cc @@ -36,14 +36,13 @@ grpc_stream* grpc_transport_stream_from_call(grpc_call* call) { for (;;) { grpc_call_element* el = grpc_call_stack_element(cs, cs->count - 1); if (el->filter == &grpc_client_channel_filter) { - grpc_core::RefCountedPtr scc = - grpc_client_channel_get_subchannel_call(el); + grpc_subchannel_call* scc = grpc_client_channel_get_subchannel_call(el); if (scc == nullptr) { fprintf(stderr, "No subchannel-call"); fflush(stderr); return nullptr; } - cs = scc->GetCallStack(); + cs = grpc_subchannel_call_get_call_stack(scc); } else if (el->filter == &grpc_connected_filter) { return grpc_connected_channel_get_stream(el); } else { diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 973f47beaf7..125b1ce5c4e 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -325,8 +325,8 @@ class FakeClientChannelFactory : public grpc_client_channel_factory { private: static void NoRef(grpc_client_channel_factory* factory) {} static void NoUnref(grpc_client_channel_factory* factory) {} - static grpc_core::Subchannel* CreateSubchannel( - grpc_client_channel_factory* factory, const grpc_channel_args* args) { + static grpc_subchannel* CreateSubchannel(grpc_client_channel_factory* factory, + const grpc_channel_args* args) { return nullptr; } static grpc_channel* CreateClientChannel(grpc_client_channel_factory* factory, From 5a0699c705177d4a3c6a35c95a92d0be3ec378a6 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Tue, 29 Jan 2019 15:24:24 -0800 Subject: [PATCH 214/814] Allow trust anchor in gRPC ssl transport security --- src/core/tsi/ssl_transport_security.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index fb6ea192106..b18da575382 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -651,6 +651,8 @@ static tsi_result ssl_ctx_load_verification_certs(SSL_CTX* context, STACK_OF(X509_NAME) * *root_name) { X509_STORE* cert_store = SSL_CTX_get_cert_store(context); + X509_STORE_set_flags(cert_store, + X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_TRUSTED_FIRST); return x509_store_load_certs(cert_store, pem_roots, pem_roots_size, root_name); } From ad9dcc1ff4c315b4a9d59a9a6623b6be32f10d27 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 29 Jan 2019 15:56:46 -0800 Subject: [PATCH 215/814] Update formatting --- src/compiler/csharp_generator.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 14ee535d071..2a87463d2d0 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -609,8 +609,8 @@ void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor* service) { out->Print("\n"); } -void GenerateBindServiceWithBinderMethod( - Printer* out, const ServiceDescriptor* service) { +void GenerateBindServiceWithBinderMethod(Printer* out, + const ServiceDescriptor* service) { out->Print( "/// Register service method with a service " "binder without implementation. Useful when customizing the service " From 80b873c3be14fd304cd5d0199f26a87104588882 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Tue, 29 Jan 2019 22:00:26 -0800 Subject: [PATCH 216/814] Fix typo breaking mac to prod --- tools/internal_ci/macos/grpc_interop_toprod.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/macos/grpc_interop_toprod.sh b/tools/internal_ci/macos/grpc_interop_toprod.sh index daca88c5c51..654da373a26 100755 --- a/tools/internal_ci/macos/grpc_interop_toprod.sh +++ b/tools/internal_ci/macos/grpc_interop_toprod.sh @@ -31,7 +31,7 @@ export GRPC_DEFAULT_SSL_ROOTS_FILE_PATH="$(pwd)/etc/roots.pem" # due to different compilation flags tools/run_tests/run_interop_tests.py -l c++ \ --cloud_to_prod --cloud_to_prod_auth \ - --google_default_creds_use_key_file=true \ + --google_default_creds_use_key_file \ --prod_servers default gateway_v4 \ --service_account_key_file="${KOKORO_GFILE_DIR}/GrpcTesting-726eb1347f15.json" \ --skip_compute_engine_creds --internal_ci -t -j 4 || FAILED="true" From 9442811db260ae7f733a70dfb1ab0a2b1144cf7a Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Tue, 29 Jan 2019 22:06:34 -0800 Subject: [PATCH 217/814] Fix spam log message --- .../security/credentials/alts/check_gcp_environment_no_op.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc b/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc index d97681b86d2..b71f66a536a 100644 --- a/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc +++ b/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc @@ -25,8 +25,8 @@ #include bool grpc_alts_is_running_on_gcp() { - gpr_log(GPR_ERROR, - "Platforms other than Linux and Windows are not supported"); + gpr_log(GPR_INFO, + "ALTS: Platforms other than Linux and Windows are not supported"); return false; } From 8410765c0a48342287e5e2f324d17da73b9679da Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 29 Jan 2019 23:36:18 -0800 Subject: [PATCH 218/814] Eliminate an unneeded log_info --- src/core/lib/surface/server.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index c20796f5acf..1e0ac0e9237 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -997,10 +997,12 @@ void grpc_server_register_completion_queue(grpc_server* server, "grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3, (server, cq, reserved)); - if (grpc_get_cq_completion_type(cq) != GRPC_CQ_NEXT) { + auto cq_type = grpc_get_cq_completion_type(cq); + if (cq_type != GRPC_CQ_NEXT && cq_type != GRPC_CQ_CALLBACK) { gpr_log(GPR_INFO, - "Completion queue which is not of type GRPC_CQ_NEXT is being " - "registered as a server-completion-queue"); + "Completion queue of type %d is being registered as a " + "server-completion-queue", + static_cast(cq_type)); /* Ideally we should log an error and abort but ruby-wrapped-language API calls grpc_completion_queue_pluck() on server completion queues */ } From 8548a932fbc82a260ba7742a8bdf48d9f6dd4be3 Mon Sep 17 00:00:00 2001 From: xichengliudui <1693291525@qq.com> Date: Wed, 30 Jan 2019 11:24:09 -0500 Subject: [PATCH 219/814] Update .cc and .md files --- src/core/ext/filters/max_age/max_age_filter.cc | 2 +- summerofcode/2018/naresh.md | 2 +- test/cpp/end2end/channelz_service_test.cc | 2 +- test/cpp/util/channel_trace_proto_helper.cc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc index 431472609eb..ec7f4e254aa 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -106,7 +106,7 @@ struct channel_data { +--------------------------------+----------------+---------+ MAX_IDLE_STATE_INIT: The initial and final state of 'idle_state'. The - channel has 1 or 1+ active calls, and the the timer is not set. Note that + channel has 1 or 1+ active calls, and the timer is not set. Note that we may put a virtual call to hold this state at channel initialization or shutdown, so that the channel won't enter other states. diff --git a/summerofcode/2018/naresh.md b/summerofcode/2018/naresh.md index 0d196bd6001..d471bff5459 100644 --- a/summerofcode/2018/naresh.md +++ b/summerofcode/2018/naresh.md @@ -128,7 +128,7 @@ bazel test --spawn_strategy=standalone --genrule_strategy=standalone //src/pytho - Use `bazel build` with a `-s` flag to see the logs being printed out to standard output while building. -- Similarly, use `bazel test` with a `--test_output=streamed` to see the the +- Similarly, use `bazel test` with a `--test_output=streamed` to see the test logs while testing. Something to know while using this flag is that all tests will be run locally, without sharding, one at a time. diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index 425334d972e..e7719b5c14e 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -708,7 +708,7 @@ TEST_F(ChannelzServerTest, GetServerSocketsPaginationTest) { get_server_sockets_request, &get_server_sockets_response); EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); - // We add one to account the the channelz stub that will end up creating + // We add one to account the channelz stub that will end up creating // a serversocket. EXPECT_EQ(get_server_sockets_response.socket_ref_size(), kNumServerSocketsCreated + 1); diff --git a/test/cpp/util/channel_trace_proto_helper.cc b/test/cpp/util/channel_trace_proto_helper.cc index ff9d8873858..2499edf6540 100644 --- a/test/cpp/util/channel_trace_proto_helper.cc +++ b/test/cpp/util/channel_trace_proto_helper.cc @@ -56,7 +56,7 @@ void VaidateProtoJsonTranslation(char* json_c_str) { EXPECT_EQ(google::protobuf::util::MessageToJsonString(msg, &proto_json_str, print_options), google::protobuf::util::Status::OK); - // uncomment these to compare the the json strings. + // uncomment these to compare the json strings. // gpr_log(GPR_ERROR, "tracer json: %s", json_str.c_str()); // gpr_log(GPR_ERROR, "proto json: %s", proto_json_str.c_str()); EXPECT_EQ(json_str, proto_json_str); From 8e085233ed82d3966ed5d284fb289bc43674be8d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 28 Jan 2019 17:59:32 -0800 Subject: [PATCH 220/814] Fix CFStream test --- .../xcshareddata/xcschemes/CFStreamTests.xcscheme | 7 +++++++ .../xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme | 9 +++++++-- .../xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme | 9 +++++++-- .../xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme | 9 +++++++-- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme index 25d6f780a1e..e4b4ce89e27 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests.xcscheme @@ -36,6 +36,13 @@ debugDocumentVersioning = "YES" debugServiceExtension = "internal" allowLocationSimulation = "YES"> + + + + diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme index 6c5c43aa721..d29ed5cb548 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Asan.xcscheme @@ -12,7 +12,6 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" enableAddressSanitizer = "YES" enableASanStackUseAfterReturn = "YES" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme index 3e39ff84d06..ab9b9be5917 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Msan.xcscheme @@ -10,7 +10,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme index f0bde837c5b..bad1ceab715 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/xcshareddata/xcschemes/CFStreamTests_Tsan.xcscheme @@ -11,7 +11,6 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" enableThreadSanitizer = "YES" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + From 4f3c1572e120b856cff028a5ed1247bf7f5a99ba Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 30 Jan 2019 10:23:07 -0800 Subject: [PATCH 221/814] Revert "Revert "C++-ify subchannel"" --- .../filters/client_channel/client_channel.cc | 114 +- .../filters/client_channel/client_channel.h | 4 +- .../client_channel/client_channel_channelz.cc | 11 +- .../client_channel/client_channel_channelz.h | 9 +- .../client_channel/client_channel_factory.cc | 2 +- .../client_channel/client_channel_factory.h | 6 +- .../client_channel/global_subchannel_pool.cc | 19 +- .../client_channel/global_subchannel_pool.h | 6 +- .../health/health_check_client.cc | 18 +- .../health/health_check_client.h | 2 +- .../lb_policy/pick_first/pick_first.cc | 2 +- .../lb_policy/round_robin/round_robin.cc | 2 +- .../lb_policy/subchannel_list.h | 37 +- .../client_channel/local_subchannel_pool.cc | 14 +- .../client_channel/local_subchannel_pool.h | 6 +- .../ext/filters/client_channel/subchannel.cc | 1506 ++++++++--------- .../ext/filters/client_channel/subchannel.h | 331 ++-- .../subchannel_pool_interface.h | 10 +- .../chttp2/client/chttp2_connector.cc | 3 +- .../chttp2/client/insecure/channel_create.cc | 4 +- .../client/secure/secure_channel_create.cc | 7 +- test/core/util/debugger_macros.cc | 5 +- test/cpp/microbenchmarks/bm_call_create.cc | 4 +- 23 files changed, 1060 insertions(+), 1062 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 35c3efab6aa..38525dbf97e 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -394,7 +394,7 @@ struct subchannel_batch_data { gpr_refcount refs; grpc_call_element* elem; - grpc_subchannel_call* subchannel_call; // Holds a ref. + grpc_core::RefCountedPtr subchannel_call; // The batch to use in the subchannel call. // Its payload field points to subchannel_call_retry_state.batch_payload. grpc_transport_stream_op_batch batch; @@ -478,7 +478,7 @@ struct pending_batch { bool send_ops_cached; }; -/** Call data. Holds a pointer to grpc_subchannel_call and the +/** Call data. Holds a pointer to SubchannelCall and the associated machinery to create such a pointer. Handles queueing of stream ops until a call object is ready, waiting for initial metadata before trying to create a call object, @@ -504,10 +504,6 @@ struct call_data { last_attempt_got_server_pushback(false) {} ~call_data() { - if (GPR_LIKELY(subchannel_call != nullptr)) { - GRPC_SUBCHANNEL_CALL_UNREF(subchannel_call, - "client_channel_destroy_call"); - } grpc_slice_unref_internal(path); GRPC_ERROR_UNREF(cancel_error); for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches); ++i) { @@ -536,7 +532,7 @@ struct call_data { grpc_core::RefCountedPtr retry_throttle_data; grpc_core::RefCountedPtr method_params; - grpc_subchannel_call* subchannel_call = nullptr; + grpc_core::RefCountedPtr subchannel_call; // Set when we get a cancel_stream op. grpc_error* cancel_error = GRPC_ERROR_NONE; @@ -807,8 +803,8 @@ static void pending_batches_add(grpc_call_element* elem, calld->subchannel_call == nullptr ? nullptr : static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); + + calld->subchannel_call->GetParentData()); retry_commit(elem, retry_state); // If we are not going to retry and have not yet started, pretend // retries are disabled so that we don't bother with retry overhead. @@ -896,10 +892,10 @@ static void resume_pending_batch_in_call_combiner(void* arg, grpc_error* ignored) { grpc_transport_stream_op_batch* batch = static_cast(arg); - grpc_subchannel_call* subchannel_call = - static_cast(batch->handler_private.extra_arg); + grpc_core::SubchannelCall* subchannel_call = + static_cast(batch->handler_private.extra_arg); // Note: This will release the call combiner. - grpc_subchannel_call_process_op(subchannel_call, batch); + subchannel_call->StartTransportStreamOpBatch(batch); } // This is called via the call combiner, so access to calld is synchronized. @@ -919,7 +915,7 @@ static void pending_batches_resume(grpc_call_element* elem) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting %" PRIuPTR " pending batches on subchannel_call=%p", - chand, calld, num_batches, calld->subchannel_call); + chand, calld, num_batches, calld->subchannel_call.get()); } grpc_core::CallCombinerClosureList closures; for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { @@ -930,7 +926,7 @@ static void pending_batches_resume(grpc_call_element* elem) { maybe_inject_recv_trailing_metadata_ready_for_lb( *calld->request->pick(), batch); } - batch->handler_private.extra_arg = calld->subchannel_call; + batch->handler_private.extra_arg = calld->subchannel_call.get(); GRPC_CLOSURE_INIT(&batch->handler_private.closure, resume_pending_batch_in_call_combiner, batch, grpc_schedule_on_exec_ctx); @@ -1019,12 +1015,7 @@ static void do_retry(grpc_call_element* elem, const ClientChannelMethodParams::RetryPolicy* retry_policy = calld->method_params->retry_policy(); GPR_ASSERT(retry_policy != nullptr); - // Reset subchannel call and connected subchannel. - if (calld->subchannel_call != nullptr) { - GRPC_SUBCHANNEL_CALL_UNREF(calld->subchannel_call, - "client_channel_call_retry"); - calld->subchannel_call = nullptr; - } + calld->subchannel_call.reset(); if (calld->have_request) { calld->have_request = false; calld->request.Destroy(); @@ -1078,8 +1069,7 @@ static bool maybe_retry(grpc_call_element* elem, subchannel_call_retry_state* retry_state = nullptr; if (batch_data != nullptr) { retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); if (retry_state->retry_dispatched) { if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: retry already dispatched", chand, @@ -1180,13 +1170,10 @@ namespace { subchannel_batch_data::subchannel_batch_data(grpc_call_element* elem, call_data* calld, int refcount, bool set_on_complete) - : elem(elem), - subchannel_call(GRPC_SUBCHANNEL_CALL_REF(calld->subchannel_call, - "batch_data_create")) { + : elem(elem), subchannel_call(calld->subchannel_call) { subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); + calld->subchannel_call->GetParentData()); batch.payload = &retry_state->batch_payload; gpr_ref_init(&refs, refcount); if (set_on_complete) { @@ -1200,7 +1187,7 @@ subchannel_batch_data::subchannel_batch_data(grpc_call_element* elem, void subchannel_batch_data::destroy() { subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data(subchannel_call)); + subchannel_call->GetParentData()); if (batch.send_initial_metadata) { grpc_metadata_batch_destroy(&retry_state->send_initial_metadata); } @@ -1213,7 +1200,7 @@ void subchannel_batch_data::destroy() { if (batch.recv_trailing_metadata) { grpc_metadata_batch_destroy(&retry_state->recv_trailing_metadata); } - GRPC_SUBCHANNEL_CALL_UNREF(subchannel_call, "batch_data_unref"); + subchannel_call.reset(); call_data* calld = static_cast(elem->call_data); GRPC_CALL_STACK_UNREF(calld->owning_call, "batch_data"); } @@ -1260,8 +1247,7 @@ static void invoke_recv_initial_metadata_callback(void* arg, // Return metadata. subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); grpc_metadata_batch_move( &retry_state->recv_initial_metadata, pending->batch->payload->recv_initial_metadata.recv_initial_metadata); @@ -1293,8 +1279,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); retry_state->completed_recv_initial_metadata = true; // If a retry was already dispatched, then we're not going to use the // result of this recv_initial_metadata op, so do nothing. @@ -1355,8 +1340,7 @@ static void invoke_recv_message_callback(void* arg, grpc_error* error) { // Return payload. subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); *pending->batch->payload->recv_message.recv_message = std::move(retry_state->recv_message); // Update bookkeeping. @@ -1384,8 +1368,7 @@ static void recv_message_ready(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); ++retry_state->completed_recv_message_count; // If a retry was already dispatched, then we're not going to use the // result of this recv_message op, so do nothing. @@ -1473,8 +1456,7 @@ static void add_closure_for_recv_trailing_metadata_ready( // Return metadata. subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); grpc_metadata_batch_move( &retry_state->recv_trailing_metadata, pending->batch->payload->recv_trailing_metadata.recv_trailing_metadata); @@ -1576,8 +1558,7 @@ static void run_closures_for_completed_call(subchannel_batch_data* batch_data, call_data* calld = static_cast(elem->call_data); subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); // Construct list of closures to execute. grpc_core::CallCombinerClosureList closures; // First, add closure for recv_trailing_metadata_ready. @@ -1611,8 +1592,7 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); retry_state->completed_recv_trailing_metadata = true; // Get the call's status and check for server pushback metadata. grpc_status_code status = GRPC_STATUS_OK; @@ -1735,8 +1715,7 @@ static void on_complete(void* arg, grpc_error* error) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - batch_data->subchannel_call)); + batch_data->subchannel_call->GetParentData()); // Update bookkeeping in retry_state. if (batch_data->batch.send_initial_metadata) { retry_state->completed_send_initial_metadata = true; @@ -1792,10 +1771,10 @@ static void on_complete(void* arg, grpc_error* error) { static void start_batch_in_call_combiner(void* arg, grpc_error* ignored) { grpc_transport_stream_op_batch* batch = static_cast(arg); - grpc_subchannel_call* subchannel_call = - static_cast(batch->handler_private.extra_arg); + grpc_core::SubchannelCall* subchannel_call = + static_cast(batch->handler_private.extra_arg); // Note: This will release the call combiner. - grpc_subchannel_call_process_op(subchannel_call, batch); + subchannel_call->StartTransportStreamOpBatch(batch); } // Adds a closure to closures that will execute batch in the call combiner. @@ -1804,7 +1783,7 @@ static void add_closure_for_subchannel_batch( grpc_core::CallCombinerClosureList* closures) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - batch->handler_private.extra_arg = calld->subchannel_call; + batch->handler_private.extra_arg = calld->subchannel_call.get(); GRPC_CLOSURE_INIT(&batch->handler_private.closure, start_batch_in_call_combiner, batch, grpc_schedule_on_exec_ctx); @@ -1978,8 +1957,7 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); + calld->subchannel_call->GetParentData()); // Create batch_data with 2 refs, since this batch will be unreffed twice: // once for the recv_trailing_metadata_ready callback when the subchannel // batch returns, and again when we actually get a recv_trailing_metadata @@ -1989,7 +1967,7 @@ static void start_internal_recv_trailing_metadata(grpc_call_element* elem) { add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data); retry_state->recv_trailing_metadata_internal_batch = batch_data; // Note: This will release the call combiner. - grpc_subchannel_call_process_op(calld->subchannel_call, &batch_data->batch); + calld->subchannel_call->StartTransportStreamOpBatch(&batch_data->batch); } // If there are any cached send ops that need to be replayed on the @@ -2196,8 +2174,7 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { } subchannel_call_retry_state* retry_state = static_cast( - grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)); + calld->subchannel_call->GetParentData()); // Construct list of closures to execute, one for each pending batch. grpc_core::CallCombinerClosureList closures; // Replay previously-returned send_* ops if needed. @@ -2220,7 +2197,7 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting %" PRIuPTR " retriable batches on subchannel_call=%p", - chand, calld, closures.size(), calld->subchannel_call); + chand, calld, closures.size(), calld->subchannel_call.get()); } // Note: This will yield the call combiner. closures.RunClosures(calld->call_combiner); @@ -2245,22 +2222,22 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { calld->call_combiner, // call_combiner parent_data_size // parent_data_size }; - grpc_error* new_error = - calld->request->pick()->connected_subchannel->CreateCall( - call_args, &calld->subchannel_call); + grpc_error* new_error = GRPC_ERROR_NONE; + calld->subchannel_call = + calld->request->pick()->connected_subchannel->CreateCall(call_args, + &new_error); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", - chand, calld, calld->subchannel_call, grpc_error_string(new_error)); + chand, calld, calld->subchannel_call.get(), + grpc_error_string(new_error)); } if (GPR_UNLIKELY(new_error != GRPC_ERROR_NONE)) { new_error = grpc_error_add_child(new_error, error); pending_batches_fail(elem, new_error, true /* yield_call_combiner */); } else { if (parent_data_size > 0) { - new (grpc_connected_subchannel_call_get_parent_data( - calld->subchannel_call)) - subchannel_call_retry_state( - calld->request->pick()->subchannel_call_context); + new (calld->subchannel_call->GetParentData()) subchannel_call_retry_state( + calld->request->pick()->subchannel_call_context); } pending_batches_resume(elem); } @@ -2488,7 +2465,7 @@ static void cc_start_transport_stream_op_batch( batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner); } else { // Note: This will release the call combiner. - grpc_subchannel_call_process_op(calld->subchannel_call, batch); + calld->subchannel_call->StartTransportStreamOpBatch(batch); } return; } @@ -2502,7 +2479,7 @@ static void cc_start_transport_stream_op_batch( if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting batch on subchannel_call=%p", chand, - calld, calld->subchannel_call); + calld, calld->subchannel_call.get()); } pending_batches_resume(elem); return; @@ -2545,8 +2522,7 @@ static void cc_destroy_call_elem(grpc_call_element* elem, grpc_closure* then_schedule_closure) { call_data* calld = static_cast(elem->call_data); if (GPR_LIKELY(calld->subchannel_call != nullptr)) { - grpc_subchannel_call_set_cleanup_closure(calld->subchannel_call, - then_schedule_closure); + calld->subchannel_call->SetAfterCallStackDestroy(then_schedule_closure); then_schedule_closure = nullptr; } calld->~call_data(); @@ -2752,8 +2728,8 @@ void grpc_client_channel_watch_connectivity_state( GRPC_ERROR_NONE); } -grpc_subchannel_call* grpc_client_channel_get_subchannel_call( - grpc_call_element* elem) { +grpc_core::RefCountedPtr +grpc_client_channel_get_subchannel_call(grpc_call_element* elem) { call_data* calld = static_cast(elem->call_data); return calld->subchannel_call; } diff --git a/src/core/ext/filters/client_channel/client_channel.h b/src/core/ext/filters/client_channel/client_channel.h index 4935fd24d87..5bfff4df9cd 100644 --- a/src/core/ext/filters/client_channel/client_channel.h +++ b/src/core/ext/filters/client_channel/client_channel.h @@ -60,7 +60,7 @@ void grpc_client_channel_watch_connectivity_state( grpc_closure* watcher_timer_init); /* Debug helper: pull the subchannel call from a call stack element */ -grpc_subchannel_call* grpc_client_channel_get_subchannel_call( - grpc_call_element* elem); +grpc_core::RefCountedPtr +grpc_client_channel_get_subchannel_call(grpc_call_element* elem); #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H */ diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 8e5426081c4..76c5a786240 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -113,12 +113,11 @@ RefCountedPtr ClientChannelNode::MakeClientChannelNode( is_top_level_channel); } -SubchannelNode::SubchannelNode(grpc_subchannel* subchannel, +SubchannelNode::SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes) : BaseNode(EntityType::kSubchannel), subchannel_(subchannel), - target_( - UniquePtr(gpr_strdup(grpc_subchannel_get_target(subchannel_)))), + target_(UniquePtr(gpr_strdup(subchannel_->GetTargetAddress()))), trace_(channel_tracer_max_nodes) {} SubchannelNode::~SubchannelNode() {} @@ -128,8 +127,8 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) { if (subchannel_ == nullptr) { state = GRPC_CHANNEL_SHUTDOWN; } else { - state = grpc_subchannel_check_connectivity( - subchannel_, nullptr, true /* inhibit_health_checking */); + state = subchannel_->CheckConnectivity(nullptr, + true /* inhibit_health_checking */); } json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); @@ -170,7 +169,7 @@ grpc_json* SubchannelNode::RenderJson() { call_counter_.PopulateCallCounts(json); json = top_level_json; // populate the child socket. - intptr_t socket_uuid = grpc_subchannel_get_child_socket_uuid(subchannel_); + intptr_t socket_uuid = subchannel_->GetChildSocketUuid(); if (socket_uuid != 0) { grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 8a5c3e7e5e5..1dc1bf595be 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -26,9 +26,10 @@ #include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" -typedef struct grpc_subchannel grpc_subchannel; - namespace grpc_core { + +class Subchannel; + namespace channelz { // Subtype of ChannelNode that overrides and provides client_channel specific @@ -59,7 +60,7 @@ class ClientChannelNode : public ChannelNode { // Handles channelz bookkeeping for sockets class SubchannelNode : public BaseNode { public: - SubchannelNode(grpc_subchannel* subchannel, size_t channel_tracer_max_nodes); + SubchannelNode(Subchannel* subchannel, size_t channel_tracer_max_nodes); ~SubchannelNode() override; void MarkSubchannelDestroyed() { @@ -84,7 +85,7 @@ class SubchannelNode : public BaseNode { void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } private: - grpc_subchannel* subchannel_; + Subchannel* subchannel_; UniquePtr target_; CallCountingHelper call_counter_; ChannelTrace trace_; diff --git a/src/core/ext/filters/client_channel/client_channel_factory.cc b/src/core/ext/filters/client_channel/client_channel_factory.cc index 130bbe04180..8c558382fdf 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.cc +++ b/src/core/ext/filters/client_channel/client_channel_factory.cc @@ -29,7 +29,7 @@ void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory) { factory->vtable->unref(factory); } -grpc_subchannel* grpc_client_channel_factory_create_subchannel( +grpc_core::Subchannel* grpc_client_channel_factory_create_subchannel( grpc_client_channel_factory* factory, const grpc_channel_args* args) { return factory->vtable->create_subchannel(factory, args); } diff --git a/src/core/ext/filters/client_channel/client_channel_factory.h b/src/core/ext/filters/client_channel/client_channel_factory.h index 91dec12282f..4b72aa46499 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -48,8 +48,8 @@ struct grpc_client_channel_factory { struct grpc_client_channel_factory_vtable { void (*ref)(grpc_client_channel_factory* factory); void (*unref)(grpc_client_channel_factory* factory); - grpc_subchannel* (*create_subchannel)(grpc_client_channel_factory* factory, - const grpc_channel_args* args); + grpc_core::Subchannel* (*create_subchannel)( + grpc_client_channel_factory* factory, const grpc_channel_args* args); grpc_channel* (*create_client_channel)(grpc_client_channel_factory* factory, const char* target, grpc_client_channel_type type, @@ -60,7 +60,7 @@ void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory); void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory); /** Create a new grpc_subchannel */ -grpc_subchannel* grpc_client_channel_factory_create_subchannel( +grpc_core::Subchannel* grpc_client_channel_factory_create_subchannel( grpc_client_channel_factory* factory, const grpc_channel_args* args); /** Create a new grpc_channel */ diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.cc b/src/core/ext/filters/client_channel/global_subchannel_pool.cc index a41d993fe66..ee6e58159a0 100644 --- a/src/core/ext/filters/client_channel/global_subchannel_pool.cc +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.cc @@ -54,9 +54,9 @@ RefCountedPtr GlobalSubchannelPool::instance() { return *instance_; } -grpc_subchannel* GlobalSubchannelPool::RegisterSubchannel( - SubchannelKey* key, grpc_subchannel* constructed) { - grpc_subchannel* c = nullptr; +Subchannel* GlobalSubchannelPool::RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) { + Subchannel* c = nullptr; // Compare and swap (CAS) loop: while (c == nullptr) { // Ref the shared map to have a local copy. @@ -64,7 +64,7 @@ grpc_subchannel* GlobalSubchannelPool::RegisterSubchannel( grpc_avl old_map = grpc_avl_ref(subchannel_map_, nullptr); gpr_mu_unlock(&mu_); // Check to see if a subchannel already exists. - c = static_cast(grpc_avl_get(old_map, key, nullptr)); + c = static_cast(grpc_avl_get(old_map, key, nullptr)); if (c != nullptr) { // The subchannel already exists. Reuse it. c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "subchannel_register+reuse"); @@ -121,15 +121,14 @@ void GlobalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { } } -grpc_subchannel* GlobalSubchannelPool::FindSubchannel(SubchannelKey* key) { +Subchannel* GlobalSubchannelPool::FindSubchannel(SubchannelKey* key) { // Lock, and take a reference to the subchannel map. // We don't need to do the search under a lock as AVL's are immutable. gpr_mu_lock(&mu_); grpc_avl index = grpc_avl_ref(subchannel_map_, nullptr); gpr_mu_unlock(&mu_); - grpc_subchannel* c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF( - static_cast(grpc_avl_get(index, key, nullptr)), - "found_from_pool"); + Subchannel* c = static_cast(grpc_avl_get(index, key, nullptr)); + if (c != nullptr) GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "found_from_pool"); grpc_avl_unref(index, nullptr); return c; } @@ -156,11 +155,11 @@ long sck_avl_compare(void* a, void* b, void* unused) { } void scv_avl_destroy(void* p, void* user_data) { - GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "global_subchannel_pool"); + GRPC_SUBCHANNEL_WEAK_UNREF((Subchannel*)p, "global_subchannel_pool"); } void* scv_avl_copy(void* p, void* unused) { - GRPC_SUBCHANNEL_WEAK_REF((grpc_subchannel*)p, "global_subchannel_pool"); + GRPC_SUBCHANNEL_WEAK_REF((Subchannel*)p, "global_subchannel_pool"); return p; } diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.h b/src/core/ext/filters/client_channel/global_subchannel_pool.h index 0deb3769360..96dc8d7b3a4 100644 --- a/src/core/ext/filters/client_channel/global_subchannel_pool.h +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.h @@ -45,10 +45,10 @@ class GlobalSubchannelPool final : public SubchannelPoolInterface { static RefCountedPtr instance(); // Implements interface methods. - grpc_subchannel* RegisterSubchannel(SubchannelKey* key, - grpc_subchannel* constructed) override; + Subchannel* RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) override; void UnregisterSubchannel(SubchannelKey* key) override; - grpc_subchannel* FindSubchannel(SubchannelKey* key) override; + Subchannel* FindSubchannel(SubchannelKey* key) override; private: // The singleton instance. (It's a pointer to RefCountedPtr so that this diff --git a/src/core/ext/filters/client_channel/health/health_check_client.cc b/src/core/ext/filters/client_channel/health/health_check_client.cc index 2232c57120e..e845d63d295 100644 --- a/src/core/ext/filters/client_channel/health/health_check_client.cc +++ b/src/core/ext/filters/client_channel/health/health_check_client.cc @@ -295,7 +295,9 @@ HealthCheckClient::CallState::~CallState() { gpr_log(GPR_INFO, "HealthCheckClient %p: destroying CallState %p", health_check_client_.get(), this); } - if (call_ != nullptr) GRPC_SUBCHANNEL_CALL_UNREF(call_, "call_ended"); + // The subchannel call is in the arena, so reset the pointer before we destroy + // the arena. + call_.reset(); for (size_t i = 0; i < GRPC_CONTEXT_COUNT; i++) { if (context_[i].destroy != nullptr) { context_[i].destroy(context_[i].value); @@ -329,8 +331,8 @@ void HealthCheckClient::CallState::StartCall() { &call_combiner_, 0, // parent_data_size }; - grpc_error* error = - health_check_client_->connected_subchannel_->CreateCall(args, &call_); + grpc_error* error = GRPC_ERROR_NONE; + call_ = health_check_client_->connected_subchannel_->CreateCall(args, &error); if (error != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "HealthCheckClient %p CallState %p: error creating health " @@ -423,14 +425,14 @@ void HealthCheckClient::CallState::StartBatchInCallCombiner(void* arg, grpc_error* error) { grpc_transport_stream_op_batch* batch = static_cast(arg); - grpc_subchannel_call* call = - static_cast(batch->handler_private.extra_arg); - grpc_subchannel_call_process_op(call, batch); + SubchannelCall* call = + static_cast(batch->handler_private.extra_arg); + call->StartTransportStreamOpBatch(batch); } void HealthCheckClient::CallState::StartBatch( grpc_transport_stream_op_batch* batch) { - batch->handler_private.extra_arg = call_; + batch->handler_private.extra_arg = call_.get(); GRPC_CLOSURE_INIT(&batch->handler_private.closure, StartBatchInCallCombiner, batch, grpc_schedule_on_exec_ctx); GRPC_CALL_COMBINER_START(&call_combiner_, &batch->handler_private.closure, @@ -452,7 +454,7 @@ void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) { GRPC_CLOSURE_CREATE(OnCancelComplete, self, grpc_schedule_on_exec_ctx)); batch->cancel_stream = true; batch->payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED; - grpc_subchannel_call_process_op(self->call_, batch); + self->call_->StartTransportStreamOpBatch(batch); } void HealthCheckClient::CallState::Cancel() { diff --git a/src/core/ext/filters/client_channel/health/health_check_client.h b/src/core/ext/filters/client_channel/health/health_check_client.h index 2369b73feac..7af88a54cfc 100644 --- a/src/core/ext/filters/client_channel/health/health_check_client.h +++ b/src/core/ext/filters/client_channel/health/health_check_client.h @@ -99,7 +99,7 @@ class HealthCheckClient : public InternallyRefCounted { grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {}; // The streaming call to the backend. Always non-NULL. - grpc_subchannel_call* call_; + RefCountedPtr call_; grpc_transport_stream_op_batch_payload payload_; grpc_transport_stream_op_batch batch_; diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index ec5c782c469..dc716a6adac 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -79,7 +79,7 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const ServerAddress& address, Subchannel* subchannel, grpc_combiner* combiner) : SubchannelData(subchannel_list, address, subchannel, combiner) {} diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 30316689ea7..aab6dd68216 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -94,7 +94,7 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const ServerAddress& address, Subchannel* subchannel, grpc_combiner* combiner) : SubchannelData(subchannel_list, address, subchannel, combiner) {} diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 2eb92b7ead0..0174a98a73d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -88,7 +88,7 @@ class SubchannelData { } // Returns a pointer to the subchannel. - grpc_subchannel* subchannel() const { return subchannel_; } + Subchannel* subchannel() const { return subchannel_; } // Returns the connected subchannel. Will be null if the subchannel // is not connected. @@ -103,8 +103,8 @@ class SubchannelData { // ProcessConnectivityChangeLocked()). grpc_connectivity_state CheckConnectivityStateLocked(grpc_error** error) { GPR_ASSERT(!connectivity_notification_pending_); - pending_connectivity_state_unsafe_ = grpc_subchannel_check_connectivity( - subchannel(), error, subchannel_list_->inhibit_health_checking()); + pending_connectivity_state_unsafe_ = subchannel()->CheckConnectivity( + error, subchannel_list_->inhibit_health_checking()); UpdateConnectedSubchannelLocked(); return pending_connectivity_state_unsafe_; } @@ -142,7 +142,7 @@ class SubchannelData { protected: SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const ServerAddress& address, Subchannel* subchannel, grpc_combiner* combiner); virtual ~SubchannelData(); @@ -170,7 +170,7 @@ class SubchannelData { SubchannelList* subchannel_list_; // The subchannel and connected subchannel. - grpc_subchannel* subchannel_; + Subchannel* subchannel_; RefCountedPtr connected_subchannel_; // Notification that connectivity has changed on subchannel. @@ -203,7 +203,7 @@ class SubchannelList : public InternallyRefCounted { for (size_t i = 0; i < subchannels_.size(); ++i) { if (subchannels_[i].subchannel() != nullptr) { grpc_core::channelz::SubchannelNode* subchannel_node = - grpc_subchannel_get_channelz_node(subchannels_[i].subchannel()); + subchannels_[i].subchannel()->channelz_node(); if (subchannel_node != nullptr) { refs_list->push_back(subchannel_node->uuid()); } @@ -276,7 +276,7 @@ class SubchannelList : public InternallyRefCounted { template SubchannelData::SubchannelData( SubchannelList* subchannel_list, - const ServerAddress& address, grpc_subchannel* subchannel, + const ServerAddress& address, Subchannel* subchannel, grpc_combiner* combiner) : subchannel_list_(subchannel_list), subchannel_(subchannel), @@ -317,7 +317,7 @@ template void SubchannelData::ResetBackoffLocked() { if (subchannel_ != nullptr) { - grpc_subchannel_reset_backoff(subchannel_); + subchannel_->ResetBackoff(); } } @@ -337,8 +337,8 @@ void SubchannelDataRef(DEBUG_LOCATION, "connectivity_watch").release(); - grpc_subchannel_notify_on_state_change( - subchannel_, subchannel_list_->policy()->interested_parties(), + subchannel_->NotifyOnStateChange( + subchannel_list_->policy()->interested_parties(), &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, subchannel_list_->inhibit_health_checking()); } @@ -357,8 +357,8 @@ void SubchannelDatapolicy()->interested_parties(), + subchannel_->NotifyOnStateChange( + subchannel_list_->policy()->interested_parties(), &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, subchannel_list_->inhibit_health_checking()); } @@ -391,9 +391,9 @@ void SubchannelData:: subchannel_, reason); } GPR_ASSERT(connectivity_notification_pending_); - grpc_subchannel_notify_on_state_change( - subchannel_, nullptr, nullptr, &connectivity_changed_closure_, - subchannel_list_->inhibit_health_checking()); + subchannel_->NotifyOnStateChange(nullptr, nullptr, + &connectivity_changed_closure_, + subchannel_list_->inhibit_health_checking()); } template @@ -401,8 +401,7 @@ bool SubchannelData::UpdateConnectedSubchannelLocked() { // If the subchannel is READY, take a ref to the connected subchannel. if (pending_connectivity_state_unsafe_ == GRPC_CHANNEL_READY) { - connected_subchannel_ = - grpc_subchannel_get_connected_subchannel(subchannel_); + connected_subchannel_ = subchannel_->connected_subchannel(); // If the subchannel became disconnected between the time that READY // was reported and the time we got here (e.g., between when a // notification callback is scheduled and when it was actually run in @@ -518,7 +517,7 @@ SubchannelList::SubchannelList( SubchannelPoolInterface::CreateChannelArg(policy_->subchannel_pool())); const size_t subchannel_address_arg_index = args_to_add.size(); args_to_add.emplace_back( - grpc_create_subchannel_address_arg(&addresses[i].address())); + Subchannel::CreateSubchannelAddressArg(&addresses[i].address())); if (addresses[i].args() != nullptr) { for (size_t j = 0; j < addresses[i].args()->num_args; ++j) { args_to_add.emplace_back(addresses[i].args()->args[j]); @@ -528,7 +527,7 @@ SubchannelList::SubchannelList( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); gpr_free(args_to_add[subchannel_address_arg_index].value.string); - grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel( + Subchannel* subchannel = grpc_client_channel_factory_create_subchannel( client_channel_factory, new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) { diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.cc b/src/core/ext/filters/client_channel/local_subchannel_pool.cc index 145fa4e0374..d1c1cacb441 100644 --- a/src/core/ext/filters/client_channel/local_subchannel_pool.cc +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.cc @@ -32,11 +32,11 @@ LocalSubchannelPool::~LocalSubchannelPool() { grpc_avl_unref(subchannel_map_, nullptr); } -grpc_subchannel* LocalSubchannelPool::RegisterSubchannel( - SubchannelKey* key, grpc_subchannel* constructed) { +Subchannel* LocalSubchannelPool::RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) { // Check to see if a subchannel already exists. - grpc_subchannel* c = static_cast( - grpc_avl_get(subchannel_map_, key, nullptr)); + Subchannel* c = + static_cast(grpc_avl_get(subchannel_map_, key, nullptr)); if (c != nullptr) { // The subchannel already exists. Reuse it. c = GRPC_SUBCHANNEL_REF(c, "subchannel_register+reuse"); @@ -54,9 +54,9 @@ void LocalSubchannelPool::UnregisterSubchannel(SubchannelKey* key) { subchannel_map_ = grpc_avl_remove(subchannel_map_, key, nullptr); } -grpc_subchannel* LocalSubchannelPool::FindSubchannel(SubchannelKey* key) { - grpc_subchannel* c = static_cast( - grpc_avl_get(subchannel_map_, key, nullptr)); +Subchannel* LocalSubchannelPool::FindSubchannel(SubchannelKey* key) { + Subchannel* c = + static_cast(grpc_avl_get(subchannel_map_, key, nullptr)); return c == nullptr ? c : GRPC_SUBCHANNEL_REF(c, "found_from_pool"); } diff --git a/src/core/ext/filters/client_channel/local_subchannel_pool.h b/src/core/ext/filters/client_channel/local_subchannel_pool.h index 9929cdb3627..a6b7e259fbb 100644 --- a/src/core/ext/filters/client_channel/local_subchannel_pool.h +++ b/src/core/ext/filters/client_channel/local_subchannel_pool.h @@ -39,10 +39,10 @@ class LocalSubchannelPool final : public SubchannelPoolInterface { // Implements interface methods. // Thread-unsafe. Intended to be invoked within the client_channel combiner. - grpc_subchannel* RegisterSubchannel(SubchannelKey* key, - grpc_subchannel* constructed) override; + Subchannel* RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) override; void UnregisterSubchannel(SubchannelKey* key) override; - grpc_subchannel* FindSubchannel(SubchannelKey* key) override; + Subchannel* FindSubchannel(SubchannelKey* key) override; private: // The vtable for subchannel operations in an AVL tree. diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index d77bb3c286b..70285659aad 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -44,7 +44,6 @@ #include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr_utils.h" -#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/channel.h" @@ -55,153 +54,256 @@ #include "src/core/lib/transport/status_metadata.h" #include "src/core/lib/uri/uri_parser.h" +// Strong and weak refs. #define INTERNAL_REF_BITS 16 #define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1)) +// Backoff parameters. #define GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS 1 #define GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER 1.6 #define GRPC_SUBCHANNEL_RECONNECT_MIN_TIMEOUT_SECONDS 20 #define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120 #define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2 -typedef struct external_state_watcher { - grpc_subchannel* subchannel; - grpc_pollset_set* pollset_set; - grpc_closure* notify; - grpc_closure closure; - struct external_state_watcher* next; - struct external_state_watcher* prev; -} external_state_watcher; +// Conversion between subchannel call and call stack. +#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ + (grpc_call_stack*)((char*)(call) + \ + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall))) +#define CALL_STACK_TO_SUBCHANNEL_CALL(callstack) \ + (SubchannelCall*)(((char*)(call_stack)) - \ + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall))) namespace grpc_core { -class ConnectedSubchannelStateWatcher; +// +// ConnectedSubchannel +// -} // namespace grpc_core +ConnectedSubchannel::ConnectedSubchannel( + grpc_channel_stack* channel_stack, const grpc_channel_args* args, + RefCountedPtr channelz_subchannel, + intptr_t socket_uuid) + : RefCounted(&grpc_trace_stream_refcount), + channel_stack_(channel_stack), + args_(grpc_channel_args_copy(args)), + channelz_subchannel_(std::move(channelz_subchannel)), + socket_uuid_(socket_uuid) {} -struct grpc_subchannel { - /** The subchannel pool this subchannel is in */ - grpc_core::RefCountedPtr subchannel_pool; - - grpc_connector* connector; - - /** refcount - - lower INTERNAL_REF_BITS bits are for internal references: - these do not keep the subchannel open. - - upper remaining bits are for public references: these do - keep the subchannel open */ - gpr_atm ref_pair; - - /** channel arguments */ - grpc_channel_args* args; - - grpc_core::SubchannelKey* key; - - /** set during connection */ - grpc_connect_out_args connecting_result; - - /** callback for connection finishing */ - grpc_closure on_connected; - - /** callback for our alarm */ - grpc_closure on_alarm; - - /** pollset_set tracking who's interested in a connection - being setup */ - grpc_pollset_set* pollset_set; - - grpc_core::UniquePtr health_check_service_name; - - /** mutex protecting remaining elements */ - gpr_mu mu; - - /** active connection, or null */ - grpc_core::RefCountedPtr connected_subchannel; - grpc_core::OrphanablePtr - connected_subchannel_watcher; - - /** have we seen a disconnection? */ - bool disconnected; - /** are we connecting */ - bool connecting; - - /** connectivity state tracking */ - grpc_connectivity_state_tracker state_tracker; - grpc_connectivity_state_tracker state_and_health_tracker; - - external_state_watcher root_external_state_watcher; - - /** backoff state */ - grpc_core::ManualConstructor backoff; - grpc_millis next_attempt_deadline; - grpc_millis min_connect_timeout_ms; - - /** do we have an active alarm? */ - bool have_alarm; - /** have we started the backoff loop */ - bool backoff_begun; - // reset_backoff() was called while alarm was pending - bool retry_immediately; - /** our alarm */ - grpc_timer alarm; - - grpc_core::RefCountedPtr - channelz_subchannel; -}; - -struct grpc_subchannel_call { - grpc_subchannel_call(grpc_core::ConnectedSubchannel* connection, - const grpc_core::ConnectedSubchannel::CallArgs& args) - : connection(connection), deadline(args.deadline) {} - - grpc_core::ConnectedSubchannel* connection; - grpc_closure* schedule_closure_after_destroy = nullptr; - // state needed to support channelz interception of recv trailing metadata. - grpc_closure recv_trailing_metadata_ready; - grpc_closure* original_recv_trailing_metadata; - grpc_metadata_batch* recv_trailing_metadata = nullptr; - grpc_millis deadline; -}; - -static void maybe_start_connecting_locked(grpc_subchannel* c); - -static const char* subchannel_connectivity_state_change_string( - grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "Subchannel state change to IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "Subchannel state change to CONNECTING"; - case GRPC_CHANNEL_READY: - return "Subchannel state change to READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "Subchannel state change to TRANSIENT_FAILURE"; - case GRPC_CHANNEL_SHUTDOWN: - return "Subchannel state change to SHUTDOWN"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); +ConnectedSubchannel::~ConnectedSubchannel() { + grpc_channel_args_destroy(args_); + GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); } -static void set_subchannel_connectivity_state_locked( - grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error, - const char* reason) { - if (c->channelz_subchannel != nullptr) { - c->channelz_subchannel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - subchannel_connectivity_state_change_string(state))); - } - grpc_connectivity_state_set(&c->state_tracker, state, error, reason); +void ConnectedSubchannel::NotifyOnStateChange( + grpc_pollset_set* interested_parties, grpc_connectivity_state* state, + grpc_closure* closure) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + grpc_channel_element* elem; + op->connectivity_state = state; + op->on_connectivity_state_change = closure; + op->bind_pollset_set = interested_parties; + elem = grpc_channel_stack_element(channel_stack_, 0); + elem->filter->start_transport_op(elem, op); } -namespace grpc_core { +void ConnectedSubchannel::Ping(grpc_closure* on_initiate, + grpc_closure* on_ack) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + grpc_channel_element* elem; + op->send_ping.on_initiate = on_initiate; + op->send_ping.on_ack = on_ack; + elem = grpc_channel_stack_element(channel_stack_, 0); + elem->filter->start_transport_op(elem, op); +} -class ConnectedSubchannelStateWatcher +namespace { + +void SubchannelCallDestroy(void* arg, grpc_error* error) { + GPR_TIMER_SCOPE("subchannel_call_destroy", 0); + SubchannelCall* call = static_cast(arg); + grpc_closure* after_call_stack_destroy = call->after_call_stack_destroy(); + call->~SubchannelCall(); + // This should be the last step to destroy the subchannel call, because + // call->after_call_stack_destroy(), if not null, will free the call arena. + grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(call), nullptr, + after_call_stack_destroy); +} + +} // namespace + +RefCountedPtr ConnectedSubchannel::CreateCall( + const CallArgs& args, grpc_error** error) { + const size_t allocation_size = + GetInitialCallSizeEstimate(args.parent_data_size); + RefCountedPtr call( + new (gpr_arena_alloc(args.arena, allocation_size)) + SubchannelCall(Ref(DEBUG_LOCATION, "subchannel_call"), args)); + grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call.get()); + const grpc_call_element_args call_args = { + callstk, /* call_stack */ + nullptr, /* server_transport_data */ + args.context, /* context */ + args.path, /* path */ + args.start_time, /* start_time */ + args.deadline, /* deadline */ + args.arena, /* arena */ + args.call_combiner /* call_combiner */ + }; + *error = grpc_call_stack_init(channel_stack_, 1, SubchannelCallDestroy, + call.get(), &call_args); + if (GPR_UNLIKELY(*error != GRPC_ERROR_NONE)) { + const char* error_string = grpc_error_string(*error); + gpr_log(GPR_ERROR, "error: %s", error_string); + return call; + } + grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); + if (channelz_subchannel_ != nullptr) { + channelz_subchannel_->RecordCallStarted(); + } + return call; +} + +size_t ConnectedSubchannel::GetInitialCallSizeEstimate( + size_t parent_data_size) const { + size_t allocation_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)); + if (parent_data_size > 0) { + allocation_size += + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + + parent_data_size; + } else { + allocation_size += channel_stack_->call_stack_size; + } + return allocation_size; +} + +// +// SubchannelCall +// + +void SubchannelCall::StartTransportStreamOpBatch( + grpc_transport_stream_op_batch* batch) { + GPR_TIMER_SCOPE("subchannel_call_process_op", 0); + MaybeInterceptRecvTrailingMetadata(batch); + grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(this); + grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0); + GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch); + top_elem->filter->start_transport_stream_op_batch(top_elem, batch); +} + +void* SubchannelCall::GetParentData() { + grpc_channel_stack* chanstk = connected_subchannel_->channel_stack(); + return (char*)this + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)) + + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(chanstk->call_stack_size); +} + +grpc_call_stack* SubchannelCall::GetCallStack() { + return SUBCHANNEL_CALL_TO_CALL_STACK(this); +} + +void SubchannelCall::SetAfterCallStackDestroy(grpc_closure* closure) { + GPR_ASSERT(after_call_stack_destroy_ == nullptr); + GPR_ASSERT(closure != nullptr); + after_call_stack_destroy_ = closure; +} + +RefCountedPtr SubchannelCall::Ref() { + IncrementRefCount(); + return RefCountedPtr(this); +} + +RefCountedPtr SubchannelCall::Ref( + const grpc_core::DebugLocation& location, const char* reason) { + IncrementRefCount(location, reason); + return RefCountedPtr(this); +} + +void SubchannelCall::Unref() { + GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), ""); +} + +void SubchannelCall::Unref(const DebugLocation& location, const char* reason) { + GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason); +} + +void SubchannelCall::MaybeInterceptRecvTrailingMetadata( + grpc_transport_stream_op_batch* batch) { + // only intercept payloads with recv trailing. + if (!batch->recv_trailing_metadata) { + return; + } + // only add interceptor is channelz is enabled. + if (connected_subchannel_->channelz_subchannel() == nullptr) { + return; + } + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, RecvTrailingMetadataReady, + this, grpc_schedule_on_exec_ctx); + // save some state needed for the interception callback. + GPR_ASSERT(recv_trailing_metadata_ == nullptr); + recv_trailing_metadata_ = + batch->payload->recv_trailing_metadata.recv_trailing_metadata; + original_recv_trailing_metadata_ = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &recv_trailing_metadata_ready_; +} + +namespace { + +// Sets *status based on the rest of the parameters. +void GetCallStatus(grpc_status_code* status, grpc_millis deadline, + grpc_metadata_batch* md_batch, grpc_error* error) { + if (error != GRPC_ERROR_NONE) { + grpc_error_get_status(error, deadline, status, nullptr, nullptr, nullptr); + } else { + if (md_batch->idx.named.grpc_status != nullptr) { + *status = grpc_get_status_code_from_metadata( + md_batch->idx.named.grpc_status->md); + } else { + *status = GRPC_STATUS_UNKNOWN; + } + } + GRPC_ERROR_UNREF(error); +} + +} // namespace + +void SubchannelCall::RecvTrailingMetadataReady(void* arg, grpc_error* error) { + SubchannelCall* call = static_cast(arg); + GPR_ASSERT(call->recv_trailing_metadata_ != nullptr); + grpc_status_code status = GRPC_STATUS_OK; + GetCallStatus(&status, call->deadline_, call->recv_trailing_metadata_, + GRPC_ERROR_REF(error)); + channelz::SubchannelNode* channelz_subchannel = + call->connected_subchannel_->channelz_subchannel(); + GPR_ASSERT(channelz_subchannel != nullptr); + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); + } + GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata_, + GRPC_ERROR_REF(error)); +} + +void SubchannelCall::IncrementRefCount() { + GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), ""); +} + +void SubchannelCall::IncrementRefCount(const grpc_core::DebugLocation& location, + const char* reason) { + GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason); +} + +// +// Subchannel::ConnectedSubchannelStateWatcher +// + +class Subchannel::ConnectedSubchannelStateWatcher : public InternallyRefCounted { public: // Must be instantiated while holding c->mu. - explicit ConnectedSubchannelStateWatcher(grpc_subchannel* c) - : subchannel_(c) { + explicit ConnectedSubchannelStateWatcher(Subchannel* c) : subchannel_(c) { // Steal subchannel ref for connecting. GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "state_watcher"); GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "connecting"); @@ -209,15 +311,15 @@ class ConnectedSubchannelStateWatcher // Callback uses initial ref to this. GRPC_CLOSURE_INIT(&on_connectivity_changed_, OnConnectivityChanged, this, grpc_schedule_on_exec_ctx); - c->connected_subchannel->NotifyOnStateChange(c->pollset_set, - &pending_connectivity_state_, - &on_connectivity_changed_); + c->connected_subchannel_->NotifyOnStateChange(c->pollset_set_, + &pending_connectivity_state_, + &on_connectivity_changed_); // Start health check if needed. grpc_connectivity_state health_state = GRPC_CHANNEL_READY; - if (c->health_check_service_name != nullptr) { - health_check_client_ = grpc_core::MakeOrphanable( - c->health_check_service_name.get(), c->connected_subchannel, - c->pollset_set, c->channelz_subchannel); + if (c->health_check_service_name_ != nullptr) { + health_check_client_ = MakeOrphanable( + c->health_check_service_name_.get(), c->connected_subchannel_, + c->pollset_set_, c->channelz_node_); GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this, grpc_schedule_on_exec_ctx); Ref().release(); // Ref for health callback tracked manually. @@ -226,9 +328,9 @@ class ConnectedSubchannelStateWatcher health_state = GRPC_CHANNEL_CONNECTING; } // Report initial state. - set_subchannel_connectivity_state_locked( - c, GRPC_CHANNEL_READY, GRPC_ERROR_NONE, "subchannel_connected"); - grpc_connectivity_state_set(&c->state_and_health_tracker, health_state, + c->SetConnectivityStateLocked(GRPC_CHANNEL_READY, GRPC_ERROR_NONE, + "subchannel_connected"); + grpc_connectivity_state_set(&c->state_and_health_tracker_, health_state, GRPC_ERROR_NONE, "subchannel_connected"); } @@ -242,33 +344,33 @@ class ConnectedSubchannelStateWatcher private: static void OnConnectivityChanged(void* arg, grpc_error* error) { auto* self = static_cast(arg); - grpc_subchannel* c = self->subchannel_; + Subchannel* c = self->subchannel_; { - MutexLock lock(&c->mu); + MutexLock lock(&c->mu_); switch (self->pending_connectivity_state_) { case GRPC_CHANNEL_TRANSIENT_FAILURE: case GRPC_CHANNEL_SHUTDOWN: { - if (!c->disconnected && c->connected_subchannel != nullptr) { + if (!c->disconnected_ && c->connected_subchannel_ != nullptr) { if (grpc_trace_stream_refcount.enabled()) { gpr_log(GPR_INFO, "Connected subchannel %p of subchannel %p has gone into " "%s. Attempting to reconnect.", - c->connected_subchannel.get(), c, + c->connected_subchannel_.get(), c, grpc_connectivity_state_name( self->pending_connectivity_state_)); } - c->connected_subchannel.reset(); - c->connected_subchannel_watcher.reset(); + c->connected_subchannel_.reset(); + c->connected_subchannel_watcher_.reset(); self->last_connectivity_state_ = GRPC_CHANNEL_TRANSIENT_FAILURE; - set_subchannel_connectivity_state_locked( - c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - "reflect_child"); - grpc_connectivity_state_set(&c->state_and_health_tracker, + c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_REF(error), + "reflect_child"); + grpc_connectivity_state_set(&c->state_and_health_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), "reflect_child"); - c->backoff_begun = false; - c->backoff->Reset(); - maybe_start_connecting_locked(c); + c->backoff_begun_ = false; + c->backoff_.Reset(); + c->MaybeStartConnectingLocked(); } else { self->last_connectivity_state_ = GRPC_CHANNEL_SHUTDOWN; } @@ -281,15 +383,14 @@ class ConnectedSubchannelStateWatcher // this watch from. And a connected subchannel should never go // from READY to CONNECTING or IDLE. self->last_connectivity_state_ = self->pending_connectivity_state_; - set_subchannel_connectivity_state_locked( - c, self->pending_connectivity_state_, GRPC_ERROR_REF(error), - "reflect_child"); + c->SetConnectivityStateLocked(self->pending_connectivity_state_, + GRPC_ERROR_REF(error), "reflect_child"); if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) { - grpc_connectivity_state_set(&c->state_and_health_tracker, + grpc_connectivity_state_set(&c->state_and_health_tracker_, self->pending_connectivity_state_, GRPC_ERROR_REF(error), "reflect_child"); } - c->connected_subchannel->NotifyOnStateChange( + c->connected_subchannel_->NotifyOnStateChange( nullptr, &self->pending_connectivity_state_, &self->on_connectivity_changed_); self = nullptr; // So we don't unref below. @@ -303,14 +404,14 @@ class ConnectedSubchannelStateWatcher static void OnHealthChanged(void* arg, grpc_error* error) { auto* self = static_cast(arg); - grpc_subchannel* c = self->subchannel_; - MutexLock lock(&c->mu); + Subchannel* c = self->subchannel_; + MutexLock lock(&c->mu_); if (self->health_state_ == GRPC_CHANNEL_SHUTDOWN) { self->Unref(); return; } if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) { - grpc_connectivity_state_set(&c->state_and_health_tracker, + grpc_connectivity_state_set(&c->state_and_health_tracker_, self->health_state_, GRPC_ERROR_REF(error), "health_changed"); } @@ -318,163 +419,63 @@ class ConnectedSubchannelStateWatcher &self->on_health_changed_); } - grpc_subchannel* subchannel_; + Subchannel* subchannel_; grpc_closure on_connectivity_changed_; grpc_connectivity_state pending_connectivity_state_ = GRPC_CHANNEL_READY; grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_READY; - grpc_core::OrphanablePtr health_check_client_; + OrphanablePtr health_check_client_; grpc_closure on_health_changed_; grpc_connectivity_state health_state_ = GRPC_CHANNEL_CONNECTING; }; -} // namespace grpc_core +// +// Subchannel::ExternalStateWatcher +// -#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ - (grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ - sizeof(grpc_subchannel_call))) -#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \ - (grpc_subchannel_call*)(((char*)(call_stack)) - \ - GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ - sizeof(grpc_subchannel_call))) - -static void on_subchannel_connected(void* subchannel, grpc_error* error); - -#ifndef NDEBUG -#define REF_REASON reason -#define REF_MUTATE_EXTRA_ARGS \ - GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char* purpose -#define REF_MUTATE_PURPOSE(x) , file, line, reason, x -#else -#define REF_REASON "" -#define REF_MUTATE_EXTRA_ARGS -#define REF_MUTATE_PURPOSE(x) -#endif - -/* - * connection implementation - */ - -static void connection_destroy(void* arg, grpc_error* error) { - grpc_channel_stack* stk = static_cast(arg); - grpc_channel_stack_destroy(stk); - gpr_free(stk); -} - -/* - * grpc_subchannel implementation - */ - -static void subchannel_destroy(void* arg, grpc_error* error) { - grpc_subchannel* c = static_cast(arg); - if (c->channelz_subchannel != nullptr) { - c->channelz_subchannel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string("Subchannel destroyed")); - c->channelz_subchannel->MarkSubchannelDestroyed(); - c->channelz_subchannel.reset(); +struct Subchannel::ExternalStateWatcher { + ExternalStateWatcher(Subchannel* subchannel, grpc_pollset_set* pollset_set, + grpc_closure* notify) + : subchannel(subchannel), pollset_set(pollset_set), notify(notify) { + GRPC_SUBCHANNEL_WEAK_REF(subchannel, "external_state_watcher+init"); + GRPC_CLOSURE_INIT(&on_state_changed, OnStateChanged, this, + grpc_schedule_on_exec_ctx); } - c->health_check_service_name.reset(); - grpc_channel_args_destroy(c->args); - grpc_connectivity_state_destroy(&c->state_tracker); - grpc_connectivity_state_destroy(&c->state_and_health_tracker); - grpc_connector_unref(c->connector); - grpc_pollset_set_destroy(c->pollset_set); - grpc_core::Delete(c->key); - gpr_mu_destroy(&c->mu); - gpr_free(c); -} -static gpr_atm ref_mutate(grpc_subchannel* c, gpr_atm delta, - int barrier REF_MUTATE_EXTRA_ARGS) { - gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta) - : gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta); -#ifndef NDEBUG - if (grpc_trace_stream_refcount.enabled()) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", c, - purpose, old_val, old_val + delta, reason); - } -#endif - return old_val; -} - -grpc_subchannel* grpc_subchannel_ref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, (1 << INTERNAL_REF_BITS), - 0 REF_MUTATE_PURPOSE("STRONG_REF")); - GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0); - return c; -} - -grpc_subchannel* grpc_subchannel_weak_ref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, 1, 0 REF_MUTATE_PURPOSE("WEAK_REF")); - GPR_ASSERT(old_refs != 0); - return c; -} - -grpc_subchannel* grpc_subchannel_ref_from_weak_ref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - if (!c) return nullptr; - for (;;) { - gpr_atm old_refs = gpr_atm_acq_load(&c->ref_pair); - if (old_refs >= (1 << INTERNAL_REF_BITS)) { - gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS); - if (gpr_atm_rel_cas(&c->ref_pair, old_refs, new_refs)) { - return c; - } - } else { - return nullptr; + static void OnStateChanged(void* arg, grpc_error* error) { + ExternalStateWatcher* w = static_cast(arg); + grpc_closure* follow_up = w->notify; + if (w->pollset_set != nullptr) { + grpc_pollset_set_del_pollset_set(w->subchannel->pollset_set_, + w->pollset_set); } + gpr_mu_lock(&w->subchannel->mu_); + if (w->subchannel->external_state_watcher_list_ == w) { + w->subchannel->external_state_watcher_list_ = w->next; + } + if (w->next != nullptr) w->next->prev = w->prev; + if (w->prev != nullptr) w->prev->next = w->next; + gpr_mu_unlock(&w->subchannel->mu_); + GRPC_SUBCHANNEL_WEAK_UNREF(w->subchannel, "external_state_watcher+done"); + Delete(w); + GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error)); } -} -static void disconnect(grpc_subchannel* c) { - // The subchannel_pool is only used once here in this subchannel, so the - // access can be outside of the lock. - if (c->subchannel_pool != nullptr) { - c->subchannel_pool->UnregisterSubchannel(c->key); - c->subchannel_pool.reset(); - } - gpr_mu_lock(&c->mu); - GPR_ASSERT(!c->disconnected); - c->disconnected = true; - grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Subchannel disconnected")); - c->connected_subchannel.reset(); - c->connected_subchannel_watcher.reset(); - gpr_mu_unlock(&c->mu); -} + Subchannel* subchannel; + grpc_pollset_set* pollset_set; + grpc_closure* notify; + grpc_closure on_state_changed; + ExternalStateWatcher* next = nullptr; + ExternalStateWatcher* prev = nullptr; +}; -void grpc_subchannel_unref(grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - // add a weak ref and subtract a strong ref (atomically) - old_refs = ref_mutate( - c, static_cast(1) - static_cast(1 << INTERNAL_REF_BITS), - 1 REF_MUTATE_PURPOSE("STRONG_UNREF")); - if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) { - disconnect(c); - } - GRPC_SUBCHANNEL_WEAK_UNREF(c, "strong-unref"); -} +// +// Subchannel +// -void grpc_subchannel_weak_unref( - grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_atm old_refs; - old_refs = ref_mutate(c, -static_cast(1), - 1 REF_MUTATE_PURPOSE("WEAK_UNREF")); - if (old_refs == 1) { - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(subchannel_destroy, c, grpc_schedule_on_exec_ctx), - GRPC_ERROR_NONE); - } -} +namespace { -static void parse_args_for_backoff_values( - const grpc_channel_args* args, grpc_core::BackOff::Options* backoff_options, - grpc_millis* min_connect_timeout_ms) { +BackOff::Options ParseArgsForBackoffValues( + const grpc_channel_args* args, grpc_millis* min_connect_timeout_ms) { grpc_millis initial_backoff_ms = GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000; *min_connect_timeout_ms = @@ -511,7 +512,8 @@ static void parse_args_for_backoff_values( } } } - backoff_options->set_initial_backoff(initial_backoff_ms) + return BackOff::Options() + .set_initial_backoff(initial_backoff_ms) .set_multiplier(fixed_reconnect_backoff ? 1.0 : GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER) @@ -520,9 +522,6 @@ static void parse_args_for_backoff_values( .set_max_backoff(max_backoff_ms); } -namespace grpc_core { -namespace { - struct HealthCheckParams { UniquePtr service_name; @@ -543,31 +542,19 @@ struct HealthCheckParams { }; } // namespace -} // namespace grpc_core -grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, - const grpc_channel_args* args) { - grpc_core::SubchannelKey* key = - grpc_core::New(args); - grpc_core::SubchannelPoolInterface* subchannel_pool = - grpc_core::SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs( - args); - GPR_ASSERT(subchannel_pool != nullptr); - grpc_subchannel* c = subchannel_pool->FindSubchannel(key); - if (c != nullptr) { - grpc_core::Delete(key); - return c; - } +Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, + const grpc_channel_args* args) + : key_(key), + connector_(connector), + backoff_(ParseArgsForBackoffValues(args, &min_connect_timeout_ms_)) { GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED(); - c = static_cast(gpr_zalloc(sizeof(*c))); - c->key = key; - gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS); - c->connector = connector; - grpc_connector_ref(c->connector); - c->pollset_set = grpc_pollset_set_create(); + gpr_atm_no_barrier_store(&ref_pair_, 1 << INTERNAL_REF_BITS); + grpc_connector_ref(connector_); + pollset_set_ = grpc_pollset_set_create(); grpc_resolved_address* addr = static_cast(gpr_malloc(sizeof(*addr))); - grpc_get_subchannel_address_arg(args, addr); + GetAddressFromSubchannelAddressArg(args, addr); grpc_resolved_address* new_address = nullptr; grpc_channel_args* new_args = nullptr; if (grpc_proxy_mappers_map_address(addr, args, &new_address, &new_args)) { @@ -576,291 +563,398 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, addr = new_address; } static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS}; - grpc_arg new_arg = grpc_create_subchannel_address_arg(addr); + grpc_arg new_arg = CreateSubchannelAddressArg(addr); gpr_free(addr); - c->args = grpc_channel_args_copy_and_add_and_remove( + args_ = grpc_channel_args_copy_and_add_and_remove( new_args != nullptr ? new_args : args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1); gpr_free(new_arg.value.string); if (new_args != nullptr) grpc_channel_args_destroy(new_args); - c->root_external_state_watcher.next = c->root_external_state_watcher.prev = - &c->root_external_state_watcher; - GRPC_CLOSURE_INIT(&c->on_connected, on_subchannel_connected, c, + GRPC_CLOSURE_INIT(&on_connecting_finished_, OnConnectingFinished, this, grpc_schedule_on_exec_ctx); - grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE, + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "subchannel"); - grpc_connectivity_state_init(&c->state_and_health_tracker, GRPC_CHANNEL_IDLE, + grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE, "subchannel"); - grpc_core::BackOff::Options backoff_options; - parse_args_for_backoff_values(args, &backoff_options, - &c->min_connect_timeout_ms); - c->backoff.Init(backoff_options); - gpr_mu_init(&c->mu); - + gpr_mu_init(&mu_); // Check whether we should enable health checking. const char* service_config_json = grpc_channel_arg_get_string( - grpc_channel_args_find(c->args, GRPC_ARG_SERVICE_CONFIG)); + grpc_channel_args_find(args_, GRPC_ARG_SERVICE_CONFIG)); if (service_config_json != nullptr) { - grpc_core::UniquePtr service_config = - grpc_core::ServiceConfig::Create(service_config_json); + UniquePtr service_config = + ServiceConfig::Create(service_config_json); if (service_config != nullptr) { - grpc_core::HealthCheckParams params; - service_config->ParseGlobalParams(grpc_core::HealthCheckParams::Parse, - ¶ms); - c->health_check_service_name = std::move(params.service_name); + HealthCheckParams params; + service_config->ParseGlobalParams(HealthCheckParams::Parse, ¶ms); + health_check_service_name_ = std::move(params.service_name); } } - - const grpc_arg* arg = - grpc_channel_args_find(c->args, GRPC_ARG_ENABLE_CHANNELZ); - bool channelz_enabled = + const grpc_arg* arg = grpc_channel_args_find(args_, GRPC_ARG_ENABLE_CHANNELZ); + const bool channelz_enabled = grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT); arg = grpc_channel_args_find( - c->args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); + args_, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); const grpc_integer_options options = { GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX}; size_t channel_tracer_max_memory = (size_t)grpc_channel_arg_get_integer(arg, options); if (channelz_enabled) { - c->channelz_subchannel = - grpc_core::MakeRefCounted( - c, channel_tracer_max_memory); - c->channelz_subchannel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string("Subchannel created")); + channelz_node_ = MakeRefCounted( + this, channel_tracer_max_memory); + channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("subchannel created")); } +} + +Subchannel::~Subchannel() { + if (channelz_node_ != nullptr) { + channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("Subchannel destroyed")); + channelz_node_->MarkSubchannelDestroyed(); + } + grpc_channel_args_destroy(args_); + grpc_connectivity_state_destroy(&state_tracker_); + grpc_connectivity_state_destroy(&state_and_health_tracker_); + grpc_connector_unref(connector_); + grpc_pollset_set_destroy(pollset_set_); + Delete(key_); + gpr_mu_destroy(&mu_); +} + +Subchannel* Subchannel::Create(grpc_connector* connector, + const grpc_channel_args* args) { + SubchannelKey* key = New(args); + SubchannelPoolInterface* subchannel_pool = + SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs(args); + GPR_ASSERT(subchannel_pool != nullptr); + Subchannel* c = subchannel_pool->FindSubchannel(key); + if (c != nullptr) { + Delete(key); + return c; + } + c = New(key, connector, args); // Try to register the subchannel before setting the subchannel pool. // Otherwise, in case of a registration race, unreffing c in - // RegisterSubchannel() will cause c to be tried to be unregistered, while its - // key maps to a different subchannel. - grpc_subchannel* registered = subchannel_pool->RegisterSubchannel(key, c); - if (registered == c) c->subchannel_pool = subchannel_pool->Ref(); + // RegisterSubchannel() will cause c to be tried to be unregistered, while + // its key maps to a different subchannel. + Subchannel* registered = subchannel_pool->RegisterSubchannel(key, c); + if (registered == c) c->subchannel_pool_ = subchannel_pool->Ref(); return registered; } -grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( - grpc_subchannel* subchannel) { - return subchannel->channelz_subchannel.get(); +Subchannel* Subchannel::Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = RefMutate((1 << INTERNAL_REF_BITS), + 0 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("STRONG_REF")); + GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0); + return this; } -intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel) { - if (subchannel->connected_subchannel != nullptr) { - return subchannel->connected_subchannel->socket_uuid(); +void Subchannel::Unref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + // add a weak ref and subtract a strong ref (atomically) + old_refs = RefMutate( + static_cast(1) - static_cast(1 << INTERNAL_REF_BITS), + 1 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("STRONG_UNREF")); + if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) { + Disconnect(); + } + GRPC_SUBCHANNEL_WEAK_UNREF(this, "strong-unref"); +} + +Subchannel* Subchannel::WeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = RefMutate(1, 0 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("WEAK_REF")); + GPR_ASSERT(old_refs != 0); + return this; +} + +namespace { + +void subchannel_destroy(void* arg, grpc_error* error) { + Subchannel* self = static_cast(arg); + Delete(self); +} + +} // namespace + +void Subchannel::WeakUnref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_atm old_refs; + old_refs = RefMutate(-static_cast(1), + 1 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("WEAK_UNREF")); + if (old_refs == 1) { + GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(subchannel_destroy, this, + grpc_schedule_on_exec_ctx), + GRPC_ERROR_NONE); + } +} + +Subchannel* Subchannel::RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + for (;;) { + gpr_atm old_refs = gpr_atm_acq_load(&ref_pair_); + if (old_refs >= (1 << INTERNAL_REF_BITS)) { + gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS); + if (gpr_atm_rel_cas(&ref_pair_, old_refs, new_refs)) { + return this; + } + } else { + return nullptr; + } + } +} + +intptr_t Subchannel::GetChildSocketUuid() { + if (connected_subchannel_ != nullptr) { + return connected_subchannel_->socket_uuid(); } else { return 0; } } -static void continue_connect_locked(grpc_subchannel* c) { - grpc_connect_in_args args; - args.interested_parties = c->pollset_set; - const grpc_millis min_deadline = - c->min_connect_timeout_ms + grpc_core::ExecCtx::Get()->Now(); - c->next_attempt_deadline = c->backoff->NextAttemptTime(); - args.deadline = std::max(c->next_attempt_deadline, min_deadline); - args.channel_args = c->args; - set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_NONE, "connecting"); - grpc_connectivity_state_set(&c->state_and_health_tracker, - GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, - "connecting"); - grpc_connector_connect(c->connector, &args, &c->connecting_result, - &c->on_connected); +const char* Subchannel::GetTargetAddress() { + const grpc_arg* addr_arg = + grpc_channel_args_find(args_, GRPC_ARG_SUBCHANNEL_ADDRESS); + const char* addr_str = grpc_channel_arg_get_string(addr_arg); + GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. + return addr_str; } -grpc_connectivity_state grpc_subchannel_check_connectivity( - grpc_subchannel* c, grpc_error** error, bool inhibit_health_checks) { - gpr_mu_lock(&c->mu); +RefCountedPtr Subchannel::connected_subchannel() { + MutexLock lock(&mu_); + return connected_subchannel_; +} + +channelz::SubchannelNode* Subchannel::channelz_node() { + return channelz_node_.get(); +} + +grpc_connectivity_state Subchannel::CheckConnectivity( + grpc_error** error, bool inhibit_health_checks) { + MutexLock lock(&mu_); grpc_connectivity_state_tracker* tracker = - inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; + inhibit_health_checks ? &state_tracker_ : &state_and_health_tracker_; grpc_connectivity_state state = grpc_connectivity_state_get(tracker, error); - gpr_mu_unlock(&c->mu); return state; } -static void on_external_state_watcher_done(void* arg, grpc_error* error) { - external_state_watcher* w = static_cast(arg); - grpc_closure* follow_up = w->notify; - if (w->pollset_set != nullptr) { - grpc_pollset_set_del_pollset_set(w->subchannel->pollset_set, - w->pollset_set); +void Subchannel::NotifyOnStateChange(grpc_pollset_set* interested_parties, + grpc_connectivity_state* state, + grpc_closure* notify, + bool inhibit_health_checks) { + grpc_connectivity_state_tracker* tracker = + inhibit_health_checks ? &state_tracker_ : &state_and_health_tracker_; + ExternalStateWatcher* w; + if (state == nullptr) { + MutexLock lock(&mu_); + for (w = external_state_watcher_list_; w != nullptr; w = w->next) { + if (w->notify == notify) { + grpc_connectivity_state_notify_on_state_change(tracker, nullptr, + &w->on_state_changed); + } + } + } else { + w = New(this, interested_parties, notify); + if (interested_parties != nullptr) { + grpc_pollset_set_add_pollset_set(pollset_set_, interested_parties); + } + MutexLock lock(&mu_); + if (external_state_watcher_list_ != nullptr) { + w->next = external_state_watcher_list_; + w->next->prev = w; + } + external_state_watcher_list_ = w; + grpc_connectivity_state_notify_on_state_change(tracker, state, + &w->on_state_changed); + MaybeStartConnectingLocked(); } - gpr_mu_lock(&w->subchannel->mu); - w->next->prev = w->prev; - w->prev->next = w->next; - gpr_mu_unlock(&w->subchannel->mu); - GRPC_SUBCHANNEL_WEAK_UNREF(w->subchannel, "external_state_watcher"); - gpr_free(w); - GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error)); } -static void on_alarm(void* arg, grpc_error* error) { - grpc_subchannel* c = static_cast(arg); - gpr_mu_lock(&c->mu); - c->have_alarm = false; - if (c->disconnected) { +void Subchannel::ResetBackoff() { + MutexLock lock(&mu_); + backoff_.Reset(); + if (have_retry_alarm_) { + retry_immediately_ = true; + grpc_timer_cancel(&retry_alarm_); + } else { + backoff_begun_ = false; + MaybeStartConnectingLocked(); + } +} + +grpc_arg Subchannel::CreateSubchannelAddressArg( + const grpc_resolved_address* addr) { + return grpc_channel_arg_string_create( + (char*)GRPC_ARG_SUBCHANNEL_ADDRESS, + addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("")); +} + +const char* Subchannel::GetUriFromSubchannelAddressArg( + const grpc_channel_args* args) { + const grpc_arg* addr_arg = + grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS); + const char* addr_str = grpc_channel_arg_get_string(addr_arg); + GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. + return addr_str; +} + +namespace { + +void UriToSockaddr(const char* uri_str, grpc_resolved_address* addr) { + grpc_uri* uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */); + GPR_ASSERT(uri != nullptr); + if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr)); + grpc_uri_destroy(uri); +} + +} // namespace + +void Subchannel::GetAddressFromSubchannelAddressArg( + const grpc_channel_args* args, grpc_resolved_address* addr) { + const char* addr_uri_str = GetUriFromSubchannelAddressArg(args); + memset(addr, 0, sizeof(*addr)); + if (*addr_uri_str != '\0') { + UriToSockaddr(addr_uri_str, addr); + } +} + +namespace { + +// Returns a string indicating the subchannel's connectivity state change to +// \a state. +const char* SubchannelConnectivityStateChangeString( + grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "Subchannel state change to IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "Subchannel state change to CONNECTING"; + case GRPC_CHANNEL_READY: + return "Subchannel state change to READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "Subchannel state change to TRANSIENT_FAILURE"; + case GRPC_CHANNEL_SHUTDOWN: + return "Subchannel state change to SHUTDOWN"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +} // namespace + +void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state, + grpc_error* error, + const char* reason) { + if (channelz_node_ != nullptr) { + channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + SubchannelConnectivityStateChangeString(state))); + } + grpc_connectivity_state_set(&state_tracker_, state, error, reason); +} + +void Subchannel::MaybeStartConnectingLocked() { + if (disconnected_) { + // Don't try to connect if we're already disconnected. + return; + } + if (connecting_) { + // Already connecting: don't restart. + return; + } + if (connected_subchannel_ != nullptr) { + // Already connected: don't restart. + return; + } + if (!grpc_connectivity_state_has_watchers(&state_tracker_) && + !grpc_connectivity_state_has_watchers(&state_and_health_tracker_)) { + // Nobody is interested in connecting: so don't just yet. + return; + } + connecting_ = true; + GRPC_SUBCHANNEL_WEAK_REF(this, "connecting"); + if (!backoff_begun_) { + backoff_begun_ = true; + ContinueConnectingLocked(); + } else { + GPR_ASSERT(!have_retry_alarm_); + have_retry_alarm_ = true; + const grpc_millis time_til_next = + next_attempt_deadline_ - ExecCtx::Get()->Now(); + if (time_til_next <= 0) { + gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", this); + } else { + gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRId64 " milliseconds", + this, time_til_next); + } + GRPC_CLOSURE_INIT(&on_retry_alarm_, OnRetryAlarm, this, + grpc_schedule_on_exec_ctx); + grpc_timer_init(&retry_alarm_, next_attempt_deadline_, &on_retry_alarm_); + } +} + +void Subchannel::OnRetryAlarm(void* arg, grpc_error* error) { + Subchannel* c = static_cast(arg); + gpr_mu_lock(&c->mu_); + c->have_retry_alarm_ = false; + if (c->disconnected_) { error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected", &error, 1); - } else if (c->retry_immediately) { - c->retry_immediately = false; + } else if (c->retry_immediately_) { + c->retry_immediately_ = false; error = GRPC_ERROR_NONE; } else { GRPC_ERROR_REF(error); } if (error == GRPC_ERROR_NONE) { gpr_log(GPR_INFO, "Failed to connect to channel, retrying"); - continue_connect_locked(c); - gpr_mu_unlock(&c->mu); + c->ContinueConnectingLocked(); + gpr_mu_unlock(&c->mu_); } else { - gpr_mu_unlock(&c->mu); + gpr_mu_unlock(&c->mu_); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } GRPC_ERROR_UNREF(error); } -static void maybe_start_connecting_locked(grpc_subchannel* c) { - if (c->disconnected) { - /* Don't try to connect if we're already disconnected */ - return; - } - if (c->connecting) { - /* Already connecting: don't restart */ - return; - } - if (c->connected_subchannel != nullptr) { - /* Already connected: don't restart */ - return; - } - if (!grpc_connectivity_state_has_watchers(&c->state_tracker) && - !grpc_connectivity_state_has_watchers(&c->state_and_health_tracker)) { - /* Nobody is interested in connecting: so don't just yet */ - return; - } - c->connecting = true; - GRPC_SUBCHANNEL_WEAK_REF(c, "connecting"); - if (!c->backoff_begun) { - c->backoff_begun = true; - continue_connect_locked(c); - } else { - GPR_ASSERT(!c->have_alarm); - c->have_alarm = true; - const grpc_millis time_til_next = - c->next_attempt_deadline - grpc_core::ExecCtx::Get()->Now(); - if (time_til_next <= 0) { - gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", c); - } else { - gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRId64 " milliseconds", c, - time_til_next); - } - GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx); - grpc_timer_init(&c->alarm, c->next_attempt_deadline, &c->on_alarm); - } +void Subchannel::ContinueConnectingLocked() { + grpc_connect_in_args args; + args.interested_parties = pollset_set_; + const grpc_millis min_deadline = + min_connect_timeout_ms_ + ExecCtx::Get()->Now(); + next_attempt_deadline_ = backoff_.NextAttemptTime(); + args.deadline = std::max(next_attempt_deadline_, min_deadline); + args.channel_args = args_; + SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + "connecting"); + grpc_connectivity_state_set(&state_and_health_tracker_, + GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + "connecting"); + grpc_connector_connect(connector_, &args, &connecting_result_, + &on_connecting_finished_); } -void grpc_subchannel_notify_on_state_change( - grpc_subchannel* c, grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, grpc_closure* notify, - bool inhibit_health_checks) { - grpc_connectivity_state_tracker* tracker = - inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; - external_state_watcher* w; - if (state == nullptr) { - gpr_mu_lock(&c->mu); - for (w = c->root_external_state_watcher.next; - w != &c->root_external_state_watcher; w = w->next) { - if (w->notify == notify) { - grpc_connectivity_state_notify_on_state_change(tracker, nullptr, - &w->closure); - } - } - gpr_mu_unlock(&c->mu); - } else { - w = static_cast(gpr_malloc(sizeof(*w))); - w->subchannel = c; - w->pollset_set = interested_parties; - w->notify = notify; - GRPC_CLOSURE_INIT(&w->closure, on_external_state_watcher_done, w, - grpc_schedule_on_exec_ctx); - if (interested_parties != nullptr) { - grpc_pollset_set_add_pollset_set(c->pollset_set, interested_parties); - } - GRPC_SUBCHANNEL_WEAK_REF(c, "external_state_watcher"); - gpr_mu_lock(&c->mu); - w->next = &c->root_external_state_watcher; - w->prev = w->next->prev; - w->next->prev = w->prev->next = w; - grpc_connectivity_state_notify_on_state_change(tracker, state, &w->closure); - maybe_start_connecting_locked(c); - gpr_mu_unlock(&c->mu); - } -} - -static bool publish_transport_locked(grpc_subchannel* c) { - /* construct channel stack */ - grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); - grpc_channel_stack_builder_set_channel_arguments( - builder, c->connecting_result.channel_args); - grpc_channel_stack_builder_set_transport(builder, - c->connecting_result.transport); - - if (!grpc_channel_init_create_stack(builder, GRPC_CLIENT_SUBCHANNEL)) { - grpc_channel_stack_builder_destroy(builder); - return false; - } - grpc_channel_stack* stk; - grpc_error* error = grpc_channel_stack_builder_finish( - builder, 0, 1, connection_destroy, nullptr, - reinterpret_cast(&stk)); - if (error != GRPC_ERROR_NONE) { - grpc_transport_destroy(c->connecting_result.transport); - gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", - grpc_error_string(error)); - GRPC_ERROR_UNREF(error); - return false; - } - intptr_t socket_uuid = c->connecting_result.socket_uuid; - memset(&c->connecting_result, 0, sizeof(c->connecting_result)); - - if (c->disconnected) { - grpc_channel_stack_destroy(stk); - gpr_free(stk); - return false; - } - - /* publish */ - c->connected_subchannel.reset(grpc_core::New( - stk, c->args, c->channelz_subchannel, socket_uuid)); - gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", - c->connected_subchannel.get(), c); - - // Instantiate state watcher. Will clean itself up. - c->connected_subchannel_watcher = - grpc_core::MakeOrphanable(c); - - return true; -} - -static void on_subchannel_connected(void* arg, grpc_error* error) { - grpc_subchannel* c = static_cast(arg); - grpc_channel_args* delete_channel_args = c->connecting_result.channel_args; - - GRPC_SUBCHANNEL_WEAK_REF(c, "on_subchannel_connected"); - gpr_mu_lock(&c->mu); - c->connecting = false; - if (c->connecting_result.transport != nullptr && - publish_transport_locked(c)) { - /* do nothing, transport was published */ - } else if (c->disconnected) { +void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) { + auto* c = static_cast(arg); + grpc_channel_args* delete_channel_args = c->connecting_result_.channel_args; + GRPC_SUBCHANNEL_WEAK_REF(c, "on_connecting_finished"); + gpr_mu_lock(&c->mu_); + c->connecting_ = false; + if (c->connecting_result_.transport != nullptr && + c->PublishTransportLocked()) { + // Do nothing, transport was published. + } else if (c->disconnected_) { GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } else { - set_subchannel_connectivity_state_locked( - c, GRPC_CHANNEL_TRANSIENT_FAILURE, + c->SetConnectivityStateLocked( + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Connect Failed", &error, 1), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), "connect_failed"); grpc_connectivity_state_set( - &c->state_and_health_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE, + &c->state_and_health_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Connect Failed", &error, 1), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), @@ -869,276 +963,92 @@ static void on_subchannel_connected(void* arg, grpc_error* error) { const char* errmsg = grpc_error_string(error); gpr_log(GPR_INFO, "Connect failed: %s", errmsg); - maybe_start_connecting_locked(c); + c->MaybeStartConnectingLocked(); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } - gpr_mu_unlock(&c->mu); - GRPC_SUBCHANNEL_WEAK_UNREF(c, "connected"); + gpr_mu_unlock(&c->mu_); + GRPC_SUBCHANNEL_WEAK_UNREF(c, "on_connecting_finished"); grpc_channel_args_destroy(delete_channel_args); } -void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel) { - gpr_mu_lock(&subchannel->mu); - subchannel->backoff->Reset(); - if (subchannel->have_alarm) { - subchannel->retry_immediately = true; - grpc_timer_cancel(&subchannel->alarm); - } else { - subchannel->backoff_begun = false; - maybe_start_connecting_locked(subchannel); +namespace { + +void ConnectionDestroy(void* arg, grpc_error* error) { + grpc_channel_stack* stk = static_cast(arg); + grpc_channel_stack_destroy(stk); + gpr_free(stk); +} + +} // namespace + +bool Subchannel::PublishTransportLocked() { + // Construct channel stack. + grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); + grpc_channel_stack_builder_set_channel_arguments( + builder, connecting_result_.channel_args); + grpc_channel_stack_builder_set_transport(builder, + connecting_result_.transport); + if (!grpc_channel_init_create_stack(builder, GRPC_CLIENT_SUBCHANNEL)) { + grpc_channel_stack_builder_destroy(builder); + return false; } - gpr_mu_unlock(&subchannel->mu); -} - -/* - * grpc_subchannel_call implementation - */ - -static void subchannel_call_destroy(void* call, grpc_error* error) { - GPR_TIMER_SCOPE("grpc_subchannel_call_unref.destroy", 0); - grpc_subchannel_call* c = static_cast(call); - grpc_core::ConnectedSubchannel* connection = c->connection; - grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c), nullptr, - c->schedule_closure_after_destroy); - connection->Unref(DEBUG_LOCATION, "subchannel_call"); - c->~grpc_subchannel_call(); -} - -void grpc_subchannel_call_set_cleanup_closure(grpc_subchannel_call* call, - grpc_closure* closure) { - GPR_ASSERT(call->schedule_closure_after_destroy == nullptr); - GPR_ASSERT(closure != nullptr); - call->schedule_closure_after_destroy = closure; -} - -grpc_subchannel_call* grpc_subchannel_call_ref( - grpc_subchannel_call* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); - return c; -} - -void grpc_subchannel_call_unref( - grpc_subchannel_call* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON); -} - -// Sets *status based on md_batch and error. -static void get_call_status(grpc_subchannel_call* call, - grpc_metadata_batch* md_batch, grpc_error* error, - grpc_status_code* status) { + grpc_channel_stack* stk; + grpc_error* error = grpc_channel_stack_builder_finish( + builder, 0, 1, ConnectionDestroy, nullptr, + reinterpret_cast(&stk)); if (error != GRPC_ERROR_NONE) { - grpc_error_get_status(error, call->deadline, status, nullptr, nullptr, - nullptr); - } else { - if (md_batch->idx.named.grpc_status != nullptr) { - *status = grpc_get_status_code_from_metadata( - md_batch->idx.named.grpc_status->md); - } else { - *status = GRPC_STATUS_UNKNOWN; - } + grpc_transport_destroy(connecting_result_.transport); + gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", + grpc_error_string(error)); + GRPC_ERROR_UNREF(error); + return false; } - GRPC_ERROR_UNREF(error); -} - -static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { - grpc_subchannel_call* call = static_cast(arg); - GPR_ASSERT(call->recv_trailing_metadata != nullptr); - grpc_status_code status = GRPC_STATUS_OK; - grpc_metadata_batch* md_batch = call->recv_trailing_metadata; - get_call_status(call, md_batch, GRPC_ERROR_REF(error), &status); - grpc_core::channelz::SubchannelNode* channelz_subchannel = - call->connection->channelz_subchannel(); - GPR_ASSERT(channelz_subchannel != nullptr); - if (status == GRPC_STATUS_OK) { - channelz_subchannel->RecordCallSucceeded(); - } else { - channelz_subchannel->RecordCallFailed(); + intptr_t socket_uuid = connecting_result_.socket_uuid; + memset(&connecting_result_, 0, sizeof(connecting_result_)); + if (disconnected_) { + grpc_channel_stack_destroy(stk); + gpr_free(stk); + return false; } - GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata, - GRPC_ERROR_REF(error)); + // Publish. + connected_subchannel_.reset( + New(stk, args_, channelz_node_, socket_uuid)); + gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", + connected_subchannel_.get(), this); + // Instantiate state watcher. Will clean itself up. + connected_subchannel_watcher_ = + MakeOrphanable(this); + return true; } -// If channelz is enabled, intercept recv_trailing so that we may check the -// status and associate it to a subchannel. -static void maybe_intercept_recv_trailing_metadata( - grpc_subchannel_call* call, grpc_transport_stream_op_batch* batch) { - // only intercept payloads with recv trailing. - if (!batch->recv_trailing_metadata) { - return; +void Subchannel::Disconnect() { + // The subchannel_pool is only used once here in this subchannel, so the + // access can be outside of the lock. + if (subchannel_pool_ != nullptr) { + subchannel_pool_->UnregisterSubchannel(key_); + subchannel_pool_.reset(); } - // only add interceptor is channelz is enabled. - if (call->connection->channelz_subchannel() == nullptr) { - return; + MutexLock lock(&mu_); + GPR_ASSERT(!disconnected_); + disconnected_ = true; + grpc_connector_shutdown(connector_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Subchannel disconnected")); + connected_subchannel_.reset(); + connected_subchannel_watcher_.reset(); +} + +gpr_atm Subchannel::RefMutate( + gpr_atm delta, int barrier GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS) { + gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&ref_pair_, delta) + : gpr_atm_no_barrier_fetch_add(&ref_pair_, delta); +#ifndef NDEBUG + if (grpc_trace_stream_refcount.enabled()) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", this, + purpose, old_val, old_val + delta, reason); } - GRPC_CLOSURE_INIT(&call->recv_trailing_metadata_ready, - recv_trailing_metadata_ready, call, - grpc_schedule_on_exec_ctx); - // save some state needed for the interception callback. - GPR_ASSERT(call->recv_trailing_metadata == nullptr); - call->recv_trailing_metadata = - batch->payload->recv_trailing_metadata.recv_trailing_metadata; - call->original_recv_trailing_metadata = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &call->recv_trailing_metadata_ready; -} - -void grpc_subchannel_call_process_op(grpc_subchannel_call* call, - grpc_transport_stream_op_batch* batch) { - GPR_TIMER_SCOPE("grpc_subchannel_call_process_op", 0); - maybe_intercept_recv_trailing_metadata(call, batch); - grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call); - grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0); - GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch); - top_elem->filter->start_transport_stream_op_batch(top_elem, batch); -} - -grpc_core::RefCountedPtr -grpc_subchannel_get_connected_subchannel(grpc_subchannel* c) { - gpr_mu_lock(&c->mu); - auto copy = c->connected_subchannel; - gpr_mu_unlock(&c->mu); - return copy; -} - -void* grpc_connected_subchannel_call_get_parent_data( - grpc_subchannel_call* subchannel_call) { - grpc_channel_stack* chanstk = subchannel_call->connection->channel_stack(); - return (char*)subchannel_call + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(chanstk->call_stack_size); -} - -grpc_call_stack* grpc_subchannel_call_get_call_stack( - grpc_subchannel_call* subchannel_call) { - return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call); -} - -static void grpc_uri_to_sockaddr(const char* uri_str, - grpc_resolved_address* addr) { - grpc_uri* uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */); - GPR_ASSERT(uri != nullptr); - if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr)); - grpc_uri_destroy(uri); -} - -void grpc_get_subchannel_address_arg(const grpc_channel_args* args, - grpc_resolved_address* addr) { - const char* addr_uri_str = grpc_get_subchannel_address_uri_arg(args); - memset(addr, 0, sizeof(*addr)); - if (*addr_uri_str != '\0') { - grpc_uri_to_sockaddr(addr_uri_str, addr); - } -} - -const char* grpc_subchannel_get_target(grpc_subchannel* subchannel) { - const grpc_arg* addr_arg = - grpc_channel_args_find(subchannel->args, GRPC_ARG_SUBCHANNEL_ADDRESS); - const char* addr_str = grpc_channel_arg_get_string(addr_arg); - GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. - return addr_str; -} - -const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args) { - const grpc_arg* addr_arg = - grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS); - const char* addr_str = grpc_channel_arg_get_string(addr_arg); - GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. - return addr_str; -} - -grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) { - return grpc_channel_arg_string_create( - (char*)GRPC_ARG_SUBCHANNEL_ADDRESS, - addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("")); -} - -namespace grpc_core { - -ConnectedSubchannel::ConnectedSubchannel( - grpc_channel_stack* channel_stack, const grpc_channel_args* args, - grpc_core::RefCountedPtr - channelz_subchannel, - intptr_t socket_uuid) - : RefCounted(&grpc_trace_stream_refcount), - channel_stack_(channel_stack), - args_(grpc_channel_args_copy(args)), - channelz_subchannel_(std::move(channelz_subchannel)), - socket_uuid_(socket_uuid) {} - -ConnectedSubchannel::~ConnectedSubchannel() { - grpc_channel_args_destroy(args_); - GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); -} - -void ConnectedSubchannel::NotifyOnStateChange( - grpc_pollset_set* interested_parties, grpc_connectivity_state* state, - grpc_closure* closure) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - grpc_channel_element* elem; - op->connectivity_state = state; - op->on_connectivity_state_change = closure; - op->bind_pollset_set = interested_parties; - elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} - -void ConnectedSubchannel::Ping(grpc_closure* on_initiate, - grpc_closure* on_ack) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - grpc_channel_element* elem; - op->send_ping.on_initiate = on_initiate; - op->send_ping.on_ack = on_ack; - elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} - -grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, - grpc_subchannel_call** call) { - const size_t allocation_size = - GetInitialCallSizeEstimate(args.parent_data_size); - *call = new (gpr_arena_alloc(args.arena, allocation_size)) - grpc_subchannel_call(this, args); - grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); - RefCountedPtr connection = - Ref(DEBUG_LOCATION, "subchannel_call"); - connection.release(); // Ref is passed to the grpc_subchannel_call object. - const grpc_call_element_args call_args = { - callstk, /* call_stack */ - nullptr, /* server_transport_data */ - args.context, /* context */ - args.path, /* path */ - args.start_time, /* start_time */ - args.deadline, /* deadline */ - args.arena, /* arena */ - args.call_combiner /* call_combiner */ - }; - grpc_error* error = grpc_call_stack_init( - channel_stack_, 1, subchannel_call_destroy, *call, &call_args); - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - const char* error_string = grpc_error_string(error); - gpr_log(GPR_ERROR, "error: %s", error_string); - return error; - } - grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); - if (channelz_subchannel_ != nullptr) { - channelz_subchannel_->RecordCallStarted(); - } - return GRPC_ERROR_NONE; -} - -size_t ConnectedSubchannel::GetInitialCallSizeEstimate( - size_t parent_data_size) const { - size_t allocation_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); - if (parent_data_size > 0) { - allocation_size += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + - parent_data_size; - } else { - allocation_size += channel_stack_->call_stack_size; - } - return allocation_size; +#endif + return old_val; } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index fac515eee5c..88282c9d95e 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -24,53 +24,49 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/connector.h" #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" +#include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/gpr/arena.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/metadata.h" // Channel arg containing a grpc_resolved_address to connect to. #define GRPC_ARG_SUBCHANNEL_ADDRESS "grpc.subchannel_address" -/** A (sub-)channel that knows how to connect to exactly one target - address. Provides a target for load balancing. */ -typedef struct grpc_subchannel grpc_subchannel; -typedef struct grpc_subchannel_call grpc_subchannel_call; - +// For debugging refcounting. #ifndef NDEBUG -#define GRPC_SUBCHANNEL_REF(p, r) \ - grpc_subchannel_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_REF(p, r) (p)->Ref(__FILE__, __LINE__, (r)) #define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ - grpc_subchannel_ref_from_weak_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_UNREF(p, r) \ - grpc_subchannel_unref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_WEAK_REF(p, r) \ - grpc_subchannel_weak_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) \ - grpc_subchannel_weak_unref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_REF(p, r) \ - grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) \ - grpc_subchannel_call_unref((p), __FILE__, __LINE__, (r)) + (p)->RefFromWeakRef(__FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_UNREF(p, r) (p)->Unref(__FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_WEAK_REF(p, r) (p)->WeakRef(__FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) (p)->WeakUnref(__FILE__, __LINE__, (r)) #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS \ - , const char *file, int line, const char *reason + const char *file, int line, const char *reason +#define GRPC_SUBCHANNEL_REF_REASON reason +#define GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS \ + , GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char* purpose +#define GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE(x) , file, line, reason, x #else -#define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p)) -#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \ - grpc_subchannel_ref_from_weak_ref((p)) -#define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p)) -#define GRPC_SUBCHANNEL_WEAK_REF(p, r) grpc_subchannel_weak_ref((p)) -#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) grpc_subchannel_weak_unref((p)) -#define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p)) -#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) grpc_subchannel_call_unref((p)) +#define GRPC_SUBCHANNEL_REF(p, r) (p)->Ref() +#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) (p)->RefFromWeakRef() +#define GRPC_SUBCHANNEL_UNREF(p, r) (p)->Unref() +#define GRPC_SUBCHANNEL_WEAK_REF(p, r) (p)->WeakRef() +#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) (p)->WeakUnref() #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS +#define GRPC_SUBCHANNEL_REF_REASON "" +#define GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS +#define GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE(x) #endif namespace grpc_core { +class SubchannelCall; + class ConnectedSubchannel : public RefCounted { public: struct CallArgs { @@ -86,8 +82,7 @@ class ConnectedSubchannel : public RefCounted { ConnectedSubchannel( grpc_channel_stack* channel_stack, const grpc_channel_args* args, - grpc_core::RefCountedPtr - channelz_subchannel, + RefCountedPtr channelz_subchannel, intptr_t socket_uuid); ~ConnectedSubchannel(); @@ -95,7 +90,8 @@ class ConnectedSubchannel : public RefCounted { grpc_connectivity_state* state, grpc_closure* closure); void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); - grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); + RefCountedPtr CreateCall(const CallArgs& args, + grpc_error** error); grpc_channel_stack* channel_stack() const { return channel_stack_; } const grpc_channel_args* args() const { return args_; } @@ -111,91 +107,204 @@ class ConnectedSubchannel : public RefCounted { grpc_channel_args* args_; // ref counted pointer to the channelz node in this connected subchannel's // owning subchannel. - grpc_core::RefCountedPtr - channelz_subchannel_; + RefCountedPtr channelz_subchannel_; // uuid of this subchannel's socket. 0 if this subchannel is not connected. const intptr_t socket_uuid_; }; +// Implements the interface of RefCounted<>. +class SubchannelCall { + public: + SubchannelCall(RefCountedPtr connected_subchannel, + const ConnectedSubchannel::CallArgs& args) + : connected_subchannel_(std::move(connected_subchannel)), + deadline_(args.deadline) {} + + // Continues processing a transport stream op batch. + void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch); + + // Returns a pointer to the parent data associated with the subchannel call. + // The data will be of the size specified in \a parent_data_size field of + // the args passed to \a ConnectedSubchannel::CreateCall(). + void* GetParentData(); + + // Returns the call stack of the subchannel call. + grpc_call_stack* GetCallStack(); + + grpc_closure* after_call_stack_destroy() const { + return after_call_stack_destroy_; + } + + // Sets the 'then_schedule_closure' argument for call stack destruction. + // Must be called once per call. + void SetAfterCallStackDestroy(grpc_closure* closure); + + // Interface of RefCounted<>. + RefCountedPtr Ref() GRPC_MUST_USE_RESULT; + RefCountedPtr Ref(const DebugLocation& location, + const char* reason) GRPC_MUST_USE_RESULT; + // When refcount drops to 0, destroys itself and the associated call stack, + // but does NOT free the memory because it's in the call arena. + void Unref(); + void Unref(const DebugLocation& location, const char* reason); + + private: + // Allow RefCountedPtr<> to access IncrementRefCount(). + template + friend class RefCountedPtr; + + // If channelz is enabled, intercepts recv_trailing so that we may check the + // status and associate it to a subchannel. + void MaybeInterceptRecvTrailingMetadata( + grpc_transport_stream_op_batch* batch); + + static void RecvTrailingMetadataReady(void* arg, grpc_error* error); + + // Interface of RefCounted<>. + void IncrementRefCount(); + void IncrementRefCount(const DebugLocation& location, const char* reason); + + RefCountedPtr connected_subchannel_; + grpc_closure* after_call_stack_destroy_ = nullptr; + // State needed to support channelz interception of recv trailing metadata. + grpc_closure recv_trailing_metadata_ready_; + grpc_closure* original_recv_trailing_metadata_ = nullptr; + grpc_metadata_batch* recv_trailing_metadata_ = nullptr; + grpc_millis deadline_; +}; + +// A subchannel that knows how to connect to exactly one target address. It +// provides a target for load balancing. +class Subchannel { + public: + // The ctor and dtor are not intended to use directly. + Subchannel(SubchannelKey* key, grpc_connector* connector, + const grpc_channel_args* args); + ~Subchannel(); + + // Creates a subchannel given \a connector and \a args. + static Subchannel* Create(grpc_connector* connector, + const grpc_channel_args* args); + + // Strong and weak refcounting. + Subchannel* Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + void Unref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + Subchannel* WeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + void WeakUnref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + Subchannel* RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + + intptr_t GetChildSocketUuid(); + + // Gets the string representing the subchannel address. + // Caller doesn't take ownership. + const char* GetTargetAddress(); + + // Gets the connected subchannel - or nullptr if not connected (which may + // happen before it initially connects or during transient failures). + RefCountedPtr connected_subchannel(); + + channelz::SubchannelNode* channelz_node(); + + // Polls the current connectivity state of the subchannel. + grpc_connectivity_state CheckConnectivity(grpc_error** error, + bool inhibit_health_checking); + + // When the connectivity state of the subchannel changes from \a *state, + // invokes \a notify and updates \a *state with the new state. + void NotifyOnStateChange(grpc_pollset_set* interested_parties, + grpc_connectivity_state* state, grpc_closure* notify, + bool inhibit_health_checks); + + // Resets the connection backoff of the subchannel. + // TODO(roth): Move connection backoff out of subchannels and up into LB + // policy code (probably by adding a SubchannelGroup between + // SubchannelList and SubchannelData), at which point this method can + // go away. + void ResetBackoff(); + + // Returns a new channel arg encoding the subchannel address as a URI + // string. Caller is responsible for freeing the string. + static grpc_arg CreateSubchannelAddressArg(const grpc_resolved_address* addr); + + // Returns the URI string from the subchannel address arg in \a args. + static const char* GetUriFromSubchannelAddressArg( + const grpc_channel_args* args); + + // Sets \a addr from the subchannel address arg in \a args. + static void GetAddressFromSubchannelAddressArg(const grpc_channel_args* args, + grpc_resolved_address* addr); + + private: + struct ExternalStateWatcher; + class ConnectedSubchannelStateWatcher; + + // Sets the subchannel's connectivity state to \a state. + void SetConnectivityStateLocked(grpc_connectivity_state state, + grpc_error* error, const char* reason); + + // Methods for connection. + void MaybeStartConnectingLocked(); + static void OnRetryAlarm(void* arg, grpc_error* error); + void ContinueConnectingLocked(); + static void OnConnectingFinished(void* arg, grpc_error* error); + bool PublishTransportLocked(); + void Disconnect(); + + gpr_atm RefMutate(gpr_atm delta, + int barrier GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS); + + // The subchannel pool this subchannel is in. + RefCountedPtr subchannel_pool_; + // TODO(juanlishen): Consider using args_ as key_ directly. + // Subchannel key that identifies this subchannel in the subchannel pool. + SubchannelKey* key_; + // Channel args. + grpc_channel_args* args_; + // pollset_set tracking who's interested in a connection being setup. + grpc_pollset_set* pollset_set_; + // Protects the other members. + gpr_mu mu_; + // Refcount + // - lower INTERNAL_REF_BITS bits are for internal references: + // these do not keep the subchannel open. + // - upper remaining bits are for public references: these do + // keep the subchannel open + gpr_atm ref_pair_; + + // Connection states. + grpc_connector* connector_ = nullptr; + // Set during connection. + grpc_connect_out_args connecting_result_; + grpc_closure on_connecting_finished_; + // Active connection, or null. + RefCountedPtr connected_subchannel_; + OrphanablePtr connected_subchannel_watcher_; + bool connecting_ = false; + bool disconnected_ = false; + + // Connectivity state tracking. + grpc_connectivity_state_tracker state_tracker_; + grpc_connectivity_state_tracker state_and_health_tracker_; + UniquePtr health_check_service_name_; + ExternalStateWatcher* external_state_watcher_list_ = nullptr; + + // Backoff state. + BackOff backoff_; + grpc_millis next_attempt_deadline_; + grpc_millis min_connect_timeout_ms_; + bool backoff_begun_ = false; + + // Retry alarm. + grpc_timer retry_alarm_; + grpc_closure on_retry_alarm_; + bool have_retry_alarm_ = false; + // reset_backoff() was called while alarm was pending. + bool retry_immediately_ = false; + + // Channelz tracking. + RefCountedPtr channelz_node_; +}; + } // namespace grpc_core -grpc_subchannel* grpc_subchannel_ref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel* grpc_subchannel_ref_from_weak_ref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_unref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel* grpc_subchannel_weak_ref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_weak_unref( - grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -grpc_subchannel_call* grpc_subchannel_call_ref( - grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_call_unref( - grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); - -grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( - grpc_subchannel* subchannel); - -intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel); - -/** Returns a pointer to the parent data associated with \a subchannel_call. - The data will be of the size specified in \a parent_data_size - field of the args passed to \a grpc_connected_subchannel_create_call(). */ -void* grpc_connected_subchannel_call_get_parent_data( - grpc_subchannel_call* subchannel_call); - -/** poll the current connectivity state of a channel */ -grpc_connectivity_state grpc_subchannel_check_connectivity( - grpc_subchannel* channel, grpc_error** error, bool inhibit_health_checking); - -/** Calls notify when the connectivity state of a channel becomes different - from *state. Updates *state with the new state of the channel. */ -void grpc_subchannel_notify_on_state_change( - grpc_subchannel* channel, grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, grpc_closure* notify, - bool inhibit_health_checks); - -/** retrieve the grpc_core::ConnectedSubchannel - or nullptr if not connected - * (which may happen before it initially connects or during transient failures) - * */ -grpc_core::RefCountedPtr -grpc_subchannel_get_connected_subchannel(grpc_subchannel* c); - -// Resets the connection backoff of the subchannel. -// TODO(roth): Move connection backoff out of subchannels and up into LB -// policy code (probably by adding a SubchannelGroup between -// SubchannelList and SubchannelData), at which point this method can -// go away. -void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel); - -/** continue processing a transport op */ -void grpc_subchannel_call_process_op(grpc_subchannel_call* subchannel_call, - grpc_transport_stream_op_batch* op); - -/** Must be called once per call. Sets the 'then_schedule_closure' argument for - call stack destruction. */ -void grpc_subchannel_call_set_cleanup_closure( - grpc_subchannel_call* subchannel_call, grpc_closure* closure); - -grpc_call_stack* grpc_subchannel_call_get_call_stack( - grpc_subchannel_call* subchannel_call); - -/** create a subchannel given a connector */ -grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, - const grpc_channel_args* args); - -/// Sets \a addr from \a args. -void grpc_get_subchannel_address_arg(const grpc_channel_args* args, - grpc_resolved_address* addr); - -const char* grpc_subchannel_get_target(grpc_subchannel* subchannel); - -/// Returns the URI string for the address to connect to. -const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args); - -/// Returns a new channel arg encoding the subchannel address as a string. -/// Caller is responsible for freeing the string. -grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr); - #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_H */ diff --git a/src/core/ext/filters/client_channel/subchannel_pool_interface.h b/src/core/ext/filters/client_channel/subchannel_pool_interface.h index 21597bf4276..eeb56faf0c0 100644 --- a/src/core/ext/filters/client_channel/subchannel_pool_interface.h +++ b/src/core/ext/filters/client_channel/subchannel_pool_interface.h @@ -26,10 +26,10 @@ #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/ref_counted.h" -struct grpc_subchannel; - namespace grpc_core { +class Subchannel; + extern TraceFlag grpc_subchannel_pool_trace; // A key that can uniquely identify a subchannel. @@ -69,15 +69,15 @@ class SubchannelPoolInterface : public RefCounted { // Registers a subchannel against a key. Returns the subchannel registered // with \a key, which may be different from \a constructed because we reuse // (instead of update) any existing subchannel already registered with \a key. - virtual grpc_subchannel* RegisterSubchannel( - SubchannelKey* key, grpc_subchannel* constructed) GRPC_ABSTRACT; + virtual Subchannel* RegisterSubchannel(SubchannelKey* key, + Subchannel* constructed) GRPC_ABSTRACT; // Removes the registered subchannel found by \a key. virtual void UnregisterSubchannel(SubchannelKey* key) GRPC_ABSTRACT; // Finds the subchannel registered for the given subchannel key. Returns NULL // if no such channel exists. Thread-safe. - virtual grpc_subchannel* FindSubchannel(SubchannelKey* key) GRPC_ABSTRACT; + virtual Subchannel* FindSubchannel(SubchannelKey* key) GRPC_ABSTRACT; // Creates a channel arg from \a subchannel pool. static grpc_arg CreateChannelArg(SubchannelPoolInterface* subchannel_pool); diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 42a2e2e896c..1e9a75d0630 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -202,7 +202,8 @@ static void chttp2_connector_connect(grpc_connector* con, grpc_closure* notify) { chttp2_connector* c = reinterpret_cast(con); grpc_resolved_address addr; - grpc_get_subchannel_address_arg(args->channel_args, &addr); + grpc_core::Subchannel::GetAddressFromSubchannelAddressArg(args->channel_args, + &addr); gpr_mu_lock(&c->mu); GPR_ASSERT(c->notify == nullptr); c->notify = notify; diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc index a5bf1bf21d4..8aabcfa2000 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -39,11 +39,11 @@ static void client_channel_factory_ref( static void client_channel_factory_unref( grpc_client_channel_factory* cc_factory) {} -static grpc_subchannel* client_channel_factory_create_subchannel( +static grpc_core::Subchannel* client_channel_factory_create_subchannel( grpc_client_channel_factory* cc_factory, const grpc_channel_args* args) { grpc_channel_args* new_args = grpc_default_authority_add_if_not_present(args); grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_subchannel* s = grpc_subchannel_create(connector, new_args); + grpc_core::Subchannel* s = grpc_core::Subchannel::Create(connector, new_args); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index 5985fa0cbdb..eb2fee2af91 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -76,7 +76,8 @@ static grpc_channel_args* get_secure_naming_channel_args( grpc_core::UniquePtr authority; if (target_authority_table != nullptr) { // Find the authority for the target. - const char* target_uri_str = grpc_get_subchannel_address_uri_arg(args); + const char* target_uri_str = + grpc_core::Subchannel::GetUriFromSubchannelAddressArg(args); grpc_uri* target_uri = grpc_uri_parse(target_uri_str, false /* suppress errors */); GPR_ASSERT(target_uri != nullptr); @@ -138,7 +139,7 @@ static grpc_channel_args* get_secure_naming_channel_args( return new_args; } -static grpc_subchannel* client_channel_factory_create_subchannel( +static grpc_core::Subchannel* client_channel_factory_create_subchannel( grpc_client_channel_factory* cc_factory, const grpc_channel_args* args) { grpc_channel_args* new_args = get_secure_naming_channel_args(args); if (new_args == nullptr) { @@ -147,7 +148,7 @@ static grpc_subchannel* client_channel_factory_create_subchannel( return nullptr; } grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_subchannel* s = grpc_subchannel_create(connector, new_args); + grpc_core::Subchannel* s = grpc_core::Subchannel::Create(connector, new_args); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/test/core/util/debugger_macros.cc b/test/core/util/debugger_macros.cc index 05fb1461733..fed6ad97285 100644 --- a/test/core/util/debugger_macros.cc +++ b/test/core/util/debugger_macros.cc @@ -36,13 +36,14 @@ grpc_stream* grpc_transport_stream_from_call(grpc_call* call) { for (;;) { grpc_call_element* el = grpc_call_stack_element(cs, cs->count - 1); if (el->filter == &grpc_client_channel_filter) { - grpc_subchannel_call* scc = grpc_client_channel_get_subchannel_call(el); + grpc_core::RefCountedPtr scc = + grpc_client_channel_get_subchannel_call(el); if (scc == nullptr) { fprintf(stderr, "No subchannel-call"); fflush(stderr); return nullptr; } - cs = grpc_subchannel_call_get_call_stack(scc); + cs = scc->GetCallStack(); } else if (el->filter == &grpc_connected_filter) { return grpc_connected_channel_get_stream(el); } else { diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 125b1ce5c4e..973f47beaf7 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -325,8 +325,8 @@ class FakeClientChannelFactory : public grpc_client_channel_factory { private: static void NoRef(grpc_client_channel_factory* factory) {} static void NoUnref(grpc_client_channel_factory* factory) {} - static grpc_subchannel* CreateSubchannel(grpc_client_channel_factory* factory, - const grpc_channel_args* args) { + static grpc_core::Subchannel* CreateSubchannel( + grpc_client_channel_factory* factory, const grpc_channel_args* args) { return nullptr; } static grpc_channel* CreateClientChannel(grpc_client_channel_factory* factory, From 452fb4a67b2efd50b1b4b83b7e2d04658b260b03 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 30 Jan 2019 15:10:51 -0800 Subject: [PATCH 222/814] Unify parameter name --- src/core/ext/filters/client_channel/subchannel.cc | 8 ++++---- src/core/ext/filters/client_channel/subchannel.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 70285659aad..1d188a655f8 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -731,10 +731,10 @@ channelz::SubchannelNode* Subchannel::channelz_node() { } grpc_connectivity_state Subchannel::CheckConnectivity( - grpc_error** error, bool inhibit_health_checks) { + grpc_error** error, bool inhibit_health_checking) { MutexLock lock(&mu_); grpc_connectivity_state_tracker* tracker = - inhibit_health_checks ? &state_tracker_ : &state_and_health_tracker_; + inhibit_health_checking ? &state_tracker_ : &state_and_health_tracker_; grpc_connectivity_state state = grpc_connectivity_state_get(tracker, error); return state; } @@ -742,9 +742,9 @@ grpc_connectivity_state Subchannel::CheckConnectivity( void Subchannel::NotifyOnStateChange(grpc_pollset_set* interested_parties, grpc_connectivity_state* state, grpc_closure* notify, - bool inhibit_health_checks) { + bool inhibit_health_checking) { grpc_connectivity_state_tracker* tracker = - inhibit_health_checks ? &state_tracker_ : &state_and_health_tracker_; + inhibit_health_checking ? &state_tracker_ : &state_and_health_tracker_; ExternalStateWatcher* w; if (state == nullptr) { MutexLock lock(&mu_); diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 88282c9d95e..47c21ff8680 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -213,7 +213,7 @@ class Subchannel { // invokes \a notify and updates \a *state with the new state. void NotifyOnStateChange(grpc_pollset_set* interested_parties, grpc_connectivity_state* state, grpc_closure* notify, - bool inhibit_health_checks); + bool inhibit_health_checking); // Resets the connection backoff of the subchannel. // TODO(roth): Move connection backoff out of subchannels and up into LB From 9b6389f05ab28ae416220fe55029f711436d3321 Mon Sep 17 00:00:00 2001 From: John Luo Date: Wed, 30 Jan 2019 13:04:55 -0800 Subject: [PATCH 223/814] Handle null implementations --- src/compiler/csharp_generator.cc | 38 ++++++++++--- src/csharp/Grpc.Core/ServiceBinderBase.cs | 54 ++++++++++++++++++- src/csharp/Grpc.Examples/MathGrpc.cs | 13 ++--- src/csharp/Grpc.HealthCheck/HealthGrpc.cs | 9 ++-- .../BenchmarkServiceGrpc.cs | 15 +++--- .../EmptyServiceGrpc.cs | 5 +- .../Grpc.IntegrationTesting/MetricsGrpc.cs | 9 ++-- .../ReportQpsScenarioServiceGrpc.cs | 7 +-- .../Grpc.IntegrationTesting/TestGrpc.cs | 37 +++++++------ .../WorkerServiceGrpc.cs | 13 ++--- src/csharp/Grpc.Reflection/ReflectionGrpc.cs | 7 +-- 11 files changed, 147 insertions(+), 60 deletions(-) diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index 2a87463d2d0..ac0af336f93 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -199,6 +199,21 @@ std::string GetCSharpMethodType(MethodType method_type) { return ""; } +std::string GetCSharpServerMethodType(MethodType method_type) { + switch (method_type) { + case METHODTYPE_NO_STREAMING: + return "grpc::UnaryServerMethod"; + case METHODTYPE_CLIENT_STREAMING: + return "grpc::ClientStreamingServerMethod"; + case METHODTYPE_SERVER_STREAMING: + return "grpc::ServerStreamingServerMethod"; + case METHODTYPE_BIDI_STREAMING: + return "grpc::DuplexStreamingServerMethod"; + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return ""; +} + std::string GetServiceNameFieldName() { return "__ServiceName"; } std::string GetMarshallerFieldName(const Descriptor* message) { @@ -613,8 +628,8 @@ void GenerateBindServiceWithBinderMethod(Printer* out, const ServiceDescriptor* service) { out->Print( "/// Register service method with a service " - "binder without implementation. Useful when customizing the service " - "binding logic.\n" + "binder with or without implementation. Useful when customizing the " + "service binding logic.\n" "/// Note: this method is part of an experimental API that can change or " "be " "removed without any prior notice.\n"); @@ -623,15 +638,26 @@ void GenerateBindServiceWithBinderMethod(Printer* out, "calling AddMethod on this object." "\n"); out->Print( - "public static void BindService(grpc::ServiceBinderBase " - "serviceBinder)\n"); + "/// An object implementing the server-side" + " handling logic.\n"); + out->Print( + "public static void BindService(grpc::ServiceBinderBase serviceBinder, " + "$implclass$ " + "serviceImpl)\n", + "implclass", GetServerClassName(service)); out->Print("{\n"); out->Indent(); for (int i = 0; i < service->method_count(); i++) { const MethodDescriptor* method = service->method(i); - out->Print("serviceBinder.AddMethod($methodfield$);\n", "methodfield", - GetMethodFieldName(method)); + out->Print( + "serviceBinder.AddMethod($methodfield$, serviceImpl == null ? null : " + "new $servermethodtype$<$inputtype$, $outputtype$>(" + "serviceImpl.$methodname$));\n", + "methodfield", GetMethodFieldName(method), "servermethodtype", + GetCSharpServerMethodType(GetMethodType(method)), "inputtype", + GetClassName(method->input_type()), "outputtype", + GetClassName(method->output_type()), "methodname", method->name()); } out->Outdent(); diff --git a/src/csharp/Grpc.Core/ServiceBinderBase.cs b/src/csharp/Grpc.Core/ServiceBinderBase.cs index 318892cc5fb..d4909f4a269 100644 --- a/src/csharp/Grpc.Core/ServiceBinderBase.cs +++ b/src/csharp/Grpc.Core/ServiceBinderBase.cs @@ -35,13 +35,63 @@ namespace Grpc.Core public class ServiceBinderBase { /// - /// Adds a method without a handler. + /// Adds a definition for a single request - single response method. /// /// The request message class. /// The response message class. /// The method. + /// The method handler. public virtual void AddMethod( - Method method) + Method method, + UnaryServerMethod handler) + where TRequest : class + where TResponse : class + { + throw new NotImplementedException(); + } + + /// + /// Adds a definition for a client streaming method. + /// + /// The request message class. + /// The response message class. + /// The method. + /// The method handler. + public virtual void AddMethod( + Method method, + ClientStreamingServerMethod handler) + where TRequest : class + where TResponse : class + { + throw new NotImplementedException(); + } + + /// + /// Adds a definition for a server streaming method. + /// + /// The request message class. + /// The response message class. + /// The method. + /// The method handler. + public virtual void AddMethod( + Method method, + ServerStreamingServerMethod handler) + where TRequest : class + where TResponse : class + { + throw new NotImplementedException(); + } + + /// + /// Adds a definition for a bidirectional streaming method. + /// + /// The request message class. + /// The response message class. + /// The method. + /// The method handler. + public virtual void AddMethod( + Method method, + DuplexStreamingServerMethod handler) where TRequest : class where TResponse : class { diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs index 85436ddc232..acd70b3714d 100644 --- a/src/csharp/Grpc.Examples/MathGrpc.cs +++ b/src/csharp/Grpc.Examples/MathGrpc.cs @@ -287,15 +287,16 @@ namespace Math { .AddMethod(__Method_Sum, serviceImpl.Sum).Build(); } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. - public static void BindService(grpc::ServiceBinderBase serviceBinder) + /// An object implementing the server-side handling logic. + public static void BindService(grpc::ServiceBinderBase serviceBinder, MathBase serviceImpl) { - serviceBinder.AddMethod(__Method_Div); - serviceBinder.AddMethod(__Method_DivMany); - serviceBinder.AddMethod(__Method_Fib); - serviceBinder.AddMethod(__Method_Sum); + serviceBinder.AddMethod(__Method_Div, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.Div)); + serviceBinder.AddMethod(__Method_DivMany, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.DivMany)); + serviceBinder.AddMethod(__Method_Fib, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.Fib)); + serviceBinder.AddMethod(__Method_Sum, serviceImpl == null ? null : new grpc::ClientStreamingServerMethod(serviceImpl.Sum)); } } diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs index 5492600da9b..e13b1147cf8 100644 --- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs +++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs @@ -233,13 +233,14 @@ namespace Grpc.Health.V1 { .AddMethod(__Method_Watch, serviceImpl.Watch).Build(); } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. - public static void BindService(grpc::ServiceBinderBase serviceBinder) + /// An object implementing the server-side handling logic. + public static void BindService(grpc::ServiceBinderBase serviceBinder, HealthBase serviceImpl) { - serviceBinder.AddMethod(__Method_Check); - serviceBinder.AddMethod(__Method_Watch); + serviceBinder.AddMethod(__Method_Check, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.Check)); + serviceBinder.AddMethod(__Method_Watch, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.Watch)); } } diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs index fcd0e3f89b3..5f18ba7accf 100644 --- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs @@ -324,16 +324,17 @@ namespace Grpc.Testing { .AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays).Build(); } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. - public static void BindService(grpc::ServiceBinderBase serviceBinder) + /// An object implementing the server-side handling logic. + public static void BindService(grpc::ServiceBinderBase serviceBinder, BenchmarkServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_UnaryCall); - serviceBinder.AddMethod(__Method_StreamingCall); - serviceBinder.AddMethod(__Method_StreamingFromClient); - serviceBinder.AddMethod(__Method_StreamingFromServer); - serviceBinder.AddMethod(__Method_StreamingBothWays); + serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.UnaryCall)); + serviceBinder.AddMethod(__Method_StreamingCall, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.StreamingCall)); + serviceBinder.AddMethod(__Method_StreamingFromClient, serviceImpl == null ? null : new grpc::ClientStreamingServerMethod(serviceImpl.StreamingFromClient)); + serviceBinder.AddMethod(__Method_StreamingFromServer, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.StreamingFromServer)); + serviceBinder.AddMethod(__Method_StreamingBothWays, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.StreamingBothWays)); } } diff --git a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs index ba74c3a6016..01af6c24f41 100644 --- a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs @@ -80,10 +80,11 @@ namespace Grpc.Testing { return grpc::ServerServiceDefinition.CreateBuilder().Build(); } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. - public static void BindService(grpc::ServiceBinderBase serviceBinder) + /// An object implementing the server-side handling logic. + public static void BindService(grpc::ServiceBinderBase serviceBinder, EmptyServiceBase serviceImpl) { } diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs index bc6ddf21f70..7b5b1a3aa7f 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs @@ -193,13 +193,14 @@ namespace Grpc.Testing { .AddMethod(__Method_GetGauge, serviceImpl.GetGauge).Build(); } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. - public static void BindService(grpc::ServiceBinderBase serviceBinder) + /// An object implementing the server-side handling logic. + public static void BindService(grpc::ServiceBinderBase serviceBinder, MetricsServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_GetAllGauges); - serviceBinder.AddMethod(__Method_GetGauge); + serviceBinder.AddMethod(__Method_GetAllGauges, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.GetAllGauges)); + serviceBinder.AddMethod(__Method_GetGauge, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.GetGauge)); } } diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs index 096eb7e1d4b..04bb9c29d63 100644 --- a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs @@ -143,12 +143,13 @@ namespace Grpc.Testing { .AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario).Build(); } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. - public static void BindService(grpc::ServiceBinderBase serviceBinder) + /// An object implementing the server-side handling logic. + public static void BindService(grpc::ServiceBinderBase serviceBinder, ReportQpsScenarioServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_ReportScenario); + serviceBinder.AddMethod(__Method_ReportScenario, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.ReportScenario)); } } diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs index c8760583177..05e1e3ccc7d 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs @@ -539,19 +539,20 @@ namespace Grpc.Testing { .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build(); } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. - public static void BindService(grpc::ServiceBinderBase serviceBinder) + /// An object implementing the server-side handling logic. + public static void BindService(grpc::ServiceBinderBase serviceBinder, TestServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_EmptyCall); - serviceBinder.AddMethod(__Method_UnaryCall); - serviceBinder.AddMethod(__Method_CacheableUnaryCall); - serviceBinder.AddMethod(__Method_StreamingOutputCall); - serviceBinder.AddMethod(__Method_StreamingInputCall); - serviceBinder.AddMethod(__Method_FullDuplexCall); - serviceBinder.AddMethod(__Method_HalfDuplexCall); - serviceBinder.AddMethod(__Method_UnimplementedCall); + serviceBinder.AddMethod(__Method_EmptyCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.EmptyCall)); + serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.UnaryCall)); + serviceBinder.AddMethod(__Method_CacheableUnaryCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.CacheableUnaryCall)); + serviceBinder.AddMethod(__Method_StreamingOutputCall, serviceImpl == null ? null : new grpc::ServerStreamingServerMethod(serviceImpl.StreamingOutputCall)); + serviceBinder.AddMethod(__Method_StreamingInputCall, serviceImpl == null ? null : new grpc::ClientStreamingServerMethod(serviceImpl.StreamingInputCall)); + serviceBinder.AddMethod(__Method_FullDuplexCall, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.FullDuplexCall)); + serviceBinder.AddMethod(__Method_HalfDuplexCall, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.HalfDuplexCall)); + serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.UnimplementedCall)); } } @@ -676,12 +677,13 @@ namespace Grpc.Testing { .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build(); } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. - public static void BindService(grpc::ServiceBinderBase serviceBinder) + /// An object implementing the server-side handling logic. + public static void BindService(grpc::ServiceBinderBase serviceBinder, UnimplementedServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_UnimplementedCall); + serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.UnimplementedCall)); } } @@ -802,13 +804,14 @@ namespace Grpc.Testing { .AddMethod(__Method_Stop, serviceImpl.Stop).Build(); } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. - public static void BindService(grpc::ServiceBinderBase serviceBinder) + /// An object implementing the server-side handling logic. + public static void BindService(grpc::ServiceBinderBase serviceBinder, ReconnectServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_Start); - serviceBinder.AddMethod(__Method_Stop); + serviceBinder.AddMethod(__Method_Start, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.Start)); + serviceBinder.AddMethod(__Method_Stop, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.Stop)); } } diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs index 7b2a9e8d481..a36f1d7a356 100644 --- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs @@ -321,15 +321,16 @@ namespace Grpc.Testing { .AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build(); } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. - public static void BindService(grpc::ServiceBinderBase serviceBinder) + /// An object implementing the server-side handling logic. + public static void BindService(grpc::ServiceBinderBase serviceBinder, WorkerServiceBase serviceImpl) { - serviceBinder.AddMethod(__Method_RunServer); - serviceBinder.AddMethod(__Method_RunClient); - serviceBinder.AddMethod(__Method_CoreCount); - serviceBinder.AddMethod(__Method_QuitWorker); + serviceBinder.AddMethod(__Method_RunServer, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.RunServer)); + serviceBinder.AddMethod(__Method_RunClient, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.RunClient)); + serviceBinder.AddMethod(__Method_CoreCount, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.CoreCount)); + serviceBinder.AddMethod(__Method_QuitWorker, serviceImpl == null ? null : new grpc::UnaryServerMethod(serviceImpl.QuitWorker)); } } diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs index 6c391361bc5..0b2bb2341b9 100644 --- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs +++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs @@ -123,12 +123,13 @@ namespace Grpc.Reflection.V1Alpha { .AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo).Build(); } - /// Register service method with a service binder without implementation. Useful when customizing the service binding logic. + /// Register service method with a service binder with or without implementation. Useful when customizing the service binding logic. /// Note: this method is part of an experimental API that can change or be removed without any prior notice. /// Service methods will be bound by calling AddMethod on this object. - public static void BindService(grpc::ServiceBinderBase serviceBinder) + /// An object implementing the server-side handling logic. + public static void BindService(grpc::ServiceBinderBase serviceBinder, ServerReflectionBase serviceImpl) { - serviceBinder.AddMethod(__Method_ServerReflectionInfo); + serviceBinder.AddMethod(__Method_ServerReflectionInfo, serviceImpl == null ? null : new grpc::DuplexStreamingServerMethod(serviceImpl.ServerReflectionInfo)); } } From 9e652ebb2f1b2d8234a42b3add313da6f8748028 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 31 Jan 2019 11:52:18 +0100 Subject: [PATCH 224/814] review comments --- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 2 +- src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index 6ad1ac85ffc..0dc73576bf5 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -4,7 +4,7 @@ - Copyright 2015, Google Inc. + Copyright 2019, Google Inc. gRPC C# Surface API $(GrpcCsharpVersion) Google Inc. diff --git a/src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs index fa04d9328d4..ad38569908e 100644 --- a/src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs +++ b/src/csharp/Grpc.Core.Api/Properties/AssemblyInfo.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2018 The gRPC Authors +// Copyright 2019 The gRPC Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From c4e59973a24ac6a2f426190398eefb0763e9dc3d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 31 Jan 2019 10:25:27 +0100 Subject: [PATCH 225/814] refactor ServerServiceDefinition and move to Grpc.Core.Api --- .../ServerServiceDefinition.cs | 41 +++++----- .../ServiceBinderBase.cs | 3 - src/csharp/Grpc.Core/ForwardedTypes.cs | 3 +- .../ServerServiceDefinitionExtensions.cs | 2 +- .../ServerServiceDefinitionExtensions.cs | 78 +++++++++++++++++++ src/csharp/Grpc.Core/Server.cs | 2 +- 6 files changed, 105 insertions(+), 24 deletions(-) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/ServerServiceDefinition.cs (74%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/ServiceBinderBase.cs (97%) create mode 100644 src/csharp/Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs diff --git a/src/csharp/Grpc.Core/ServerServiceDefinition.cs b/src/csharp/Grpc.Core.Api/ServerServiceDefinition.cs similarity index 74% rename from src/csharp/Grpc.Core/ServerServiceDefinition.cs rename to src/csharp/Grpc.Core.Api/ServerServiceDefinition.cs index b040ab379c8..8c76f0bcc97 100644 --- a/src/csharp/Grpc.Core/ServerServiceDefinition.cs +++ b/src/csharp/Grpc.Core.Api/ServerServiceDefinition.cs @@ -18,33 +18,31 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using Grpc.Core.Interceptors; -using Grpc.Core.Internal; -using Grpc.Core.Utils; namespace Grpc.Core { /// - /// Mapping of method names to server call handlers. + /// Stores mapping of methods to server call handlers. /// Normally, the ServerServiceDefinition objects will be created by the BindService factory method /// that is part of the autogenerated code for a protocol buffers service definition. /// public class ServerServiceDefinition { - readonly ReadOnlyDictionary callHandlers; + readonly IReadOnlyList> addMethodActions; - internal ServerServiceDefinition(Dictionary callHandlers) + internal ServerServiceDefinition(List> addMethodActions) { - this.callHandlers = new ReadOnlyDictionary(callHandlers); + this.addMethodActions = addMethodActions.AsReadOnly(); } - internal IDictionary CallHandlers + /// + /// Forwards all the previously stored AddMethod calls to the service binder. + /// + internal void BindService(ServiceBinderBase serviceBinder) { - get + foreach (var addMethodAction in addMethodActions) { - return this.callHandlers; + addMethodAction(serviceBinder); } } @@ -62,7 +60,10 @@ namespace Grpc.Core /// public class Builder { - readonly Dictionary callHandlers = new Dictionary(); + // to maintain legacy behavior, we need to detect duplicate keys and throw the same exception as before + readonly Dictionary duplicateDetector = new Dictionary(); + // for each AddMethod call, we store an action that will later register the method and handler with ServiceBinderBase + readonly List> addMethodActions = new List>(); /// /// Creates a new instance of builder. @@ -85,7 +86,8 @@ namespace Grpc.Core where TRequest : class where TResponse : class { - callHandlers.Add(method.FullName, ServerCalls.UnaryCall(method, handler)); + duplicateDetector.Add(method.FullName, null); + addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler)); return this; } @@ -103,7 +105,8 @@ namespace Grpc.Core where TRequest : class where TResponse : class { - callHandlers.Add(method.FullName, ServerCalls.ClientStreamingCall(method, handler)); + duplicateDetector.Add(method.FullName, null); + addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler)); return this; } @@ -121,7 +124,8 @@ namespace Grpc.Core where TRequest : class where TResponse : class { - callHandlers.Add(method.FullName, ServerCalls.ServerStreamingCall(method, handler)); + duplicateDetector.Add(method.FullName, null); + addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler)); return this; } @@ -139,7 +143,8 @@ namespace Grpc.Core where TRequest : class where TResponse : class { - callHandlers.Add(method.FullName, ServerCalls.DuplexStreamingCall(method, handler)); + duplicateDetector.Add(method.FullName, null); + addMethodActions.Add((serviceBinder) => serviceBinder.AddMethod(method, handler)); return this; } @@ -149,7 +154,7 @@ namespace Grpc.Core /// The ServerServiceDefinition object. public ServerServiceDefinition Build() { - return new ServerServiceDefinition(callHandlers); + return new ServerServiceDefinition(addMethodActions); } } } diff --git a/src/csharp/Grpc.Core/ServiceBinderBase.cs b/src/csharp/Grpc.Core.Api/ServiceBinderBase.cs similarity index 97% rename from src/csharp/Grpc.Core/ServiceBinderBase.cs rename to src/csharp/Grpc.Core.Api/ServiceBinderBase.cs index d4909f4a269..074bfae1ea0 100644 --- a/src/csharp/Grpc.Core/ServiceBinderBase.cs +++ b/src/csharp/Grpc.Core.Api/ServiceBinderBase.cs @@ -20,8 +20,6 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; -using Grpc.Core.Interceptors; -using Grpc.Core.Internal; using Grpc.Core.Utils; namespace Grpc.Core @@ -30,7 +28,6 @@ namespace Grpc.Core /// Allows binding server-side method implementations in alternative serving stacks. /// Instances of this class are usually populated by the BindService method /// that is part of the autogenerated code for a protocol buffers service definition. - /// /// public class ServiceBinderBase { diff --git a/src/csharp/Grpc.Core/ForwardedTypes.cs b/src/csharp/Grpc.Core/ForwardedTypes.cs index 8e104fd410d..e17696a626f 100644 --- a/src/csharp/Grpc.Core/ForwardedTypes.cs +++ b/src/csharp/Grpc.Core/ForwardedTypes.cs @@ -25,7 +25,6 @@ using Grpc.Core.Utils; // https://docs.microsoft.com/en-us/dotnet/framework/app-domains/type-forwarding-in-the-common-language-runtime // TODO(jtattermusch): move types needed for implementing a client -// TODO(jtattermusch): ServerServiceDefinition depends on IServerCallHandler (which depends on other stuff) [assembly:TypeForwardedToAttribute(typeof(ILogger))] [assembly:TypeForwardedToAttribute(typeof(LogLevel))] @@ -50,6 +49,8 @@ using Grpc.Core.Utils; [assembly:TypeForwardedToAttribute(typeof(ClientStreamingServerMethod<,>))] [assembly:TypeForwardedToAttribute(typeof(ServerStreamingServerMethod<,>))] [assembly:TypeForwardedToAttribute(typeof(DuplexStreamingServerMethod<,>))] +[assembly:TypeForwardedToAttribute(typeof(ServerServiceDefinition))] +[assembly:TypeForwardedToAttribute(typeof(ServiceBinderBase))] [assembly:TypeForwardedToAttribute(typeof(Status))] [assembly:TypeForwardedToAttribute(typeof(StatusCode))] [assembly:TypeForwardedToAttribute(typeof(WriteOptions))] diff --git a/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs index 56ead8a6a15..36eb08cf528 100644 --- a/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs +++ b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs @@ -44,7 +44,7 @@ namespace Grpc.Core.Interceptors { GrpcPreconditions.CheckNotNull(serverServiceDefinition, nameof(serverServiceDefinition)); GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor)); - return new ServerServiceDefinition(serverServiceDefinition.CallHandlers.ToDictionary(x => x.Key, x => x.Value.Intercept(interceptor))); + return new ServerServiceDefinition(serverServiceDefinition.GetCallHandlers().ToDictionary(x => x.Key, x => x.Value.Intercept(interceptor))); } /// diff --git a/src/csharp/Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs b/src/csharp/Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs new file mode 100644 index 00000000000..d79b5007e87 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs @@ -0,0 +1,78 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Grpc.Core.Internal; + +namespace Grpc.Core +{ + internal static class ServerServiceDefinitionExtensions + { + /// + /// Maps methods from ServerServiceDefinition to server call handlers. + /// + internal static ReadOnlyDictionary GetCallHandlers(this ServerServiceDefinition serviceDefinition) + { + var binder = new DefaultServiceBinder(); + serviceDefinition.BindService(binder); + return binder.GetCallHandlers(); + } + + /// + /// Helper for converting ServerServiceDefinition to server call handlers. + /// + private class DefaultServiceBinder : ServiceBinderBase + { + readonly Dictionary callHandlers = new Dictionary(); + + internal ReadOnlyDictionary GetCallHandlers() + { + return new ReadOnlyDictionary(this.callHandlers); + } + + public override void AddMethod( + Method method, + UnaryServerMethod handler) + { + callHandlers.Add(method.FullName, ServerCalls.UnaryCall(method, handler)); + } + + public override void AddMethod( + Method method, + ClientStreamingServerMethod handler) + { + callHandlers.Add(method.FullName, ServerCalls.ClientStreamingCall(method, handler)); + } + + public override void AddMethod( + Method method, + ServerStreamingServerMethod handler) + { + callHandlers.Add(method.FullName, ServerCalls.ServerStreamingCall(method, handler)); + } + + public override void AddMethod( + Method method, + DuplexStreamingServerMethod handler) + { + callHandlers.Add(method.FullName, ServerCalls.DuplexStreamingCall(method, handler)); + } + } + } +} diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs index 64bb407c57f..26d182ae53b 100644 --- a/src/csharp/Grpc.Core/Server.cs +++ b/src/csharp/Grpc.Core/Server.cs @@ -257,7 +257,7 @@ namespace Grpc.Core lock (myLock) { GrpcPreconditions.CheckState(!startRequested); - foreach (var entry in serviceDefinition.CallHandlers) + foreach (var entry in serviceDefinition.GetCallHandlers()) { callHandlers.Add(entry.Key, entry.Value); } From 83a3b3b382d465575c93a51326fa5d80d6ae574c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 31 Jan 2019 11:35:59 +0100 Subject: [PATCH 226/814] fix ServerServiceDefinition interception --- .../ServerServiceDefinitionExtensions.cs | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs index 36eb08cf528..321cf080faa 100644 --- a/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs +++ b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs @@ -44,7 +44,10 @@ namespace Grpc.Core.Interceptors { GrpcPreconditions.CheckNotNull(serverServiceDefinition, nameof(serverServiceDefinition)); GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor)); - return new ServerServiceDefinition(serverServiceDefinition.GetCallHandlers().ToDictionary(x => x.Key, x => x.Value.Intercept(interceptor))); + + var binder = new InterceptingServiceBinder(interceptor); + serverServiceDefinition.BindService(binder); + return binder.GetInterceptedServerServiceDefinition(); } /// @@ -75,5 +78,52 @@ namespace Grpc.Core.Interceptors return serverServiceDefinition; } + + /// + /// Helper for creating ServerServiceDefinition with intercepted handlers. + /// + private class InterceptingServiceBinder : ServiceBinderBase + { + readonly ServerServiceDefinition.Builder builder = ServerServiceDefinition.CreateBuilder(); + readonly Interceptor interceptor; + + public InterceptingServiceBinder(Interceptor interceptor) + { + this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor)); + } + + internal ServerServiceDefinition GetInterceptedServerServiceDefinition() + { + return builder.Build(); + } + + public override void AddMethod( + Method method, + UnaryServerMethod handler) + { + builder.AddMethod(method, (request, context) => interceptor.UnaryServerHandler(request, context, handler)); + } + + public override void AddMethod( + Method method, + ClientStreamingServerMethod handler) + { + builder.AddMethod(method, (requestStream, context) => interceptor.ClientStreamingServerHandler(requestStream, context, handler)); + } + + public override void AddMethod( + Method method, + ServerStreamingServerMethod handler) + { + builder.AddMethod(method, (request, responseStream, context) => interceptor.ServerStreamingServerHandler(request, responseStream, context, handler)); + } + + public override void AddMethod( + Method method, + DuplexStreamingServerMethod handler) + { + builder.AddMethod(method, (requestStream, responseStream, context) => interceptor.DuplexStreamingServerHandler(requestStream, responseStream, context, handler)); + } + } } } From 8a33ae4c520d9dd7fed6e6777b86e5613307ed60 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 31 Jan 2019 11:42:43 +0100 Subject: [PATCH 227/814] simplify IServerCallHandler --- .../Grpc.Core/Internal/ServerCallHandler.cs | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index c3859f1de27..0c9297413c3 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -31,7 +31,6 @@ namespace Grpc.Core.Internal internal interface IServerCallHandler { Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq); - IServerCallHandler Intercept(Interceptor interceptor); } internal class UnaryServerCallHandler : IServerCallHandler @@ -91,11 +90,6 @@ namespace Grpc.Core.Internal } await finishedTask.ConfigureAwait(false); } - - public IServerCallHandler Intercept(Interceptor interceptor) - { - return new UnaryServerCallHandler(method, (request, context) => interceptor.UnaryServerHandler(request, context, handler)); - } } internal class ServerStreamingServerCallHandler : IServerCallHandler @@ -154,11 +148,6 @@ namespace Grpc.Core.Internal } await finishedTask.ConfigureAwait(false); } - - public IServerCallHandler Intercept(Interceptor interceptor) - { - return new ServerStreamingServerCallHandler(method, (request, responseStream, context) => interceptor.ServerStreamingServerHandler(request, responseStream, context, handler)); - } } internal class ClientStreamingServerCallHandler : IServerCallHandler @@ -217,11 +206,6 @@ namespace Grpc.Core.Internal } await finishedTask.ConfigureAwait(false); } - - public IServerCallHandler Intercept(Interceptor interceptor) - { - return new ClientStreamingServerCallHandler(method, (requestStream, context) => interceptor.ClientStreamingServerHandler(requestStream, context, handler)); - } } internal class DuplexStreamingServerCallHandler : IServerCallHandler @@ -277,11 +261,6 @@ namespace Grpc.Core.Internal } await finishedTask.ConfigureAwait(false); } - - public IServerCallHandler Intercept(Interceptor interceptor) - { - return new DuplexStreamingServerCallHandler(method, (requestStream, responseStream, context) => interceptor.DuplexStreamingServerHandler(requestStream, responseStream, context, handler)); - } } internal class UnimplementedMethodCallHandler : IServerCallHandler @@ -310,11 +289,6 @@ namespace Grpc.Core.Internal { return callHandlerImpl.HandleCall(newRpc, cq); } - - public IServerCallHandler Intercept(Interceptor interceptor) - { - return this; // Do not intercept unimplemented methods. - } } internal static class HandlerUtils From d8f2e99167ad73f46d9a4af8543945044b4440d4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 31 Jan 2019 15:58:30 +0100 Subject: [PATCH 228/814] Increase VM timeout for grpc_ios_binary_size job --- tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg index dc35ce81ffd..f639b4ef77c 100644 --- a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg @@ -16,7 +16,7 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/macos/grpc_ios_binary_size.sh" -timeout_mins: 60 +timeout_mins: 90 before_action { fetch_keystore { keystore_resource { From 5a382a3b59ddb2331ed4b8521ef9abbb551506f2 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sat, 26 Jan 2019 17:42:02 -0500 Subject: [PATCH 229/814] Introduce weak and nonline attribute. This will be used to mark symbols such as nallocx as weak and replace with better implementation when available. --- include/grpc/impl/codegen/port_platform.h | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index aaeb23694e8..358e444e890 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -520,6 +520,35 @@ typedef unsigned __int64 uint64_t; #define CENSUSAPI GRPCAPI #endif +#ifndef GPR_HAS_ATTRIBUTE +#ifdef __has_attribute +#define GPR_HAS_ATTRIBUTE(a) __has_attribute(a) +#else +#define GPR_HAS_ATTRIBUTE(a) 0 +#endif +#endif /* GPR_HAS_ATTRIBUTE */ + +#ifndef GPR_ATTRIBUTE_NOINLINE +#if GPR_HAS_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)) +#define GPR_ATTRIBUTE_NOINLINE __attribute__((noinline)) +#define GPR_HAS_ATTRIBUTE_NOINLINE 1 +#else +#define GPR_ATTRIBUTE_NOINLINE +#endif +#endif /* GPR_ATTRIBUTE_NOINLINE */ + +#ifndef GPR_ATTRIBUTE_WEAK +/* Attribute weak is broken on LLVM/windows: + * https://bugs.llvm.org/show_bug.cgi?id=37598 */ +#if (GPR_HAS_ATTRIBUTE(weak) || (defined(__GNUC__) && !defined(__clang__))) && \ + !(defined(__llvm__) && defined(_WIN32)) +#define GPR_ATTRIBUTE_WEAK __attribute__((weak)) +#define GPR_HAS_ATTRIBUTE_WEAK 1 +#else +#define GPR_ATTRIBUTE_WEAK +#endif +#endif /* GPR_ATTRIBUTE_WEAK */ + #ifndef GPR_ATTRIBUTE_NO_TSAN /* (1) */ #if defined(__has_feature) #if __has_feature(thread_sanitizer) From a4f8534a98748a0d29a8cfd93edcf8af2481f106 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 31 Jan 2019 10:45:02 -0800 Subject: [PATCH 230/814] Unref watcher after releasing lock --- .../ext/filters/client_channel/subchannel.cc | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 1d188a655f8..4276df3067f 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -405,18 +405,22 @@ class Subchannel::ConnectedSubchannelStateWatcher static void OnHealthChanged(void* arg, grpc_error* error) { auto* self = static_cast(arg); Subchannel* c = self->subchannel_; - MutexLock lock(&c->mu_); - if (self->health_state_ == GRPC_CHANNEL_SHUTDOWN) { - self->Unref(); - return; + { + MutexLock lock(&c->mu_); + if (self->health_state_ != GRPC_CHANNEL_SHUTDOWN) { + if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) { + grpc_connectivity_state_set(&c->state_and_health_tracker_, + self->health_state_, + GRPC_ERROR_REF(error), "health_changed"); + } + self->health_check_client_->NotifyOnHealthChange( + &self->health_state_, &self->on_health_changed_); + self = nullptr; // So we don't unref below. + } } - if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) { - grpc_connectivity_state_set(&c->state_and_health_tracker_, - self->health_state_, GRPC_ERROR_REF(error), - "health_changed"); - } - self->health_check_client_->NotifyOnHealthChange(&self->health_state_, - &self->on_health_changed_); + // Don't unref until we've released the lock, because this might + // cause the subchannel (which contains the lock) to be destroyed. + if (self != nullptr) self->Unref(); } Subchannel* subchannel_; From 8c02418caa84d938964f2c441b7ff565eedefc06 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 31 Jan 2019 11:55:42 -0800 Subject: [PATCH 231/814] Reset keepalive timer on reading bytes --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index c2b57ed2905..a0ca89ec510 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -2554,6 +2554,10 @@ static void read_action_locked(void* tp, grpc_error* error) { } else if (t->closed_with_error == GRPC_ERROR_NONE) { keep_reading = true; GRPC_CHTTP2_REF_TRANSPORT(t, "keep_reading"); + /* Since we have read a byte, reset the keepalive timer */ + if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_WAITING) { + grpc_timer_cancel(&t->keepalive_ping_timer); + } } grpc_slice_buffer_reset_and_unref_internal(&t->read_buffer); From c372768feeef4991800b09607409f4af546a3684 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 31 Jan 2019 12:10:43 -0800 Subject: [PATCH 232/814] Install Bazel using its installation script --- templates/tools/dockerfile/bazel.include | 5 +++-- .../tools/dockerfile/test/sanity/Dockerfile.template | 1 + tools/dockerfile/test/bazel/Dockerfile | 5 +++-- tools/dockerfile/test/sanity/Dockerfile | 8 ++++++++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/templates/tools/dockerfile/bazel.include b/templates/tools/dockerfile/bazel.include index c7714f56630..62d68607453 100644 --- a/templates/tools/dockerfile/bazel.include +++ b/templates/tools/dockerfile/bazel.include @@ -2,5 +2,6 @@ # Bazel installation RUN apt-get update && apt-get install -y wget && apt-get clean -RUN wget -q https://github.com/bazelbuild/bazel/releases/download/0.17.1/bazel-0.17.1-linux-x86_64 -O /usr/local/bin/bazel -RUN chmod 755 /usr/local/bin/bazel +RUN wget https://github.com/bazelbuild/bazel/releases/download/0.20.0/bazel-0.20.0-installer-linux-x86_64.sh && ${'\\'} + bash ./bazel-0.20.0-installer-linux-x86_64.sh && ${'\\'} + rm bazel-0.20.0-installer-linux-x86_64.sh diff --git a/templates/tools/dockerfile/test/sanity/Dockerfile.template b/templates/tools/dockerfile/test/sanity/Dockerfile.template index a4f9183beac..2e4bdf537b7 100644 --- a/templates/tools/dockerfile/test/sanity/Dockerfile.template +++ b/templates/tools/dockerfile/test/sanity/Dockerfile.template @@ -32,6 +32,7 @@ RUN python3 -m pip install simplejson mako virtualenv lxml <%include file="../../clang5.include"/> + <%include file="../../bazel.include"/> # Define the default command. CMD ["bash"] diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile index 22d5d7c71c2..7dee0051176 100644 --- a/tools/dockerfile/test/bazel/Dockerfile +++ b/tools/dockerfile/test/bazel/Dockerfile @@ -52,8 +52,9 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t # Bazel installation RUN apt-get update && apt-get install -y wget && apt-get clean -RUN wget -q https://github.com/bazelbuild/bazel/releases/download/0.17.1/bazel-0.17.1-linux-x86_64 -O /usr/local/bin/bazel -RUN chmod 755 /usr/local/bin/bazel +RUN wget https://github.com/bazelbuild/bazel/releases/download/0.20.0/bazel-0.20.0-installer-linux-x86_64.sh && \ + bash ./bazel-0.20.0-installer-linux-x86_64.sh && \ + rm bazel-0.20.0-installer-linux-x86_64.sh RUN mkdir -p /var/local/jenkins diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile index aeee02a50fa..7a6fbfee7f4 100644 --- a/tools/dockerfile/test/sanity/Dockerfile +++ b/tools/dockerfile/test/sanity/Dockerfile @@ -94,6 +94,14 @@ ENV CLANG_FORMAT=clang-format RUN ln -s /clang+llvm-5.0.0-linux-x86_64-ubuntu14.04/bin/clang-tidy /usr/local/bin/clang-tidy ENV CLANG_TIDY=clang-tidy +#======================== +# Bazel installation + +RUN apt-get update && apt-get install -y wget && apt-get clean +RUN wget https://github.com/bazelbuild/bazel/releases/download/0.20.0/bazel-0.20.0-installer-linux-x86_64.sh && \ + bash ./bazel-0.20.0-installer-linux-x86_64.sh && \ + rm bazel-0.20.0-installer-linux-x86_64.sh + # Define the default command. CMD ["bash"] From bb73d8ce21a16307ac02ca551bcb47c8c4d88fd5 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 31 Jan 2019 14:58:18 -0800 Subject: [PATCH 233/814] Fix for 17338. Delay shutdown of buffer list till tcp_free to avoid races --- src/core/lib/iomgr/tcp_posix.cc | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 792ffd27385..32ee10c185a 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -343,6 +343,13 @@ static void tcp_free(grpc_tcp* tcp) { grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); gpr_free(tcp->peer_string); + /* The lock is not really necessary here, since all refs have been released */ + gpr_mu_lock(&tcp->tb_mu); + grpc_core::TracedBuffer::Shutdown( + &tcp->tb_head, tcp->outgoing_buffer_arg, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed")); + gpr_mu_unlock(&tcp->tb_mu); + tcp->outgoing_buffer_arg = nullptr; gpr_mu_destroy(&tcp->tb_mu); gpr_free(tcp); } @@ -389,12 +396,6 @@ static void tcp_destroy(grpc_endpoint* ep) { grpc_tcp* tcp = reinterpret_cast(ep); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { - gpr_mu_lock(&tcp->tb_mu); - grpc_core::TracedBuffer::Shutdown( - &tcp->tb_head, tcp->outgoing_buffer_arg, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed")); - gpr_mu_unlock(&tcp->tb_mu); - tcp->outgoing_buffer_arg = nullptr; gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); grpc_fd_set_error(tcp->em_fd); } @@ -1184,12 +1185,6 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { /* Stop errors notification. */ - gpr_mu_lock(&tcp->tb_mu); - grpc_core::TracedBuffer::Shutdown( - &tcp->tb_head, tcp->outgoing_buffer_arg, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed")); - gpr_mu_unlock(&tcp->tb_mu); - tcp->outgoing_buffer_arg = nullptr; gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); grpc_fd_set_error(tcp->em_fd); } From 139d9f6e94ebe75220ae93fe4e84aa941aa62cdd Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 31 Jan 2019 15:06:34 -0800 Subject: [PATCH 234/814] Revert "Revert c-ares as the default resolvre" This reverts commit ca30b2240f6f8e86b51452097c3cb43c5d4f7117. --- .../client_channel/resolver/dns/c_ares/dns_resolver_ares.cc | 3 ++- .../test/cpp/naming/resolver_component_tests_defs.include | 1 - test/core/client_channel/resolvers/dns_resolver_test.cc | 2 +- test/cpp/naming/resolver_component_tests_runner.py | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index fe245bfef09..bf8b0ea5f62 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -478,7 +478,8 @@ static grpc_address_resolver_vtable ares_resolver = { grpc_resolve_address_ares, blocking_resolve_address_ares}; static bool should_use_ares(const char* resolver_env) { - return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0; + return resolver_env == nullptr || strlen(resolver_env) == 0 || + gpr_stricmp(resolver_env, "ares") == 0; } void grpc_resolver_dns_ares_init() { diff --git a/templates/test/cpp/naming/resolver_component_tests_defs.include b/templates/test/cpp/naming/resolver_component_tests_defs.include index b34845e01a3..d38316cbe68 100644 --- a/templates/test/cpp/naming/resolver_component_tests_defs.include +++ b/templates/test/cpp/naming/resolver_component_tests_defs.include @@ -55,7 +55,6 @@ if cur_resolver and cur_resolver != 'ares': 'needs to use GRPC_DNS_RESOLVER=ares.')) test_runner_log('Exit 1 without running tests.') sys.exit(1) -os.environ.update({'GRPC_DNS_RESOLVER': 'ares'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index f426eab9592..6f153cc9bf6 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -75,7 +75,7 @@ int main(int argc, char** argv) { test_succeeds(dns, "dns:www.google.com"); test_succeeds(dns, "dns:///www.google.com"); char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); - if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) { + if (resolver_env != nullptr && gpr_stricmp(resolver_env, "native") == 0) { test_fails(dns, "dns://8.8.8.8/8.8.8.8:8888"); } else { test_succeeds(dns, "dns://8.8.8.8/8.8.8.8:8888"); diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index 8a5b1f53dcf..a4438cb100e 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -55,7 +55,6 @@ if cur_resolver and cur_resolver != 'ares': 'needs to use GRPC_DNS_RESOLVER=ares.')) test_runner_log('Exit 1 without running tests.') sys.exit(1) -os.environ.update({'GRPC_DNS_RESOLVER': 'ares'}) os.environ.update({'GRPC_TRACE': 'cares_resolver'}) def wait_until_dns_server_is_up(args, From adfe2238ef16008d6f61fd1f209c7783cc556de5 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 31 Jan 2019 20:56:13 -0800 Subject: [PATCH 235/814] ignore duplicate root cert in cert list instead of fail. --- src/core/tsi/ssl_transport_security.cc | 11 ++++++++--- test/core/tsi/ssl_transport_security_test.cc | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index b18da575382..5ced404f39d 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -619,10 +619,15 @@ static tsi_result x509_store_load_certs(X509_STORE* cert_store, sk_X509_NAME_push(*root_names, root_name); root_name = nullptr; } + ERR_clear_error(); if (!X509_STORE_add_cert(cert_store, root)) { - gpr_log(GPR_ERROR, "Could not add root certificate to ssl context."); - result = TSI_INTERNAL_ERROR; - break; + size_t error = ERR_get_error(); + if (ERR_GET_LIB(error) != ERR_LIB_X509 || + ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) { + gpr_log(GPR_ERROR, "Could not add root certificate to ssl context."); + result = TSI_INTERNAL_ERROR; + break; + } } X509_free(root); num_roots++; diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index fc6c6ba3208..bb69907527c 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -776,10 +776,24 @@ void ssl_tsi_test_handshaker_factory_internals() { test_tsi_ssl_client_handshaker_factory_bad_params(); } +void ssl_tsi_test_duplicate_root_certificates() { + const char* root_cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "ca.pem"); + char* dup_root_cert = static_cast( + gpr_zalloc(sizeof(char) * (strlen(root_cert) * 2 + 1))); + memcpy(dup_root_cert, root_cert, strlen(root_cert)); + memcpy(dup_root_cert + strlen(root_cert), root_cert, strlen(root_cert)); + tsi_ssl_root_certs_store* root_store = + tsi_ssl_root_certs_store_create(dup_root_cert); + GPR_ASSERT(root_store != nullptr); + // Free memory. + tsi_ssl_root_certs_store_destroy(root_store); + gpr_free((void*)root_cert); + gpr_free((void*)dup_root_cert); +} + int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); grpc_init(); - ssl_tsi_test_do_handshake_tiny_handshake_buffer(); ssl_tsi_test_do_handshake_small_handshake_buffer(); ssl_tsi_test_do_handshake(); @@ -801,6 +815,7 @@ int main(int argc, char** argv) { ssl_tsi_test_do_round_trip_for_all_configs(); ssl_tsi_test_do_round_trip_odd_buffer_size(); ssl_tsi_test_handshaker_factory_internals(); + ssl_tsi_test_duplicate_root_certificates(); grpc_shutdown(); return 0; } From 73b846492aa26606c0cc5cfe0ecd14f633a533ad Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 1 Feb 2019 07:28:35 +0100 Subject: [PATCH 236/814] change namespace to internal --- .../Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs b/src/csharp/Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs index d79b5007e87..cc4654c9acf 100644 --- a/src/csharp/Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs +++ b/src/csharp/Grpc.Core/Internal/ServerServiceDefinitionExtensions.cs @@ -20,7 +20,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using Grpc.Core.Internal; -namespace Grpc.Core +namespace Grpc.Core.Internal { internal static class ServerServiceDefinitionExtensions { From 64e095953a7adc37502dfb86c5dc96434bf375bf Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 1 Feb 2019 05:16:19 -0800 Subject: [PATCH 237/814] Remove an overly-conservative mutex from callback CQ implementation --- src/core/lib/surface/completion_queue.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 426a4a3f24e..f473b23788e 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -854,15 +854,11 @@ static void cq_end_op_for_callback( // for reserved storage. Invoke the done callback right away to release it. done(done_arg, storage); - gpr_mu_lock(cq->mu); - cq_check_tag(cq, tag, false); /* Used in debug builds only */ + cq_check_tag(cq, tag, true); /* Used in debug builds only */ gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1); if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { - gpr_mu_unlock(cq->mu); cq_finish_shutdown_callback(cq); - } else { - gpr_mu_unlock(cq->mu); } GRPC_ERROR_UNREF(error); From ef208401747d76446531192ec742a77b2a735d14 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 7 Dec 2018 10:01:11 -0500 Subject: [PATCH 238/814] Reorder fields in slice to share the same bytes for length fields. Ref-counted and inlined slices both have a lenght value, but they are not in the same byte offset. As a result, we will have two different loads based on a branch. Instead move them to the same byteoffset, so that we will have one move and the same number of branches. Difference can be seen on: https://godbolt.org/z/kqFZcP --- include/grpc/impl/codegen/slice.h | 2 +- .../chttp2/transport/hpack_encoder.cc | 2 +- src/core/lib/transport/static_metadata.cc | 558 +++++++++--------- 3 files changed, 281 insertions(+), 281 deletions(-) diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h index 90dbfd3b1f8..62339daae5e 100644 --- a/include/grpc/impl/codegen/slice.h +++ b/include/grpc/impl/codegen/slice.h @@ -81,8 +81,8 @@ struct grpc_slice { struct grpc_slice_refcount* refcount; union grpc_slice_data { struct grpc_slice_refcounted { - uint8_t* bytes; size_t length; + uint8_t* bytes; } refcounted; struct grpc_slice_inlined { uint8_t length; diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index dbe9df6ae38..9b4c3ce7e11 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -59,7 +59,7 @@ static grpc_slice_refcount terminal_slice_refcount = {nullptr, nullptr}; static const grpc_slice terminal_slice = { &terminal_slice_refcount, /* refcount */ - {{nullptr, 0}} /* data.refcounted */ + {{0, nullptr}} /* data.refcounted */ }; typedef struct { diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 3dfaaaad5c8..963626a9dc9 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -236,113 +236,113 @@ grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = { }; const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { - {&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, - {&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[6], {{g_bytes + 38, 12}}}, - {&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[8], {{g_bytes + 61, 16}}}, - {&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[11], {{g_bytes + 110, 21}}}, - {&grpc_static_metadata_refcounts[12], {{g_bytes + 131, 13}}}, - {&grpc_static_metadata_refcounts[13], {{g_bytes + 144, 14}}}, - {&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[17], {{g_bytes + 201, 30}}}, - {&grpc_static_metadata_refcounts[18], {{g_bytes + 231, 37}}}, - {&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}}, - {&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}}, - {&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}}, - {&grpc_static_metadata_refcounts[22], {{g_bytes + 290, 26}}}, - {&grpc_static_metadata_refcounts[23], {{g_bytes + 316, 22}}}, - {&grpc_static_metadata_refcounts[24], {{g_bytes + 338, 12}}}, - {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}, - {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}, - {&grpc_static_metadata_refcounts[27], {{g_bytes + 352, 1}}}, - {&grpc_static_metadata_refcounts[28], {{g_bytes + 353, 1}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}, - {&grpc_static_metadata_refcounts[30], {{g_bytes + 354, 19}}}, - {&grpc_static_metadata_refcounts[31], {{g_bytes + 373, 12}}}, - {&grpc_static_metadata_refcounts[32], {{g_bytes + 385, 30}}}, - {&grpc_static_metadata_refcounts[33], {{g_bytes + 415, 31}}}, - {&grpc_static_metadata_refcounts[34], {{g_bytes + 446, 36}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 28}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 80}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 590, 7}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 601, 11}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 612, 3}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 615, 4}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 619, 1}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 620, 11}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 631, 4}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 635, 5}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 640, 3}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 643, 3}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 646, 3}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 649, 3}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 652, 3}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 655, 3}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 658, 3}}}, - {&grpc_static_metadata_refcounts[53], {{g_bytes + 661, 14}}}, - {&grpc_static_metadata_refcounts[54], {{g_bytes + 675, 13}}}, - {&grpc_static_metadata_refcounts[55], {{g_bytes + 688, 15}}}, - {&grpc_static_metadata_refcounts[56], {{g_bytes + 703, 13}}}, - {&grpc_static_metadata_refcounts[57], {{g_bytes + 716, 6}}}, - {&grpc_static_metadata_refcounts[58], {{g_bytes + 722, 27}}}, - {&grpc_static_metadata_refcounts[59], {{g_bytes + 749, 3}}}, - {&grpc_static_metadata_refcounts[60], {{g_bytes + 752, 5}}}, - {&grpc_static_metadata_refcounts[61], {{g_bytes + 757, 13}}}, - {&grpc_static_metadata_refcounts[62], {{g_bytes + 770, 13}}}, - {&grpc_static_metadata_refcounts[63], {{g_bytes + 783, 19}}}, - {&grpc_static_metadata_refcounts[64], {{g_bytes + 802, 16}}}, - {&grpc_static_metadata_refcounts[65], {{g_bytes + 818, 14}}}, - {&grpc_static_metadata_refcounts[66], {{g_bytes + 832, 16}}}, - {&grpc_static_metadata_refcounts[67], {{g_bytes + 848, 13}}}, - {&grpc_static_metadata_refcounts[68], {{g_bytes + 861, 6}}}, - {&grpc_static_metadata_refcounts[69], {{g_bytes + 867, 4}}}, - {&grpc_static_metadata_refcounts[70], {{g_bytes + 871, 4}}}, - {&grpc_static_metadata_refcounts[71], {{g_bytes + 875, 6}}}, - {&grpc_static_metadata_refcounts[72], {{g_bytes + 881, 7}}}, - {&grpc_static_metadata_refcounts[73], {{g_bytes + 888, 4}}}, - {&grpc_static_metadata_refcounts[74], {{g_bytes + 892, 8}}}, - {&grpc_static_metadata_refcounts[75], {{g_bytes + 900, 17}}}, - {&grpc_static_metadata_refcounts[76], {{g_bytes + 917, 13}}}, - {&grpc_static_metadata_refcounts[77], {{g_bytes + 930, 8}}}, - {&grpc_static_metadata_refcounts[78], {{g_bytes + 938, 19}}}, - {&grpc_static_metadata_refcounts[79], {{g_bytes + 957, 13}}}, - {&grpc_static_metadata_refcounts[80], {{g_bytes + 970, 4}}}, - {&grpc_static_metadata_refcounts[81], {{g_bytes + 974, 8}}}, - {&grpc_static_metadata_refcounts[82], {{g_bytes + 982, 12}}}, - {&grpc_static_metadata_refcounts[83], {{g_bytes + 994, 18}}}, - {&grpc_static_metadata_refcounts[84], {{g_bytes + 1012, 19}}}, - {&grpc_static_metadata_refcounts[85], {{g_bytes + 1031, 5}}}, - {&grpc_static_metadata_refcounts[86], {{g_bytes + 1036, 7}}}, - {&grpc_static_metadata_refcounts[87], {{g_bytes + 1043, 7}}}, - {&grpc_static_metadata_refcounts[88], {{g_bytes + 1050, 11}}}, - {&grpc_static_metadata_refcounts[89], {{g_bytes + 1061, 6}}}, - {&grpc_static_metadata_refcounts[90], {{g_bytes + 1067, 10}}}, - {&grpc_static_metadata_refcounts[91], {{g_bytes + 1077, 25}}}, - {&grpc_static_metadata_refcounts[92], {{g_bytes + 1102, 17}}}, - {&grpc_static_metadata_refcounts[93], {{g_bytes + 1119, 4}}}, - {&grpc_static_metadata_refcounts[94], {{g_bytes + 1123, 3}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1126, 16}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1142, 1}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1151, 8}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1159, 16}}}, - {&grpc_static_metadata_refcounts[100], {{g_bytes + 1175, 4}}}, - {&grpc_static_metadata_refcounts[101], {{g_bytes + 1179, 3}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1182, 11}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1193, 16}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1209, 13}}}, - {&grpc_static_metadata_refcounts[105], {{g_bytes + 1222, 12}}}, - {&grpc_static_metadata_refcounts[106], {{g_bytes + 1234, 21}}}, + {&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, + {&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, + {&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[3], {{10, g_bytes + 19}}}, + {&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, + {&grpc_static_metadata_refcounts[5], {{2, g_bytes + 36}}}, + {&grpc_static_metadata_refcounts[6], {{12, g_bytes + 38}}}, + {&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, + {&grpc_static_metadata_refcounts[8], {{16, g_bytes + 61}}}, + {&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, + {&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[11], {{21, g_bytes + 110}}}, + {&grpc_static_metadata_refcounts[12], {{13, g_bytes + 131}}}, + {&grpc_static_metadata_refcounts[13], {{14, g_bytes + 144}}}, + {&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, + {&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, + {&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[17], {{30, g_bytes + 201}}}, + {&grpc_static_metadata_refcounts[18], {{37, g_bytes + 231}}}, + {&grpc_static_metadata_refcounts[19], {{10, g_bytes + 268}}}, + {&grpc_static_metadata_refcounts[20], {{4, g_bytes + 278}}}, + {&grpc_static_metadata_refcounts[21], {{8, g_bytes + 282}}}, + {&grpc_static_metadata_refcounts[22], {{26, g_bytes + 290}}}, + {&grpc_static_metadata_refcounts[23], {{22, g_bytes + 316}}}, + {&grpc_static_metadata_refcounts[24], {{12, g_bytes + 338}}}, + {&grpc_static_metadata_refcounts[25], {{1, g_bytes + 350}}}, + {&grpc_static_metadata_refcounts[26], {{1, g_bytes + 351}}}, + {&grpc_static_metadata_refcounts[27], {{1, g_bytes + 352}}}, + {&grpc_static_metadata_refcounts[28], {{1, g_bytes + 353}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}, + {&grpc_static_metadata_refcounts[30], {{19, g_bytes + 354}}}, + {&grpc_static_metadata_refcounts[31], {{12, g_bytes + 373}}}, + {&grpc_static_metadata_refcounts[32], {{30, g_bytes + 385}}}, + {&grpc_static_metadata_refcounts[33], {{31, g_bytes + 415}}}, + {&grpc_static_metadata_refcounts[34], {{36, g_bytes + 446}}}, + {&grpc_static_metadata_refcounts[35], {{28, g_bytes + 482}}}, + {&grpc_static_metadata_refcounts[36], {{80, g_bytes + 510}}}, + {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}, + {&grpc_static_metadata_refcounts[39], {{11, g_bytes + 601}}}, + {&grpc_static_metadata_refcounts[40], {{3, g_bytes + 612}}}, + {&grpc_static_metadata_refcounts[41], {{4, g_bytes + 615}}}, + {&grpc_static_metadata_refcounts[42], {{1, g_bytes + 619}}}, + {&grpc_static_metadata_refcounts[43], {{11, g_bytes + 620}}}, + {&grpc_static_metadata_refcounts[44], {{4, g_bytes + 631}}}, + {&grpc_static_metadata_refcounts[45], {{5, g_bytes + 635}}}, + {&grpc_static_metadata_refcounts[46], {{3, g_bytes + 640}}}, + {&grpc_static_metadata_refcounts[47], {{3, g_bytes + 643}}}, + {&grpc_static_metadata_refcounts[48], {{3, g_bytes + 646}}}, + {&grpc_static_metadata_refcounts[49], {{3, g_bytes + 649}}}, + {&grpc_static_metadata_refcounts[50], {{3, g_bytes + 652}}}, + {&grpc_static_metadata_refcounts[51], {{3, g_bytes + 655}}}, + {&grpc_static_metadata_refcounts[52], {{3, g_bytes + 658}}}, + {&grpc_static_metadata_refcounts[53], {{14, g_bytes + 661}}}, + {&grpc_static_metadata_refcounts[54], {{13, g_bytes + 675}}}, + {&grpc_static_metadata_refcounts[55], {{15, g_bytes + 688}}}, + {&grpc_static_metadata_refcounts[56], {{13, g_bytes + 703}}}, + {&grpc_static_metadata_refcounts[57], {{6, g_bytes + 716}}}, + {&grpc_static_metadata_refcounts[58], {{27, g_bytes + 722}}}, + {&grpc_static_metadata_refcounts[59], {{3, g_bytes + 749}}}, + {&grpc_static_metadata_refcounts[60], {{5, g_bytes + 752}}}, + {&grpc_static_metadata_refcounts[61], {{13, g_bytes + 757}}}, + {&grpc_static_metadata_refcounts[62], {{13, g_bytes + 770}}}, + {&grpc_static_metadata_refcounts[63], {{19, g_bytes + 783}}}, + {&grpc_static_metadata_refcounts[64], {{16, g_bytes + 802}}}, + {&grpc_static_metadata_refcounts[65], {{14, g_bytes + 818}}}, + {&grpc_static_metadata_refcounts[66], {{16, g_bytes + 832}}}, + {&grpc_static_metadata_refcounts[67], {{13, g_bytes + 848}}}, + {&grpc_static_metadata_refcounts[68], {{6, g_bytes + 861}}}, + {&grpc_static_metadata_refcounts[69], {{4, g_bytes + 867}}}, + {&grpc_static_metadata_refcounts[70], {{4, g_bytes + 871}}}, + {&grpc_static_metadata_refcounts[71], {{6, g_bytes + 875}}}, + {&grpc_static_metadata_refcounts[72], {{7, g_bytes + 881}}}, + {&grpc_static_metadata_refcounts[73], {{4, g_bytes + 888}}}, + {&grpc_static_metadata_refcounts[74], {{8, g_bytes + 892}}}, + {&grpc_static_metadata_refcounts[75], {{17, g_bytes + 900}}}, + {&grpc_static_metadata_refcounts[76], {{13, g_bytes + 917}}}, + {&grpc_static_metadata_refcounts[77], {{8, g_bytes + 930}}}, + {&grpc_static_metadata_refcounts[78], {{19, g_bytes + 938}}}, + {&grpc_static_metadata_refcounts[79], {{13, g_bytes + 957}}}, + {&grpc_static_metadata_refcounts[80], {{4, g_bytes + 970}}}, + {&grpc_static_metadata_refcounts[81], {{8, g_bytes + 974}}}, + {&grpc_static_metadata_refcounts[82], {{12, g_bytes + 982}}}, + {&grpc_static_metadata_refcounts[83], {{18, g_bytes + 994}}}, + {&grpc_static_metadata_refcounts[84], {{19, g_bytes + 1012}}}, + {&grpc_static_metadata_refcounts[85], {{5, g_bytes + 1031}}}, + {&grpc_static_metadata_refcounts[86], {{7, g_bytes + 1036}}}, + {&grpc_static_metadata_refcounts[87], {{7, g_bytes + 1043}}}, + {&grpc_static_metadata_refcounts[88], {{11, g_bytes + 1050}}}, + {&grpc_static_metadata_refcounts[89], {{6, g_bytes + 1061}}}, + {&grpc_static_metadata_refcounts[90], {{10, g_bytes + 1067}}}, + {&grpc_static_metadata_refcounts[91], {{25, g_bytes + 1077}}}, + {&grpc_static_metadata_refcounts[92], {{17, g_bytes + 1102}}}, + {&grpc_static_metadata_refcounts[93], {{4, g_bytes + 1119}}}, + {&grpc_static_metadata_refcounts[94], {{3, g_bytes + 1123}}}, + {&grpc_static_metadata_refcounts[95], {{16, g_bytes + 1126}}}, + {&grpc_static_metadata_refcounts[96], {{1, g_bytes + 1142}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}, + {&grpc_static_metadata_refcounts[98], {{8, g_bytes + 1151}}}, + {&grpc_static_metadata_refcounts[99], {{16, g_bytes + 1159}}}, + {&grpc_static_metadata_refcounts[100], {{4, g_bytes + 1175}}}, + {&grpc_static_metadata_refcounts[101], {{3, g_bytes + 1179}}}, + {&grpc_static_metadata_refcounts[102], {{11, g_bytes + 1182}}}, + {&grpc_static_metadata_refcounts[103], {{16, g_bytes + 1193}}}, + {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}, + {&grpc_static_metadata_refcounts[105], {{12, g_bytes + 1222}}}, + {&grpc_static_metadata_refcounts[106], {{21, g_bytes + 1234}}}, }; uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { @@ -404,178 +404,178 @@ grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) { } grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { - {{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 612, 3}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 615, 4}}}}, - {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 619, 1}}}}, - {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 620, 11}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 631, 4}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 635, 5}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 640, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 643, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 646, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 649, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 652, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 655, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 658, 3}}}}, - {{&grpc_static_metadata_refcounts[53], {{g_bytes + 661, 14}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[54], {{g_bytes + 675, 13}}}}, - {{&grpc_static_metadata_refcounts[55], {{g_bytes + 688, 15}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[56], {{g_bytes + 703, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[57], {{g_bytes + 716, 6}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[58], {{g_bytes + 722, 27}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[59], {{g_bytes + 749, 3}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[60], {{g_bytes + 752, 5}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[61], {{g_bytes + 757, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[62], {{g_bytes + 770, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[63], {{g_bytes + 783, 19}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[64], {{g_bytes + 802, 16}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[65], {{g_bytes + 818, 14}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[66], {{g_bytes + 832, 16}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[67], {{g_bytes + 848, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[68], {{g_bytes + 861, 6}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[69], {{g_bytes + 867, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[70], {{g_bytes + 871, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[71], {{g_bytes + 875, 6}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[72], {{g_bytes + 881, 7}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[73], {{g_bytes + 888, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[74], {{g_bytes + 892, 8}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[75], {{g_bytes + 900, 17}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[76], {{g_bytes + 917, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[77], {{g_bytes + 930, 8}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[78], {{g_bytes + 938, 19}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[79], {{g_bytes + 957, 13}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[80], {{g_bytes + 970, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[81], {{g_bytes + 974, 8}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[82], {{g_bytes + 982, 12}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[83], {{g_bytes + 994, 18}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[84], {{g_bytes + 1012, 19}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[85], {{g_bytes + 1031, 5}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[86], {{g_bytes + 1036, 7}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[87], {{g_bytes + 1043, 7}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[88], {{g_bytes + 1050, 11}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[89], {{g_bytes + 1061, 6}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[90], {{g_bytes + 1067, 10}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1077, 25}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[92], {{g_bytes + 1102, 17}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1119, 4}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1123, 3}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[95], {{g_bytes + 1126, 16}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1142, 1}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 590, 7}}}}, - {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1151, 8}}}}, - {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1159, 16}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[100], {{g_bytes + 1175, 4}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[101], {{g_bytes + 1179, 3}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}}, - {{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[102], {{g_bytes + 1182, 11}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 590, 7}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1193, 16}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1209, 13}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[105], {{g_bytes + 1222, 12}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[106], {{g_bytes + 1234, 21}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1209, 13}}}}, + {{&grpc_static_metadata_refcounts[3], {{10, g_bytes + 19}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, + {&grpc_static_metadata_refcounts[40], {{3, g_bytes + 612}}}}, + {{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, + {&grpc_static_metadata_refcounts[41], {{4, g_bytes + 615}}}}, + {{&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, + {&grpc_static_metadata_refcounts[42], {{1, g_bytes + 619}}}}, + {{&grpc_static_metadata_refcounts[0], {{5, g_bytes + 0}}}, + {&grpc_static_metadata_refcounts[43], {{11, g_bytes + 620}}}}, + {{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, + {&grpc_static_metadata_refcounts[44], {{4, g_bytes + 631}}}}, + {{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, + {&grpc_static_metadata_refcounts[45], {{5, g_bytes + 635}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[46], {{3, g_bytes + 640}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[47], {{3, g_bytes + 643}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[48], {{3, g_bytes + 646}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[49], {{3, g_bytes + 649}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[50], {{3, g_bytes + 652}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[51], {{3, g_bytes + 655}}}}, + {{&grpc_static_metadata_refcounts[2], {{7, g_bytes + 12}}}, + {&grpc_static_metadata_refcounts[52], {{3, g_bytes + 658}}}}, + {{&grpc_static_metadata_refcounts[53], {{14, g_bytes + 661}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[54], {{13, g_bytes + 675}}}}, + {{&grpc_static_metadata_refcounts[55], {{15, g_bytes + 688}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[56], {{13, g_bytes + 703}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[57], {{6, g_bytes + 716}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[58], {{27, g_bytes + 722}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[59], {{3, g_bytes + 749}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[60], {{5, g_bytes + 752}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[61], {{13, g_bytes + 757}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[62], {{13, g_bytes + 770}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[63], {{19, g_bytes + 783}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[64], {{16, g_bytes + 802}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[65], {{14, g_bytes + 818}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[66], {{16, g_bytes + 832}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[67], {{13, g_bytes + 848}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[68], {{6, g_bytes + 861}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[69], {{4, g_bytes + 867}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[70], {{4, g_bytes + 871}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[71], {{6, g_bytes + 875}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[72], {{7, g_bytes + 881}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[73], {{4, g_bytes + 888}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[20], {{4, g_bytes + 278}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[74], {{8, g_bytes + 892}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[75], {{17, g_bytes + 900}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[76], {{13, g_bytes + 917}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[77], {{8, g_bytes + 930}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[78], {{19, g_bytes + 938}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[79], {{13, g_bytes + 957}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[80], {{4, g_bytes + 970}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[81], {{8, g_bytes + 974}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[82], {{12, g_bytes + 982}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[83], {{18, g_bytes + 994}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[84], {{19, g_bytes + 1012}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[85], {{5, g_bytes + 1031}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[86], {{7, g_bytes + 1036}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[87], {{7, g_bytes + 1043}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[88], {{11, g_bytes + 1050}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[89], {{6, g_bytes + 1061}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[90], {{10, g_bytes + 1067}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[91], {{25, g_bytes + 1077}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[92], {{17, g_bytes + 1102}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[19], {{10, g_bytes + 268}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[93], {{4, g_bytes + 1119}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[94], {{3, g_bytes + 1123}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[95], {{16, g_bytes + 1126}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, + {&grpc_static_metadata_refcounts[96], {{1, g_bytes + 1142}}}}, + {{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, + {&grpc_static_metadata_refcounts[25], {{1, g_bytes + 350}}}}, + {{&grpc_static_metadata_refcounts[7], {{11, g_bytes + 50}}}, + {&grpc_static_metadata_refcounts[26], {{1, g_bytes + 351}}}}, + {{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, + {{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, + {{&grpc_static_metadata_refcounts[9], {{13, g_bytes + 77}}}, + {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}}, + {{&grpc_static_metadata_refcounts[5], {{2, g_bytes + 36}}}, + {&grpc_static_metadata_refcounts[98], {{8, g_bytes + 1151}}}}, + {{&grpc_static_metadata_refcounts[14], {{12, g_bytes + 158}}}, + {&grpc_static_metadata_refcounts[99], {{16, g_bytes + 1159}}}}, + {{&grpc_static_metadata_refcounts[4], {{7, g_bytes + 29}}}, + {&grpc_static_metadata_refcounts[100], {{4, g_bytes + 1175}}}}, + {{&grpc_static_metadata_refcounts[1], {{7, g_bytes + 5}}}, + {&grpc_static_metadata_refcounts[101], {{3, g_bytes + 1179}}}}, + {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, + {{&grpc_static_metadata_refcounts[15], {{16, g_bytes + 170}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, + {{&grpc_static_metadata_refcounts[21], {{8, g_bytes + 282}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[102], {{11, g_bytes + 1182}}}, + {&grpc_static_metadata_refcounts[29], {{0, g_bytes + 354}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[37], {{7, g_bytes + 590}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[103], {{16, g_bytes + 1193}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[105], {{12, g_bytes + 1222}}}}, + {{&grpc_static_metadata_refcounts[10], {{20, g_bytes + 90}}}, + {&grpc_static_metadata_refcounts[106], {{21, g_bytes + 1234}}}}, + {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[97], {{8, g_bytes + 1143}}}}, + {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[38], {{4, g_bytes + 597}}}}, + {{&grpc_static_metadata_refcounts[16], {{15, g_bytes + 186}}}, + {&grpc_static_metadata_refcounts[104], {{13, g_bytes + 1209}}}}, }; const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78, 79, 80, 81, 82}; From c5255e9a5ee81a5c52f9815e5a88df56f1f8a913 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 31 Jan 2019 21:59:43 -0800 Subject: [PATCH 239/814] python: do not store raised exception in _Context.abort() Python 3 exceptions include a `__traceback__` attribute that includes refs to all local variables. Saving the exception results in leaking references to the, among other things, the Cython grpc_call wrapper and prevents garbage collection and release of core resources, even after the server is shutdown. See https://www.python.org/dev/peps/pep-3134/#open-issue-garbage-collection --- src/python/grpcio/grpc/_server.py | 10 ++++---- .../grpcio_tests/tests/unit/_abort_test.py | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index b44840272c9..6caaece82c4 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -100,7 +100,7 @@ class _RPCState(object): self.statused = False self.rpc_errors = [] self.callbacks = [] - self.abortion = None + self.aborted = False def _raise_rpc_error(state): @@ -287,8 +287,8 @@ class _Context(grpc.ServicerContext): with self._state.condition: self._state.code = code self._state.details = _common.encode(details) - self._state.abortion = Exception() - raise self._state.abortion + self._state.aborted = True + raise Exception() def abort_with_status(self, status): self._state.trailing_metadata = status.trailing_metadata @@ -392,7 +392,7 @@ def _call_behavior(rpc_event, state, behavior, argument, request_deserializer): return behavior(argument, context), True except Exception as exception: # pylint: disable=broad-except with state.condition: - if exception is state.abortion: + if state.aborted: _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, b'RPC Aborted') elif exception not in state.rpc_errors: @@ -410,7 +410,7 @@ def _take_response_from_response_iterator(rpc_event, state, response_iterator): return None, True except Exception as exception: # pylint: disable=broad-except with state.condition: - if exception is state.abortion: + if state.aborted: _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, b'RPC Aborted') elif exception not in state.rpc_errors: diff --git a/src/python/grpcio_tests/tests/unit/_abort_test.py b/src/python/grpcio_tests/tests/unit/_abort_test.py index 6438f6897a0..7acbf61031e 100644 --- a/src/python/grpcio_tests/tests/unit/_abort_test.py +++ b/src/python/grpcio_tests/tests/unit/_abort_test.py @@ -16,6 +16,7 @@ import unittest import collections import logging +import weakref import grpc @@ -39,7 +40,15 @@ class _Status( pass +class _Object(object): + pass + + +do_not_leak_me = _Object() + + def abort_unary_unary(request, servicer_context): + this_should_not_be_leaked = do_not_leak_me servicer_context.abort( grpc.StatusCode.INTERNAL, _ABORT_DETAILS, @@ -101,6 +110,22 @@ class AbortTest(unittest.TestCase): self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL) self.assertEqual(rpc_error.details(), _ABORT_DETAILS) + # This test ensures that abort() does not store the raised exception, which + # on Python 3 (via the `__traceback__` attribute) holds a reference to + # all local vars. Storing the raised exception can prevent GC and stop the + # grpc_call from being unref'ed, even after server shutdown. + def test_abort_does_not_leak_local_vars(self): + global do_not_leak_me # pylint: disable=global-statement + weak_ref = weakref.ref(do_not_leak_me) + + # Servicer will abort() after creating a local ref to do_not_leak_me. + with self.assertRaises(grpc.RpcError) as exception_context: + self._channel.unary_unary(_ABORT)(_REQUEST) + rpc_error = exception_context.exception + + do_not_leak_me = None + self.assertIsNone(weak_ref()) + def test_abort_with_status(self): with self.assertRaises(grpc.RpcError) as exception_context: self._channel.unary_unary(_ABORT_WITH_STATUS)(_REQUEST) From c215e8e3593b08ea6a81727f187a68efc2d30d1f Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 1 Feb 2019 12:14:06 -0800 Subject: [PATCH 240/814] Fix internal build --- test/cpp/util/channel_trace_proto_helper.cc | 40 +++++++-------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/test/cpp/util/channel_trace_proto_helper.cc b/test/cpp/util/channel_trace_proto_helper.cc index ff9d8873858..da858b6bb7e 100644 --- a/test/cpp/util/channel_trace_proto_helper.cc +++ b/test/cpp/util/channel_trace_proto_helper.cc @@ -16,53 +16,37 @@ * */ -#include "test/cpp/util/channel_trace_proto_helper.h" +#include -#include -#include +#include "test/cpp/util/channel_trace_proto_helper.h" #include #include +#include +#include #include #include "src/proto/grpc/channelz/channelz.pb.h" namespace grpc { -namespace testing { - -namespace { // Generic helper that takes in a json string, converts it to a proto, and // then back to json. This ensures that the json string was correctly formatted // according to https://developers.google.com/protocol-buffers/docs/proto3#json template void VaidateProtoJsonTranslation(char* json_c_str) { - std::string json_str(json_c_str); + grpc::string json_str(json_c_str); Message msg; - google::protobuf::util::JsonParseOptions parse_options; - // If the following line is failing, then uncomment the last line of the - // comment, and uncomment the lines that print the two strings. You can - // then compare the output, and determine what fields are missing. - // - // parse_options.ignore_unknown_fields = true; - EXPECT_EQ(google::protobuf::util::JsonStringToMessage(json_str, &msg, - parse_options), - google::protobuf::util::Status::OK); - std::string proto_json_str; - google::protobuf::util::JsonPrintOptions print_options; - // We usually do not want this to be true, however it can be helpful to - // uncomment and see the output produced then all fields are printed. - // print_options.always_print_primitive_fields = true; - EXPECT_EQ(google::protobuf::util::MessageToJsonString(msg, &proto_json_str, - print_options), - google::protobuf::util::Status::OK); - // uncomment these to compare the the json strings. - // gpr_log(GPR_ERROR, "tracer json: %s", json_str.c_str()); - // gpr_log(GPR_ERROR, "proto json: %s", proto_json_str.c_str()); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, &msg); + EXPECT_TRUE(s.ok()); + grpc::string proto_json_str; + s = grpc::protobuf::json::MessageToJsonString(msg, &proto_json_str); + EXPECT_TRUE(s.ok()); EXPECT_EQ(json_str, proto_json_str); } -} // namespace +namespace testing { void ValidateChannelTraceProtoJsonTranslation(char* json_c_str) { VaidateProtoJsonTranslation(json_c_str); From d68c0d29d968695431e77380a5d57d932a800358 Mon Sep 17 00:00:00 2001 From: Rohan Talip Date: Thu, 31 Jan 2019 11:32:08 -0800 Subject: [PATCH 241/814] Renamed the param in the documentation for HandleParameter to match the actual parameter. This should prevent warnings like the following: === BUILD TARGET FirebaseFirestore OF PROJECT Pods WITH CONFIGURATION Debug === In file included from $PROJECT_DIR/platforms/ios/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/stream.mm:17: In file included from $PROJECT_DIR/platforms/ios/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/stream.h:27: In file included from $PROJECT_DIR/platforms/ios/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_connection.h:28: In file included from $PROJECT_DIR/platforms/ios/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_stream.h:35: In file included from $PROJECT_DIR/platforms/ios/build/emulator/grpcpp.framework/Headers/generic/generic_stub.h:24: In file included from $PROJECT_DIR/platforms/ios/build/emulator/grpcpp.framework/Headers/support/async_stream.h:22: In file included from $PROJECT_DIR/platforms/ios/build/emulator/grpcpp.framework/Headers/impl/codegen/async_stream.h:26: In file included from $PROJECT_DIR/platforms/ios/build/emulator/grpcpp.framework/Headers/impl/codegen/service_type.h:24: $PROJECT_DIR/platforms/ios/build/emulator/grpcpp.framework/Headers/impl/codegen/rpc_service_method.h:49:16: warning: parameter 'rpc_requester' not found in the function declaration [-Wdocumentation] /// \param rpc_requester : used only by the callback API. It is a function ^~~~~~~~~~~~~ $PROJECT_DIR/platforms/ios/build/emulator/grpcpp.framework/Headers/impl/codegen/rpc_service_method.h:49:16: note: did you mean 'requester'? /// \param rpc_requester : used only by the callback API. It is a function ^~~~~~~~~~~~~ requester 1 warning generated. --- include/grpcpp/impl/codegen/rpc_service_method.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/rpc_service_method.h b/include/grpcpp/impl/codegen/rpc_service_method.h index f465c5fc2f9..56df61cdfae 100644 --- a/include/grpcpp/impl/codegen/rpc_service_method.h +++ b/include/grpcpp/impl/codegen/rpc_service_method.h @@ -46,7 +46,7 @@ class MethodHandler { /// \param context : the ServerContext structure for this server call /// \param req : the request payload, if appropriate for this RPC /// \param req_status : the request status after any interceptors have run - /// \param rpc_requester : used only by the callback API. It is a function + /// \param requester : used only by the callback API. It is a function /// called by the RPC Controller to request another RPC (and also /// to set up the state required to make that request possible) HandlerParameter(Call* c, ServerContext* context, void* req, From 632aa8125f8614a3ea68dec8d27d42cefcaf0237 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 1 Feb 2019 13:15:19 -0800 Subject: [PATCH 242/814] reintroduce anon namespace --- test/cpp/util/channel_trace_proto_helper.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/cpp/util/channel_trace_proto_helper.cc b/test/cpp/util/channel_trace_proto_helper.cc index da858b6bb7e..4cb1a5d0f44 100644 --- a/test/cpp/util/channel_trace_proto_helper.cc +++ b/test/cpp/util/channel_trace_proto_helper.cc @@ -29,6 +29,8 @@ #include "src/proto/grpc/channelz/channelz.pb.h" namespace grpc { + +namespace { // Generic helper that takes in a json string, converts it to a proto, and // then back to json. This ensures that the json string was correctly formatted @@ -46,6 +48,8 @@ void VaidateProtoJsonTranslation(char* json_c_str) { EXPECT_EQ(json_str, proto_json_str); } +} // namespace + namespace testing { void ValidateChannelTraceProtoJsonTranslation(char* json_c_str) { From fa74259769507e084795065627470f643acaaa34 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 1 Feb 2019 13:19:34 -0800 Subject: [PATCH 243/814] Reintroduce commented debugging tips --- test/cpp/util/channel_trace_proto_helper.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/cpp/util/channel_trace_proto_helper.cc b/test/cpp/util/channel_trace_proto_helper.cc index 4cb1a5d0f44..80d084f585b 100644 --- a/test/cpp/util/channel_trace_proto_helper.cc +++ b/test/cpp/util/channel_trace_proto_helper.cc @@ -29,7 +29,7 @@ #include "src/proto/grpc/channelz/channelz.pb.h" namespace grpc { - + namespace { // Generic helper that takes in a json string, converts it to a proto, and @@ -39,12 +39,25 @@ template void VaidateProtoJsonTranslation(char* json_c_str) { grpc::string json_str(json_c_str); Message msg; + grpc::protobuf::json::JsonParseOptions parse_options; + // If the following line is failing, then uncomment the last line of the + // comment, and uncomment the lines that print the two strings. You can + // then compare the output, and determine what fields are missing. + // + // parse_options.ignore_unknown_fields = true; grpc::protobuf::util::Status s = - grpc::protobuf::json::JsonStringToMessage(json_str, &msg); + grpc::protobuf::json::JsonStringToMessage(json_str, &msg, parse_options); EXPECT_TRUE(s.ok()); grpc::string proto_json_str; + grpc::protobuf::json::JsonPrintOptions print_options; + // We usually do not want this to be true, however it can be helpful to + // uncomment and see the output produced then all fields are printed. + // print_options.always_print_primitive_fields = true; s = grpc::protobuf::json::MessageToJsonString(msg, &proto_json_str); EXPECT_TRUE(s.ok()); + // uncomment these to compare the the json strings. + // gpr_log(GPR_ERROR, "tracer json: %s", json_str.c_str()); + // gpr_log(GPR_ERROR, "proto json: %s", proto_json_str.c_str()); EXPECT_EQ(json_str, proto_json_str); } From e56c832c0d538d7c21da7258fd7167fd4bfce7b3 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 1 Feb 2019 13:44:50 -0800 Subject: [PATCH 244/814] Replace list of outstanding callback requests with count only --- include/grpcpp/server.h | 26 ++++----- src/cpp/server/server_cc.cc | 104 +++++++++++++++--------------------- 2 files changed, 53 insertions(+), 77 deletions(-) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index df68cf31441..d1717ce87d2 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -248,22 +249,15 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { /// the \a sync_server_cqs) std::vector> sync_req_mgrs_; - // Outstanding callback requests. The vector is indexed by method with a list - // per method. Each element should store its own iterator in the list and - // should erase it when the request is actually bound to an RPC. Synchronize - // this list with its own mu_ (not the server mu_) since these must be active - // at Shutdown when the server mu_ is locked. - // TODO(vjpai): Merge with the core request matcher to avoid duplicate work - struct MethodReqList { - std::mutex reqs_mu; - // Maintain our own list size count since list::size is still linear - // for some libraries (supposed to be constant since C++11) - // TODO(vjpai): Remove reqs_list_sz and use list::size when possible - size_t reqs_list_sz{0}; - std::list reqs_list; - using iterator = decltype(reqs_list)::iterator; - }; - std::vector callback_reqs_; + // Outstanding unmatched callback requests, indexed by method. + // NOTE: Using a gpr_atm rather than atomic_int because atomic_int isn't + // copyable or movable and thus will cause compilation errors. We + // actually only want to extend the vector before the threaded use + // starts, but this is still a limitation. + std::vector callback_unmatched_reqs_count_; + + // List of callback requests to start when server actually starts + std::list callback_reqs_to_start_; // Server status std::mutex mu_; diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 1e642681467..cd747b3b430 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -350,10 +350,10 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { class Server::CallbackRequest final : public internal::CompletionQueueTag { public: - CallbackRequest(Server* server, Server::MethodReqList* list, + CallbackRequest(Server* server, size_t method_idx, internal::RpcServiceMethod* method, void* method_tag) : server_(server), - req_list_(list), + method_index_(method_idx), method_(method), method_tag_(method_tag), has_request_payload_( @@ -428,46 +428,31 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { GPR_ASSERT(!req_->FinalizeResult(&ignored, &new_ok)); GPR_ASSERT(ignored == req_); - bool spawn_new = false; - { - std::unique_lock l(req_->req_list_->reqs_mu); - req_->req_list_->reqs_list.erase(req_->req_list_iterator_); - req_->req_list_->reqs_list_sz--; - if (!ok) { - // The call has been shutdown. - // Delete its contents to free up the request. - // First release the lock in case the deletion of the request - // completes the full server shutdown and allows the destructor - // of the req_list to proceed. - l.unlock(); - delete req_; - return; - } - - // If this was the last request in the list or it is below the soft - // minimum and there are spare requests available, set up a new one, but - // do it outside the lock since the Request could otherwise deadlock - if (req_->req_list_->reqs_list_sz == 0 || - (req_->req_list_->reqs_list_sz < - SOFT_MINIMUM_SPARE_CALLBACK_REQS_PER_METHOD && - req_->server_->callback_reqs_outstanding_ < - SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING)) { - spawn_new = true; - } + auto count = + static_cast(gpr_atm_no_barrier_fetch_add( + &req_->server_ + ->callback_unmatched_reqs_count_[req_->method_index_], + static_cast(-1))) - + 1; + if (!ok) { + // The call has been shutdown. + // Delete its contents to free up the request. + delete req_; + return; } - if (spawn_new) { - auto* new_req = new CallbackRequest(req_->server_, req_->req_list_, + + // If this was the last request in the list or it is below the soft + // minimum and there are spare requests available, set up a new one. + if (count == 0 || (count < SOFT_MINIMUM_SPARE_CALLBACK_REQS_PER_METHOD && + count < SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING)) { + auto* new_req = new CallbackRequest(req_->server_, req_->method_index_, req_->method_, req_->method_tag_); if (!new_req->Request()) { - // The server must have just decided to shutdown. Erase - // from the list under lock but release the lock before - // deleting the new_req (in case that request was what - // would allow the destruction of the req_list) - { - std::lock_guard l(new_req->req_list_->reqs_mu); - new_req->req_list_->reqs_list.erase(new_req->req_list_iterator_); - new_req->req_list_->reqs_list_sz--; - } + // The server must have just decided to shutdown. + gpr_atm_no_barrier_fetch_add( + &new_req->server_ + ->callback_unmatched_reqs_count_[new_req->method_index_], + static_cast(-1)); delete new_req; } } @@ -557,20 +542,18 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { } void Setup() { + gpr_atm_no_barrier_fetch_add( + &server_->callback_unmatched_reqs_count_[method_index_], + static_cast(1)); grpc_metadata_array_init(&request_metadata_); ctx_.Setup(gpr_inf_future(GPR_CLOCK_REALTIME)); request_payload_ = nullptr; request_ = nullptr; request_status_ = Status(); - std::lock_guard l(req_list_->reqs_mu); - req_list_->reqs_list.push_front(this); - req_list_->reqs_list_sz++; - req_list_iterator_ = req_list_->reqs_list.begin(); } Server* const server_; - Server::MethodReqList* req_list_; - Server::MethodReqList::iterator req_list_iterator_; + size_t method_index_; internal::RpcServiceMethod* const method_; void* const method_tag_; const bool has_request_payload_; @@ -791,12 +774,11 @@ Server::~Server() { } grpc_server_destroy(server_); - for (auto* method_list : callback_reqs_) { - // The entries of the method_list should have already been emptied - // during Shutdown as each request is failed by Shutdown. Check that - // this actually happened. - GPR_ASSERT(method_list->reqs_list.empty()); - delete method_list; + for (auto per_method_count : callback_unmatched_reqs_count_) { + // There should be no more unmatched callbacks for any method + // as each request is failed by Shutdown. Check that this actually + // happened + GPR_ASSERT(static_cast(per_method_count) == 0); } } @@ -852,6 +834,7 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { } const char* method_name = nullptr; + for (auto it = service->methods_.begin(); it != service->methods_.end(); ++it) { if (it->get() == nullptr) { // Handled by generic service if any. @@ -877,15 +860,15 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { } } else { // a callback method. Register at least some callback requests - callback_reqs_.push_back(new Server::MethodReqList); - auto* method_req_list = callback_reqs_.back(); + callback_unmatched_reqs_count_.push_back(static_cast(0)); + auto method_index = callback_unmatched_reqs_count_.size() - 1; // TODO(vjpai): Register these dynamically based on need for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) { - new CallbackRequest(this, method_req_list, method, - method_registration_tag); + callback_reqs_to_start_.push_back(new CallbackRequest( + this, method_index, method, method_registration_tag)); } - // Enqueue it so that it will be Request'ed later once - // all request matchers are created at core server startup + // Enqueue it so that it will be Request'ed later after all request + // matchers are created at core server startup } method_name = method->name(); @@ -974,11 +957,10 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { (*it)->Start(); } - for (auto* cbmethods : callback_reqs_) { - for (auto* cbreq : cbmethods->reqs_list) { - GPR_ASSERT(cbreq->Request()); - } + for (auto* cbreq : callback_reqs_to_start_) { + GPR_ASSERT(cbreq->Request()); } + callback_reqs_to_start_.clear(); if (default_health_check_service_impl != nullptr) { default_health_check_service_impl->StartServingThread(); From 09cd07cfa066fc0925f5437cec172e1140898868 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Fri, 1 Feb 2019 14:13:19 -0800 Subject: [PATCH 245/814] revision 1 --- src/core/tsi/ssl_transport_security.cc | 3 +-- test/core/tsi/ssl_transport_security_test.cc | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 5ced404f39d..2107bcaa748 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -621,7 +621,7 @@ static tsi_result x509_store_load_certs(X509_STORE* cert_store, } ERR_clear_error(); if (!X509_STORE_add_cert(cert_store, root)) { - size_t error = ERR_get_error(); + unsigned long error = ERR_get_error(); if (ERR_GET_LIB(error) != ERR_LIB_X509 || ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) { gpr_log(GPR_ERROR, "Could not add root certificate to ssl context."); @@ -632,7 +632,6 @@ static tsi_result x509_store_load_certs(X509_STORE* cert_store, X509_free(root); num_roots++; } - if (num_roots == 0) { gpr_log(GPR_ERROR, "Could not load any root certificate."); result = TSI_INVALID_ARGUMENT; diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index bb69907527c..033618a2d42 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -777,7 +777,7 @@ void ssl_tsi_test_handshaker_factory_internals() { } void ssl_tsi_test_duplicate_root_certificates() { - const char* root_cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "ca.pem"); + char* root_cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "ca.pem"); char* dup_root_cert = static_cast( gpr_zalloc(sizeof(char) * (strlen(root_cert) * 2 + 1))); memcpy(dup_root_cert, root_cert, strlen(root_cert)); @@ -787,8 +787,8 @@ void ssl_tsi_test_duplicate_root_certificates() { GPR_ASSERT(root_store != nullptr); // Free memory. tsi_ssl_root_certs_store_destroy(root_store); - gpr_free((void*)root_cert); - gpr_free((void*)dup_root_cert); + gpr_free(root_cert); + gpr_free(dup_root_cert); } int main(int argc, char** argv) { From 3492539b32f84b60f122757777d4255a89507fb9 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 1 Feb 2019 15:46:32 -0500 Subject: [PATCH 246/814] Use full_fetch_add for ref counting the backup poller. There were spurious TSAN errors on PR #17823 because TSAN doesn't really understand how `g_uncovered_notifications_pending` works. It's odd in the sense that we destroy the backup poller, when the ref count reaches 1 (instead of 0 which is commonly used). Prior to PR #17823, TSAN doesn't complain because we (unnecessarily) always grab the pollset's lock, which TSAN understands. This commit uses full_fetch_add to explain the synchronization primitive to TSAN. --- src/core/lib/iomgr/tcp_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 792ffd27385..448e5f7b558 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -195,7 +195,7 @@ static void run_poller(void* bp, grpc_error* error_ignored) { static void drop_uncovered(grpc_tcp* tcp) { backup_poller* p = (backup_poller*)gpr_atm_acq_load(&g_backup_poller); gpr_atm old_count = - gpr_atm_no_barrier_fetch_add(&g_uncovered_notifications_pending, -1); + gpr_atm_full_fetch_add(&g_uncovered_notifications_pending, -1); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "BACKUP_POLLER:%p uncover cnt %d->%d", p, static_cast(old_count), static_cast(old_count) - 1); From 8521c0394bd950b97aef68d69cc16471aab1472f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 1 Feb 2019 15:21:13 -0800 Subject: [PATCH 247/814] Address optional reviewer comments --- include/grpcpp/server.h | 2 +- src/cpp/server/server_cc.cc | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index d1717ce87d2..885bd8de8d7 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -256,7 +256,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { // starts, but this is still a limitation. std::vector callback_unmatched_reqs_count_; - // List of callback requests to start when server actually starts + // List of callback requests to start when server actually starts. std::list callback_reqs_to_start_; // Server status diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index cd747b3b430..21f84de5c1e 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -428,11 +428,11 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { GPR_ASSERT(!req_->FinalizeResult(&ignored, &new_ok)); GPR_ASSERT(ignored == req_); - auto count = + int count = static_cast(gpr_atm_no_barrier_fetch_add( &req_->server_ ->callback_unmatched_reqs_count_[req_->method_index_], - static_cast(-1))) - + -1)) - 1; if (!ok) { // The call has been shutdown. @@ -452,7 +452,7 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { gpr_atm_no_barrier_fetch_add( &new_req->server_ ->callback_unmatched_reqs_count_[new_req->method_index_], - static_cast(-1)); + -1); delete new_req; } } @@ -543,8 +543,7 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { void Setup() { gpr_atm_no_barrier_fetch_add( - &server_->callback_unmatched_reqs_count_[method_index_], - static_cast(1)); + &server_->callback_unmatched_reqs_count_[method_index_], 1); grpc_metadata_array_init(&request_metadata_); ctx_.Setup(gpr_inf_future(GPR_CLOCK_REALTIME)); request_payload_ = nullptr; @@ -774,11 +773,12 @@ Server::~Server() { } grpc_server_destroy(server_); - for (auto per_method_count : callback_unmatched_reqs_count_) { + for (auto& per_method_count : callback_unmatched_reqs_count_) { // There should be no more unmatched callbacks for any method // as each request is failed by Shutdown. Check that this actually // happened - GPR_ASSERT(static_cast(per_method_count) == 0); + GPR_ASSERT(static_cast(gpr_atm_no_barrier_load(&per_method_count)) == + 0); } } @@ -860,7 +860,7 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { } } else { // a callback method. Register at least some callback requests - callback_unmatched_reqs_count_.push_back(static_cast(0)); + callback_unmatched_reqs_count_.push_back(0); auto method_index = callback_unmatched_reqs_count_.size() - 1; // TODO(vjpai): Register these dynamically based on need for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) { From fd185cd1ea07ac282c6ce6e4aed1536e94ce078f Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 31 Jan 2019 13:28:42 -0800 Subject: [PATCH 248/814] Disable c-ares on iOS --- include/grpc/impl/codegen/port_platform.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index aaeb23694e8..45371847c7a 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -189,6 +189,8 @@ #define GPR_PLATFORM_STRING "ios" #define GPR_CPU_IPHONE 1 #define GPR_PTHREAD_TLS 1 +/* the c-ares resolver isnt safe to enable on iOS */ +#define GRPC_ARES 0 #else /* TARGET_OS_IPHONE */ #define GPR_PLATFORM_STRING "osx" #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED From 82171553cfda63af93077de3e0d47223dfbc517f Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 1 Feb 2019 15:23:44 -0800 Subject: [PATCH 249/814] clang fmt --- test/cpp/util/channel_trace_proto_helper.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/util/channel_trace_proto_helper.cc b/test/cpp/util/channel_trace_proto_helper.cc index 80d084f585b..b473b7d7aa5 100644 --- a/test/cpp/util/channel_trace_proto_helper.cc +++ b/test/cpp/util/channel_trace_proto_helper.cc @@ -61,7 +61,7 @@ void VaidateProtoJsonTranslation(char* json_c_str) { EXPECT_EQ(json_str, proto_json_str); } -} // namespace +} // namespace namespace testing { From 28252eb0ddba424b49873d0e7f002eba4a05aecd Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 1 Feb 2019 15:32:34 -0800 Subject: [PATCH 250/814] force gc in test --- src/python/grpcio_tests/tests/unit/_abort_test.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/python/grpcio_tests/tests/unit/_abort_test.py b/src/python/grpcio_tests/tests/unit/_abort_test.py index 7acbf61031e..636f1379ad8 100644 --- a/src/python/grpcio_tests/tests/unit/_abort_test.py +++ b/src/python/grpcio_tests/tests/unit/_abort_test.py @@ -15,6 +15,7 @@ import unittest import collections +import gc import logging import weakref @@ -124,6 +125,8 @@ class AbortTest(unittest.TestCase): rpc_error = exception_context.exception do_not_leak_me = None + # Force garbage collection + gc.collect() self.assertIsNone(weak_ref()) def test_abort_with_status(self): From 6b19927bc4cfeffc617509681d1e5b9d097ac252 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Thu, 3 Jan 2019 13:27:20 -0800 Subject: [PATCH 251/814] Bad connection test --- CMakeLists.txt | 39 + Makefile | 36 + build.yaml | 15 + test/core/bad_connection/BUILD | 32 + test/core/bad_connection/close_fd_test.cc | 764 ++++++++++++++++++ .../generated/sources_and_headers.json | 16 + tools/run_tests/generated/tests.json | 24 + 7 files changed, 926 insertions(+) create mode 100644 test/core/bad_connection/BUILD create mode 100644 test/core/bad_connection/close_fd_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 9813eec7062..ad7911ce702 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,6 +257,9 @@ add_dependencies(buildtests_c channel_create_test) add_dependencies(buildtests_c chttp2_hpack_encoder_test) add_dependencies(buildtests_c chttp2_stream_map_test) add_dependencies(buildtests_c chttp2_varint_test) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_c close_fd_test) +endif() add_dependencies(buildtests_c cmdline_test) add_dependencies(buildtests_c combiner_test) add_dependencies(buildtests_c compression_test) @@ -6302,6 +6305,42 @@ target_link_libraries(chttp2_varint_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(close_fd_test + test/core/bad_connection/close_fd_test.cc +) + + +target_include_directories(close_fd_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(close_fd_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(close_fd_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(close_fd_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) add_executable(cmdline_test test/core/util/cmdline_test.cc diff --git a/Makefile b/Makefile index b9b7ab4c254..2eea2337e54 100644 --- a/Makefile +++ b/Makefile @@ -986,6 +986,7 @@ chttp2_hpack_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test chttp2_stream_map_test: $(BINDIR)/$(CONFIG)/chttp2_stream_map_test chttp2_varint_test: $(BINDIR)/$(CONFIG)/chttp2_varint_test client_fuzzer: $(BINDIR)/$(CONFIG)/client_fuzzer +close_fd_test: $(BINDIR)/$(CONFIG)/close_fd_test cmdline_test: $(BINDIR)/$(CONFIG)/cmdline_test combiner_test: $(BINDIR)/$(CONFIG)/combiner_test compression_test: $(BINDIR)/$(CONFIG)/compression_test @@ -1450,6 +1451,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test \ $(BINDIR)/$(CONFIG)/chttp2_stream_map_test \ $(BINDIR)/$(CONFIG)/chttp2_varint_test \ + $(BINDIR)/$(CONFIG)/close_fd_test \ $(BINDIR)/$(CONFIG)/cmdline_test \ $(BINDIR)/$(CONFIG)/combiner_test \ $(BINDIR)/$(CONFIG)/compression_test \ @@ -1988,6 +1990,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/chttp2_stream_map_test || ( echo test chttp2_stream_map_test failed ; exit 1 ) $(E) "[RUN] Testing chttp2_varint_test" $(Q) $(BINDIR)/$(CONFIG)/chttp2_varint_test || ( echo test chttp2_varint_test failed ; exit 1 ) + $(E) "[RUN] Testing close_fd_test" + $(Q) $(BINDIR)/$(CONFIG)/close_fd_test || ( echo test close_fd_test failed ; exit 1 ) $(E) "[RUN] Testing cmdline_test" $(Q) $(BINDIR)/$(CONFIG)/cmdline_test || ( echo test cmdline_test failed ; exit 1 ) $(E) "[RUN] Testing combiner_test" @@ -11123,6 +11127,38 @@ endif endif +CLOSE_FD_TEST_SRC = \ + test/core/bad_connection/close_fd_test.cc \ + +CLOSE_FD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CLOSE_FD_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/close_fd_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/close_fd_test: $(CLOSE_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(CLOSE_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/close_fd_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/bad_connection/close_fd_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_close_fd_test: $(CLOSE_FD_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(CLOSE_FD_TEST_OBJS:.o=.dep) +endif +endif + + CMDLINE_TEST_SRC = \ test/core/util/cmdline_test.cc \ diff --git a/build.yaml b/build.yaml index 0946e853d1b..f9085f3ee5b 100644 --- a/build.yaml +++ b/build.yaml @@ -2246,6 +2246,21 @@ targets: - test/core/end2end/fuzzers/client_fuzzer_corpus dict: test/core/end2end/fuzzers/hpack.dictionary maxlen: 2048 +- name: close_fd_test + build: test + language: c + src: + - test/core/bad_connection/close_fd_test.cc + deps: + - grpc_test_util + - grpc + - gpr + exclude_configs: + - tsan + platforms: + - mac + - linux + - posix - name: cmdline_test build: test language: c diff --git a/test/core/bad_connection/BUILD b/test/core/bad_connection/BUILD new file mode 100644 index 00000000000..8ada933e796 --- /dev/null +++ b/test/core/bad_connection/BUILD @@ -0,0 +1,32 @@ +# Copyright 2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_cc_binary", "grpc_package") + +licenses(["notice"]) # Apache v2 + +grpc_package(name = "test/core/bad_connection") + +grpc_cc_binary( + name = "close_fd_test", + srcs = [ + "close_fd_test.cc", + ], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/core/bad_connection/close_fd_test.cc b/test/core/bad_connection/close_fd_test.cc new file mode 100644 index 00000000000..317526a563a --- /dev/null +++ b/test/core/bad_connection/close_fd_test.cc @@ -0,0 +1,764 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * close_fd_test tests the behavior of grpc core when the transport gets + * disconnected. + * The test creates an http2 transport over a socket pair and closes the + * client or server file descriptor to simulate connection breakage while + * an RPC call is in progress. + * + */ +#include "src/core/lib/iomgr/port.h" + +// This test won't work except with posix sockets enabled +#ifdef GRPC_POSIX_SOCKET + +#include "test/core/util/test_config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/completion_queue.h" +#include "src/core/lib/surface/server.h" + +static void* tag(intptr_t t) { return (void*)t; } + +typedef struct test_ctx test_ctx; + +struct test_ctx { + /* completion queue for call notifications on the server */ + grpc_completion_queue* cq; + /* completion queue registered to server for shutdown events */ + grpc_completion_queue* shutdown_cq; + /* client's completion queue */ + grpc_completion_queue* client_cq; + /* completion queue bound to call on the server */ + grpc_completion_queue* bound_cq; + /* Server responds to client calls */ + grpc_server* server; + /* Client calls are sent over the channel */ + grpc_channel* client; + /* encapsulates client, server endpoints */ + grpc_endpoint_pair* ep; +}; + +static test_ctx g_ctx; + +/* chttp2 transport that is immediately available (used for testing + connected_channel without a client_channel */ + +static void server_setup_transport(grpc_transport* transport) { + grpc_core::ExecCtx exec_ctx; + grpc_endpoint_add_to_pollset(g_ctx.ep->server, grpc_cq_pollset(g_ctx.cq)); + grpc_server_setup_transport(g_ctx.server, transport, nullptr, + grpc_server_get_channel_args(g_ctx.server), + nullptr); +} + +static void client_setup_transport(grpc_transport* transport) { + grpc_core::ExecCtx exec_ctx; + grpc_endpoint_add_to_pollset(g_ctx.ep->client, + grpc_cq_pollset(g_ctx.client_cq)); + grpc_arg authority_arg = grpc_channel_arg_string_create( + const_cast(GRPC_ARG_DEFAULT_AUTHORITY), + const_cast("test-authority")); + grpc_channel_args* args = + grpc_channel_args_copy_and_add(nullptr, &authority_arg, 1); + /* TODO (pjaikumar): use GRPC_CLIENT_CHANNEL instead of + * GRPC_CLIENT_DIRECT_CHANNEL */ + g_ctx.client = grpc_channel_create("socketpair-target", args, + GRPC_CLIENT_DIRECT_CHANNEL, transport); + grpc_channel_args_destroy(args); +} + +static void init_client() { + grpc_core::ExecCtx exec_ctx; + grpc_transport* transport; + transport = grpc_create_chttp2_transport(nullptr, g_ctx.ep->client, true); + client_setup_transport(transport); + GPR_ASSERT(g_ctx.client); + grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); +} + +static void init_server() { + grpc_core::ExecCtx exec_ctx; + grpc_transport* transport; + GPR_ASSERT(!g_ctx.server); + g_ctx.server = grpc_server_create(nullptr, nullptr); + grpc_server_register_completion_queue(g_ctx.server, g_ctx.cq, nullptr); + grpc_server_start(g_ctx.server); + transport = grpc_create_chttp2_transport(nullptr, g_ctx.ep->server, false); + server_setup_transport(transport); + grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); +} + +static void test_init() { + grpc_endpoint_pair* sfd = + static_cast(gpr_malloc(sizeof(grpc_endpoint_pair))); + memset(&g_ctx, 0, sizeof(g_ctx)); + g_ctx.ep = sfd; + g_ctx.cq = grpc_completion_queue_create_for_next(nullptr); + g_ctx.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); + g_ctx.bound_cq = grpc_completion_queue_create_for_next(nullptr); + g_ctx.client_cq = grpc_completion_queue_create_for_next(nullptr); + + /* Create endpoints */ + *sfd = grpc_iomgr_create_endpoint_pair("fixture", nullptr); + /* Create client, server and setup transport over endpoint pair */ + init_server(); + init_client(); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event event; + do { + event = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(1), + nullptr); + } while (event.type != GRPC_QUEUE_SHUTDOWN); +} + +static void drain_and_destroy_cq(grpc_completion_queue* cq) { + grpc_completion_queue_shutdown(cq); + drain_cq(cq); + grpc_completion_queue_destroy(cq); +} + +static void shutdown_server() { + if (!g_ctx.server) return; + grpc_server_shutdown_and_notify(g_ctx.server, g_ctx.shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(g_ctx.shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(1), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(g_ctx.server); + g_ctx.server = nullptr; +} + +static void shutdown_client() { + if (!g_ctx.client) return; + grpc_channel_destroy(g_ctx.client); + g_ctx.client = nullptr; +} + +static void end_test() { + shutdown_server(); + shutdown_client(); + + drain_and_destroy_cq(g_ctx.cq); + drain_and_destroy_cq(g_ctx.client_cq); + drain_and_destroy_cq(g_ctx.bound_cq); + grpc_completion_queue_destroy(g_ctx.shutdown_cq); + gpr_free(g_ctx.ep); +} + +typedef enum fd_type { CLIENT_FD, SERVER_FD } fd_type; + +static const char* fd_type_str(fd_type fdtype) { + if (fdtype == CLIENT_FD) { + return "client"; + } else if (fdtype == SERVER_FD) { + return "server"; + } else { + gpr_log(GPR_ERROR, "Unexpected fd_type %d", fdtype); + abort(); + } +} + +static void _test_close_before_server_recv(fd_type fdtype) { + grpc_core::ExecCtx exec_ctx; + grpc_call* call; + grpc_call* server_call; + grpc_event event; + grpc_slice request_payload_slice = + grpc_slice_from_copied_string("hello world"); + grpc_slice response_payload_slice = + grpc_slice_from_copied_string("hello you"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + gpr_log(GPR_INFO, "Running test: test_close_%s_before_server_recv", + fd_type_str(fdtype)); + test_init(); + + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_call_details call_details; + grpc_status_code status = GRPC_STATUS__DO_NOT_USE; + grpc_call_error error; + grpc_slice details; + + gpr_timespec deadline = grpc_timeout_seconds_to_deadline(1); + call = grpc_channel_create_call( + g_ctx.client, nullptr, GRPC_PROPAGATE_DEFAULTS, g_ctx.client_cq, + grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr); + GPR_ASSERT(call); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(call, ops, static_cast(op - ops), + tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = grpc_server_request_call(g_ctx.server, &server_call, &call_details, + &request_metadata_recv, g_ctx.bound_cq, + g_ctx.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + event = grpc_completion_queue_next( + g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(101)); + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + + grpc_endpoint_pair* sfd = g_ctx.ep; + int fd; + if (fdtype == SERVER_FD) { + fd = sfd->server->vtable->get_fd(sfd->server); + } else { + GPR_ASSERT(fdtype == CLIENT_FD); + fd = sfd->client->vtable->get_fd(sfd->client); + } + /* Connection is closed before the server receives the client's message. */ + close(fd); + + error = grpc_call_start_batch(server_call, ops, static_cast(op - ops), + tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + event = grpc_completion_queue_next( + g_ctx.bound_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + + /* Batch operation completes on the server side. + * event.success will be true if the op completes successfully. + * event.success will be false if the op completes with an error. This can + * happen due to a race with closing the fd resulting in pending writes + * failing due to stream closure. + * */ + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + GPR_ASSERT(event.tag == tag(102)); + + event = grpc_completion_queue_next( + g_ctx.client_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + /* When the client fd is closed, the server gets EPIPE. + * When server fd is closed, server gets EBADF. + * In both cases server sends GRPC_STATUS_UNAVALABLE to the client. However, + * the client may not receive this grpc_status as it's socket is being closed. + * If the client didn't get grpc_status from the server it will time out + * waiting on the completion queue. So there 2 2 possibilities: + * 1. client times out waiting for server's response + * 2. client receives GRPC_STATUS_UNAVAILABLE from server + */ + if (event.type == GRPC_QUEUE_TIMEOUT) { + GPR_ASSERT(event.success == 0); + GPR_ASSERT(event.tag == nullptr); + /* status is not initialized */ + GPR_ASSERT(status == GRPC_STATUS__DO_NOT_USE); + } else { + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(1)); + GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); + } + + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_unref(call); + grpc_call_unref(server_call); + + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + end_test(); +} + +static void test_close_before_server_recv() { + /* Close client side of the connection before server receives message from + * client */ + _test_close_before_server_recv(CLIENT_FD); + /* Close server side of the connection before server receives message from + * client */ + _test_close_before_server_recv(SERVER_FD); +} + +static void _test_close_before_server_send(fd_type fdtype) { + grpc_core::ExecCtx exec_ctx; + grpc_call* call; + grpc_call* server_call; + grpc_event event; + grpc_slice request_payload_slice = + grpc_slice_from_copied_string("hello world"); + grpc_slice response_payload_slice = + grpc_slice_from_copied_string("hello you"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + gpr_log(GPR_INFO, "Running test: test_close_%s_before_server_send", + fd_type_str(fdtype)); + test_init(); + + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_call_details call_details; + grpc_status_code status = GRPC_STATUS__DO_NOT_USE; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + + gpr_timespec deadline = grpc_timeout_seconds_to_deadline(1); + call = grpc_channel_create_call( + g_ctx.client, nullptr, GRPC_PROPAGATE_DEFAULTS, g_ctx.client_cq, + grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr); + GPR_ASSERT(call); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(call, ops, static_cast(op - ops), + tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = grpc_server_request_call(g_ctx.server, &server_call, &call_details, + &request_metadata_recv, g_ctx.bound_cq, + g_ctx.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + event = grpc_completion_queue_next( + g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(101)); + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(server_call, ops, static_cast(op - ops), + tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + event = grpc_completion_queue_next( + g_ctx.bound_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(102)); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_OK; + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_details; + op->flags = 0; + op->reserved = nullptr; + op++; + + grpc_endpoint_pair* sfd = g_ctx.ep; + int fd; + if (fdtype == SERVER_FD) { + fd = sfd->server->vtable->get_fd(sfd->server); + } else { + GPR_ASSERT(fdtype == CLIENT_FD); + fd = sfd->client->vtable->get_fd(sfd->client); + } + + /* Connection is closed before the server sends message and status to the + * client. */ + close(fd); + error = grpc_call_start_batch(server_call, ops, static_cast(op - ops), + tag(103), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + /* Batch operation succeeds on the server side */ + event = grpc_completion_queue_next( + g_ctx.bound_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(103)); + + event = grpc_completion_queue_next( + g_ctx.client_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + /* In both cases server sends GRPC_STATUS_UNAVALABLE to the client. However, + * the client may not receive this grpc_status as it's socket is being closed. + * If the client didn't get grpc_status from the server it will time out + * waiting on the completion queue + */ + if (event.type == GRPC_OP_COMPLETE) { + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.tag == tag(1)); + GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); + } else { + GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(event.success == 0); + GPR_ASSERT(event.tag == nullptr); + /* status is not initialized */ + GPR_ASSERT(status == GRPC_STATUS__DO_NOT_USE); + } + GPR_ASSERT(was_cancelled == 0); + + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_unref(call); + grpc_call_unref(server_call); + + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + end_test(); +} + +static void test_close_before_server_send() { + /* Close client side of the connection before server sends message to client + * */ + _test_close_before_server_send(CLIENT_FD); + /* Close server side of the connection before server sends message to client + * */ + _test_close_before_server_send(SERVER_FD); +} + +static void _test_close_before_client_send(fd_type fdtype) { + grpc_core::ExecCtx exec_ctx; + grpc_call* call; + grpc_event event; + grpc_slice request_payload_slice = + grpc_slice_from_copied_string("hello world"); + grpc_slice response_payload_slice = + grpc_slice_from_copied_string("hello you"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer* response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + gpr_log(GPR_INFO, "Running test: test_close_%s_before_client_send", + fd_type_str(fdtype)); + test_init(); + + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + + gpr_timespec deadline = grpc_timeout_seconds_to_deadline(1); + call = grpc_channel_create_call( + g_ctx.client, nullptr, GRPC_PROPAGATE_DEFAULTS, g_ctx.client_cq, + grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr); + GPR_ASSERT(call); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->flags = 0; + op->reserved = nullptr; + op++; + + grpc_endpoint_pair* sfd = g_ctx.ep; + int fd; + if (fdtype == SERVER_FD) { + fd = sfd->server->vtable->get_fd(sfd->server); + } else { + GPR_ASSERT(fdtype == CLIENT_FD); + fd = sfd->client->vtable->get_fd(sfd->client); + } + /* Connection is closed before the client sends a batch to the server */ + close(fd); + + error = grpc_call_start_batch(call, ops, static_cast(op - ops), + tag(1), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + /* Status unavailable is returned to the client when client or server fd is + * closed */ + event = grpc_completion_queue_next( + g_ctx.client_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.success == 1); + GPR_ASSERT(event.type == GRPC_OP_COMPLETE); + GPR_ASSERT(event.tag == tag(1)); + GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); + + /* No event is received on the server */ + event = grpc_completion_queue_next( + g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.success == 0); + GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(event.tag == nullptr); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_unref(call); + + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + end_test(); +} +static void test_close_before_client_send() { + /* Close client side of the connection before client sends message to server + * */ + _test_close_before_client_send(CLIENT_FD); + /* Close server side of the connection before client sends message to server + * */ + _test_close_before_client_send(SERVER_FD); +} + +static void _test_close_before_call_create(fd_type fdtype) { + grpc_core::ExecCtx exec_ctx; + grpc_call* call; + grpc_event event; + test_init(); + + gpr_timespec deadline = grpc_timeout_milliseconds_to_deadline(100); + + grpc_endpoint_pair* sfd = g_ctx.ep; + int fd; + if (fdtype == SERVER_FD) { + fd = sfd->server->vtable->get_fd(sfd->server); + } else { + GPR_ASSERT(fdtype == CLIENT_FD); + fd = sfd->client->vtable->get_fd(sfd->client); + } + /* Connection is closed before the client creates a call */ + close(fd); + + call = grpc_channel_create_call( + g_ctx.client, nullptr, GRPC_PROPAGATE_DEFAULTS, g_ctx.client_cq, + grpc_slice_from_static_string("/foo"), nullptr, deadline, nullptr); + GPR_ASSERT(call); + + /* Client and server time out waiting on their completion queues and nothing + * is sent or received */ + event = grpc_completion_queue_next( + g_ctx.client_cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(event.success == 0); + GPR_ASSERT(event.tag == nullptr); + + event = grpc_completion_queue_next( + g_ctx.cq, grpc_timeout_milliseconds_to_deadline(100), nullptr); + GPR_ASSERT(event.type == GRPC_QUEUE_TIMEOUT); + GPR_ASSERT(event.success == 0); + GPR_ASSERT(event.tag == nullptr); + + grpc_call_unref(call); + end_test(); +} + +static void test_close_before_call_create() { + /* Close client side of the connection before client creates a call */ + _test_close_before_call_create(CLIENT_FD); + /* Close server side of the connection before client creates a call */ + _test_close_before_call_create(SERVER_FD); +} + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + /* Init grpc */ + grpc_init(); + int iterations = 10; + + for (int i = 0; i < iterations; ++i) { + test_close_before_call_create(); + test_close_before_client_send(); + test_close_before_server_recv(); + test_close_before_server_send(); + } + + grpc_shutdown(); + + return 0; +} + +#else /* GRPC_POSIX_SOCKET */ + +int main(int argc, char** argv) { return 1; } + +#endif /* GRPC_POSIX_SOCKET */ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 9e07c548b69..506b64c19fc 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -271,6 +271,22 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "close_fd_test", + "src": [ + "test/core/bad_connection/close_fd_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index b41fef6b795..9a1ff126a29 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -311,6 +311,30 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [ + "tsan" + ], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "close_fd_test", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From c0125a7cd4eda6cb7cf9e35733c6671cb8addc53 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Fri, 1 Feb 2019 16:58:21 -0800 Subject: [PATCH 252/814] Unskip google default creds for Go and Java in cloud to prod tests --- tools/run_tests/run_interop_tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 603977545ce..11bd959052e 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -229,7 +229,7 @@ class JavaLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_GOOGLE_DEFAULT_CREDS + return [] def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -254,7 +254,7 @@ class JavaOkHttpClient: return {} def unimplemented_test_cases(self): - return _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS + return _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE def __str__(self): return 'javaokhttp' @@ -285,7 +285,7 @@ class GoLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_GOOGLE_DEFAULT_CREDS + return _SKIP_COMPRESSION def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION From 95fe85f090a2c3a26156ce1c1f96368abb9494db Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 1 Feb 2019 23:32:37 -0800 Subject: [PATCH 253/814] Revert "Fix for 17338. Delay shutdown of buffer list till tcp_free to avoid races" --- src/core/lib/iomgr/tcp_posix.cc | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 61db36bd99e..448e5f7b558 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -343,13 +343,6 @@ static void tcp_free(grpc_tcp* tcp) { grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); gpr_free(tcp->peer_string); - /* The lock is not really necessary here, since all refs have been released */ - gpr_mu_lock(&tcp->tb_mu); - grpc_core::TracedBuffer::Shutdown( - &tcp->tb_head, tcp->outgoing_buffer_arg, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed")); - gpr_mu_unlock(&tcp->tb_mu); - tcp->outgoing_buffer_arg = nullptr; gpr_mu_destroy(&tcp->tb_mu); gpr_free(tcp); } @@ -396,6 +389,12 @@ static void tcp_destroy(grpc_endpoint* ep) { grpc_tcp* tcp = reinterpret_cast(ep); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { + gpr_mu_lock(&tcp->tb_mu); + grpc_core::TracedBuffer::Shutdown( + &tcp->tb_head, tcp->outgoing_buffer_arg, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed")); + gpr_mu_unlock(&tcp->tb_mu); + tcp->outgoing_buffer_arg = nullptr; gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); grpc_fd_set_error(tcp->em_fd); } @@ -1185,6 +1184,12 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { /* Stop errors notification. */ + gpr_mu_lock(&tcp->tb_mu); + grpc_core::TracedBuffer::Shutdown( + &tcp->tb_head, tcp->outgoing_buffer_arg, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed")); + gpr_mu_unlock(&tcp->tb_mu); + tcp->outgoing_buffer_arg = nullptr; gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); grpc_fd_set_error(tcp->em_fd); } From 92d37b1273bff03156803f8431903461c799983c Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Sat, 2 Feb 2019 09:14:05 -0800 Subject: [PATCH 254/814] SOFT_MAXIMUM is supposed to be per-server, not per-method --- src/cpp/server/server_cc.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 21f84de5c1e..05f78dbe6fe 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -444,7 +444,8 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { // If this was the last request in the list or it is below the soft // minimum and there are spare requests available, set up a new one. if (count == 0 || (count < SOFT_MINIMUM_SPARE_CALLBACK_REQS_PER_METHOD && - count < SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING)) { + req_->server_->callback_reqs_outstanding_ < + SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING)) { auto* new_req = new CallbackRequest(req_->server_, req_->method_index_, req_->method_, req_->method_tag_); if (!new_req->Request()) { From f37e18b8fd1728c8bfadfd139e324438e964a981 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Sat, 2 Feb 2019 10:09:36 -0800 Subject: [PATCH 255/814] Dummy Shutdown should still unref the error --- src/core/lib/iomgr/buffer_list.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 215ab03a563..3dba15312d6 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -148,7 +148,9 @@ class TracedBuffer { public: /* Dummy shutdown function */ static void Shutdown(grpc_core::TracedBuffer** head, void* remaining, - grpc_error* shutdown_err) {} + grpc_error* shutdown_err) { + GRPC_ERROR_UNREF(shutdown_err); + } }; #endif /* GRPC_LINUX_ERRQUEUE */ From e83e463b5a14cf0de5d8c9e1197d06f925160111 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sat, 26 Jan 2019 16:23:30 -0500 Subject: [PATCH 256/814] Track the pollsets of an FD in PO_MULTI mode for pollex. Each pollset in pollex has a lock, grabbed upon adding an FD to the pollset. Since this is called on a per-call basis, there is a flat array caching the FDs of the pollset, to avoid unnecessarily calling epoll_ctl multiple times for the same FD. This has two problems: 1) When multiple threads add FDs to the same pollset, we will have contention on the pollset lock. 2) When we have many FDs we simply run out of cache storage, and call epoll_ctl(). This commit changes the caching strategy by simply storing the pollsets of an FD inside that FD, when we are in PO_MULTI mode. This results in address in both (1) and (2). Moreover, this commit fixes another performance bug. When we have a release FD callback, we do not call close(). That FD will remain in our epollset, until the new owner of the FD actually call close(). This results in a lot of spurious wake ups when we simply hand off gRPC FDs to other FDs. --- src/core/lib/iomgr/ev_epollex_linux.cc | 300 ++++++++++++------------- 1 file changed, 138 insertions(+), 162 deletions(-) diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 0a0891013af..d6947d00e84 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -45,6 +45,7 @@ #include "src/core/lib/gpr/spinlock.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/iomgr/block_annotate.h" @@ -78,18 +79,6 @@ typedef enum { PO_MULTI, PO_FD, PO_EMPTY } pollable_type; typedef struct pollable pollable; -typedef struct cached_fd { - // Set to the grpc_fd's salt value. See 'salt' variable' in grpc_fd for more - // details - intptr_t salt; - - // The underlying fd - int fd; - - // A recency time counter that helps to determine the LRU fd in the cache - uint64_t last_used; -} cached_fd; - /// A pollable is something that can be polled: it has an epoll set to poll on, /// and a wakeup fd for kicks /// There are three broad types: @@ -120,33 +109,6 @@ struct pollable { int event_cursor; int event_count; struct epoll_event events[MAX_EPOLL_EVENTS]; - - // We may be calling pollable_add_fd() on the same (pollable, fd) multiple - // times. To prevent pollable_add_fd() from making multiple sys calls to - // epoll_ctl() to add the fd, we maintain a cache of what fds are already - // present in the underlying epoll-set. - // - // Since this is not a correctness issue, we do not need to maintain all the - // fds in the cache. Hence we just use an LRU cache of size 'MAX_FDS_IN_CACHE' - // - // NOTE: An ideal implementation of this should do the following: - // 1) Add fds to the cache in pollable_add_fd() function (i.e whenever the fd - // is added to the pollable's epoll set) - // 2) Remove the fd from the cache whenever the fd is removed from the - // underlying epoll set (i.e whenever fd_orphan() is called). - // - // Implementing (2) above (i.e removing fds from cache on fd_orphan) adds a - // lot of complexity since an fd can be present in multiple pollables. So our - // implementation ONLY DOES (1) and NOT (2). - // - // The cache_fd.salt variable helps here to maintain correctness (it serves as - // an epoch that differentiates one grpc_fd from the other even though both of - // them may have the same fd number) - // - // The following implements LRU-eviction cache of fds in this pollable - cached_fd fd_cache[MAX_FDS_IN_CACHE]; - int fd_cache_size; - uint64_t fd_cache_counter; // Recency timer tick counter }; static const char* pollable_type_string(pollable_type t) { @@ -189,37 +151,86 @@ static void pollable_unref(pollable* p, int line, const char* reason); * Fd Declarations */ -// Monotonically increasing Epoch counter that is assinged to each grpc_fd. See -// the description of 'salt' variable in 'grpc_fd' for more details -// TODO: (sreek/kpayson) gpr_atm is intptr_t which may not be wide-enough on -// 32-bit systems. Change this to int_64 - atleast on 32-bit systems -static gpr_atm g_fd_salt; - struct grpc_fd { - int fd; + grpc_fd(int fd, const char* name, bool track_err) + : fd(fd), track_err(track_err) { + gpr_mu_init(&orphan_mu); + gpr_mu_init(&pollable_mu); + read_closure.InitEvent(); + write_closure.InitEvent(); + error_closure.InitEvent(); - // Since fd numbers can be reused (after old fds are closed), this serves as - // an epoch that uniquely identifies this fd (i.e the pair (salt, fd) is - // unique (until the salt counter (i.e g_fd_salt) overflows) - intptr_t salt; + char* fd_name; + gpr_asprintf(&fd_name, "%s fd=%d", name, fd); + grpc_iomgr_register_object(&iomgr_object, fd_name); +#ifndef NDEBUG + if (grpc_trace_fd_refcount.enabled()) { + gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, this, fd_name); + } +#endif + gpr_free(fd_name); + } + + // This is really the dtor, but the poller threads waking up from + // epoll_wait() may access the (read|write|error)_closure after destruction. + // Since the object will be added to the free pool, this behavior is + // not going to cause issues, except spurious events if the FD is reused + // while the race happens. + void destroy() { + grpc_iomgr_unregister_object(&iomgr_object); + + POLLABLE_UNREF(pollable_obj, "fd_pollable"); + pollsets.clear(); + gpr_mu_destroy(&pollable_mu); + gpr_mu_destroy(&orphan_mu); + + read_closure.DestroyEvent(); + write_closure.DestroyEvent(); + error_closure.DestroyEvent(); + + invalidate(); + } + +#ifndef NDEBUG + /* Since an fd is never really destroyed (i.e gpr_free() is not called), it is + * hard-to-debug cases where fd fields are accessed even after calling + * fd_destroy(). The following invalidates fd fields to make catching such + * errors easier */ + void invalidate() { + fd = -1; + gpr_atm_no_barrier_store(&refst, -1); + memset(&orphan_mu, -1, sizeof(orphan_mu)); + memset(&pollable_mu, -1, sizeof(pollable_mu)); + pollable_obj = nullptr; + on_done_closure = nullptr; + memset(&iomgr_object, -1, sizeof(iomgr_object)); + track_err = false; + } +#else + void invalidate() {} +#endif + + int fd; // refst format: // bit 0 : 1=Active / 0=Orphaned // bits 1-n : refcount // Ref/Unref by two to avoid altering the orphaned bit - gpr_atm refst; + gpr_atm refst = 1; gpr_mu orphan_mu; + // Protects pollable_obj and pollsets. gpr_mu pollable_mu; - pollable* pollable_obj; + grpc_core::InlinedVector pollsets; // Used in PO_MULTI. + pollable* pollable_obj = nullptr; // Used in PO_FD. - grpc_core::ManualConstructor read_closure; - grpc_core::ManualConstructor write_closure; - grpc_core::ManualConstructor error_closure; + grpc_core::LockfreeEvent read_closure; + grpc_core::LockfreeEvent write_closure; + grpc_core::LockfreeEvent error_closure; - struct grpc_fd* freelist_next; - grpc_closure* on_done_closure; + struct grpc_fd* freelist_next = nullptr; + grpc_closure* on_done_closure = nullptr; grpc_iomgr_object iomgr_object; @@ -258,6 +269,7 @@ struct grpc_pollset_worker { struct grpc_pollset { gpr_mu mu; gpr_atm worker_count; + gpr_atm active_pollable_type; pollable* active_pollable; bool kicked_without_poller; grpc_closure* shutdown_closure; @@ -337,39 +349,10 @@ static void ref_by(grpc_fd* fd, int n) { GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0); } -#ifndef NDEBUG -#define INVALIDATE_FD(fd) invalidate_fd(fd) -/* Since an fd is never really destroyed (i.e gpr_free() is not called), it is - * hard to cases where fd fields are accessed even after calling fd_destroy(). - * The following invalidates fd fields to make catching such errors easier */ -static void invalidate_fd(grpc_fd* fd) { - fd->fd = -1; - fd->salt = -1; - gpr_atm_no_barrier_store(&fd->refst, -1); - memset(&fd->orphan_mu, -1, sizeof(fd->orphan_mu)); - memset(&fd->pollable_mu, -1, sizeof(fd->pollable_mu)); - fd->pollable_obj = nullptr; - fd->on_done_closure = nullptr; - memset(&fd->iomgr_object, -1, sizeof(fd->iomgr_object)); - fd->track_err = false; -} -#else -#define INVALIDATE_FD(fd) -#endif - /* Uninitialize and add to the freelist */ static void fd_destroy(void* arg, grpc_error* error) { grpc_fd* fd = static_cast(arg); - grpc_iomgr_unregister_object(&fd->iomgr_object); - POLLABLE_UNREF(fd->pollable_obj, "fd_pollable"); - gpr_mu_destroy(&fd->pollable_mu); - gpr_mu_destroy(&fd->orphan_mu); - - fd->read_closure->DestroyEvent(); - fd->write_closure->DestroyEvent(); - fd->error_closure->DestroyEvent(); - - INVALIDATE_FD(fd); + fd->destroy(); /* Add the fd to the freelist */ gpr_mu_lock(&fd_freelist_mu); @@ -429,35 +412,9 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) { if (new_fd == nullptr) { new_fd = static_cast(gpr_malloc(sizeof(grpc_fd))); - new_fd->read_closure.Init(); - new_fd->write_closure.Init(); - new_fd->error_closure.Init(); } - new_fd->fd = fd; - new_fd->salt = gpr_atm_no_barrier_fetch_add(&g_fd_salt, 1); - gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1); - gpr_mu_init(&new_fd->orphan_mu); - gpr_mu_init(&new_fd->pollable_mu); - new_fd->pollable_obj = nullptr; - new_fd->read_closure->InitEvent(); - new_fd->write_closure->InitEvent(); - new_fd->error_closure->InitEvent(); - new_fd->freelist_next = nullptr; - new_fd->on_done_closure = nullptr; - - char* fd_name; - gpr_asprintf(&fd_name, "%s fd=%d", name, fd); - grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name); -#ifndef NDEBUG - if (grpc_trace_fd_refcount.enabled()) { - gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, new_fd, fd_name); - } -#endif - gpr_free(fd_name); - - new_fd->track_err = track_err; - return new_fd; + return new (new_fd) grpc_fd(fd, name, track_err); } static int fd_wrapped_fd(grpc_fd* fd) { @@ -465,6 +422,7 @@ static int fd_wrapped_fd(grpc_fd* fd) { return (gpr_atm_acq_load(&fd->refst) & 1) ? ret_fd : -1; } +static int pollset_epoll_fd_locked(grpc_pollset* pollset); static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, const char* reason) { bool is_fd_closed = false; @@ -475,7 +433,6 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, // true so that the pollable will no longer access its owner_fd field. gpr_mu_lock(&fd->pollable_mu); pollable* pollable_obj = fd->pollable_obj; - gpr_mu_unlock(&fd->pollable_mu); if (pollable_obj) { gpr_mu_lock(&pollable_obj->owner_orphan_mu); @@ -487,6 +444,20 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, /* If release_fd is not NULL, we should be relinquishing control of the file descriptor fd->fd (but we still own the grpc_fd structure). */ if (release_fd != nullptr) { + // Remove the FD from all epolls sets, before releasing it. + // Otherwise, we will receive epoll events after we release the FD. + epoll_event ev_fd; + memset(&ev_fd, 0, sizeof(ev_fd)); + if (release_fd != nullptr) { + if (pollable_obj != nullptr) { // For PO_FD. + epoll_ctl(pollable_obj->epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); + } + for (size_t i = 0; i < fd->pollsets.size(); ++i) { // For PO_MULTI. + grpc_pollset* pollset = fd->pollsets[i]; + const int epfd = pollset_epoll_fd_locked(pollset); + epoll_ctl(epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); + } + } *release_fd = fd->fd; } else { close(fd->fd); @@ -508,40 +479,56 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, gpr_mu_unlock(&pollable_obj->owner_orphan_mu); } + gpr_mu_unlock(&fd->pollable_mu); gpr_mu_unlock(&fd->orphan_mu); UNREF_BY(fd, 2, reason); /* Drop the reference */ } static bool fd_is_shutdown(grpc_fd* fd) { - return fd->read_closure->IsShutdown(); + return fd->read_closure.IsShutdown(); } /* Might be called multiple times */ static void fd_shutdown(grpc_fd* fd, grpc_error* why) { - if (fd->read_closure->SetShutdown(GRPC_ERROR_REF(why))) { + if (fd->read_closure.SetShutdown(GRPC_ERROR_REF(why))) { if (shutdown(fd->fd, SHUT_RDWR)) { if (errno != ENOTCONN) { gpr_log(GPR_ERROR, "Error shutting down fd %d. errno: %d", grpc_fd_wrapped_fd(fd), errno); } } - fd->write_closure->SetShutdown(GRPC_ERROR_REF(why)); - fd->error_closure->SetShutdown(GRPC_ERROR_REF(why)); + fd->write_closure.SetShutdown(GRPC_ERROR_REF(why)); + fd->error_closure.SetShutdown(GRPC_ERROR_REF(why)); } GRPC_ERROR_UNREF(why); } static void fd_notify_on_read(grpc_fd* fd, grpc_closure* closure) { - fd->read_closure->NotifyOn(closure); + fd->read_closure.NotifyOn(closure); } static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { - fd->write_closure->NotifyOn(closure); + fd->write_closure.NotifyOn(closure); } static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - fd->error_closure->NotifyOn(closure); + fd->error_closure.NotifyOn(closure); +} + +static bool fd_has_pollset(grpc_fd* fd, grpc_pollset* pollset) { + grpc_core::MutexLock lock(&fd->pollable_mu); + for (size_t i = 0; i < fd->pollsets.size(); ++i) { + if (fd->pollsets[i] == pollset) { + return true; + } + } + return false; +} + +static void fd_add_pollset(grpc_fd* fd, grpc_pollset* pollset) { + grpc_core::MutexLock lock(&fd->pollable_mu); + fd->pollsets.push_back(pollset); } /******************************************************************************* @@ -594,8 +581,6 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) { (*p)->root_worker = nullptr; (*p)->event_cursor = 0; (*p)->event_count = 0; - (*p)->fd_cache_size = 0; - (*p)->fd_cache_counter = 0; return GRPC_ERROR_NONE; } @@ -637,39 +622,6 @@ static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) { grpc_error* error = GRPC_ERROR_NONE; static const char* err_desc = "pollable_add_fd"; const int epfd = p->epfd; - gpr_mu_lock(&p->mu); - p->fd_cache_counter++; - - // Handle the case of overflow for our cache counter by - // reseting the recency-counter on all cache objects - if (p->fd_cache_counter == 0) { - for (int i = 0; i < p->fd_cache_size; i++) { - p->fd_cache[i].last_used = 0; - } - } - - int lru_idx = 0; - for (int i = 0; i < p->fd_cache_size; i++) { - if (p->fd_cache[i].fd == fd->fd && p->fd_cache[i].salt == fd->salt) { - GRPC_STATS_INC_POLLSET_FD_CACHE_HITS(); - p->fd_cache[i].last_used = p->fd_cache_counter; - gpr_mu_unlock(&p->mu); - return GRPC_ERROR_NONE; - } else if (p->fd_cache[i].last_used < p->fd_cache[lru_idx].last_used) { - lru_idx = i; - } - } - - // Add to cache - if (p->fd_cache_size < MAX_FDS_IN_CACHE) { - lru_idx = p->fd_cache_size; - p->fd_cache_size++; - } - p->fd_cache[lru_idx].fd = fd->fd; - p->fd_cache[lru_idx].salt = fd->salt; - p->fd_cache[lru_idx].last_used = p->fd_cache_counter; - gpr_mu_unlock(&p->mu); - if (grpc_polling_trace.enabled()) { gpr_log(GPR_INFO, "add fd %p (%d) to pollable %p", fd, fd->fd, p); } @@ -849,6 +801,7 @@ static grpc_error* pollset_kick_all(grpc_pollset* pollset) { static void pollset_init(grpc_pollset* pollset, gpr_mu** mu) { gpr_mu_init(&pollset->mu); gpr_atm_no_barrier_store(&pollset->worker_count, 0); + gpr_atm_no_barrier_store(&pollset->active_pollable_type, PO_EMPTY); pollset->active_pollable = POLLABLE_REF(g_empty_pollable, "pollset"); pollset->kicked_without_poller = false; pollset->shutdown_closure = nullptr; @@ -869,11 +822,11 @@ static int poll_deadline_to_millis_timeout(grpc_millis millis) { return static_cast(delta); } -static void fd_become_readable(grpc_fd* fd) { fd->read_closure->SetReady(); } +static void fd_become_readable(grpc_fd* fd) { fd->read_closure.SetReady(); } -static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); } +static void fd_become_writable(grpc_fd* fd) { fd->write_closure.SetReady(); } -static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); } +static void fd_has_errors(grpc_fd* fd) { fd->error_closure.SetReady(); } /* Get the pollable_obj attached to this fd. If none is attached, create a new * pollable object (of type PO_FD), attach it to the fd and return it @@ -1283,6 +1236,8 @@ static grpc_error* pollset_add_fd_locked(grpc_pollset* pollset, grpc_fd* fd) { POLLABLE_UNREF(pollset->active_pollable, "pollset"); pollset->active_pollable = po_at_start; } else { + gpr_atm_rel_store(&pollset->active_pollable_type, + pollset->active_pollable->type); POLLABLE_UNREF(po_at_start, "pollset_add_fd"); } return error; @@ -1329,17 +1284,38 @@ static grpc_error* pollset_as_multipollable_locked(grpc_pollset* pollset, pollset->active_pollable = po_at_start; *pollable_obj = nullptr; } else { + gpr_atm_rel_store(&pollset->active_pollable_type, + pollset->active_pollable->type); *pollable_obj = POLLABLE_REF(pollset->active_pollable, "pollset_set"); POLLABLE_UNREF(po_at_start, "pollset_as_multipollable"); } return error; } +// Caller must hold the lock for `pollset->mu`. +static int pollset_epoll_fd_locked(grpc_pollset* pollset) { + return pollset->active_pollable->epfd; +} + static void pollset_add_fd(grpc_pollset* pollset, grpc_fd* fd) { GPR_TIMER_SCOPE("pollset_add_fd", 0); - gpr_mu_lock(&pollset->mu); + + // We never transition from PO_MULTI to other modes (i.e., PO_FD or PO_EMOPTY) + // and, thus, it is safe to simply store and check whether the FD has already + // been added to the active pollable previously. + if (gpr_atm_acq_load(&pollset->active_pollable_type) == PO_MULTI && + fd_has_pollset(fd, pollset)) { + return; + } + + grpc_core::MutexLock lock(&pollset->mu); grpc_error* error = pollset_add_fd_locked(pollset, fd); - gpr_mu_unlock(&pollset->mu); + + // If we are in PO_MULTI mode, we should update the pollsets of the FD. + if (gpr_atm_no_barrier_load(&pollset->active_pollable_type) == PO_MULTI) { + fd_add_pollset(fd, pollset); + } + GRPC_LOG_IF_ERROR("pollset_add_fd", error); } From cc19a553386064c8436915f9b4fbbf9711f1803a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 4 Feb 2019 07:50:29 -0800 Subject: [PATCH 257/814] Revert "Revert "Fix for 17338. Delay shutdown of buffer list till tcp_free to avoid races"" --- src/core/lib/iomgr/tcp_posix.cc | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 448e5f7b558..61db36bd99e 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -343,6 +343,13 @@ static void tcp_free(grpc_tcp* tcp) { grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); gpr_free(tcp->peer_string); + /* The lock is not really necessary here, since all refs have been released */ + gpr_mu_lock(&tcp->tb_mu); + grpc_core::TracedBuffer::Shutdown( + &tcp->tb_head, tcp->outgoing_buffer_arg, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed")); + gpr_mu_unlock(&tcp->tb_mu); + tcp->outgoing_buffer_arg = nullptr; gpr_mu_destroy(&tcp->tb_mu); gpr_free(tcp); } @@ -389,12 +396,6 @@ static void tcp_destroy(grpc_endpoint* ep) { grpc_tcp* tcp = reinterpret_cast(ep); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { - gpr_mu_lock(&tcp->tb_mu); - grpc_core::TracedBuffer::Shutdown( - &tcp->tb_head, tcp->outgoing_buffer_arg, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed")); - gpr_mu_unlock(&tcp->tb_mu); - tcp->outgoing_buffer_arg = nullptr; gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); grpc_fd_set_error(tcp->em_fd); } @@ -1184,12 +1185,6 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { /* Stop errors notification. */ - gpr_mu_lock(&tcp->tb_mu); - grpc_core::TracedBuffer::Shutdown( - &tcp->tb_head, tcp->outgoing_buffer_arg, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed")); - gpr_mu_unlock(&tcp->tb_mu); - tcp->outgoing_buffer_arg = nullptr; gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); grpc_fd_set_error(tcp->em_fd); } From b23abe832ca53f0e0aa1259c73a33385f36cd39d Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 4 Feb 2019 11:40:53 -0800 Subject: [PATCH 258/814] GPR_ARRAY_SIZE is meant for arrays --- test/core/iomgr/timer_heap_test.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/core/iomgr/timer_heap_test.cc b/test/core/iomgr/timer_heap_test.cc index 872cf17486f..b574e0a680e 100644 --- a/test/core/iomgr/timer_heap_test.cc +++ b/test/core/iomgr/timer_heap_test.cc @@ -164,13 +164,13 @@ static void test2(void) { size_t num_inserted = 0; grpc_timer_heap_init(&pq); - memset(elems, 0, elems_size); + memset(elems, 0, elems_size * sizeof(elems[0])); for (size_t round = 0; round < 10000; round++) { int r = rand() % 1000; if (r <= 550) { /* 55% of the time we try to add something */ - elem_struct* el = search_elems(elems, GPR_ARRAY_SIZE(elems), false); + elem_struct* el = search_elems(elems, elems_size, false); if (el != nullptr) { el->elem.deadline = random_deadline(); grpc_timer_heap_add(&pq, &el->elem); @@ -180,7 +180,7 @@ static void test2(void) { } } else if (r <= 650) { /* 10% of the time we try to remove something */ - elem_struct* el = search_elems(elems, GPR_ARRAY_SIZE(elems), true); + elem_struct* el = search_elems(elems, elems_size, true); if (el != nullptr) { grpc_timer_heap_remove(&pq, &el->elem); el->inserted = false; From d6ca2c9c9546c2b562a777bc8c26bdd30284c7d6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 5 Feb 2019 16:52:31 +0100 Subject: [PATCH 259/814] v4 kokoro perf image changes --- .../gce/create_linux_kokoro_performance_worker_from_image.sh | 2 +- tools/gce/linux_kokoro_performance_worker_init.sh | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/gce/create_linux_kokoro_performance_worker_from_image.sh b/tools/gce/create_linux_kokoro_performance_worker_from_image.sh index 28c49a66f24..903166122eb 100755 --- a/tools/gce/create_linux_kokoro_performance_worker_from_image.sh +++ b/tools/gce/create_linux_kokoro_performance_worker_from_image.sh @@ -22,7 +22,7 @@ cd "$(dirname "$0")" CLOUD_PROJECT=grpc-testing ZONE=us-central1-b # this zone allows 32core machines -LATEST_PERF_WORKER_IMAGE=grpc-performance-kokoro-v3 # update if newer image exists +LATEST_PERF_WORKER_IMAGE=grpc-performance-kokoro-v4 # update if newer image exists INSTANCE_NAME="${1:-grpc-kokoro-performance-server}" MACHINE_TYPE="${2:-n1-standard-32}" diff --git a/tools/gce/linux_kokoro_performance_worker_init.sh b/tools/gce/linux_kokoro_performance_worker_init.sh index d67ff58506f..1bf2228279e 100755 --- a/tools/gce/linux_kokoro_performance_worker_init.sh +++ b/tools/gce/linux_kokoro_performance_worker_init.sh @@ -215,6 +215,11 @@ sudo mkdir /tmpfs sudo chown kbuilder /tmpfs touch /tmpfs/READY +# Disable automatic updates to prevent spurious apt-get install failures +# See https://github.com/grpc/grpc/issues/17794 +sudo sed -i 's/APT::Periodic::Update-Package-Lists "1"/APT::Periodic::Update-Package-Lists "0"/' /etc/apt/apt.conf.d/10periodic +sudo sed -i 's/APT::Periodic::AutocleanInterval "1"/APT::Periodic::AutocleanInterval "0"/' /etc/apt/apt.conf.d/10periodic + # Restart for VM to pick up kernel update echo 'Successfully initialized the linux worker, going for reboot in 10 seconds' sleep 10 From 5a20b60cda22b17af2580759fd5f4dcc620f3a30 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 5 Feb 2019 09:17:41 -0800 Subject: [PATCH 260/814] fix flake in test_abort_does_not_leak_local_vars --- src/python/grpcio_tests/tests/unit/_abort_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/python/grpcio_tests/tests/unit/_abort_test.py b/src/python/grpcio_tests/tests/unit/_abort_test.py index 636f1379ad8..64952c899e4 100644 --- a/src/python/grpcio_tests/tests/unit/_abort_test.py +++ b/src/python/grpcio_tests/tests/unit/_abort_test.py @@ -120,13 +120,13 @@ class AbortTest(unittest.TestCase): weak_ref = weakref.ref(do_not_leak_me) # Servicer will abort() after creating a local ref to do_not_leak_me. - with self.assertRaises(grpc.RpcError) as exception_context: + with self.assertRaises(grpc.RpcError): self._channel.unary_unary(_ABORT)(_REQUEST) - rpc_error = exception_context.exception + # Server may still have a stack frame reference to the exception even + # after client sees error, so ensure server has shutdown. + self._server.stop(None) do_not_leak_me = None - # Force garbage collection - gc.collect() self.assertIsNone(weak_ref()) def test_abort_with_status(self): From 510fba2deb23ec7f0455c463f46eab0dffe01cb6 Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Tue, 5 Feb 2019 11:07:19 -0800 Subject: [PATCH 261/814] Removing BoringSSL-specific ubsan suppressions. Let's see if #17791 is really fixed. --- test/core/util/ubsan_suppressions.txt | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt index 8ed7d4d7fb6..951df98fbb0 100644 --- a/test/core/util/ubsan_suppressions.txt +++ b/test/core/util/ubsan_suppressions.txt @@ -1,11 +1,4 @@ -# boringssl stuff -nonnull-attribute:bn_wexpand -nonnull-attribute:CBB_add_bytes -nonnull-attribute:rsa_blinding_get -nonnull-attribute:ssl_copy_key_material -alignment:CRYPTO_cbc128_encrypt -alignment:CRYPTO_gcm128_encrypt -alignment:poly1305_block_copy +# Protobuf stuff nonnull-attribute:google::protobuf::* alignment:google::protobuf::* nonnull-attribute:_tr_stored_block @@ -16,11 +9,6 @@ enum:transport_security_test enum:algorithm_test alignment:transport_security_test # TODO(jtattermusch): address issues and remove the supressions -nonnull-attribute:gsec_aes_gcm_aead_crypter_decrypt_iovec -nonnull-attribute:gsec_test_random_encrypt_decrypt -nonnull-attribute:gsec_test_multiple_random_encrypt_decrypt -nonnull-attribute:gsec_test_copy -nonnull-attribute:gsec_test_encrypt_decrypt_test_vector alignment:absl::little_endian::Store64 alignment:absl::little_endian::Load64 float-divide-by-zero:grpc::testing::postprocess_scenario_result From 9abc673def87532617607bda44b2aae9398df3eb Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Tue, 5 Feb 2019 13:00:33 -0800 Subject: [PATCH 262/814] Restore gsec* suppressions These aren't from BoringSSL --- test/core/util/ubsan_suppressions.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt index 951df98fbb0..8e17d37ec7e 100644 --- a/test/core/util/ubsan_suppressions.txt +++ b/test/core/util/ubsan_suppressions.txt @@ -9,6 +9,11 @@ enum:transport_security_test enum:algorithm_test alignment:transport_security_test # TODO(jtattermusch): address issues and remove the supressions +nonnull-attribute:gsec_aes_gcm_aead_crypter_decrypt_iovec +nonnull-attribute:gsec_test_random_encrypt_decrypt +nonnull-attribute:gsec_test_multiple_random_encrypt_decrypt +nonnull-attribute:gsec_test_copy +nonnull-attribute:gsec_test_encrypt_decrypt_test_vector alignment:absl::little_endian::Store64 alignment:absl::little_endian::Load64 float-divide-by-zero:grpc::testing::postprocess_scenario_result From bca92b2b7e2f2fcd2ede72e37d02e3787ed6bce3 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Thu, 24 Jan 2019 18:30:01 -0800 Subject: [PATCH 263/814] Added test for wall-clock time change on the client --- CMakeLists.txt | 45 ++ Makefile | 48 ++ build.yaml | 16 + src/core/lib/gpr/time.cc | 8 + src/core/lib/gpr/time_posix.cc | 10 +- test/cpp/end2end/BUILD | 24 +- test/cpp/end2end/time_change_test.cc | 422 ++++++++++++++++++ .../generated/sources_and_headers.json | 18 + tools/run_tests/generated/tests.json | 22 + 9 files changed, 610 insertions(+), 3 deletions(-) create mode 100644 test/cpp/end2end/time_change_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 9813eec7062..9ec075c63b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -699,6 +699,9 @@ endif() add_dependencies(buildtests_cxx stress_test) add_dependencies(buildtests_cxx thread_manager_test) add_dependencies(buildtests_cxx thread_stress_test) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx time_change_test) +endif() add_dependencies(buildtests_cxx transport_pid_controller_test) add_dependencies(buildtests_cxx transport_security_common_api_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -15973,6 +15976,48 @@ target_link_libraries(thread_stress_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + +add_executable(time_change_test + test/cpp/end2end/time_change_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(time_change_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(time_change_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index b9b7ab4c254..3a3eacb5764 100644 --- a/Makefile +++ b/Makefile @@ -1248,6 +1248,7 @@ streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test stress_test: $(BINDIR)/$(CONFIG)/stress_test thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test +time_change_test: $(BINDIR)/$(CONFIG)/time_change_test transport_pid_controller_test: $(BINDIR)/$(CONFIG)/transport_pid_controller_test transport_security_common_api_test: $(BINDIR)/$(CONFIG)/transport_security_common_api_test writes_per_rpc_test: $(BINDIR)/$(CONFIG)/writes_per_rpc_test @@ -1756,6 +1757,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/stress_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \ + $(BINDIR)/$(CONFIG)/time_change_test \ $(BINDIR)/$(CONFIG)/transport_pid_controller_test \ $(BINDIR)/$(CONFIG)/transport_security_common_api_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \ @@ -1943,6 +1945,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/stress_test \ $(BINDIR)/$(CONFIG)/thread_manager_test \ $(BINDIR)/$(CONFIG)/thread_stress_test \ + $(BINDIR)/$(CONFIG)/time_change_test \ $(BINDIR)/$(CONFIG)/transport_pid_controller_test \ $(BINDIR)/$(CONFIG)/transport_security_common_api_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \ @@ -2458,6 +2461,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/thread_manager_test || ( echo test thread_manager_test failed ; exit 1 ) $(E) "[RUN] Testing thread_stress_test" $(Q) $(BINDIR)/$(CONFIG)/thread_stress_test || ( echo test thread_stress_test failed ; exit 1 ) + $(E) "[RUN] Testing time_change_test" + $(Q) $(BINDIR)/$(CONFIG)/time_change_test || ( echo test time_change_test failed ; exit 1 ) $(E) "[RUN] Testing transport_pid_controller_test" $(Q) $(BINDIR)/$(CONFIG)/transport_pid_controller_test || ( echo test transport_pid_controller_test failed ; exit 1 ) $(E) "[RUN] Testing transport_security_common_api_test" @@ -21025,6 +21030,49 @@ endif endif +TIME_CHANGE_TEST_SRC = \ + test/cpp/end2end/time_change_test.cc \ + +TIME_CHANGE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIME_CHANGE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/time_change_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/time_change_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/time_change_test: $(PROTOBUF_DEP) $(TIME_CHANGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(TIME_CHANGE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/time_change_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/time_change_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_time_change_test: $(TIME_CHANGE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(TIME_CHANGE_TEST_OBJS:.o=.dep) +endif +endif + + TRANSPORT_PID_CONTROLLER_TEST_SRC = \ test/core/transport/pid_controller_test.cc \ diff --git a/build.yaml b/build.yaml index 0946e853d1b..20089c1eba7 100644 --- a/build.yaml +++ b/build.yaml @@ -5558,6 +5558,22 @@ targets: - grpc++_unsecure - grpc_unsecure - gpr +- name: time_change_test + gtest: true + build: test + language: c++ + src: + - test/cpp/end2end/time_change_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr + platforms: + - mac + - linux + - posix - name: transport_pid_controller_test build: test language: c++ diff --git a/src/core/lib/gpr/time.cc b/src/core/lib/gpr/time.cc index 64c1c98f560..8927dab5a30 100644 --- a/src/core/lib/gpr/time.cc +++ b/src/core/lib/gpr/time.cc @@ -135,6 +135,10 @@ gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) { gpr_timespec sum; int64_t inc = 0; GPR_ASSERT(b.clock_type == GPR_TIMESPAN); + // tv_nsec in a timespan is always +ve. -ve timespan is represented as (-ve + // tv_sec, +ve tv_nsec). For example, timespan = -2.5 seconds is represented + // as {-3, 5e8, GPR_TIMESPAN} + GPR_ASSERT(b.tv_nsec >= 0); sum.clock_type = a.clock_type; sum.tv_nsec = a.tv_nsec + b.tv_nsec; if (sum.tv_nsec >= GPR_NS_PER_SEC) { @@ -165,6 +169,10 @@ gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) { int64_t dec = 0; if (b.clock_type == GPR_TIMESPAN) { diff.clock_type = a.clock_type; + // tv_nsec in a timespan is always +ve. -ve timespan is represented as (-ve + // tv_sec, +ve tv_nsec). For example, timespan = -2.5 seconds is represented + // as {-3, 5e8, GPR_TIMESPAN} + GPR_ASSERT(b.tv_nsec >= 0); } else { GPR_ASSERT(a.clock_type == b.clock_type); diff.clock_type = GPR_TIMESPAN; diff --git a/src/core/lib/gpr/time_posix.cc b/src/core/lib/gpr/time_posix.cc index 28836bfa54e..1b3e36486fc 100644 --- a/src/core/lib/gpr/time_posix.cc +++ b/src/core/lib/gpr/time_posix.cc @@ -133,12 +133,18 @@ gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type) = now_impl; #ifdef GPR_LOW_LEVEL_COUNTERS gpr_atm gpr_now_call_count; #endif - gpr_timespec gpr_now(gpr_clock_type clock_type) { #ifdef GPR_LOW_LEVEL_COUNTERS __atomic_fetch_add(&gpr_now_call_count, 1, __ATOMIC_RELAXED); #endif - return gpr_now_impl(clock_type); + // validate clock type + GPR_ASSERT(clock_type == GPR_CLOCK_MONOTONIC || + clock_type == GPR_CLOCK_REALTIME || + clock_type == GPR_CLOCK_PRECISE); + gpr_timespec ts = gpr_now_impl(clock_type); + // tv_nsecs must be in the range [0, 1e9). + GPR_ASSERT(ts.tv_nsec >= 0 && ts.tv_nsec < 1e9); + return ts; } void gpr_sleep_until(gpr_timespec until) { diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 4c28eee4d15..cbf09354a03 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -80,6 +80,27 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "time_change_test", + srcs = ["time_change_test.cc"], + data = [ + ":client_crash_test_server", + ], + external_deps = [ + "gtest", + ], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + grpc_cc_test( name = "client_crash_test", srcs = ["client_crash_test.cc"], @@ -110,6 +131,7 @@ grpc_cc_binary( "gtest", ], deps = [ + ":test_service_impl", "//:gpr", "//:grpc", "//:grpc++", @@ -219,10 +241,10 @@ grpc_cc_test( grpc_cc_test( name = "end2end_test", + size = "large", # with poll-cv this takes long, see #17493 deps = [ ":end2end_test_lib", ], - size = "large", # with poll-cv this takes long, see #17493 ) grpc_cc_test( diff --git a/test/cpp/end2end/time_change_test.cc b/test/cpp/end2end/time_change_test.cc new file mode 100644 index 00000000000..9fbd01299d0 --- /dev/null +++ b/test/cpp/end2end/time_change_test.cc @@ -0,0 +1,422 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/iomgr/timer.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" +#include "test/cpp/util/subprocess.h" + +#include +#include +#include +#include + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; + +static std::string g_root; + +static gpr_mu g_mu; +extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type); +gpr_timespec (*gpr_now_impl_orig)(gpr_clock_type clock_type) = gpr_now_impl; +static int g_time_shift_sec = 0; +static int g_time_shift_nsec = 0; +static gpr_timespec now_impl(gpr_clock_type clock) { + auto ts = gpr_now_impl_orig(clock); + // We only manipulate the realtime clock to simulate changes in wall-clock + // time + if (clock != GPR_CLOCK_REALTIME) { + return ts; + } + GPR_ASSERT(ts.tv_nsec >= 0); + GPR_ASSERT(ts.tv_nsec < GPR_NS_PER_SEC); + gpr_mu_lock(&g_mu); + ts.tv_sec += g_time_shift_sec; + ts.tv_nsec += g_time_shift_nsec; + gpr_mu_unlock(&g_mu); + if (ts.tv_nsec >= GPR_NS_PER_SEC) { + ts.tv_nsec -= GPR_NS_PER_SEC; + ++ts.tv_sec; + } else if (ts.tv_nsec < 0) { + --ts.tv_sec; + ts.tv_nsec = GPR_NS_PER_SEC + ts.tv_nsec; + } + return ts; +} + +// offset the value returned by gpr_now(GPR_CLOCK_REALTIME) by msecs +// milliseconds +static void set_now_offset(int msecs) { + g_time_shift_sec = msecs / 1000; + g_time_shift_nsec = (msecs % 1000) * 1e6; +} + +// restore the original implementation of gpr_now() +static void reset_now_offset() { + g_time_shift_sec = 0; + g_time_shift_nsec = 0; +} + +namespace grpc { +namespace testing { + +namespace { + +// gpr_now() is called with invalid clock_type +TEST(TimespecTest, GprNowInvalidClockType) { + // initialize to some junk value + gpr_clock_type invalid_clock_type = (gpr_clock_type)32641; + EXPECT_DEATH(gpr_now(invalid_clock_type), ".*"); +} + +// Add timespan with negative nanoseconds +TEST(TimespecTest, GprTimeAddNegativeNs) { + gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); + gpr_timespec bad_ts = {1, -1000, GPR_TIMESPAN}; + EXPECT_DEATH(gpr_time_add(now, bad_ts), ".*"); +} + +// Subtract timespan with negative nanoseconds +TEST(TimespecTest, GprTimeSubNegativeNs) { + // Nanoseconds must always be positive. Negative timestamps are represented by + // (negative seconds, positive nanoseconds) + gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); + gpr_timespec bad_ts = {1, -1000, GPR_TIMESPAN}; + EXPECT_DEATH(gpr_time_sub(now, bad_ts), ".*"); +} + +// Add negative milliseconds to gpr_timespec +TEST(TimespecTest, GrpcNegativeMillisToTimespec) { + // -1500 milliseconds converts to timespec (-2 secs, 5 * 10^8 nsec) + gpr_timespec ts = grpc_millis_to_timespec(-1500, GPR_CLOCK_MONOTONIC); + GPR_ASSERT(ts.tv_sec = -2); + GPR_ASSERT(ts.tv_nsec = 5e8); + GPR_ASSERT(ts.clock_type == GPR_CLOCK_MONOTONIC); +} + +class TimeChangeTest : public ::testing::Test { + protected: + TimeChangeTest() {} + + void SetUp() { + auto port = grpc_pick_unused_port_or_die(); + std::ostringstream addr_stream; + addr_stream << "localhost:" << port; + auto addr = addr_stream.str(); + server_.reset(new SubProcess({ + g_root + "/client_crash_test_server", + "--address=" + addr, + })); + GPR_ASSERT(server_); + channel_ = CreateChannel(addr, InsecureChannelCredentials()); + GPR_ASSERT(channel_); + stub_ = grpc::testing::EchoTestService::NewStub(channel_); + } + + void TearDown() { + server_.reset(); + reset_now_offset(); + } + + std::unique_ptr CreateStub() { + return grpc::testing::EchoTestService::NewStub(channel_); + } + + std::shared_ptr GetChannel() { return channel_; } + // time jump offsets in milliseconds + const int TIME_OFFSET1 = 20123; + const int TIME_OFFSET2 = 5678; + + private: + std::unique_ptr server_; + std::shared_ptr channel_; + std::unique_ptr stub_; +}; + +// Wall-clock time jumps forward on client before bidi stream is created +TEST_F(TimeChangeTest, TimeJumpForwardBeforeStreamCreated) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "1"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + + // time jumps forward by TIME_OFFSET1 milliseconds + set_now_offset(TIME_OFFSET1); + auto stream = stub->BidiStream(&context); + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +// Wall-clock time jumps back on client before bidi stream is created +TEST_F(TimeChangeTest, TimeJumpBackBeforeStreamCreated) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "1"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + + // time jumps back by TIME_OFFSET1 milliseconds + set_now_offset(-TIME_OFFSET1); + auto stream = stub->BidiStream(&context); + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + EXPECT_EQ(request.message(), response.message()); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +// Wall-clock time jumps forward on client while call is in progress +TEST_F(TimeChangeTest, TimeJumpForwardAfterStreamCreated) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "2"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->Read(&response)); + + // time jumps forward by TIME_OFFSET1 milliseconds. + set_now_offset(TIME_OFFSET1); + + request.set_message("World"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +// Wall-clock time jumps back on client while call is in progress +TEST_F(TimeChangeTest, TimeJumpBackAfterStreamCreated) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "2"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->Read(&response)); + + // time jumps back TIME_OFFSET1 milliseconds. + set_now_offset(-TIME_OFFSET1); + + request.set_message("World"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +// Wall-clock time jumps forward on client before connection to server is up +TEST_F(TimeChangeTest, TimeJumpForwardBeforeServerConnect) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "2"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + + // time jumps forward by TIME_OFFSET2 milliseconds + set_now_offset(TIME_OFFSET2); + + auto ret = + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000)); + // We use monotonic clock for pthread_cond_timedwait() deadline on linux, and + // realtime clock on other platforms - see gpr_cv_wait() in sync_posix.cc. + // So changes in system clock affect deadlines on non-linux platforms +#ifdef GPR_LINUX + EXPECT_TRUE(ret); + auto stub = CreateStub(); + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->Read(&response)); + request.set_message("World"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +#else + EXPECT_FALSE(ret); +#endif +} + +// Wall-clock time jumps back on client before connection to server is up +TEST_F(TimeChangeTest, TimeJumpBackBeforeServerConnect) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "2"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + + // time jumps back by TIME_OFFSET2 milliseconds + set_now_offset(-TIME_OFFSET2); + + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->Read(&response)); + request.set_message("World"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->WritesDone()); + EXPECT_TRUE(stream->Read(&response)); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +// Wall-clock time jumps forward and backwards during call +TEST_F(TimeChangeTest, TimeJumpForwardAndBackDuringCall) { + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(5000)); + context.AddMetadata(kServerResponseStreamsToSend, "2"); + + auto channel = GetChannel(); + GPR_ASSERT(channel); + + EXPECT_TRUE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(5000))); + auto stub = CreateStub(); + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + + // time jumps back by TIME_OFFSET2 milliseconds + set_now_offset(-TIME_OFFSET2); + + EXPECT_TRUE(stream->Read(&response)); + request.set_message("World"); + + // time jumps forward by TIME_OFFSET milliseconds + set_now_offset(TIME_OFFSET1); + + EXPECT_TRUE(stream->Write(request)); + + // time jumps back by TIME_OFFSET2 milliseconds + set_now_offset(-TIME_OFFSET2); + + EXPECT_TRUE(stream->WritesDone()); + + // time jumps back by TIME_OFFSET2 milliseconds + set_now_offset(-TIME_OFFSET2); + + EXPECT_TRUE(stream->Read(&response)); + + // time jumps back by TIME_OFFSET2 milliseconds + set_now_offset(-TIME_OFFSET2); + + auto status = stream->Finish(); + EXPECT_TRUE(status.ok()); +} + +} // namespace + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + std::string me = argv[0]; + // get index of last slash in path to test binary + auto lslash = me.rfind('/'); + // set g_root = path to directory containing test binary + if (lslash != std::string::npos) { + g_root = me.substr(0, lslash); + } else { + g_root = "."; + } + + gpr_mu_init(&g_mu); + gpr_now_impl = now_impl; + + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + auto ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 9e07c548b69..558afccc28b 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4894,6 +4894,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "time_change_test", + "src": [ + "test/cpp/end2end/time_change_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index b41fef6b795..fef3ec65ec4 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -5548,6 +5548,28 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "time_change_test", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From 45c684f89486643c7af8e76e161c5947e4dbf356 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 5 Feb 2019 14:05:28 -0800 Subject: [PATCH 264/814] Allow an alarm to be set again after firing --- include/grpcpp/alarm_impl.h | 5 ++--- src/cpp/common/alarm.cc | 14 ++++++------- test/cpp/common/alarm_test.cc | 38 +++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/include/grpcpp/alarm_impl.h b/include/grpcpp/alarm_impl.h index 7844e7c8866..543dcd82a4c 100644 --- a/include/grpcpp/alarm_impl.h +++ b/include/grpcpp/alarm_impl.h @@ -16,8 +16,8 @@ * */ -/// An Alarm posts the user provided tag to its associated completion queue upon -/// expiry or cancellation. +/// An Alarm posts the user-provided tag to its associated completion queue or +/// invokes the user-provided function on expiry or cancellation. #ifndef GRPCPP_ALARM_IMPL_H #define GRPCPP_ALARM_IMPL_H @@ -32,7 +32,6 @@ namespace grpc_impl { -/// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h). class Alarm : private ::grpc::GrpcLibraryCodegen { public: /// Create an unset completion queue alarm diff --git a/src/cpp/common/alarm.cc b/src/cpp/common/alarm.cc index 6bfe26f04c4..dbec80cde4f 100644 --- a/src/cpp/common/alarm.cc +++ b/src/cpp/common/alarm.cc @@ -40,12 +40,7 @@ class AlarmImpl : public ::grpc::internal::CompletionQueueTag { gpr_ref_init(&refs_, 1); grpc_timer_init_unset(&timer_); } - ~AlarmImpl() { - grpc_core::ExecCtx exec_ctx; - if (cq_ != nullptr) { - GRPC_CQ_INTERNAL_UNREF(cq_, "alarm"); - } - } + ~AlarmImpl() {} bool FinalizeResult(void** tag, bool* status) override { *tag = tag_; Unref(); @@ -63,10 +58,15 @@ class AlarmImpl : public ::grpc::internal::CompletionQueueTag { // queue the op on the completion queue AlarmImpl* alarm = static_cast(arg); alarm->Ref(); + // Preserve the cq and reset the cq_ so that the alarm + // can be reset when the alarm tag is delivered. + grpc_completion_queue* cq = alarm->cq_; + alarm->cq_ = nullptr; grpc_cq_end_op( - alarm->cq_, alarm, error, + cq, alarm, error, [](void* arg, grpc_cq_completion* completion) {}, arg, &alarm->completion_); + GRPC_CQ_INTERNAL_UNREF(cq, "alarm"); }, this, grpc_schedule_on_exec_ctx); grpc_timer_init(&timer_, grpc_timespec_to_millis_round_up(deadline), diff --git a/test/cpp/common/alarm_test.cc b/test/cpp/common/alarm_test.cc index 802cdc209a0..4d410a5d460 100644 --- a/test/cpp/common/alarm_test.cc +++ b/test/cpp/common/alarm_test.cc @@ -47,6 +47,44 @@ TEST(AlarmTest, RegularExpiry) { EXPECT_EQ(junk, output_tag); } +TEST(AlarmTest, RegularExpiryMultiSet) { + CompletionQueue cq; + void* junk = reinterpret_cast(1618033); + Alarm alarm; + + for (int i = 0; i < 3; i++) { + alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk); + + void* output_tag; + bool ok; + const CompletionQueue::NextStatus status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10)); + + EXPECT_EQ(status, CompletionQueue::GOT_EVENT); + EXPECT_TRUE(ok); + EXPECT_EQ(junk, output_tag); + } +} + +TEST(AlarmTest, RegularExpiryMultiSetMultiCQ) { + void* junk = reinterpret_cast(1618033); + Alarm alarm; + + for (int i = 0; i < 3; i++) { + CompletionQueue cq; + alarm.Set(&cq, grpc_timeout_seconds_to_deadline(1), junk); + + void* output_tag; + bool ok; + const CompletionQueue::NextStatus status = + cq.AsyncNext(&output_tag, &ok, grpc_timeout_seconds_to_deadline(10)); + + EXPECT_EQ(status, CompletionQueue::GOT_EVENT); + EXPECT_TRUE(ok); + EXPECT_EQ(junk, output_tag); + } +} + struct Completion { bool completed = false; std::mutex mu; From 84a537b1d12c8f75577992b5201c832455c46a3c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 5 Feb 2019 14:22:47 -0800 Subject: [PATCH 265/814] Default compression level quick fix --- src/cpp/server/server_builder.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 0dc03b68768..64210a2f8d1 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -139,6 +139,7 @@ ServerBuilder& ServerBuilder::SetCompressionAlgorithmSupportStatus( ServerBuilder& ServerBuilder::SetDefaultCompressionLevel( grpc_compression_level level) { + maybe_default_compression_level_.is_set = true; maybe_default_compression_level_.level = level; return *this; } From fdae4dc8331024fbc96f4c53f9e3be671b410152 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 5 Feb 2019 16:10:41 -0800 Subject: [PATCH 266/814] Second attemp to fix use-after-free in health check client --- src/core/ext/filters/client_channel/subchannel.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 4276df3067f..35225b0d5c3 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -407,7 +407,8 @@ class Subchannel::ConnectedSubchannelStateWatcher Subchannel* c = self->subchannel_; { MutexLock lock(&c->mu_); - if (self->health_state_ != GRPC_CHANNEL_SHUTDOWN) { + if (self->health_state_ != GRPC_CHANNEL_SHUTDOWN && + self->health_check_client_ != nullptr) { if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) { grpc_connectivity_state_set(&c->state_and_health_tracker_, self->health_state_, From 474a931036d40d85eb8b91120f806c81ac1cb1ef Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 6 Feb 2019 10:28:40 +0100 Subject: [PATCH 267/814] Revert "added retry statements to jq installation commands" --- .../helper_scripts/prepare_build_linux_perf_rc | 8 +------- tools/internal_ci/linux/grpc_run_tests_matrix.sh | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc index b66ac38942f..ff5593e031a 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc @@ -21,13 +21,7 @@ ulimit -c unlimited # Performance PR testing needs GH API key and PR metadata to comment results if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then - retry=0 - until [ $retry -ge 3 ] - do - sudo apt-get install -y jq && break - retry=$[$retry+1] - sleep 5 - done + sudo apt-get install -y jq export ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) fi diff --git a/tools/internal_ci/linux/grpc_run_tests_matrix.sh b/tools/internal_ci/linux/grpc_run_tests_matrix.sh index f8fd963ccf3..f9acd814ae8 100755 --- a/tools/internal_ci/linux/grpc_run_tests_matrix.sh +++ b/tools/internal_ci/linux/grpc_run_tests_matrix.sh @@ -23,13 +23,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc # If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ] && [ -n "$RUN_TESTS_FLAGS" ]; then sudo apt-get update - retry=0 - until [ $retry -ge 3 ] - do - sudo apt-get install -y jq && break - retry=$[$retry+1] - sleep 5 - done + sudo apt-get install -y jq ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref) export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch" fi From 440f734d59d8109fd20d4d95879fe22a74970908 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 6 Feb 2019 07:39:22 -0800 Subject: [PATCH 268/814] Remove owners for tools/run_tests/performance --- .github/CODEOWNERS | 1 - tools/run_tests/performance/OWNERS | 9 --------- 2 files changed, 10 deletions(-) delete mode 100644 tools/run_tests/performance/OWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0a7141c1be3..1fcdb6ba53c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,4 +6,3 @@ /cmake/** @jtattermusch @nicolasnoble @apolcyn /src/core/ext/filters/client_channel/** @markdroth @apolcyn @AspirinSJL /tools/dockerfile/** @jtattermusch @apolcyn @nicolasnoble -/tools/run_tests/performance/** @ncteisen @apolcyn @jtattermusch diff --git a/tools/run_tests/performance/OWNERS b/tools/run_tests/performance/OWNERS deleted file mode 100644 index 9cf8c131111..00000000000 --- a/tools/run_tests/performance/OWNERS +++ /dev/null @@ -1,9 +0,0 @@ -set noparent - -# These owners are in place to ensure that scenario_result_schema.json is not -# modified without also running tools/run_tests/performance/patch_scenario_results_schema.py -# to update the BigQuery schema - -@ncteisen -@apolcyn -@jtattermusch From 0da52ab133b7fd6e9ae2fbd7518af25ce4d8e004 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 6 Feb 2019 17:58:04 +0100 Subject: [PATCH 269/814] Fix typo in flow control trace --- src/core/ext/transport/chttp2/transport/flow_control.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/flow_control.cc b/src/core/ext/transport/chttp2/transport/flow_control.cc index 53932bcb7f5..ee2bb930802 100644 --- a/src/core/ext/transport/chttp2/transport/flow_control.cc +++ b/src/core/ext/transport/chttp2/transport/flow_control.cc @@ -111,7 +111,7 @@ void FlowControlTrace::Finish() { saw_str = gpr_leftpad("", ' ', kTracePadding); } gpr_log(GPR_DEBUG, - "%p[%u][%s] | %s | trw:%s, ttw:%s, taw:%s, srw:%s, slw:%s, saw:%s", + "%p[%u][%s] | %s | trw:%s, tlw:%s, taw:%s, srw:%s, slw:%s, saw:%s", tfc_, sfc_ != nullptr ? sfc_->stream()->id : 0, tfc_->transport()->is_client ? "cli" : "svr", reason_, trw_str, tlw_str, taw_str, srw_str, slw_str, saw_str); From 94564d1c223e3ecdd2d734959f48d7bf53e3fdf0 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 5 Feb 2019 15:03:46 -0500 Subject: [PATCH 270/814] Update the channelz compaction test to use 300 entries. --- test/core/channel/channelz_registry_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc index ed3d629dc99..31841f9f967 100644 --- a/test/core/channel/channelz_registry_test.cc +++ b/test/core/channel/channelz_registry_test.cc @@ -112,7 +112,7 @@ TEST_F(ChannelzRegistryTest, NullIfNotPresentTest) { } TEST_F(ChannelzRegistryTest, TestCompaction) { - const int kLoopIterations = 100; + const int kLoopIterations = 300; // These channels that will stay in the registry for the duration of the test. std::vector> even_channels; even_channels.reserve(kLoopIterations); From ade38d75c1041f7bf650ba10969967a864c72b1b Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 6 Feb 2019 10:47:40 -0800 Subject: [PATCH 271/814] Fix tsan --- src/core/lib/iomgr/error.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index 59236b20c59..f4abad9b288 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -303,11 +303,15 @@ static void internal_add_error(grpc_error** err, grpc_error* new_err) { // It is very common to include and extra int and string in an error #define SURPLUS_CAPACITY (2 * SLOTS_PER_INT + SLOTS_PER_TIME) -static bool g_error_creation_allowed = true; +static gpr_atm g_error_creation_allowed = true; -void grpc_disable_error_creation() { g_error_creation_allowed = false; } +void grpc_disable_error_creation() { + gpr_atm_no_barrier_store(&g_error_creation_allowed, false); +} -void grpc_enable_error_creation() { g_error_creation_allowed = true; } +void grpc_enable_error_creation() { + gpr_atm_no_barrier_store(&g_error_creation_allowed, true); +} grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc, grpc_error** referencing, @@ -323,7 +327,7 @@ grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc, return GRPC_ERROR_OOM; } #ifndef NDEBUG - if (!g_error_creation_allowed) { + if (!gpr_atm_no_barrier_load(&g_error_creation_allowed)) { gpr_log(GPR_ERROR, "Error creation occurred when error creation was disabled [%s:%d]", file, line); From bc4c77bf95be0e0ad186d3e0b950a1ddb21507a4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 6 Feb 2019 19:51:09 +0100 Subject: [PATCH 272/814] ignore reserved bit in WINDOW_UPDATE frame --- .../ext/transport/chttp2/transport/frame_window_update.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.cc b/src/core/ext/transport/chttp2/transport/frame_window_update.cc index 4b586dc3e7f..b8738ea7ea0 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.cc +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.cc @@ -88,8 +88,9 @@ grpc_error* grpc_chttp2_window_update_parser_parse(void* parser, } if (p->byte == 4) { - uint32_t received_update = p->amount; - if (received_update == 0 || (received_update & 0x80000000u)) { + // top bit is reserved and must be ignored. + uint32_t received_update = p->amount & 0x7fffffffu; + if (received_update == 0) { char* msg; gpr_asprintf(&msg, "invalid window update bytes: %d", p->amount); grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); From 3fe3be39febd94198393b02b444ae6d0ec88f422 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 6 Feb 2019 11:04:54 -0800 Subject: [PATCH 273/814] Add empty binary metadata test --- test/cpp/end2end/end2end_test.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 05cd4330c61..4bddbb4bdf2 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -758,6 +758,18 @@ TEST_P(End2endTest, MultipleRpcs) { } } +TEST_P(End2endTest, EmptyBinaryMetadata) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello hello hello hello"); + ClientContext context; + context.AddMetadata("custom-bin", ""); + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()); +} + TEST_P(End2endTest, ReconnectChannel) { if (GetParam().inproc) { return; From e2b668e314b225d00562d201048686a091320494 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 5 Feb 2019 15:03:46 -0500 Subject: [PATCH 274/814] Fix an issue upon setting kEmptinessTheshold. The bug is that kEmptinessTheshold is always set to 0. --- src/core/lib/channel/channelz_registry.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index 7cca247d64d..9f0169aeaab 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -62,7 +62,7 @@ void ChannelzRegistry::InternalRegister(BaseNode* node) { } void ChannelzRegistry::MaybePerformCompactionLocked() { - constexpr double kEmptinessTheshold = 1 / 3; + constexpr double kEmptinessTheshold = 1. / 3; double emptiness_ratio = double(num_empty_slots_) / double(entities_.capacity()); if (emptiness_ratio > kEmptinessTheshold) { From 058ceccd71a61e6b1a717996df10147784b2d442 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 6 Feb 2019 13:31:10 -0800 Subject: [PATCH 275/814] Add test to check that reads reset the keepalive timer --- test/core/end2end/tests/keepalive_timeout.cc | 206 +++++++++++++++++++ 1 file changed, 206 insertions(+) diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index 5f6a36dac44..d4e1fe34af3 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -220,8 +220,214 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { config.tear_down_data(&f); } +/* Verify that reads reset the keepalive ping timer. The client sends 10 pings + * with a sleep of 5ms in between. It has a configured keepalive timer of 10ms. + * In the success case, each ping ack should reset the keepalive timer so that + * the keepalive ping is never sent. */ +static void test_read_delays_keepalive(grpc_end2end_test_config config) { + const int kPingIntervalMS = 5; + grpc_arg keepalive_arg_elems[3]; + keepalive_arg_elems[0].type = GRPC_ARG_INTEGER; + keepalive_arg_elems[0].key = const_cast(GRPC_ARG_KEEPALIVE_TIME_MS); + keepalive_arg_elems[0].value.integer = kPingIntervalMS * 2; + keepalive_arg_elems[1].type = GRPC_ARG_INTEGER; + keepalive_arg_elems[1].key = const_cast(GRPC_ARG_KEEPALIVE_TIMEOUT_MS); + keepalive_arg_elems[1].value.integer = 0; + keepalive_arg_elems[2].type = GRPC_ARG_INTEGER; + keepalive_arg_elems[2].key = const_cast(GRPC_ARG_HTTP2_BDP_PROBE); + keepalive_arg_elems[2].value.integer = 0; + grpc_channel_args keepalive_args = {GPR_ARRAY_SIZE(keepalive_arg_elems), + keepalive_arg_elems}; + grpc_end2end_test_fixture f = begin_test(config, "test_read_delays_keepalive", + &keepalive_args, nullptr); + /* Disable ping ack to trigger the keepalive timeout */ + grpc_set_disable_ping_ack(true); + grpc_call* c; + grpc_call* s; + cq_verifier* cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + grpc_byte_buffer* request_payload; + grpc_byte_buffer* request_payload_recv; + grpc_byte_buffer* response_payload; + grpc_byte_buffer* response_payload_recv; + int i; + grpc_slice request_payload_slice = + grpc_slice_from_copied_string("hello world"); + grpc_slice response_payload_slice = + grpc_slice_from_copied_string("hello you"); + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast(op - ops), tag(1), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(100)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(100), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(101), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + for (i = 0; i < 10; i++) { + request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); + response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast(op - ops), tag(2), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast(op - ops), + tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast(op - ops), + tag(103), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); + cq_verify(cqv); + + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + /* Sleep for a short interval to check if the client sends any pings */ + gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(kPingIntervalMS)); + } + + grpc_slice_unref(request_payload_slice); + grpc_slice_unref(response_payload_slice); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast(op - ops), tag(3), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(104), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(104), 1); + cq_verify(cqv); + + grpc_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_slice_unref(details); + + end_test(&f); + config.tear_down_data(&f); +} + void keepalive_timeout(grpc_end2end_test_config config) { test_keepalive_timeout(config); + test_read_delays_keepalive(config); } void keepalive_timeout_pre_init(void) {} From 8a5c52e53fdf9b9f855bfb0eba893b06ae0b6b00 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 6 Feb 2019 23:07:00 +0100 Subject: [PATCH 276/814] move Logging types back to Grpc.Core --- src/csharp/Grpc.Core/ForwardedTypes.cs | 2 -- src/csharp/{Grpc.Core.Api => Grpc.Core}/Logging/ILogger.cs | 0 src/csharp/{Grpc.Core.Api => Grpc.Core}/Logging/LogLevel.cs | 0 3 files changed, 2 deletions(-) rename src/csharp/{Grpc.Core.Api => Grpc.Core}/Logging/ILogger.cs (100%) rename src/csharp/{Grpc.Core.Api => Grpc.Core}/Logging/LogLevel.cs (100%) diff --git a/src/csharp/Grpc.Core/ForwardedTypes.cs b/src/csharp/Grpc.Core/ForwardedTypes.cs index e17696a626f..dd7f292a248 100644 --- a/src/csharp/Grpc.Core/ForwardedTypes.cs +++ b/src/csharp/Grpc.Core/ForwardedTypes.cs @@ -26,8 +26,6 @@ using Grpc.Core.Utils; // TODO(jtattermusch): move types needed for implementing a client -[assembly:TypeForwardedToAttribute(typeof(ILogger))] -[assembly:TypeForwardedToAttribute(typeof(LogLevel))] [assembly:TypeForwardedToAttribute(typeof(GrpcPreconditions))] [assembly:TypeForwardedToAttribute(typeof(AuthContext))] [assembly:TypeForwardedToAttribute(typeof(ContextPropagationOptions))] diff --git a/src/csharp/Grpc.Core.Api/Logging/ILogger.cs b/src/csharp/Grpc.Core/Logging/ILogger.cs similarity index 100% rename from src/csharp/Grpc.Core.Api/Logging/ILogger.cs rename to src/csharp/Grpc.Core/Logging/ILogger.cs diff --git a/src/csharp/Grpc.Core.Api/Logging/LogLevel.cs b/src/csharp/Grpc.Core/Logging/LogLevel.cs similarity index 100% rename from src/csharp/Grpc.Core.Api/Logging/LogLevel.cs rename to src/csharp/Grpc.Core/Logging/LogLevel.cs From d77bf34c1c2b8423f7cd0ee8b4e7e3f1b7a3d8a0 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Wed, 6 Feb 2019 14:14:31 -0800 Subject: [PATCH 277/814] Fixed typo in templates documentation --- templates/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/README.md b/templates/README.md index a7aeec26c7c..a8104b1ace6 100644 --- a/templates/README.md +++ b/templates/README.md @@ -41,7 +41,7 @@ filegroups: # groups of files that are automatically expanded ... libs: # list of libraries to build ... -target: # list of targets to build +targets: # list of targets to build ... ``` From 6b74b1350b259d5b75b3871f94ff3f56ce281fc1 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 6 Feb 2019 15:59:40 -0800 Subject: [PATCH 278/814] Experiment with timing values to make sure that tests pass --- test/core/end2end/tests/keepalive_timeout.cc | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index d4e1fe34af3..38ff37fca6a 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -91,6 +91,7 @@ static void end_test(grpc_end2end_test_fixture* f) { /* Client sends a request, server replies with a payload, then waits for the keepalive watchdog timeouts before returning status. */ +#if 0 static void test_keepalive_timeout(grpc_end2end_test_config config) { grpc_call* c; grpc_call* s; @@ -219,17 +220,19 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { end_test(&f); config.tear_down_data(&f); } +#endif -/* Verify that reads reset the keepalive ping timer. The client sends 10 pings - * with a sleep of 5ms in between. It has a configured keepalive timer of 10ms. - * In the success case, each ping ack should reset the keepalive timer so that - * the keepalive ping is never sent. */ +/* Verify that reads reset the keepalive ping timer. The client sends 30 pings + * with a sleep of 10ms in between. It has a configured keepalive timer of + * 200ms. In the success case, each ping ack should reset the keepalive timer so + * that the keepalive ping is never sent. */ static void test_read_delays_keepalive(grpc_end2end_test_config config) { + gpr_log(GPR_ERROR, "ura"); const int kPingIntervalMS = 5; grpc_arg keepalive_arg_elems[3]; keepalive_arg_elems[0].type = GRPC_ARG_INTEGER; keepalive_arg_elems[0].key = const_cast(GRPC_ARG_KEEPALIVE_TIME_MS); - keepalive_arg_elems[0].value.integer = kPingIntervalMS * 2; + keepalive_arg_elems[0].value.integer = 20 * kPingIntervalMS; keepalive_arg_elems[1].type = GRPC_ARG_INTEGER; keepalive_arg_elems[1].key = const_cast(GRPC_ARG_KEEPALIVE_TIMEOUT_MS); keepalive_arg_elems[1].value.integer = 0; @@ -322,7 +325,7 @@ static void test_read_delays_keepalive(grpc_end2end_test_config config) { nullptr); GPR_ASSERT(GRPC_CALL_OK == error); - for (i = 0; i < 10; i++) { + for (i = 0; i < 30; i++) { request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); @@ -374,7 +377,9 @@ static void test_read_delays_keepalive(grpc_end2end_test_config config) { grpc_byte_buffer_destroy(request_payload_recv); grpc_byte_buffer_destroy(response_payload_recv); /* Sleep for a short interval to check if the client sends any pings */ + gpr_log(GPR_ERROR, "before sleep"); gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(kPingIntervalMS)); + gpr_log(GPR_ERROR, "after sleep"); } grpc_slice_unref(request_payload_slice); @@ -426,7 +431,7 @@ static void test_read_delays_keepalive(grpc_end2end_test_config config) { } void keepalive_timeout(grpc_end2end_test_config config) { - test_keepalive_timeout(config); + // test_keepalive_timeout(config); test_read_delays_keepalive(config); } From 26605fa3095e9e8676433e05fba7368a6e12a6f1 Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Wed, 6 Feb 2019 17:02:57 -0800 Subject: [PATCH 279/814] Revert "Track the pollsets of an FD in PO_MULTI mode for pollex." --- src/core/lib/iomgr/ev_epollex_linux.cc | 300 +++++++++++++------------ 1 file changed, 162 insertions(+), 138 deletions(-) diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index d6947d00e84..0a0891013af 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -45,7 +45,6 @@ #include "src/core/lib/gpr/spinlock.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/iomgr/block_annotate.h" @@ -79,6 +78,18 @@ typedef enum { PO_MULTI, PO_FD, PO_EMPTY } pollable_type; typedef struct pollable pollable; +typedef struct cached_fd { + // Set to the grpc_fd's salt value. See 'salt' variable' in grpc_fd for more + // details + intptr_t salt; + + // The underlying fd + int fd; + + // A recency time counter that helps to determine the LRU fd in the cache + uint64_t last_used; +} cached_fd; + /// A pollable is something that can be polled: it has an epoll set to poll on, /// and a wakeup fd for kicks /// There are three broad types: @@ -109,6 +120,33 @@ struct pollable { int event_cursor; int event_count; struct epoll_event events[MAX_EPOLL_EVENTS]; + + // We may be calling pollable_add_fd() on the same (pollable, fd) multiple + // times. To prevent pollable_add_fd() from making multiple sys calls to + // epoll_ctl() to add the fd, we maintain a cache of what fds are already + // present in the underlying epoll-set. + // + // Since this is not a correctness issue, we do not need to maintain all the + // fds in the cache. Hence we just use an LRU cache of size 'MAX_FDS_IN_CACHE' + // + // NOTE: An ideal implementation of this should do the following: + // 1) Add fds to the cache in pollable_add_fd() function (i.e whenever the fd + // is added to the pollable's epoll set) + // 2) Remove the fd from the cache whenever the fd is removed from the + // underlying epoll set (i.e whenever fd_orphan() is called). + // + // Implementing (2) above (i.e removing fds from cache on fd_orphan) adds a + // lot of complexity since an fd can be present in multiple pollables. So our + // implementation ONLY DOES (1) and NOT (2). + // + // The cache_fd.salt variable helps here to maintain correctness (it serves as + // an epoch that differentiates one grpc_fd from the other even though both of + // them may have the same fd number) + // + // The following implements LRU-eviction cache of fds in this pollable + cached_fd fd_cache[MAX_FDS_IN_CACHE]; + int fd_cache_size; + uint64_t fd_cache_counter; // Recency timer tick counter }; static const char* pollable_type_string(pollable_type t) { @@ -151,86 +189,37 @@ static void pollable_unref(pollable* p, int line, const char* reason); * Fd Declarations */ +// Monotonically increasing Epoch counter that is assinged to each grpc_fd. See +// the description of 'salt' variable in 'grpc_fd' for more details +// TODO: (sreek/kpayson) gpr_atm is intptr_t which may not be wide-enough on +// 32-bit systems. Change this to int_64 - atleast on 32-bit systems +static gpr_atm g_fd_salt; + struct grpc_fd { - grpc_fd(int fd, const char* name, bool track_err) - : fd(fd), track_err(track_err) { - gpr_mu_init(&orphan_mu); - gpr_mu_init(&pollable_mu); - read_closure.InitEvent(); - write_closure.InitEvent(); - error_closure.InitEvent(); - - char* fd_name; - gpr_asprintf(&fd_name, "%s fd=%d", name, fd); - grpc_iomgr_register_object(&iomgr_object, fd_name); -#ifndef NDEBUG - if (grpc_trace_fd_refcount.enabled()) { - gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, this, fd_name); - } -#endif - gpr_free(fd_name); - } - - // This is really the dtor, but the poller threads waking up from - // epoll_wait() may access the (read|write|error)_closure after destruction. - // Since the object will be added to the free pool, this behavior is - // not going to cause issues, except spurious events if the FD is reused - // while the race happens. - void destroy() { - grpc_iomgr_unregister_object(&iomgr_object); - - POLLABLE_UNREF(pollable_obj, "fd_pollable"); - pollsets.clear(); - gpr_mu_destroy(&pollable_mu); - gpr_mu_destroy(&orphan_mu); - - read_closure.DestroyEvent(); - write_closure.DestroyEvent(); - error_closure.DestroyEvent(); - - invalidate(); - } - -#ifndef NDEBUG - /* Since an fd is never really destroyed (i.e gpr_free() is not called), it is - * hard-to-debug cases where fd fields are accessed even after calling - * fd_destroy(). The following invalidates fd fields to make catching such - * errors easier */ - void invalidate() { - fd = -1; - gpr_atm_no_barrier_store(&refst, -1); - memset(&orphan_mu, -1, sizeof(orphan_mu)); - memset(&pollable_mu, -1, sizeof(pollable_mu)); - pollable_obj = nullptr; - on_done_closure = nullptr; - memset(&iomgr_object, -1, sizeof(iomgr_object)); - track_err = false; - } -#else - void invalidate() {} -#endif - int fd; + // Since fd numbers can be reused (after old fds are closed), this serves as + // an epoch that uniquely identifies this fd (i.e the pair (salt, fd) is + // unique (until the salt counter (i.e g_fd_salt) overflows) + intptr_t salt; + // refst format: // bit 0 : 1=Active / 0=Orphaned // bits 1-n : refcount // Ref/Unref by two to avoid altering the orphaned bit - gpr_atm refst = 1; + gpr_atm refst; gpr_mu orphan_mu; - // Protects pollable_obj and pollsets. gpr_mu pollable_mu; - grpc_core::InlinedVector pollsets; // Used in PO_MULTI. - pollable* pollable_obj = nullptr; // Used in PO_FD. + pollable* pollable_obj; - grpc_core::LockfreeEvent read_closure; - grpc_core::LockfreeEvent write_closure; - grpc_core::LockfreeEvent error_closure; + grpc_core::ManualConstructor read_closure; + grpc_core::ManualConstructor write_closure; + grpc_core::ManualConstructor error_closure; - struct grpc_fd* freelist_next = nullptr; - grpc_closure* on_done_closure = nullptr; + struct grpc_fd* freelist_next; + grpc_closure* on_done_closure; grpc_iomgr_object iomgr_object; @@ -269,7 +258,6 @@ struct grpc_pollset_worker { struct grpc_pollset { gpr_mu mu; gpr_atm worker_count; - gpr_atm active_pollable_type; pollable* active_pollable; bool kicked_without_poller; grpc_closure* shutdown_closure; @@ -349,10 +337,39 @@ static void ref_by(grpc_fd* fd, int n) { GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0); } +#ifndef NDEBUG +#define INVALIDATE_FD(fd) invalidate_fd(fd) +/* Since an fd is never really destroyed (i.e gpr_free() is not called), it is + * hard to cases where fd fields are accessed even after calling fd_destroy(). + * The following invalidates fd fields to make catching such errors easier */ +static void invalidate_fd(grpc_fd* fd) { + fd->fd = -1; + fd->salt = -1; + gpr_atm_no_barrier_store(&fd->refst, -1); + memset(&fd->orphan_mu, -1, sizeof(fd->orphan_mu)); + memset(&fd->pollable_mu, -1, sizeof(fd->pollable_mu)); + fd->pollable_obj = nullptr; + fd->on_done_closure = nullptr; + memset(&fd->iomgr_object, -1, sizeof(fd->iomgr_object)); + fd->track_err = false; +} +#else +#define INVALIDATE_FD(fd) +#endif + /* Uninitialize and add to the freelist */ static void fd_destroy(void* arg, grpc_error* error) { grpc_fd* fd = static_cast(arg); - fd->destroy(); + grpc_iomgr_unregister_object(&fd->iomgr_object); + POLLABLE_UNREF(fd->pollable_obj, "fd_pollable"); + gpr_mu_destroy(&fd->pollable_mu); + gpr_mu_destroy(&fd->orphan_mu); + + fd->read_closure->DestroyEvent(); + fd->write_closure->DestroyEvent(); + fd->error_closure->DestroyEvent(); + + INVALIDATE_FD(fd); /* Add the fd to the freelist */ gpr_mu_lock(&fd_freelist_mu); @@ -412,9 +429,35 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) { if (new_fd == nullptr) { new_fd = static_cast(gpr_malloc(sizeof(grpc_fd))); + new_fd->read_closure.Init(); + new_fd->write_closure.Init(); + new_fd->error_closure.Init(); } - return new (new_fd) grpc_fd(fd, name, track_err); + new_fd->fd = fd; + new_fd->salt = gpr_atm_no_barrier_fetch_add(&g_fd_salt, 1); + gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1); + gpr_mu_init(&new_fd->orphan_mu); + gpr_mu_init(&new_fd->pollable_mu); + new_fd->pollable_obj = nullptr; + new_fd->read_closure->InitEvent(); + new_fd->write_closure->InitEvent(); + new_fd->error_closure->InitEvent(); + new_fd->freelist_next = nullptr; + new_fd->on_done_closure = nullptr; + + char* fd_name; + gpr_asprintf(&fd_name, "%s fd=%d", name, fd); + grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name); +#ifndef NDEBUG + if (grpc_trace_fd_refcount.enabled()) { + gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, new_fd, fd_name); + } +#endif + gpr_free(fd_name); + + new_fd->track_err = track_err; + return new_fd; } static int fd_wrapped_fd(grpc_fd* fd) { @@ -422,7 +465,6 @@ static int fd_wrapped_fd(grpc_fd* fd) { return (gpr_atm_acq_load(&fd->refst) & 1) ? ret_fd : -1; } -static int pollset_epoll_fd_locked(grpc_pollset* pollset); static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, const char* reason) { bool is_fd_closed = false; @@ -433,6 +475,7 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, // true so that the pollable will no longer access its owner_fd field. gpr_mu_lock(&fd->pollable_mu); pollable* pollable_obj = fd->pollable_obj; + gpr_mu_unlock(&fd->pollable_mu); if (pollable_obj) { gpr_mu_lock(&pollable_obj->owner_orphan_mu); @@ -444,20 +487,6 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, /* If release_fd is not NULL, we should be relinquishing control of the file descriptor fd->fd (but we still own the grpc_fd structure). */ if (release_fd != nullptr) { - // Remove the FD from all epolls sets, before releasing it. - // Otherwise, we will receive epoll events after we release the FD. - epoll_event ev_fd; - memset(&ev_fd, 0, sizeof(ev_fd)); - if (release_fd != nullptr) { - if (pollable_obj != nullptr) { // For PO_FD. - epoll_ctl(pollable_obj->epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); - } - for (size_t i = 0; i < fd->pollsets.size(); ++i) { // For PO_MULTI. - grpc_pollset* pollset = fd->pollsets[i]; - const int epfd = pollset_epoll_fd_locked(pollset); - epoll_ctl(epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); - } - } *release_fd = fd->fd; } else { close(fd->fd); @@ -479,56 +508,40 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, gpr_mu_unlock(&pollable_obj->owner_orphan_mu); } - gpr_mu_unlock(&fd->pollable_mu); gpr_mu_unlock(&fd->orphan_mu); UNREF_BY(fd, 2, reason); /* Drop the reference */ } static bool fd_is_shutdown(grpc_fd* fd) { - return fd->read_closure.IsShutdown(); + return fd->read_closure->IsShutdown(); } /* Might be called multiple times */ static void fd_shutdown(grpc_fd* fd, grpc_error* why) { - if (fd->read_closure.SetShutdown(GRPC_ERROR_REF(why))) { + if (fd->read_closure->SetShutdown(GRPC_ERROR_REF(why))) { if (shutdown(fd->fd, SHUT_RDWR)) { if (errno != ENOTCONN) { gpr_log(GPR_ERROR, "Error shutting down fd %d. errno: %d", grpc_fd_wrapped_fd(fd), errno); } } - fd->write_closure.SetShutdown(GRPC_ERROR_REF(why)); - fd->error_closure.SetShutdown(GRPC_ERROR_REF(why)); + fd->write_closure->SetShutdown(GRPC_ERROR_REF(why)); + fd->error_closure->SetShutdown(GRPC_ERROR_REF(why)); } GRPC_ERROR_UNREF(why); } static void fd_notify_on_read(grpc_fd* fd, grpc_closure* closure) { - fd->read_closure.NotifyOn(closure); + fd->read_closure->NotifyOn(closure); } static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { - fd->write_closure.NotifyOn(closure); + fd->write_closure->NotifyOn(closure); } static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - fd->error_closure.NotifyOn(closure); -} - -static bool fd_has_pollset(grpc_fd* fd, grpc_pollset* pollset) { - grpc_core::MutexLock lock(&fd->pollable_mu); - for (size_t i = 0; i < fd->pollsets.size(); ++i) { - if (fd->pollsets[i] == pollset) { - return true; - } - } - return false; -} - -static void fd_add_pollset(grpc_fd* fd, grpc_pollset* pollset) { - grpc_core::MutexLock lock(&fd->pollable_mu); - fd->pollsets.push_back(pollset); + fd->error_closure->NotifyOn(closure); } /******************************************************************************* @@ -581,6 +594,8 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) { (*p)->root_worker = nullptr; (*p)->event_cursor = 0; (*p)->event_count = 0; + (*p)->fd_cache_size = 0; + (*p)->fd_cache_counter = 0; return GRPC_ERROR_NONE; } @@ -622,6 +637,39 @@ static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) { grpc_error* error = GRPC_ERROR_NONE; static const char* err_desc = "pollable_add_fd"; const int epfd = p->epfd; + gpr_mu_lock(&p->mu); + p->fd_cache_counter++; + + // Handle the case of overflow for our cache counter by + // reseting the recency-counter on all cache objects + if (p->fd_cache_counter == 0) { + for (int i = 0; i < p->fd_cache_size; i++) { + p->fd_cache[i].last_used = 0; + } + } + + int lru_idx = 0; + for (int i = 0; i < p->fd_cache_size; i++) { + if (p->fd_cache[i].fd == fd->fd && p->fd_cache[i].salt == fd->salt) { + GRPC_STATS_INC_POLLSET_FD_CACHE_HITS(); + p->fd_cache[i].last_used = p->fd_cache_counter; + gpr_mu_unlock(&p->mu); + return GRPC_ERROR_NONE; + } else if (p->fd_cache[i].last_used < p->fd_cache[lru_idx].last_used) { + lru_idx = i; + } + } + + // Add to cache + if (p->fd_cache_size < MAX_FDS_IN_CACHE) { + lru_idx = p->fd_cache_size; + p->fd_cache_size++; + } + p->fd_cache[lru_idx].fd = fd->fd; + p->fd_cache[lru_idx].salt = fd->salt; + p->fd_cache[lru_idx].last_used = p->fd_cache_counter; + gpr_mu_unlock(&p->mu); + if (grpc_polling_trace.enabled()) { gpr_log(GPR_INFO, "add fd %p (%d) to pollable %p", fd, fd->fd, p); } @@ -801,7 +849,6 @@ static grpc_error* pollset_kick_all(grpc_pollset* pollset) { static void pollset_init(grpc_pollset* pollset, gpr_mu** mu) { gpr_mu_init(&pollset->mu); gpr_atm_no_barrier_store(&pollset->worker_count, 0); - gpr_atm_no_barrier_store(&pollset->active_pollable_type, PO_EMPTY); pollset->active_pollable = POLLABLE_REF(g_empty_pollable, "pollset"); pollset->kicked_without_poller = false; pollset->shutdown_closure = nullptr; @@ -822,11 +869,11 @@ static int poll_deadline_to_millis_timeout(grpc_millis millis) { return static_cast(delta); } -static void fd_become_readable(grpc_fd* fd) { fd->read_closure.SetReady(); } +static void fd_become_readable(grpc_fd* fd) { fd->read_closure->SetReady(); } -static void fd_become_writable(grpc_fd* fd) { fd->write_closure.SetReady(); } +static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); } -static void fd_has_errors(grpc_fd* fd) { fd->error_closure.SetReady(); } +static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); } /* Get the pollable_obj attached to this fd. If none is attached, create a new * pollable object (of type PO_FD), attach it to the fd and return it @@ -1236,8 +1283,6 @@ static grpc_error* pollset_add_fd_locked(grpc_pollset* pollset, grpc_fd* fd) { POLLABLE_UNREF(pollset->active_pollable, "pollset"); pollset->active_pollable = po_at_start; } else { - gpr_atm_rel_store(&pollset->active_pollable_type, - pollset->active_pollable->type); POLLABLE_UNREF(po_at_start, "pollset_add_fd"); } return error; @@ -1284,38 +1329,17 @@ static grpc_error* pollset_as_multipollable_locked(grpc_pollset* pollset, pollset->active_pollable = po_at_start; *pollable_obj = nullptr; } else { - gpr_atm_rel_store(&pollset->active_pollable_type, - pollset->active_pollable->type); *pollable_obj = POLLABLE_REF(pollset->active_pollable, "pollset_set"); POLLABLE_UNREF(po_at_start, "pollset_as_multipollable"); } return error; } -// Caller must hold the lock for `pollset->mu`. -static int pollset_epoll_fd_locked(grpc_pollset* pollset) { - return pollset->active_pollable->epfd; -} - static void pollset_add_fd(grpc_pollset* pollset, grpc_fd* fd) { GPR_TIMER_SCOPE("pollset_add_fd", 0); - - // We never transition from PO_MULTI to other modes (i.e., PO_FD or PO_EMOPTY) - // and, thus, it is safe to simply store and check whether the FD has already - // been added to the active pollable previously. - if (gpr_atm_acq_load(&pollset->active_pollable_type) == PO_MULTI && - fd_has_pollset(fd, pollset)) { - return; - } - - grpc_core::MutexLock lock(&pollset->mu); + gpr_mu_lock(&pollset->mu); grpc_error* error = pollset_add_fd_locked(pollset, fd); - - // If we are in PO_MULTI mode, we should update the pollsets of the FD. - if (gpr_atm_no_barrier_load(&pollset->active_pollable_type) == PO_MULTI) { - fd_add_pollset(fd, pollset); - } - + gpr_mu_unlock(&pollset->mu); GRPC_LOG_IF_ERROR("pollset_add_fd", error); } From bfd89bcec589298780af86336b39ead756775a95 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 6 Feb 2019 17:56:03 -0800 Subject: [PATCH 280/814] Don't run for poll and poll-cv --- test/core/end2end/tests/keepalive_timeout.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index 38ff37fca6a..f39a33cff9b 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -91,7 +91,6 @@ static void end_test(grpc_end2end_test_fixture* f) { /* Client sends a request, server replies with a payload, then waits for the keepalive watchdog timeouts before returning status. */ -#if 0 static void test_keepalive_timeout(grpc_end2end_test_config config) { grpc_call* c; grpc_call* s; @@ -220,15 +219,20 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { end_test(&f); config.tear_down_data(&f); } -#endif /* Verify that reads reset the keepalive ping timer. The client sends 30 pings * with a sleep of 10ms in between. It has a configured keepalive timer of * 200ms. In the success case, each ping ack should reset the keepalive timer so * that the keepalive ping is never sent. */ static void test_read_delays_keepalive(grpc_end2end_test_config config) { - gpr_log(GPR_ERROR, "ura"); - const int kPingIntervalMS = 5; + char* poller = gpr_getenv("GRPC_POLL_STRATEGY"); + /* It is hard to get the timing right for the polling engines poll and poll-cv */ + if(poller != nullptr && (0 == strcmp(poller, "poll-cv") || 0 == strcmp(poller, "poll"))) { + gpr_free(poller); + return; + } + gpr_free(poller); + const int kPingIntervalMS = 100; grpc_arg keepalive_arg_elems[3]; keepalive_arg_elems[0].type = GRPC_ARG_INTEGER; keepalive_arg_elems[0].key = const_cast(GRPC_ARG_KEEPALIVE_TIME_MS); @@ -377,9 +381,7 @@ static void test_read_delays_keepalive(grpc_end2end_test_config config) { grpc_byte_buffer_destroy(request_payload_recv); grpc_byte_buffer_destroy(response_payload_recv); /* Sleep for a short interval to check if the client sends any pings */ - gpr_log(GPR_ERROR, "before sleep"); gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(kPingIntervalMS)); - gpr_log(GPR_ERROR, "after sleep"); } grpc_slice_unref(request_payload_slice); @@ -431,7 +433,7 @@ static void test_read_delays_keepalive(grpc_end2end_test_config config) { } void keepalive_timeout(grpc_end2end_test_config config) { - // test_keepalive_timeout(config); + test_keepalive_timeout(config); test_read_delays_keepalive(config); } From 5a9eb31a3e6ca2aa80bd41e7018ccabd71a4e9c1 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 6 Feb 2019 18:15:28 -0800 Subject: [PATCH 281/814] Clang format --- test/core/end2end/tests/keepalive_timeout.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index f39a33cff9b..c4025e93b82 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -226,8 +226,10 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { * that the keepalive ping is never sent. */ static void test_read_delays_keepalive(grpc_end2end_test_config config) { char* poller = gpr_getenv("GRPC_POLL_STRATEGY"); - /* It is hard to get the timing right for the polling engines poll and poll-cv */ - if(poller != nullptr && (0 == strcmp(poller, "poll-cv") || 0 == strcmp(poller, "poll"))) { + /* It is hard to get the timing right for the polling engines poll and poll-cv + */ + if (poller != nullptr && + (0 == strcmp(poller, "poll-cv") || 0 == strcmp(poller, "poll"))) { gpr_free(poller); return; } From 25797cf8062288a24fe300307f356dc9665776e8 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 6 Feb 2019 18:45:06 -0800 Subject: [PATCH 282/814] Add logging around GOAWAYs and keepalives --- .../chttp2/transport/chttp2_transport.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index c2b57ed2905..34477c93230 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1119,9 +1119,6 @@ static void queue_setting_update(grpc_chttp2_transport* t, void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, uint32_t goaway_error, grpc_slice goaway_text) { - // GRPC_CHTTP2_IF_TRACING( - // gpr_log(GPR_INFO, "got goaway [%d]: %s", goaway_error, msg)); - // Discard the error from a previous goaway frame (if any) if (t->goaway_error != GRPC_ERROR_NONE) { GRPC_ERROR_UNREF(t->goaway_error); @@ -1132,6 +1129,9 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, GRPC_ERROR_INT_HTTP2_ERROR, static_cast(goaway_error)), GRPC_ERROR_STR_RAW_BYTES, goaway_text); + gpr_log(GPR_ERROR, "%s: Got goaway [%d] err=%s", t->peer_string, goaway_error, + grpc_error_string(t->goaway_error)); + /* When a client receives a GOAWAY with error code ENHANCE_YOUR_CALM and debug * data equal to "too_many_pings", it should log the occurrence at a log level * that is enabled by default and double the configured KEEPALIVE_TIME used @@ -1774,6 +1774,8 @@ void grpc_chttp2_ack_ping(grpc_chttp2_transport* t, uint64_t id) { } static void send_goaway(grpc_chttp2_transport* t, grpc_error* error) { + gpr_log(GPR_ERROR, "%s: Sending goaway err=%s", t->peer_string, + grpc_error_string(error)); t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED; grpc_http2_error_code http_error; grpc_slice slice; @@ -2723,6 +2725,9 @@ static void start_keepalive_ping_locked(void* arg, grpc_error* error) { if (t->channelz_socket != nullptr) { t->channelz_socket->RecordKeepaliveSent(); } + if (grpc_http_trace.enabled()) { + gpr_log(GPR_INFO, "%s: Start keepalive ping", t->peer_string); + } GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive watchdog"); grpc_timer_init(&t->keepalive_watchdog_timer, grpc_core::ExecCtx::Get()->Now() + t->keepalive_timeout, @@ -2733,6 +2738,9 @@ static void finish_keepalive_ping_locked(void* arg, grpc_error* error) { grpc_chttp2_transport* t = static_cast(arg); if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { if (error == GRPC_ERROR_NONE) { + if (grpc_http_trace.enabled()) { + gpr_log(GPR_INFO, "%s: Finish keepalive ping", t->peer_string); + } t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING; grpc_timer_cancel(&t->keepalive_watchdog_timer); GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping"); @@ -2748,6 +2756,8 @@ static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) { grpc_chttp2_transport* t = static_cast(arg); if (t->keepalive_state == GRPC_CHTTP2_KEEPALIVE_STATE_PINGING) { if (error == GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "%s: Keepalive watchdog fired. Closing transport.", + t->peer_string); t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; close_transport_locked( t, grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( From 3af64e8495c8cb62966273db5c48c95f5e4ab905 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 6 Feb 2019 19:22:15 -0800 Subject: [PATCH 283/814] Reduce logging level to info from error for goaway --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 34477c93230..8e8c9b88493 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1129,7 +1129,8 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, GRPC_ERROR_INT_HTTP2_ERROR, static_cast(goaway_error)), GRPC_ERROR_STR_RAW_BYTES, goaway_text); - gpr_log(GPR_ERROR, "%s: Got goaway [%d] err=%s", t->peer_string, goaway_error, + /* We want to log this irrespective of whether http tracing is enabled */ + gpr_log(GPR_INFO, "%s: Got goaway [%d] err=%s", t->peer_string, goaway_error, grpc_error_string(t->goaway_error)); /* When a client receives a GOAWAY with error code ENHANCE_YOUR_CALM and debug @@ -1774,7 +1775,8 @@ void grpc_chttp2_ack_ping(grpc_chttp2_transport* t, uint64_t id) { } static void send_goaway(grpc_chttp2_transport* t, grpc_error* error) { - gpr_log(GPR_ERROR, "%s: Sending goaway err=%s", t->peer_string, + /* We want to log this irrespective of whether http tracing is enabled */ + gpr_log(GPR_INFO, "%s: Sending goaway err=%s", t->peer_string, grpc_error_string(error)); t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED; grpc_http2_error_code http_error; From 486b1fe3206d922d80b201861b8816b30639a0c9 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 7 Feb 2019 10:21:09 +0100 Subject: [PATCH 284/814] Fix bad_client_simple_request test. The data of 0xffffffff is actually not illegal, the top bit should be ingored according to the spec. --- test/core/bad_client/tests/simple_request.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/core/bad_client/tests/simple_request.cc b/test/core/bad_client/tests/simple_request.cc index 34049aaaffc..614f5869976 100644 --- a/test/core/bad_client/tests/simple_request.cc +++ b/test/core/bad_client/tests/simple_request.cc @@ -147,11 +147,12 @@ int main(int argc, char** argv) { /* push a window update with bad flags */ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr, PFX_STR "\x00\x00\x00\x08\x10\x00\x00\x00\x01", 0); - /* push a window update with bad data */ + /* push a window update with bad data (0 is not legal window size increment) + */ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr, PFX_STR "\x00\x00\x04\x08\x00\x00\x00\x00\x01" - "\xff\xff\xff\xff", + "\x00\x00\x00\x00", 0); /* push a short goaway */ GRPC_RUN_BAD_CLIENT_TEST(failure_verifier, nullptr, From 75dec4d0f22eb0dbd51bb584ca624f861744d218 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 7 Feb 2019 11:15:07 -0500 Subject: [PATCH 285/814] Track the pollsets of an FD in PO_MULTI mode for pollex. Each pollset in pollex has a lock, grabbed upon adding an FD to the pollset. Since this is called on a per-call basis, there is a flat array caching the FDs of the pollset, to avoid unnecessarily calling epoll_ctl multiple times for the same FD. This has two problems: 1) When multiple threads add FDs to the same pollset, we will have contention on the pollset lock. 2) When we have many FDs we simply run out of cache storage, and call epoll_ctl(). This commit changes the caching strategy by simply storing the epfd of pollsets of an FD inside that FD, when we are in PO_MULTI mode. This results in address in both (1) and (2). Moreover, this commit fixes another performance bug. When we have a release FD callback, we do not call close(). That FD will remain in our epollset, until the new owner of the FD actually call close(). This results in a lot of spurious wake ups when we simply hand off gRPC FDs to other FDs. Note that this is a revision on the reverted commit e83e463b5a14cf0de5d8c9e1197d06f925160111 (PR #17823). The main change is to track the epfd of the pollset instead of the pollset pointer, so that if the pollset is deleted we can still access the FD. It also halves the size of the cache vector for 64-bit machines. --- src/core/lib/iomgr/ev_epollex_linux.cc | 295 +++++++++++-------------- 1 file changed, 133 insertions(+), 162 deletions(-) diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 0a0891013af..b6d13b44d12 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -45,6 +45,7 @@ #include "src/core/lib/gpr/spinlock.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/iomgr/block_annotate.h" @@ -78,18 +79,6 @@ typedef enum { PO_MULTI, PO_FD, PO_EMPTY } pollable_type; typedef struct pollable pollable; -typedef struct cached_fd { - // Set to the grpc_fd's salt value. See 'salt' variable' in grpc_fd for more - // details - intptr_t salt; - - // The underlying fd - int fd; - - // A recency time counter that helps to determine the LRU fd in the cache - uint64_t last_used; -} cached_fd; - /// A pollable is something that can be polled: it has an epoll set to poll on, /// and a wakeup fd for kicks /// There are three broad types: @@ -120,33 +109,6 @@ struct pollable { int event_cursor; int event_count; struct epoll_event events[MAX_EPOLL_EVENTS]; - - // We may be calling pollable_add_fd() on the same (pollable, fd) multiple - // times. To prevent pollable_add_fd() from making multiple sys calls to - // epoll_ctl() to add the fd, we maintain a cache of what fds are already - // present in the underlying epoll-set. - // - // Since this is not a correctness issue, we do not need to maintain all the - // fds in the cache. Hence we just use an LRU cache of size 'MAX_FDS_IN_CACHE' - // - // NOTE: An ideal implementation of this should do the following: - // 1) Add fds to the cache in pollable_add_fd() function (i.e whenever the fd - // is added to the pollable's epoll set) - // 2) Remove the fd from the cache whenever the fd is removed from the - // underlying epoll set (i.e whenever fd_orphan() is called). - // - // Implementing (2) above (i.e removing fds from cache on fd_orphan) adds a - // lot of complexity since an fd can be present in multiple pollables. So our - // implementation ONLY DOES (1) and NOT (2). - // - // The cache_fd.salt variable helps here to maintain correctness (it serves as - // an epoch that differentiates one grpc_fd from the other even though both of - // them may have the same fd number) - // - // The following implements LRU-eviction cache of fds in this pollable - cached_fd fd_cache[MAX_FDS_IN_CACHE]; - int fd_cache_size; - uint64_t fd_cache_counter; // Recency timer tick counter }; static const char* pollable_type_string(pollable_type t) { @@ -189,37 +151,86 @@ static void pollable_unref(pollable* p, int line, const char* reason); * Fd Declarations */ -// Monotonically increasing Epoch counter that is assinged to each grpc_fd. See -// the description of 'salt' variable in 'grpc_fd' for more details -// TODO: (sreek/kpayson) gpr_atm is intptr_t which may not be wide-enough on -// 32-bit systems. Change this to int_64 - atleast on 32-bit systems -static gpr_atm g_fd_salt; - struct grpc_fd { - int fd; + grpc_fd(int fd, const char* name, bool track_err) + : fd(fd), track_err(track_err) { + gpr_mu_init(&orphan_mu); + gpr_mu_init(&pollable_mu); + read_closure.InitEvent(); + write_closure.InitEvent(); + error_closure.InitEvent(); - // Since fd numbers can be reused (after old fds are closed), this serves as - // an epoch that uniquely identifies this fd (i.e the pair (salt, fd) is - // unique (until the salt counter (i.e g_fd_salt) overflows) - intptr_t salt; + char* fd_name; + gpr_asprintf(&fd_name, "%s fd=%d", name, fd); + grpc_iomgr_register_object(&iomgr_object, fd_name); +#ifndef NDEBUG + if (grpc_trace_fd_refcount.enabled()) { + gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, this, fd_name); + } +#endif + gpr_free(fd_name); + } + + // This is really the dtor, but the poller threads waking up from + // epoll_wait() may access the (read|write|error)_closure after destruction. + // Since the object will be added to the free pool, this behavior is + // not going to cause issues, except spurious events if the FD is reused + // while the race happens. + void destroy() { + grpc_iomgr_unregister_object(&iomgr_object); + + POLLABLE_UNREF(pollable_obj, "fd_pollable"); + pollset_fds.clear(); + gpr_mu_destroy(&pollable_mu); + gpr_mu_destroy(&orphan_mu); + + read_closure.DestroyEvent(); + write_closure.DestroyEvent(); + error_closure.DestroyEvent(); + + invalidate(); + } + +#ifndef NDEBUG + /* Since an fd is never really destroyed (i.e gpr_free() is not called), it is + * hard-to-debug cases where fd fields are accessed even after calling + * fd_destroy(). The following invalidates fd fields to make catching such + * errors easier */ + void invalidate() { + fd = -1; + gpr_atm_no_barrier_store(&refst, -1); + memset(&orphan_mu, -1, sizeof(orphan_mu)); + memset(&pollable_mu, -1, sizeof(pollable_mu)); + pollable_obj = nullptr; + on_done_closure = nullptr; + memset(&iomgr_object, -1, sizeof(iomgr_object)); + track_err = false; + } +#else + void invalidate() {} +#endif + + int fd; // refst format: // bit 0 : 1=Active / 0=Orphaned // bits 1-n : refcount // Ref/Unref by two to avoid altering the orphaned bit - gpr_atm refst; + gpr_atm refst = 1; gpr_mu orphan_mu; + // Protects pollable_obj and pollset_fds. gpr_mu pollable_mu; - pollable* pollable_obj; + grpc_core::InlinedVector pollset_fds; // Used in PO_MULTI. + pollable* pollable_obj = nullptr; // Used in PO_FD. - grpc_core::ManualConstructor read_closure; - grpc_core::ManualConstructor write_closure; - grpc_core::ManualConstructor error_closure; + grpc_core::LockfreeEvent read_closure; + grpc_core::LockfreeEvent write_closure; + grpc_core::LockfreeEvent error_closure; - struct grpc_fd* freelist_next; - grpc_closure* on_done_closure; + struct grpc_fd* freelist_next = nullptr; + grpc_closure* on_done_closure = nullptr; grpc_iomgr_object iomgr_object; @@ -258,6 +269,7 @@ struct grpc_pollset_worker { struct grpc_pollset { gpr_mu mu; gpr_atm worker_count; + gpr_atm active_pollable_type; pollable* active_pollable; bool kicked_without_poller; grpc_closure* shutdown_closure; @@ -337,39 +349,10 @@ static void ref_by(grpc_fd* fd, int n) { GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0); } -#ifndef NDEBUG -#define INVALIDATE_FD(fd) invalidate_fd(fd) -/* Since an fd is never really destroyed (i.e gpr_free() is not called), it is - * hard to cases where fd fields are accessed even after calling fd_destroy(). - * The following invalidates fd fields to make catching such errors easier */ -static void invalidate_fd(grpc_fd* fd) { - fd->fd = -1; - fd->salt = -1; - gpr_atm_no_barrier_store(&fd->refst, -1); - memset(&fd->orphan_mu, -1, sizeof(fd->orphan_mu)); - memset(&fd->pollable_mu, -1, sizeof(fd->pollable_mu)); - fd->pollable_obj = nullptr; - fd->on_done_closure = nullptr; - memset(&fd->iomgr_object, -1, sizeof(fd->iomgr_object)); - fd->track_err = false; -} -#else -#define INVALIDATE_FD(fd) -#endif - /* Uninitialize and add to the freelist */ static void fd_destroy(void* arg, grpc_error* error) { grpc_fd* fd = static_cast(arg); - grpc_iomgr_unregister_object(&fd->iomgr_object); - POLLABLE_UNREF(fd->pollable_obj, "fd_pollable"); - gpr_mu_destroy(&fd->pollable_mu); - gpr_mu_destroy(&fd->orphan_mu); - - fd->read_closure->DestroyEvent(); - fd->write_closure->DestroyEvent(); - fd->error_closure->DestroyEvent(); - - INVALIDATE_FD(fd); + fd->destroy(); /* Add the fd to the freelist */ gpr_mu_lock(&fd_freelist_mu); @@ -429,35 +412,9 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) { if (new_fd == nullptr) { new_fd = static_cast(gpr_malloc(sizeof(grpc_fd))); - new_fd->read_closure.Init(); - new_fd->write_closure.Init(); - new_fd->error_closure.Init(); } - new_fd->fd = fd; - new_fd->salt = gpr_atm_no_barrier_fetch_add(&g_fd_salt, 1); - gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1); - gpr_mu_init(&new_fd->orphan_mu); - gpr_mu_init(&new_fd->pollable_mu); - new_fd->pollable_obj = nullptr; - new_fd->read_closure->InitEvent(); - new_fd->write_closure->InitEvent(); - new_fd->error_closure->InitEvent(); - new_fd->freelist_next = nullptr; - new_fd->on_done_closure = nullptr; - - char* fd_name; - gpr_asprintf(&fd_name, "%s fd=%d", name, fd); - grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name); -#ifndef NDEBUG - if (grpc_trace_fd_refcount.enabled()) { - gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, new_fd, fd_name); - } -#endif - gpr_free(fd_name); - - new_fd->track_err = track_err; - return new_fd; + return new (new_fd) grpc_fd(fd, name, track_err); } static int fd_wrapped_fd(grpc_fd* fd) { @@ -475,7 +432,6 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, // true so that the pollable will no longer access its owner_fd field. gpr_mu_lock(&fd->pollable_mu); pollable* pollable_obj = fd->pollable_obj; - gpr_mu_unlock(&fd->pollable_mu); if (pollable_obj) { gpr_mu_lock(&pollable_obj->owner_orphan_mu); @@ -487,6 +443,19 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, /* If release_fd is not NULL, we should be relinquishing control of the file descriptor fd->fd (but we still own the grpc_fd structure). */ if (release_fd != nullptr) { + // Remove the FD from all epolls sets, before releasing it. + // Otherwise, we will receive epoll events after we release the FD. + epoll_event ev_fd; + memset(&ev_fd, 0, sizeof(ev_fd)); + if (release_fd != nullptr) { + if (pollable_obj != nullptr) { // For PO_FD. + epoll_ctl(pollable_obj->epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); + } + for (size_t i = 0; i < fd->pollset_fds.size(); ++i) { // For PO_MULTI. + const int epfd = fd->pollset_fds[i]; + epoll_ctl(epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); + } + } *release_fd = fd->fd; } else { close(fd->fd); @@ -508,40 +477,58 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, gpr_mu_unlock(&pollable_obj->owner_orphan_mu); } + gpr_mu_unlock(&fd->pollable_mu); gpr_mu_unlock(&fd->orphan_mu); UNREF_BY(fd, 2, reason); /* Drop the reference */ } static bool fd_is_shutdown(grpc_fd* fd) { - return fd->read_closure->IsShutdown(); + return fd->read_closure.IsShutdown(); } /* Might be called multiple times */ static void fd_shutdown(grpc_fd* fd, grpc_error* why) { - if (fd->read_closure->SetShutdown(GRPC_ERROR_REF(why))) { + if (fd->read_closure.SetShutdown(GRPC_ERROR_REF(why))) { if (shutdown(fd->fd, SHUT_RDWR)) { if (errno != ENOTCONN) { gpr_log(GPR_ERROR, "Error shutting down fd %d. errno: %d", grpc_fd_wrapped_fd(fd), errno); } } - fd->write_closure->SetShutdown(GRPC_ERROR_REF(why)); - fd->error_closure->SetShutdown(GRPC_ERROR_REF(why)); + fd->write_closure.SetShutdown(GRPC_ERROR_REF(why)); + fd->error_closure.SetShutdown(GRPC_ERROR_REF(why)); } GRPC_ERROR_UNREF(why); } static void fd_notify_on_read(grpc_fd* fd, grpc_closure* closure) { - fd->read_closure->NotifyOn(closure); + fd->read_closure.NotifyOn(closure); } static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { - fd->write_closure->NotifyOn(closure); + fd->write_closure.NotifyOn(closure); } static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - fd->error_closure->NotifyOn(closure); + fd->error_closure.NotifyOn(closure); +} + +static bool fd_has_pollset(grpc_fd* fd, grpc_pollset* pollset) { + const int epfd = pollset->active_pollable->epfd; + grpc_core::MutexLock lock(&fd->pollable_mu); + for (size_t i = 0; i < fd->pollset_fds.size(); ++i) { + if (fd->pollset_fds[i] == epfd) { + return true; + } + } + return false; +} + +static void fd_add_pollset(grpc_fd* fd, grpc_pollset* pollset) { + const int epfd = pollset->active_pollable->epfd; + grpc_core::MutexLock lock(&fd->pollable_mu); + fd->pollset_fds.push_back(epfd); } /******************************************************************************* @@ -594,8 +581,6 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) { (*p)->root_worker = nullptr; (*p)->event_cursor = 0; (*p)->event_count = 0; - (*p)->fd_cache_size = 0; - (*p)->fd_cache_counter = 0; return GRPC_ERROR_NONE; } @@ -637,39 +622,6 @@ static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) { grpc_error* error = GRPC_ERROR_NONE; static const char* err_desc = "pollable_add_fd"; const int epfd = p->epfd; - gpr_mu_lock(&p->mu); - p->fd_cache_counter++; - - // Handle the case of overflow for our cache counter by - // reseting the recency-counter on all cache objects - if (p->fd_cache_counter == 0) { - for (int i = 0; i < p->fd_cache_size; i++) { - p->fd_cache[i].last_used = 0; - } - } - - int lru_idx = 0; - for (int i = 0; i < p->fd_cache_size; i++) { - if (p->fd_cache[i].fd == fd->fd && p->fd_cache[i].salt == fd->salt) { - GRPC_STATS_INC_POLLSET_FD_CACHE_HITS(); - p->fd_cache[i].last_used = p->fd_cache_counter; - gpr_mu_unlock(&p->mu); - return GRPC_ERROR_NONE; - } else if (p->fd_cache[i].last_used < p->fd_cache[lru_idx].last_used) { - lru_idx = i; - } - } - - // Add to cache - if (p->fd_cache_size < MAX_FDS_IN_CACHE) { - lru_idx = p->fd_cache_size; - p->fd_cache_size++; - } - p->fd_cache[lru_idx].fd = fd->fd; - p->fd_cache[lru_idx].salt = fd->salt; - p->fd_cache[lru_idx].last_used = p->fd_cache_counter; - gpr_mu_unlock(&p->mu); - if (grpc_polling_trace.enabled()) { gpr_log(GPR_INFO, "add fd %p (%d) to pollable %p", fd, fd->fd, p); } @@ -849,6 +801,7 @@ static grpc_error* pollset_kick_all(grpc_pollset* pollset) { static void pollset_init(grpc_pollset* pollset, gpr_mu** mu) { gpr_mu_init(&pollset->mu); gpr_atm_no_barrier_store(&pollset->worker_count, 0); + gpr_atm_no_barrier_store(&pollset->active_pollable_type, PO_EMPTY); pollset->active_pollable = POLLABLE_REF(g_empty_pollable, "pollset"); pollset->kicked_without_poller = false; pollset->shutdown_closure = nullptr; @@ -869,11 +822,11 @@ static int poll_deadline_to_millis_timeout(grpc_millis millis) { return static_cast(delta); } -static void fd_become_readable(grpc_fd* fd) { fd->read_closure->SetReady(); } +static void fd_become_readable(grpc_fd* fd) { fd->read_closure.SetReady(); } -static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); } +static void fd_become_writable(grpc_fd* fd) { fd->write_closure.SetReady(); } -static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); } +static void fd_has_errors(grpc_fd* fd) { fd->error_closure.SetReady(); } /* Get the pollable_obj attached to this fd. If none is attached, create a new * pollable object (of type PO_FD), attach it to the fd and return it @@ -1283,6 +1236,8 @@ static grpc_error* pollset_add_fd_locked(grpc_pollset* pollset, grpc_fd* fd) { POLLABLE_UNREF(pollset->active_pollable, "pollset"); pollset->active_pollable = po_at_start; } else { + gpr_atm_rel_store(&pollset->active_pollable_type, + pollset->active_pollable->type); POLLABLE_UNREF(po_at_start, "pollset_add_fd"); } return error; @@ -1329,6 +1284,8 @@ static grpc_error* pollset_as_multipollable_locked(grpc_pollset* pollset, pollset->active_pollable = po_at_start; *pollable_obj = nullptr; } else { + gpr_atm_rel_store(&pollset->active_pollable_type, + pollset->active_pollable->type); *pollable_obj = POLLABLE_REF(pollset->active_pollable, "pollset_set"); POLLABLE_UNREF(po_at_start, "pollset_as_multipollable"); } @@ -1337,9 +1294,23 @@ static grpc_error* pollset_as_multipollable_locked(grpc_pollset* pollset, static void pollset_add_fd(grpc_pollset* pollset, grpc_fd* fd) { GPR_TIMER_SCOPE("pollset_add_fd", 0); - gpr_mu_lock(&pollset->mu); + + // We never transition from PO_MULTI to other modes (i.e., PO_FD or PO_EMOPTY) + // and, thus, it is safe to simply store and check whether the FD has already + // been added to the active pollable previously. + if (gpr_atm_acq_load(&pollset->active_pollable_type) == PO_MULTI && + fd_has_pollset(fd, pollset)) { + return; + } + + grpc_core::MutexLock lock(&pollset->mu); grpc_error* error = pollset_add_fd_locked(pollset, fd); - gpr_mu_unlock(&pollset->mu); + + // If we are in PO_MULTI mode, we should update the pollsets of the FD. + if (gpr_atm_no_barrier_load(&pollset->active_pollable_type) == PO_MULTI) { + fd_add_pollset(fd, pollset); + } + GRPC_LOG_IF_ERROR("pollset_add_fd", error); } From f919ace038044b4ee88fa0fb77c87ac8a19d1f06 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 7 Feb 2019 08:34:54 -0800 Subject: [PATCH 286/814] Add a microbenchmark for immediately-firing alarms --- CMakeLists.txt | 48 ++++++++++++++ Makefile | 49 ++++++++++++++ build.yaml | 20 ++++++ test/cpp/microbenchmarks/BUILD | 7 ++ test/cpp/microbenchmarks/bm_alarm.cc | 64 +++++++++++++++++++ .../generated/sources_and_headers.json | 21 ++++++ tools/run_tests/generated/tests.json | 22 +++++++ 7 files changed, 231 insertions(+) create mode 100644 test/cpp/microbenchmarks/bm_alarm.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 7425e62f8f0..6f1a0f6af9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -538,6 +538,9 @@ add_dependencies(buildtests_cxx auth_property_iterator_test) add_dependencies(buildtests_cxx backoff_test) add_dependencies(buildtests_cxx bdp_estimator_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_dependencies(buildtests_cxx bm_alarm) +endif() +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx bm_arena) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -11177,6 +11180,51 @@ endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) +add_executable(bm_alarm + test/cpp/microbenchmarks/bm_alarm.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(bm_alarm + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(bm_alarm + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_benchmark + ${_gRPC_BENCHMARK_LIBRARIES} + grpc++_test_util_unsecure + grpc_test_util_unsecure + grpc++_unsecure + grpc_unsecure + gpr + grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif() +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) + add_executable(bm_arena test/cpp/microbenchmarks/bm_arena.cc third_party/googletest/googletest/src/gtest-all.cc diff --git a/Makefile b/Makefile index 7caf155058a..e41c0584c7d 100644 --- a/Makefile +++ b/Makefile @@ -1137,6 +1137,7 @@ async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test backoff_test: $(BINDIR)/$(CONFIG)/backoff_test bdp_estimator_test: $(BINDIR)/$(CONFIG)/bdp_estimator_test +bm_alarm: $(BINDIR)/$(CONFIG)/bm_alarm bm_arena: $(BINDIR)/$(CONFIG)/bm_arena bm_byte_buffer: $(BINDIR)/$(CONFIG)/bm_byte_buffer bm_call_create: $(BINDIR)/$(CONFIG)/bm_call_create @@ -1654,6 +1655,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/auth_property_iterator_test \ $(BINDIR)/$(CONFIG)/backoff_test \ $(BINDIR)/$(CONFIG)/bdp_estimator_test \ + $(BINDIR)/$(CONFIG)/bm_alarm \ $(BINDIR)/$(CONFIG)/bm_arena \ $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ @@ -1842,6 +1844,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/auth_property_iterator_test \ $(BINDIR)/$(CONFIG)/backoff_test \ $(BINDIR)/$(CONFIG)/bdp_estimator_test \ + $(BINDIR)/$(CONFIG)/bm_alarm \ $(BINDIR)/$(CONFIG)/bm_arena \ $(BINDIR)/$(CONFIG)/bm_byte_buffer \ $(BINDIR)/$(CONFIG)/bm_call_create \ @@ -2285,6 +2288,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/backoff_test || ( echo test backoff_test failed ; exit 1 ) $(E) "[RUN] Testing bdp_estimator_test" $(Q) $(BINDIR)/$(CONFIG)/bdp_estimator_test || ( echo test bdp_estimator_test failed ; exit 1 ) + $(E) "[RUN] Testing bm_alarm" + $(Q) $(BINDIR)/$(CONFIG)/bm_alarm || ( echo test bm_alarm failed ; exit 1 ) $(E) "[RUN] Testing bm_arena" $(Q) $(BINDIR)/$(CONFIG)/bm_arena || ( echo test bm_arena failed ; exit 1 ) $(E) "[RUN] Testing bm_byte_buffer" @@ -16186,6 +16191,50 @@ endif endif +BM_ALARM_SRC = \ + test/cpp/microbenchmarks/bm_alarm.cc \ + +BM_ALARM_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_ALARM_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/bm_alarm: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/bm_alarm: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/bm_alarm: $(PROTOBUF_DEP) $(BM_ALARM_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BM_ALARM_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_alarm + +endif + +endif + +$(BM_ALARM_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX +$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_alarm.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a + +deps_bm_alarm: $(BM_ALARM_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BM_ALARM_OBJS:.o=.dep) +endif +endif + + BM_ARENA_SRC = \ test/cpp/microbenchmarks/bm_arena.cc \ diff --git a/build.yaml b/build.yaml index bcd98aaac00..ec00450f28a 100644 --- a/build.yaml +++ b/build.yaml @@ -3936,6 +3936,26 @@ targets: - grpc - gpr uses_polling: false +- name: bm_alarm + build: test + language: c++ + src: + - test/cpp/microbenchmarks/bm_alarm.cc + deps: + - grpc_benchmark + - benchmark + - grpc++_test_util_unsecure + - grpc_test_util_unsecure + - grpc++_unsecure + - grpc_unsecure + - gpr + - grpc++_test_config + benchmark: true + defaults: benchmark + platforms: + - mac + - linux + - posix - name: bm_arena build: test language: c++ diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index a29462f78fc..70b4000780c 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -54,6 +54,13 @@ grpc_cc_binary( deps = [":helpers"], ) +grpc_cc_binary( + name = "bm_alarm", + testonly = 1, + srcs = ["bm_alarm.cc"], + deps = [":helpers"], +) + grpc_cc_binary( name = "bm_arena", testonly = 1, diff --git a/test/cpp/microbenchmarks/bm_alarm.cc b/test/cpp/microbenchmarks/bm_alarm.cc new file mode 100644 index 00000000000..64aad6476de --- /dev/null +++ b/test/cpp/microbenchmarks/bm_alarm.cc @@ -0,0 +1,64 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* This benchmark exists to ensure that immediately-firing alarms are fast */ + +#include +#include +#include +#include +#include +#include "test/core/util/test_config.h" +#include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" + +namespace grpc { +namespace testing { + +auto& force_library_initialization = Library::get(); + +static void BM_Alarm_Tag_Immediate(benchmark::State& state) { + TrackCounters track_counters; + CompletionQueue cq; + Alarm alarm; + void* output_tag; + bool ok; + auto deadline = grpc_timeout_seconds_to_deadline(0); + while (state.KeepRunning()) { + alarm.Set(&cq, deadline, nullptr); + cq.Next(&output_tag, &ok); + } + track_counters.Finish(state); +} +BENCHMARK(BM_Alarm_Tag_Immediate); + +} // namespace testing +} // namespace grpc + +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 6693fcec58e..ab01b8fca6a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -2708,6 +2708,27 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "benchmark", + "gpr", + "grpc++_test_config", + "grpc++_test_util_unsecure", + "grpc++_unsecure", + "grpc_benchmark", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "bm_alarm", + "src": [ + "test/cpp/microbenchmarks/bm_alarm.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "benchmark", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index f35be0c1f43..9a202ecf167 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3415,6 +3415,28 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_alarm", + "platforms": [ + "linux", + "mac", + "posix" + ], + "uses_polling": true + }, { "args": [], "benchmark": true, From 7e210fac5bb160c086ac3b0c2299190ae8a1e7df Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 6 Feb 2019 10:30:25 -0800 Subject: [PATCH 287/814] Pre-fetch Cocoapods master repo --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 23619ecbb8b..2ecd39465d4 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -48,6 +48,10 @@ set -ex # cocoapods export LANG=en_US.UTF-8 +# pre-fetch cocoapods master repo with HEAD only +mkdir -p ~/.cocoapods/repos +git clone --depth 1 https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/master + time pod repo update # needed by python # python From 817c28f22fb39bc4c278cae65588a4009b6c4261 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 7 Feb 2019 18:33:02 +0100 Subject: [PATCH 288/814] scaffolding for flaky network test --- .../internal_ci/linux/grpc_flaky_network.cfg | 23 ++++++++++++++ .../linux/grpc_flaky_network_in_docker.sh | 31 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 tools/internal_ci/linux/grpc_flaky_network.cfg create mode 100755 tools/internal_ci/linux/grpc_flaky_network_in_docker.sh diff --git a/tools/internal_ci/linux/grpc_flaky_network.cfg b/tools/internal_ci/linux/grpc_flaky_network.cfg new file mode 100644 index 00000000000..de7a3b9cd8f --- /dev/null +++ b/tools/internal_ci/linux/grpc_flaky_network.cfg @@ -0,0 +1,23 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_bazel.sh" +timeout_mins: 240 +env_vars { + key: "BAZEL_SCRIPT" + value: "tools/internal_ci/linux/grpc_flaky_network_in_docker.sh" +} diff --git a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh new file mode 100755 index 00000000000..42b6d44c1cb --- /dev/null +++ b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Run the flaky network test +# +# NOTE: No empty lines should appear in this file before igncr is set! +set -ex -o igncr || set -ex + +mkdir -p /var/local/git +git clone /var/local/jenkins/grpc /var/local/git/grpc +(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \ +&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \ +${name}') +cd /var/local/git/grpc + +# TODO(jtattermusch): install prerequsites if needed + +# TODO(jtattermusch): run the flaky network test instead +bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/... From 1fab48edfc539c5ac1bb2870d3158dd907c64936 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 6 Feb 2019 13:53:51 -0800 Subject: [PATCH 289/814] Add null input handling in grpc_json_destroy() --- src/core/lib/json/json.cc | 5 +---- .../credentials/google_default/google_default_credentials.cc | 2 +- src/core/lib/security/credentials/jwt/json_token.cc | 2 +- src/core/lib/security/credentials/jwt/jwt_verifier.cc | 4 ++-- .../lib/security/credentials/oauth2/oauth2_credentials.cc | 4 ++-- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/core/lib/json/json.cc b/src/core/lib/json/json.cc index e78b73cefd3..2ed45fe55fe 100644 --- a/src/core/lib/json/json.cc +++ b/src/core/lib/json/json.cc @@ -35,24 +35,21 @@ grpc_json* grpc_json_create(grpc_json_type type) { } void grpc_json_destroy(grpc_json* json) { + if (json == nullptr) return; while (json->child) { grpc_json_destroy(json->child); } - if (json->next) { json->next->prev = json->prev; } - if (json->prev) { json->prev->next = json->next; } else if (json->parent) { json->parent->child = json->next; } - if (json->owns_value) { gpr_free((void*)json->value); } - gpr_free(json); } diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc index aa57fa2c5ec..b6a79c1030e 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc @@ -272,7 +272,7 @@ end: GPR_ASSERT((result == nullptr) + (error == GRPC_ERROR_NONE) == 1); if (creds_path != nullptr) gpr_free(creds_path); grpc_slice_unref_internal(creds_data); - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); *creds = result; return error; } diff --git a/src/core/lib/security/credentials/jwt/json_token.cc b/src/core/lib/security/credentials/jwt/json_token.cc index 1c4827df0fc..113e2b83754 100644 --- a/src/core/lib/security/credentials/jwt/json_token.cc +++ b/src/core/lib/security/credentials/jwt/json_token.cc @@ -121,7 +121,7 @@ grpc_auth_json_key grpc_auth_json_key_create_from_string( char* scratchpad = gpr_strdup(json_string); grpc_json* json = grpc_json_parse_string(scratchpad); grpc_auth_json_key result = grpc_auth_json_key_create_from_json(json); - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); gpr_free(scratchpad); return result; } diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc index cdef0f322a9..87fe3cc8e08 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc @@ -666,7 +666,7 @@ static void on_keys_retrieved(void* user_data, grpc_error* error) { } end: - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); EVP_PKEY_free(verification_key); ctx->user_cb(ctx->user_data, status, claims); verifier_cb_ctx_destroy(ctx); @@ -719,7 +719,7 @@ static void on_openid_config_retrieved(void* user_data, grpc_error* error) { return; error: - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, nullptr); verifier_cb_ctx_destroy(ctx); } diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index ad63b01e754..b9af757d05e 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -80,7 +80,7 @@ grpc_auth_refresh_token grpc_auth_refresh_token_create_from_string( grpc_json* json = grpc_json_parse_string(scratchpad); grpc_auth_refresh_token result = grpc_auth_refresh_token_create_from_json(json); - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); gpr_free(scratchpad); return result; } @@ -199,7 +199,7 @@ end: } if (null_terminated_body != nullptr) gpr_free(null_terminated_body); if (new_access_token != nullptr) gpr_free(new_access_token); - if (json != nullptr) grpc_json_destroy(json); + grpc_json_destroy(json); return status; } From 619e6c8ef61d5740f81160c782d202f064971d25 Mon Sep 17 00:00:00 2001 From: Keith Moyer Date: Thu, 7 Feb 2019 11:25:50 -0800 Subject: [PATCH 290/814] Compare mask with zero Masking a value and comparing to one will only work if the mask itself is equal to one (which is not the case here). Comparing to zero works for any mask. --- src/core/lib/iomgr/tcp_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 61db36bd99e..dc168c58e34 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -740,7 +740,7 @@ static void process_errors(grpc_tcp* tcp) { return; } if (grpc_tcp_trace.enabled()) { - if ((msg.msg_flags & MSG_CTRUNC) == 1) { + if ((msg.msg_flags & MSG_CTRUNC) != 0) { gpr_log(GPR_INFO, "Error message was truncated."); } } From 236d657afc54180e3ae1f56ca1dcc5756fd4c1b4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 7 Feb 2019 16:06:11 +0100 Subject: [PATCH 291/814] change Grpc.nuspec metapackage into csproj --- src/csharp/Grpc.nuspec | 22 ---------------------- src/csharp/Grpc/.gitignore | 2 ++ src/csharp/Grpc/Grpc.csproj | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 22 deletions(-) delete mode 100644 src/csharp/Grpc.nuspec create mode 100644 src/csharp/Grpc/.gitignore create mode 100644 src/csharp/Grpc/Grpc.csproj diff --git a/src/csharp/Grpc.nuspec b/src/csharp/Grpc.nuspec deleted file mode 100644 index 7fbd8619230..00000000000 --- a/src/csharp/Grpc.nuspec +++ /dev/null @@ -1,22 +0,0 @@ - - - - Grpc - gRPC C# - C# implementation of gRPC - an RPC library and framework - C# implementation of gRPC - an RPC library and framework. See project site for more info. - $version$ - Google Inc. - grpc-packages - https://github.com/grpc/grpc/blob/master/LICENSE - https://github.com/grpc/grpc - false - Release $version$ of gRPC C# - Copyright 2015, Google Inc. - gRPC RPC Protocol HTTP/2 - - - - - - diff --git a/src/csharp/Grpc/.gitignore b/src/csharp/Grpc/.gitignore new file mode 100644 index 00000000000..1746e3269ed --- /dev/null +++ b/src/csharp/Grpc/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj new file mode 100644 index 00000000000..9f17e319714 --- /dev/null +++ b/src/csharp/Grpc/Grpc.csproj @@ -0,0 +1,25 @@ + + + + + + + Copyright 2015, Google Inc. + gRPC C# + C# implementation of gRPC - an RPC library and framework. + $(GrpcCsharpVersion) + Google Inc. + net45;netstandard1.5 + Grpc + gRPC RPC Protocol HTTP/2 + https://github.com/grpc/grpc + https://github.com/grpc/grpc/blob/master/LICENSE + + false + true + + + + + + From aaaa32ef7d482f9cf2fc29f32169f510551ac008 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 7 Feb 2019 16:36:18 +0100 Subject: [PATCH 292/814] change Grpc.Core.NativeDebug metapackage into csproj --- src/csharp/Grpc.Core.NativeDebug.nuspec | 25 ------------ src/csharp/Grpc.Core.NativeDebug/.gitignore | 2 + .../Grpc.Core.NativeDebug.csproj | 40 +++++++++++++++++++ 3 files changed, 42 insertions(+), 25 deletions(-) delete mode 100644 src/csharp/Grpc.Core.NativeDebug.nuspec create mode 100644 src/csharp/Grpc.Core.NativeDebug/.gitignore create mode 100644 src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj diff --git a/src/csharp/Grpc.Core.NativeDebug.nuspec b/src/csharp/Grpc.Core.NativeDebug.nuspec deleted file mode 100644 index d4bb8ad2237..00000000000 --- a/src/csharp/Grpc.Core.NativeDebug.nuspec +++ /dev/null @@ -1,25 +0,0 @@ - - - - Grpc.Core.NativeDebug - Grpc.Core: Native Debug Symbols - Debug symbols for the native library contained in Grpc.Core - Currently contains grpc_csharp_ext.pdb - $version$ - Google Inc. - grpc-packages - https://github.com/grpc/grpc/blob/master/LICENSE - https://github.com/grpc/grpc - false - Release $version$ - Copyright 2015, Google Inc. - gRPC RPC Protocol HTTP/2 - - - - - - - - - diff --git a/src/csharp/Grpc.Core.NativeDebug/.gitignore b/src/csharp/Grpc.Core.NativeDebug/.gitignore new file mode 100644 index 00000000000..1746e3269ed --- /dev/null +++ b/src/csharp/Grpc.Core.NativeDebug/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj new file mode 100644 index 00000000000..5f1cac05425 --- /dev/null +++ b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj @@ -0,0 +1,40 @@ + + + + + + + Copyright 2015, Google Inc. + Grpc.Core: Native Debug Symbols + Debug symbols for the native library contained in Grpc.Core + $(GrpcCsharpVersion) + Google Inc. + net45;netstandard1.5 + Grpc.Core.NativeDebug + gRPC RPC Protocol HTTP/2 + https://github.com/grpc/grpc + https://github.com/grpc/grpc/blob/master/LICENSE + + false + true + + + + + runtimes/win/native/grpc_csharp_ext.x86.dll + true + + + runtimes/win/native/grpc_csharp_ext.x86.pdb + true + + + runtimes/win/native/grpc_csharp_ext.x64.dll + true + + + runtimes/win/native/grpc_csharp_ext.x64.pdb + true + + + From 9197a6ea25ef2db778c6b72f33ae6ca5133ea142 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 7 Feb 2019 16:42:13 +0100 Subject: [PATCH 293/814] simplify c# build_packages scripts, get rid of a template --- src/csharp/build_packages_dotnetcli.bat | 11 +--- .../build_packages_dotnetcli.bat.template | 61 ------------------- 2 files changed, 3 insertions(+), 69 deletions(-) delete mode 100755 templates/src/csharp/build_packages_dotnetcli.bat.template diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 9fdfbcbd315..a482d3a5305 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -12,11 +12,6 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. -@rem Current package versions -set VERSION=1.19.0-dev - -@rem Adjust the location of nuget.exe -set NUGET=C:\nuget\nuget.exe set DOTNET=dotnet mkdir ..\..\artifacts @@ -41,9 +36,9 @@ xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\bu %DOTNET% pack --configuration Release Grpc.HealthCheck --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Reflection --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Tools --output ..\..\..\artifacts || goto :error - -%NUGET% pack Grpc.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts || goto :error -%NUGET% pack Grpc.Core.NativeDebug.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts +@rem build auxiliary packages +%DOTNET% pack --configuration Release Grpc --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Core.NativeDebug --output ..\..\..\artifacts || goto :error @rem copy resulting nuget packages to artifacts directory xcopy /Y /I *.nupkg ..\..\artifacts\ || goto :error diff --git a/templates/src/csharp/build_packages_dotnetcli.bat.template b/templates/src/csharp/build_packages_dotnetcli.bat.template deleted file mode 100755 index aa35ae1e6fc..00000000000 --- a/templates/src/csharp/build_packages_dotnetcli.bat.template +++ /dev/null @@ -1,61 +0,0 @@ -%YAML 1.2 ---- | - @rem Copyright 2016 gRPC authors. - @rem - @rem Licensed under the Apache License, Version 2.0 (the "License"); - @rem you may not use this file except in compliance with the License. - @rem You may obtain a copy of the License at - @rem - @rem http://www.apache.org/licenses/LICENSE-2.0 - @rem - @rem Unless required by applicable law or agreed to in writing, software - @rem distributed under the License is distributed on an "AS IS" BASIS, - @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - @rem See the License for the specific language governing permissions and - @rem limitations under the License. - - @rem Current package versions - set VERSION=${settings.csharp_version} - - @rem Adjust the location of nuget.exe - set NUGET=C:\nuget\nuget.exe - set DOTNET=dotnet - - mkdir ..\..\artifacts - - @rem Collect the artifacts built by the previous build step - mkdir nativelibs - powershell -Command "cp -r ..\..\input_artifacts\csharp_ext_* nativelibs" - - @rem Collect protoc artifacts built by the previous build step - mkdir protoc_plugins - powershell -Command "cp -r ..\..\input_artifacts\protoc_* protoc_plugins" - - %%DOTNET% restore Grpc.sln || goto :error - - @rem To be able to build, we also need to put grpc_csharp_ext to its normal location - xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\build\x64\Release${"\\"} - - %%DOTNET% pack --configuration Release Grpc.Core.Api --output ..\..\..\artifacts || goto :error - %%DOTNET% pack --configuration Release Grpc.Core --output ..\..\..\artifacts || goto :error - %%DOTNET% pack --configuration Release Grpc.Core.Testing --output ..\..\..\artifacts || goto :error - %%DOTNET% pack --configuration Release Grpc.Auth --output ..\..\..\artifacts || goto :error - %%DOTNET% pack --configuration Release Grpc.HealthCheck --output ..\..\..\artifacts || goto :error - %%DOTNET% pack --configuration Release Grpc.Reflection --output ..\..\..\artifacts || goto :error - %%DOTNET% pack --configuration Release Grpc.Tools --output ..\..\..\artifacts || goto :error - - %%NUGET% pack Grpc.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts || goto :error - %%NUGET% pack Grpc.Core.NativeDebug.nuspec -Version %VERSION% -OutputDirectory ..\..\artifacts - - @rem copy resulting nuget packages to artifacts directory - xcopy /Y /I *.nupkg ..\..\artifacts\ || goto :error - - @rem create a zipfile with the artifacts as well - powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('..\..\artifacts', 'csharp_nugets_windows_dotnetcli.zip');" - xcopy /Y /I csharp_nugets_windows_dotnetcli.zip ..\..\artifacts\ || goto :error - - goto :EOF - - :error - echo Failed! - exit /b %errorlevel% From 70a05a7c531b239040c0fddee54f295eb443b266 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 7 Feb 2019 16:45:07 +0100 Subject: [PATCH 294/814] unify usage of Version vs VersionPrefix --- src/csharp/Grpc.Tools/Grpc.Tools.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index 61fa75a4ec2..aa39dd0fe9b 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -4,7 +4,7 @@ Protobuf.MSBuild - $(GrpcCsharpVersion) + $(GrpcCsharpVersion) net45;netstandard1.3 From 8a9e0742373ce5cc5815a3b04662dd13f84f7e65 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 7 Feb 2019 21:43:15 +0100 Subject: [PATCH 295/814] build -dev nugets with timestamp suffix --- src/csharp/build_packages_dotnetcli.bat | 3 +++ src/csharp/expand_dev_version.sh | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/csharp/expand_dev_version.sh diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index a482d3a5305..f500310865b 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -24,6 +24,9 @@ powershell -Command "cp -r ..\..\input_artifacts\csharp_ext_* nativelibs" mkdir protoc_plugins powershell -Command "cp -r ..\..\input_artifacts\protoc_* protoc_plugins" +@rem Add current timestamp to dev nugets +expand_dev_version.sh + %DOTNET% restore Grpc.sln || goto :error @rem To be able to build, we also need to put grpc_csharp_ext to its normal location diff --git a/src/csharp/expand_dev_version.sh b/src/csharp/expand_dev_version.sh new file mode 100644 index 00000000000..555f22a619c --- /dev/null +++ b/src/csharp/expand_dev_version.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Updates the GrpcSharpVersion property so that we can build +# dev nuget packages differentiated by timestamp. + +set -e + +cd "$(dirname "$0")" + +DEV_DATETIME_SUFFIX=$(date -u "+%Y%m%d%H%M") +# expand the -dev suffix to contain current timestamp +sed -ibak "s/-dev<\/GrpcCsharpVersion>/-dev${DEV_DATETIME_SUFFIX}<\/GrpcCsharpVersion>/" Grpc.Core/Version.csproj.include From a61785f18492b4780d69322490ec710c4e3af008 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 7 Feb 2019 12:52:04 -0800 Subject: [PATCH 296/814] Don't count internal ApplicationCallbackExcCtx against ExcCtx count This was originally done for ExcCtx in https://github.com/grpc/grpc/pull/15825. This avoids a hang in our pre-fork handler, where grpc_core::Executor::RunClosures attempts to increment the thread count from an invocation of grpc_prefork(): --- src/core/lib/iomgr/exec_ctx.h | 33 ++++++++++++++++++++++------- src/core/lib/iomgr/executor.cc | 3 ++- src/core/lib/iomgr/timer_manager.cc | 3 ++- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index 16ac14ba6c5..ef11f99dae0 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -49,6 +49,10 @@ typedef struct grpc_combiner grpc_combiner; be counted by fork handlers */ #define GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD 4 +/* This application callback exec ctx was initialized by an internal thread, and + should not be counted by fork handlers */ +#define GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD 1 + extern grpc_closure_scheduler* grpc_schedule_on_exec_ctx; gpr_timespec grpc_millis_to_timespec(grpc_millis millis, gpr_clock_type clock); @@ -229,13 +233,12 @@ class ExecCtx { class ApplicationCallbackExecCtx { public: - ApplicationCallbackExecCtx() { - if (reinterpret_cast( - gpr_tls_get(&callback_exec_ctx_)) == nullptr) { - grpc_core::Fork::IncExecCtxCount(); - gpr_tls_set(&callback_exec_ctx_, reinterpret_cast(this)); - } - } + /** Default Constructor */ + ApplicationCallbackExecCtx() { Set(this, flags_); } + + /** Parameterised Constructor */ + ApplicationCallbackExecCtx(uintptr_t fl) : flags_(fl) { Set(this, flags_); } + ~ApplicationCallbackExecCtx() { if (reinterpret_cast( gpr_tls_get(&callback_exec_ctx_)) == this) { @@ -248,12 +251,25 @@ class ApplicationCallbackExecCtx { (*f->functor_run)(f, f->internal_success); } gpr_tls_set(&callback_exec_ctx_, reinterpret_cast(nullptr)); - grpc_core::Fork::DecExecCtxCount(); + if (!(GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags_)) { + grpc_core::Fork::DecExecCtxCount(); + } } else { GPR_DEBUG_ASSERT(head_ == nullptr); GPR_DEBUG_ASSERT(tail_ == nullptr); } } + + static void Set(ApplicationCallbackExecCtx* exec_ctx, uintptr_t flags) { + if (reinterpret_cast( + gpr_tls_get(&callback_exec_ctx_)) == nullptr) { + if (!(GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags)) { + grpc_core::Fork::IncExecCtxCount(); + } + gpr_tls_set(&callback_exec_ctx_, reinterpret_cast(exec_ctx)); + } + } + static void Enqueue(grpc_experimental_completion_queue_functor* functor, int is_success) { functor->internal_success = is_success; @@ -278,6 +294,7 @@ class ApplicationCallbackExecCtx { static void GlobalShutdown(void) { gpr_tls_destroy(&callback_exec_ctx_); } private: + uintptr_t flags_; grpc_experimental_completion_queue_functor* head_{nullptr}; grpc_experimental_completion_queue_functor* tail_{nullptr}; GPR_TLS_CLASS_DECL(callback_exec_ctx_); diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index 1e7c6a907a2..2ad8972fc79 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -116,7 +116,8 @@ size_t Executor::RunClosures(const char* executor_name, // application-level callbacks. No need to create a new ExecCtx, though, // since there already is one and it is flushed (but not destructed) in this // function itself. - grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx( + GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD); grpc_closure* c = list.head; while (c != nullptr) { diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index 1da242938a2..4469db70dd0 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -110,7 +110,8 @@ static void run_some_timers() { // could start seeing application-level callbacks. No need to // create a new ExecCtx, though, since there already is one and it is // flushed (but not destructed) in this function itself - grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx( + GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD); // if there's something to execute... gpr_mu_lock(&g_mu); From db1c09ad49840ae9e030c84e0fabd2e5c4ebddd8 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 7 Feb 2019 12:51:25 -0800 Subject: [PATCH 297/814] Fix subchannel call destruction --- .../ext/filters/client_channel/subchannel.cc | 36 ++++++++++--------- .../ext/filters/client_channel/subchannel.h | 6 ++-- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 35225b0d5c3..1a07edad09c 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -116,21 +116,6 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate, elem->filter->start_transport_op(elem, op); } -namespace { - -void SubchannelCallDestroy(void* arg, grpc_error* error) { - GPR_TIMER_SCOPE("subchannel_call_destroy", 0); - SubchannelCall* call = static_cast(arg); - grpc_closure* after_call_stack_destroy = call->after_call_stack_destroy(); - call->~SubchannelCall(); - // This should be the last step to destroy the subchannel call, because - // call->after_call_stack_destroy(), if not null, will free the call arena. - grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(call), nullptr, - after_call_stack_destroy); -} - -} // namespace - RefCountedPtr ConnectedSubchannel::CreateCall( const CallArgs& args, grpc_error** error) { const size_t allocation_size = @@ -149,7 +134,7 @@ RefCountedPtr ConnectedSubchannel::CreateCall( args.arena, /* arena */ args.call_combiner /* call_combiner */ }; - *error = grpc_call_stack_init(channel_stack_, 1, SubchannelCallDestroy, + *error = grpc_call_stack_init(channel_stack_, 1, SubchannelCall::Destroy, call.get(), &call_args); if (GPR_UNLIKELY(*error != GRPC_ERROR_NONE)) { const char* error_string = grpc_error_string(*error); @@ -226,6 +211,25 @@ void SubchannelCall::Unref(const DebugLocation& location, const char* reason) { GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason); } +void SubchannelCall::Destroy(void* arg, grpc_error* error) { + GPR_TIMER_SCOPE("subchannel_call_destroy", 0); + SubchannelCall* self = static_cast(arg); + // Keep some members before destroying the subchannel call. + grpc_closure* after_call_stack_destroy = self->after_call_stack_destroy_; + RefCountedPtr connected_subchannel = + std::move(self->connected_subchannel_); + // Destroy the subchannel call. + self->~SubchannelCall(); + // Destroy the call stack. This should be after destroying the subchannel + // call, because call->after_call_stack_destroy(), if not null, will free the + // call arena. + grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(self), nullptr, + after_call_stack_destroy); + // Automatically reset connected_subchannel. This should be after destroying + // the call stack, because destroying call stack needs access to the channel + // stack. +} + void SubchannelCall::MaybeInterceptRecvTrailingMetadata( grpc_transport_stream_op_batch* batch) { // only intercept payloads with recv trailing. diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 47c21ff8680..bb8e45bf965 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -131,10 +131,6 @@ class SubchannelCall { // Returns the call stack of the subchannel call. grpc_call_stack* GetCallStack(); - grpc_closure* after_call_stack_destroy() const { - return after_call_stack_destroy_; - } - // Sets the 'then_schedule_closure' argument for call stack destruction. // Must be called once per call. void SetAfterCallStackDestroy(grpc_closure* closure); @@ -148,6 +144,8 @@ class SubchannelCall { void Unref(); void Unref(const DebugLocation& location, const char* reason); + static void Destroy(void* arg, grpc_error* error); + private: // Allow RefCountedPtr<> to access IncrementRefCount(). template From 56a93d4c18eb63128cba815e11976cd59f7fa452 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 7 Feb 2019 14:41:20 -0800 Subject: [PATCH 298/814] Add no enum sanitizer annotations around functions that need to fill/load in grpc_status_code --- src/core/lib/surface/call.cc | 6 +++--- src/core/lib/transport/error_utils.cc | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index d53eb704420..3efe81f51eb 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1494,9 +1494,9 @@ static void free_no_op_completion(void* p, grpc_cq_completion* completion) { gpr_free(completion); } -static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, - size_t nops, void* notify_tag, - int is_notify_tag_closure) { +__attribute__((no_sanitize("enum"))) static grpc_call_error call_start_batch( + grpc_call* call, const grpc_op* ops, size_t nops, void* notify_tag, + int is_notify_tag_closure) { GPR_TIMER_SCOPE("call_start_batch", 0); size_t i; diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc index 558f1d494cd..3294b2accdd 100644 --- a/src/core/lib/transport/error_utils.cc +++ b/src/core/lib/transport/error_utils.cc @@ -44,10 +44,10 @@ static grpc_error* recursively_find_error_with_field(grpc_error* error, return nullptr; } -void grpc_error_get_status(grpc_error* error, grpc_millis deadline, - grpc_status_code* code, grpc_slice* slice, - grpc_http2_error_code* http_error, - const char** error_string) { +__attribute__((no_sanitize("enum"))) void grpc_error_get_status( + grpc_error* error, grpc_millis deadline, grpc_status_code* code, + grpc_slice* slice, grpc_http2_error_code* http_error, + const char** error_string) { // Start with the parent error and recurse through the tree of children // until we find the first one that has a status code. grpc_error* found_error = From 64fed49459fa24048fc2765c3ac5dbc6317b97a8 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Mon, 4 Feb 2019 14:18:43 -0800 Subject: [PATCH 299/814] Added bazel_skylib dependency in preparation for protobuf update Protobuf 3.7.0 will depend on bazel_skylib, so gRPC needs to add it as a dependency in its own workspace. --- bazel/grpc_deps.bzl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 30c5d2a4843..e5cd03f8faa 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -185,6 +185,14 @@ def grpc_deps(): sha256 = "ee854b5de299138c1f4a2edb5573d22b21d975acfc7aa938f36d30b49ef97498", ) + if "bazel_skylib" not in native.existing_rules(): + http_archive( + name = "bazel_skylib", + sha256 = "ba5d15ca230efca96320085d8e4d58da826d1f81b444ef8afccd8b23e0799b52", + strip_prefix = "bazel-skylib-f83cb8dd6f5658bc574ccd873e25197055265d1c", + urls = ["https://github.com/bazelbuild/bazel-skylib/archive/f83cb8dd6f5658bc574ccd873e25197055265d1c.tar.gz"], + ) + if "io_opencensus_cpp" not in native.existing_rules(): http_archive( name = "io_opencensus_cpp", From 06d76ebf235490a2372b6fea8223959b5ad1004d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 7 Feb 2019 11:02:52 +0100 Subject: [PATCH 300/814] Fix formatting of bazel_skylib dependency --- bazel/grpc_deps.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index e5cd03f8faa..61a46e1ee5c 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -190,7 +190,7 @@ def grpc_deps(): name = "bazel_skylib", sha256 = "ba5d15ca230efca96320085d8e4d58da826d1f81b444ef8afccd8b23e0799b52", strip_prefix = "bazel-skylib-f83cb8dd6f5658bc574ccd873e25197055265d1c", - urls = ["https://github.com/bazelbuild/bazel-skylib/archive/f83cb8dd6f5658bc574ccd873e25197055265d1c.tar.gz"], + url = "https://github.com/bazelbuild/bazel-skylib/archive/f83cb8dd6f5658bc574ccd873e25197055265d1c.tar.gz", ) if "io_opencensus_cpp" not in native.existing_rules(): From 7cd19f2af3f5c79e8e96158ec67dde8005f6b8e7 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Thu, 7 Feb 2019 14:50:44 -0800 Subject: [PATCH 301/814] Updated check_bazel_workspace.py --- tools/run_tests/sanity/check_bazel_workspace.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py index 1486d0bd277..36016349383 100755 --- a/tools/run_tests/sanity/check_bazel_workspace.py +++ b/tools/run_tests/sanity/check_bazel_workspace.py @@ -34,6 +34,7 @@ git_submodule_hashes = { for s in git_submodules } +_BAZEL_SKYLIB_DEP_NAME = 'bazel_skylib' _BAZEL_TOOLCHAINS_DEP_NAME = 'com_github_bazelbuild_bazeltoolchains' _TWISTED_TWISTED_DEP_NAME = 'com_github_twisted_twisted' _YAML_PYYAML_DEP_NAME = 'com_github_yaml_pyyaml' @@ -53,6 +54,7 @@ _GRPC_DEP_NAMES = [ 'com_github_cares_cares', 'com_google_absl', 'io_opencensus_cpp', + _BAZEL_SKYLIB_DEP_NAME, _BAZEL_TOOLCHAINS_DEP_NAME, _TWISTED_TWISTED_DEP_NAME, _YAML_PYYAML_DEP_NAME, @@ -62,6 +64,7 @@ _GRPC_DEP_NAMES = [ ] _GRPC_BAZEL_ONLY_DEPS = [ + _BAZEL_SKYLIB_DEP_NAME, _BAZEL_TOOLCHAINS_DEP_NAME, _TWISTED_TWISTED_DEP_NAME, _YAML_PYYAML_DEP_NAME, From ff72f3eeff2839b5727f562e6ad273a27a3a22d4 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 7 Feb 2019 14:57:58 -0800 Subject: [PATCH 302/814] Skip the test instead --- src/core/lib/surface/call.cc | 6 +++--- src/core/lib/transport/error_utils.cc | 8 ++++---- test/core/util/ubsan_suppressions.txt | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 3efe81f51eb..d53eb704420 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1494,9 +1494,9 @@ static void free_no_op_completion(void* p, grpc_cq_completion* completion) { gpr_free(completion); } -__attribute__((no_sanitize("enum"))) static grpc_call_error call_start_batch( - grpc_call* call, const grpc_op* ops, size_t nops, void* notify_tag, - int is_notify_tag_closure) { +static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, + size_t nops, void* notify_tag, + int is_notify_tag_closure) { GPR_TIMER_SCOPE("call_start_batch", 0); size_t i; diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc index 3294b2accdd..558f1d494cd 100644 --- a/src/core/lib/transport/error_utils.cc +++ b/src/core/lib/transport/error_utils.cc @@ -44,10 +44,10 @@ static grpc_error* recursively_find_error_with_field(grpc_error* error, return nullptr; } -__attribute__((no_sanitize("enum"))) void grpc_error_get_status( - grpc_error* error, grpc_millis deadline, grpc_status_code* code, - grpc_slice* slice, grpc_http2_error_code* http_error, - const char** error_string) { +void grpc_error_get_status(grpc_error* error, grpc_millis deadline, + grpc_status_code* code, grpc_slice* slice, + grpc_http2_error_code* http_error, + const char** error_string) { // Start with the parent error and recurse through the tree of children // until we find the first one that has a status code. grpc_error* found_error = diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt index 8e17d37ec7e..06533d9eb62 100644 --- a/test/core/util/ubsan_suppressions.txt +++ b/test/core/util/ubsan_suppressions.txt @@ -21,3 +21,4 @@ enum:grpc_op_string signed-integer-overflow:chrono enum:grpc_http2_error_to_grpc_status enum:grpc_chttp2_cancel_stream +enum:api_fuzzer From 89ee1a8b102f7058b35afbabf6d8ffe9bac4a25c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 7 Feb 2019 19:13:45 -0800 Subject: [PATCH 303/814] Improved interception docs --- include/grpcpp/impl/codegen/interceptor.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 03520867f9c..3af783a61b6 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -45,6 +45,10 @@ namespace experimental { /// PRE_RECV means an interception between the time that a certain /// operation has been requested and it is available. POST_RECV means that a /// result is available but has not yet been passed back to the application. +/// A batch of interception points will only contain either PRE or POST hooks +/// but not both types. For example, a batch with PRE_SEND hook points will not +/// contain POST_RECV or POST_SEND ops. Likewise, a batch with POST_* ops can +/// not contain PRE_* ops. enum class InterceptionHookPoints { /// The first three in this list are for clients and servers PRE_SEND_INITIAL_METADATA, @@ -52,8 +56,8 @@ enum class InterceptionHookPoints { POST_SEND_MESSAGE, PRE_SEND_STATUS, // server only PRE_SEND_CLOSE, // client only: WritesDone for stream; after write in unary - /// The following three are for hijacked clients only and can only be - /// registered by the global interceptor + /// The following three are for hijacked clients only. A batch with PRE_RECV_* + /// hook points will never contain hook points of other types. PRE_RECV_INITIAL_METADATA, PRE_RECV_MESSAGE, PRE_RECV_STATUS, From c71b2f4fb71d2b9c8a0a2f1efa56b26a9bc8fac7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 7 Feb 2019 19:36:31 -0800 Subject: [PATCH 304/814] Global Interceptor Registration allowed only once --- include/grpcpp/impl/codegen/client_interceptor.h | 12 ++++-------- src/cpp/client/client_interceptor.cc | 5 +++++ test/cpp/end2end/client_interceptors_end2end_test.cc | 9 --------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 7dfe2290a3f..defbeabfb63 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -172,14 +172,10 @@ class ClientRpcInfo { // PLEASE DO NOT USE THIS. ALWAYS PREFER PER CHANNEL INTERCEPTORS OVER A GLOBAL // INTERCEPTOR. IF USAGE IS ABSOLUTELY NECESSARY, PLEASE READ THE SAFETY NOTES. // Registers a global client interceptor factory object, which is used for all -// RPCs made in this process. If the argument is nullptr, the global -// interceptor factory is deregistered. The application is responsible for -// maintaining the life of the object while gRPC operations are in progress. It -// is unsafe to try to register/deregister if any gRPC operation is in progress. -// For safety, it is in the best interests of the developer to register the -// global interceptor factory once at the start of the process before any gRPC -// operations have begun. Deregistration is optional since gRPC does not -// maintain any references to the object. +// RPCs made in this process. The application is responsible for maintaining the +// life of the object while gRPC operations are in progress. The global +// interceptor factory should only be registered once at the start of the +// process before any gRPC operations have begun. void RegisterGlobalClientInterceptorFactory( ClientInterceptorFactoryInterface* factory); diff --git a/src/cpp/client/client_interceptor.cc b/src/cpp/client/client_interceptor.cc index 3a5cac9830f..15ab89c5e67 100644 --- a/src/cpp/client/client_interceptor.cc +++ b/src/cpp/client/client_interceptor.cc @@ -28,6 +28,11 @@ experimental::ClientInterceptorFactoryInterface* namespace experimental { void RegisterGlobalClientInterceptorFactory( ClientInterceptorFactoryInterface* factory) { + if (internal::g_global_client_interceptor_factory != nullptr) { + GPR_ASSERT(false && + "It is illegal to call RegisterGlobalClientInterceptorFactory " + "multiple times."); + } internal::g_global_client_interceptor_factory = factory; } } // namespace experimental diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index 177922f4576..d9099d722b2 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -894,9 +894,6 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, DummyGlobalInterceptor) { MakeCall(channel); // Make sure all 20 dummy interceptors were run with the global interceptor EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 21); - // Reset the global interceptor. This is again 'safe' because there are no - // other ongoing gRPC operations - experimental::RegisterGlobalClientInterceptorFactory(nullptr); } TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) { @@ -920,9 +917,6 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) { MakeCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); - // Reset the global interceptor. This is again 'safe' because there are no - // other ongoing gRPC operations - experimental::RegisterGlobalClientInterceptorFactory(nullptr); } TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { @@ -946,9 +940,6 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { MakeCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); - // Reset the global interceptor. This is again 'safe' because there are no - // other ongoing gRPC operations - experimental::RegisterGlobalClientInterceptorFactory(nullptr); } } // namespace From f815656256139f8772cc0223da5029be3868d8c0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 8 Feb 2019 00:12:29 -0800 Subject: [PATCH 305/814] Instantiate an application callback exec ctx in security filter --- src/core/lib/security/transport/server_auth_filter.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc index f93eb4275e3..81b9c2ce074 100644 --- a/src/core/lib/security/transport/server_auth_filter.cc +++ b/src/core/lib/security/transport/server_auth_filter.cc @@ -169,6 +169,7 @@ static void on_md_processing_done( grpc_status_code status, const char* error_details) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; // If the call was not cancelled while we were in flight, process the result. if (gpr_atm_full_cas(&calld->state, static_cast(STATE_INIT), From cd22177e04424ee36d5c22dc8e55cd3480dfcb64 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 8 Feb 2019 10:05:19 -0800 Subject: [PATCH 306/814] Add manual test suite --- src/objective-c/manual_tests/AppDelegate.h | 25 ++ src/objective-c/manual_tests/AppDelegate.m | 23 ++ .../GrpcIosTest.xcodeproj/project.pbxproj | 380 ++++++++++++++++++ src/objective-c/manual_tests/Info.plist | 43 ++ src/objective-c/manual_tests/Main.storyboard | 61 +++ src/objective-c/manual_tests/Podfile | 100 +++++ src/objective-c/manual_tests/ViewController.m | 117 ++++++ src/objective-c/manual_tests/main.m | 26 ++ 8 files changed, 775 insertions(+) create mode 100644 src/objective-c/manual_tests/AppDelegate.h create mode 100644 src/objective-c/manual_tests/AppDelegate.m create mode 100644 src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj create mode 100644 src/objective-c/manual_tests/Info.plist create mode 100644 src/objective-c/manual_tests/Main.storyboard create mode 100644 src/objective-c/manual_tests/Podfile create mode 100644 src/objective-c/manual_tests/ViewController.m create mode 100644 src/objective-c/manual_tests/main.m diff --git a/src/objective-c/manual_tests/AppDelegate.h b/src/objective-c/manual_tests/AppDelegate.h new file mode 100644 index 00000000000..b4b675059a4 --- /dev/null +++ b/src/objective-c/manual_tests/AppDelegate.h @@ -0,0 +1,25 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +@interface AppDelegate : UIResponder + +@property(strong, nonatomic) UIWindow *window; + +@end diff --git a/src/objective-c/manual_tests/AppDelegate.m b/src/objective-c/manual_tests/AppDelegate.m new file mode 100644 index 00000000000..659f7528d22 --- /dev/null +++ b/src/objective-c/manual_tests/AppDelegate.m @@ -0,0 +1,23 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "AppDelegate.h" + +@implementation AppDelegate + +@end diff --git a/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj b/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..00004e06cad --- /dev/null +++ b/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj @@ -0,0 +1,380 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 4E1314BB1DA3DC6ECCEB96AB /* libPods-GrpcIosTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D22EC48A487B02F76135EA3 /* libPods-GrpcIosTest.a */; }; + 5EDA909B220DF1B00046D27A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EDA9094220DF1B00046D27A /* ViewController.m */; }; + 5EDA909C220DF1B00046D27A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EDA9096220DF1B00046D27A /* main.m */; }; + 5EDA909E220DF1B00046D27A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5EDA9098220DF1B00046D27A /* Main.storyboard */; }; + 5EDA909F220DF1B00046D27A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EDA9099220DF1B00046D27A /* AppDelegate.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D22EC48A487B02F76135EA3 /* libPods-GrpcIosTest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-GrpcIosTest.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EDA907B220DF0BC0046D27A /* GrpcIosTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GrpcIosTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EDA9094220DF1B00046D27A /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = SOURCE_ROOT; }; + 5EDA9095220DF1B00046D27A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; }; + 5EDA9096220DF1B00046D27A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; }; + 5EDA9098220DF1B00046D27A /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = SOURCE_ROOT; }; + 5EDA9099220DF1B00046D27A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; }; + 7C9FAFB11727DCA50888C1B8 /* Pods-GrpcIosTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GrpcIosTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GrpcIosTest/Pods-GrpcIosTest.debug.xcconfig"; sourceTree = ""; }; + A4E7CA72304A7B43FE8A5BC7 /* Pods-GrpcIosTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GrpcIosTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-GrpcIosTest/Pods-GrpcIosTest.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5EDA9078220DF0BC0046D27A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4E1314BB1DA3DC6ECCEB96AB /* libPods-GrpcIosTest.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2B8131AC634883AFEC02557C /* Pods */ = { + isa = PBXGroup; + children = ( + 7C9FAFB11727DCA50888C1B8 /* Pods-GrpcIosTest.debug.xcconfig */, + A4E7CA72304A7B43FE8A5BC7 /* Pods-GrpcIosTest.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 5EDA9072220DF0BC0046D27A = { + isa = PBXGroup; + children = ( + 5EDA9095220DF1B00046D27A /* AppDelegate.h */, + 5EDA9099220DF1B00046D27A /* AppDelegate.m */, + 5EDA9096220DF1B00046D27A /* main.m */, + 5EDA9098220DF1B00046D27A /* Main.storyboard */, + 5EDA9094220DF1B00046D27A /* ViewController.m */, + 5EDA907C220DF0BC0046D27A /* Products */, + 2B8131AC634883AFEC02557C /* Pods */, + E73D92116C1C328622A8C77F /* Frameworks */, + ); + sourceTree = ""; + }; + 5EDA907C220DF0BC0046D27A /* Products */ = { + isa = PBXGroup; + children = ( + 5EDA907B220DF0BC0046D27A /* GrpcIosTest.app */, + ); + name = Products; + sourceTree = ""; + }; + E73D92116C1C328622A8C77F /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1D22EC48A487B02F76135EA3 /* libPods-GrpcIosTest.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5EDA907A220DF0BC0046D27A /* GrpcIosTest */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EDA9091220DF0BD0046D27A /* Build configuration list for PBXNativeTarget "GrpcIosTest" */; + buildPhases = ( + 33B0CC39F9DDEC2CEFB413C5 /* [CP] Check Pods Manifest.lock */, + 5EDA9077220DF0BC0046D27A /* Sources */, + 5EDA9078220DF0BC0046D27A /* Frameworks */, + 5EDA9079220DF0BC0046D27A /* Resources */, + 3EA5D3D73BDF48C306548037 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GrpcIosTest; + productName = GrpcIosTest; + productReference = 5EDA907B220DF0BC0046D27A /* GrpcIosTest.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5EDA9073220DF0BC0046D27A /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1000; + ORGANIZATIONNAME = gRPC; + TargetAttributes = { + 5EDA907A220DF0BC0046D27A = { + CreatedOnToolsVersion = 10.0; + }; + }; + }; + buildConfigurationList = 5EDA9076220DF0BC0046D27A /* Build configuration list for PBXProject "GrpcIosTest" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5EDA9072220DF0BC0046D27A; + productRefGroup = 5EDA907C220DF0BC0046D27A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5EDA907A220DF0BC0046D27A /* GrpcIosTest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5EDA9079220DF0BC0046D27A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EDA909E220DF1B00046D27A /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 33B0CC39F9DDEC2CEFB413C5 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-GrpcIosTest-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 3EA5D3D73BDF48C306548037 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-GrpcIosTest/Pods-GrpcIosTest-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-GrpcIosTest/Pods-GrpcIosTest-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5EDA9077220DF0BC0046D27A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EDA909C220DF1B00046D27A /* main.m in Sources */, + 5EDA909B220DF1B00046D27A /* ViewController.m in Sources */, + 5EDA909F220DF1B00046D27A /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 5EDA908F220DF0BD0046D27A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 5EDA9090220DF0BD0046D27A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5EDA9092220DF0BD0046D27A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7C9FAFB11727DCA50888C1B8 /* Pods-GrpcIosTest.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.GrpcIosTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5EDA9093220DF0BD0046D27A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A4E7CA72304A7B43FE8A5BC7 /* Pods-GrpcIosTest.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.GrpcIosTest; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5EDA9076220DF0BC0046D27A /* Build configuration list for PBXProject "GrpcIosTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EDA908F220DF0BD0046D27A /* Debug */, + 5EDA9090220DF0BD0046D27A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5EDA9091220DF0BD0046D27A /* Build configuration list for PBXNativeTarget "GrpcIosTest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EDA9092220DF0BD0046D27A /* Debug */, + 5EDA9093220DF0BD0046D27A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5EDA9073220DF0BC0046D27A /* Project object */; +} diff --git a/src/objective-c/manual_tests/Info.plist b/src/objective-c/manual_tests/Info.plist new file mode 100644 index 00000000000..8824c40c504 --- /dev/null +++ b/src/objective-c/manual_tests/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/src/objective-c/manual_tests/Main.storyboard b/src/objective-c/manual_tests/Main.storyboard new file mode 100644 index 00000000000..e88f30e324b --- /dev/null +++ b/src/objective-c/manual_tests/Main.storyboard @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/manual_tests/Podfile b/src/objective-c/manual_tests/Podfile new file mode 100644 index 00000000000..7cb650a3412 --- /dev/null +++ b/src/objective-c/manual_tests/Podfile @@ -0,0 +1,100 @@ +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' + +install! 'cocoapods', :deterministic_uuids => false + +# Location of gRPC's repo root relative to this file. +GRPC_LOCAL_SRC = '../../..' + +# Install the dependencies in the main target plus all test targets. +%w( +GrpcIosTest +).each do |target_name| + target target_name do + pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true + + pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" + + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + + pod 'gRPC', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC + pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true + pod 'RemoteTest', :path => "../tests/RemoteTestClient", :inhibit_warnings => true + end +end + +# gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's +# pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded +# and before they are installed in the user project. +# +# This podspec searches for the gRPC core library headers under "$(PODS_ROOT)/gRPC-Core", where +# Cocoapods normally places the downloaded sources. When doing local development of the libraries, +# though, Cocoapods just takes the sources from whatever directory was specified using `:path`, and +# doesn't copy them under $(PODS_ROOT). When using static libraries, one can sometimes rely on the +# symbolic links to the pods headers that Cocoapods creates under "$(PODS_ROOT)/Headers". But those +# aren't created when using dynamic frameworks. So our solution is to modify the podspec on the fly +# to point at the local directory where the sources are. +# +# TODO(jcanizales): Send a PR to Cocoapods to get rid of this need. +pre_install do |installer| + # This is the gRPC-Core podspec object, as initialized by its podspec file. + grpc_core_spec = installer.pod_targets.find{|t| t.name.start_with?('gRPC-Core')}.root_spec + + # Copied from gRPC-Core.podspec, except for the adjusted src_root: + src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}" + grpc_core_spec.pod_target_xcconfig = { + 'GRPC_SRC_ROOT' => src_root, + 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"', + 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"', + # If we don't set these two settings, `include/grpc/support/time.h` and + # `src/core/lib/gpr/string.h` shadow the system `` and ``, breaking the + # build. + 'USE_HEADERMAP' => 'NO', + 'ALWAYS_SEARCH_USER_PATHS' => 'NO', + } +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' + end + + # CocoaPods creates duplicated library targets of gRPC-Core when the test targets include + # non-default subspecs of gRPC-Core. All of these library targets start with prefix 'gRPC-Core' + # and require the same error suppresion. + if target.name.start_with?('gRPC-Core') + target.build_configurations.each do |config| + # TODO(zyc): Remove this setting after the issue is resolved + # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void + # function" warning + config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1' + end + end + + # Activate Cronet for the dedicated build configuration 'Cronet', which will be used solely by + # the test target 'InteropTestsRemoteWithCronet' + # Activate GRPCCall+InternalTests functions for the dedicated build configuration 'Test', which will + # be used by all test targets using it. + if target.name == 'gRPC' || target.name.start_with?('gRPC.') + target.build_configurations.each do |config| + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_TEST_OBJC=1' + end + end + + # Enable NSAssert on gRPC + if target.name == 'gRPC' || target.name.start_with?('gRPC.') || + target.name == 'ProtoRPC' || target.name.start_with?('ProtoRPC.') || + target.name == 'RxLibrary' || target.name.start_with?('RxLibrary.') + target.build_configurations.each do |config| + if config.name != 'Release' + config.build_settings['ENABLE_NS_ASSERTIONS'] = 'YES' + end + end + end + end +end diff --git a/src/objective-c/manual_tests/ViewController.m b/src/objective-c/manual_tests/ViewController.m new file mode 100644 index 00000000000..c87e50285cf --- /dev/null +++ b/src/objective-c/manual_tests/ViewController.m @@ -0,0 +1,117 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +#import +#import +#import +#import + +NSString *const kRemoteHost = @"grpc-test.sandbox.googleapis.com"; +const int32_t kMessageSize = 100; + +@interface ViewController : UIViewController + +@end + +@implementation ViewController { + RMTTestService *_service; + dispatch_queue_t _dispatchQueue; + GRPCStreamingProtoCall *_call; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); +} + +- (IBAction)tapUnaryCall:(id)sender { + if (_service == nil) { + _service = [RMTTestService serviceWithHost:kRemoteHost]; + } + + // Set up request proto message + RMTSimpleRequest *request = [RMTSimpleRequest message]; + request.responseType = RMTPayloadType_Compressable; + request.responseSize = kMessageSize; + request.payload.body = [NSMutableData dataWithLength:kMessageSize]; + + GRPCUnaryProtoCall *call = [_service unaryCallWithMessage:request + responseHandler:self + callOptions:nil]; + [call start]; +} + +- (IBAction)tapStreamingCallStart:(id)sender { + if (_service == nil) { + _service = [RMTTestService serviceWithHost:kRemoteHost]; + } + + // Set up request proto message + RMTStreamingOutputCallRequest *request = RMTStreamingOutputCallRequest.message; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kMessageSize; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kMessageSize]; + + GRPCStreamingProtoCall *call = [_service fullDuplexCallWithResponseHandler:self callOptions:nil]; + [call start]; + _call = call; + // display something to confirm the tester the call is started + NSLog(@"Started streaming call"); +} + +- (IBAction)tapStreamingCallSend:(id)sender { + if (_call == nil) return; + + RMTStreamingOutputCallRequest *request = RMTStreamingOutputCallRequest.message; + RMTResponseParameters *parameters = [RMTResponseParameters message]; + parameters.size = kMessageSize; + [request.responseParametersArray addObject:parameters]; + request.payload.body = [NSMutableData dataWithLength:kMessageSize]; + + [_call writeMessage:request]; +} + +- (IBAction)tapStreamingCallStop:(id)sender { + if (_call == nil) return; + + [_call finish]; + + _call = nil; +} + +- (void)didReceiveInitialMetadata:(NSDictionary *)initialMetadata { + NSLog(@"Recv initial metadata: %@", initialMetadata); +} + +- (void)didReceiveProtoMessage:(GPBMessage *)message { + NSLog(@"Recv message: %@", message); +} + +- (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata + error:(nullable NSError *)error { + NSLog(@"Recv trailing metadata: %@, error: %@", trailingMetadata, error); +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue; +} + +@end diff --git a/src/objective-c/manual_tests/main.m b/src/objective-c/manual_tests/main.m new file mode 100644 index 00000000000..2797c6f17f2 --- /dev/null +++ b/src/objective-c/manual_tests/main.m @@ -0,0 +1,26 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} From ae88ee803ddf2bba46c6b32c70c80279550b38cf Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 8 Feb 2019 10:45:07 -0800 Subject: [PATCH 307/814] clang-format --- src/objective-c/manual_tests/AppDelegate.h | 4 ++-- src/objective-c/manual_tests/ViewController.m | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/objective-c/manual_tests/AppDelegate.h b/src/objective-c/manual_tests/AppDelegate.h index b4b675059a4..183abcf4ec8 100644 --- a/src/objective-c/manual_tests/AppDelegate.h +++ b/src/objective-c/manual_tests/AppDelegate.h @@ -18,8 +18,8 @@ #import -@interface AppDelegate : UIResponder +@interface AppDelegate : UIResponder -@property(strong, nonatomic) UIWindow *window; +@property(strong, nonatomic) UIWindow* window; @end diff --git a/src/objective-c/manual_tests/ViewController.m b/src/objective-c/manual_tests/ViewController.m index c87e50285cf..00bb516bdfc 100644 --- a/src/objective-c/manual_tests/ViewController.m +++ b/src/objective-c/manual_tests/ViewController.m @@ -18,15 +18,15 @@ #import -#import -#import #import #import +#import +#import NSString *const kRemoteHost = @"grpc-test.sandbox.googleapis.com"; const int32_t kMessageSize = 100; -@interface ViewController : UIViewController +@interface ViewController : UIViewController @end @@ -52,9 +52,8 @@ const int32_t kMessageSize = 100; request.responseSize = kMessageSize; request.payload.body = [NSMutableData dataWithLength:kMessageSize]; - GRPCUnaryProtoCall *call = [_service unaryCallWithMessage:request - responseHandler:self - callOptions:nil]; + GRPCUnaryProtoCall *call = + [_service unaryCallWithMessage:request responseHandler:self callOptions:nil]; [call start]; } From 07945070430dc817602b08f8aa00a0fd6597dd8f Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 8 Feb 2019 13:07:27 -0800 Subject: [PATCH 308/814] Don't pass service config from parent channel to grpclb balancer channel. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 5 +- test/cpp/end2end/grpclb_end2end_test.cc | 52 +++++++++++++++---- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 750b312fae9..63e381d64c7 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -917,6 +917,9 @@ grpc_channel_args* BuildBalancerChannelArgs( // LB policy name, since we want to use the default (pick_first) in // the LB channel. GRPC_ARG_LB_POLICY_NAME, + // Strip out the service config, since we don't want the LB policy + // config specified for the parent channel to affect the LB channel. + GRPC_ARG_SERVICE_CONFIG, // The channel arg for the server URI, since that will be different for // the LB channel than for the parent channel. The client channel // factory will re-add this arg with the right value. @@ -928,7 +931,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // resolver will have is_balancer=false, whereas our own addresses have // is_balancer=true. We need the LB channel to return addresses with // is_balancer=false so that it does not wind up recursively using the - // grpclb LB policy, as per the special case logic in client_channel.c. + // grpclb LB policy. GRPC_ARG_SERVER_ADDRESS_LIST, // The fake resolver response generator, because we are replacing it // with the one from the grpclb policy, used to propagate updates to diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index b589cd4044a..b56e65e50af 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -404,14 +404,6 @@ class GrpclbEnd2endTest : public ::testing::Test { } } - void SetNextResolutionAllBalancers() { - std::vector addresses; - for (size_t i = 0; i < balancer_servers_.size(); ++i) { - addresses.emplace_back(AddressData{balancer_servers_[i].port_, true, ""}); - } - SetNextResolution(addresses); - } - void ResetStub(int fallback_timeout = 0, const grpc::string& expected_targets = "") { ChannelArguments args; @@ -533,12 +525,29 @@ class GrpclbEnd2endTest : public ::testing::Test { return addresses; } - void SetNextResolution(const std::vector& address_data) { + void SetNextResolutionAllBalancers( + const char* service_config_json = nullptr) { + std::vector addresses; + for (size_t i = 0; i < balancer_servers_.size(); ++i) { + addresses.emplace_back(AddressData{balancer_servers_[i].port_, true, ""}); + } + SetNextResolution(addresses, service_config_json); + } + + void SetNextResolution(const std::vector& address_data, + const char* service_config_json = nullptr) { grpc_core::ExecCtx exec_ctx; grpc_core::ServerAddressList addresses = CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); - grpc_channel_args fake_result = {1, &fake_addresses}; + std::vector args = { + CreateServerAddressListChannelArg(&addresses), + }; + if (service_config_json != nullptr) { + args.push_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_SERVICE_CONFIG), + const_cast(service_config_json))); + } + grpc_channel_args fake_result = {args.size(), args.data()}; response_generator_->SetResponse(&fake_result); } @@ -693,6 +702,27 @@ TEST_F(SingleBalancerTest, Vanilla) { EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } +TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfig) { + SetNextResolutionAllBalancers( + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"grpclb\":{} }\n" + " ]\n" + "}"); + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + CheckRpcSendOk(1, 1000 /* timeout_ms */, true /* wait_for_ready */); + balancers_[0]->NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { SetNextResolutionAllBalancers(); // Same backend listed twice. From 67c010b44fdf91e81ef529bd68c3b0cd242a5c5d Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 8 Feb 2019 14:21:34 -0800 Subject: [PATCH 309/814] Add default initialization value --- src/core/lib/iomgr/exec_ctx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index ef11f99dae0..246c6f659b3 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -294,7 +294,7 @@ class ApplicationCallbackExecCtx { static void GlobalShutdown(void) { gpr_tls_destroy(&callback_exec_ctx_); } private: - uintptr_t flags_; + uintptr_t flags_{0u}; grpc_experimental_completion_queue_functor* head_{nullptr}; grpc_experimental_completion_queue_functor* tail_{nullptr}; GPR_TLS_CLASS_DECL(callback_exec_ctx_); From cddb5519f248762494a2c4d0c0ee6f288c780a5f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 8 Feb 2019 15:57:29 -0800 Subject: [PATCH 310/814] Add a test only method to reset global interceptor --- src/cpp/client/client_interceptor.cc | 5 +++++ test/cpp/end2end/client_interceptors_end2end_test.cc | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/src/cpp/client/client_interceptor.cc b/src/cpp/client/client_interceptor.cc index 15ab89c5e67..a91950cae2d 100644 --- a/src/cpp/client/client_interceptor.cc +++ b/src/cpp/client/client_interceptor.cc @@ -35,5 +35,10 @@ void RegisterGlobalClientInterceptorFactory( } internal::g_global_client_interceptor_factory = factory; } + +// For testing purposes only. +void TestOnlyResetGlobalClientInterceptorFactory() { + internal::g_global_client_interceptor_factory = nullptr; +} } // namespace experimental } // namespace grpc diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index d9099d722b2..cdeadb5364c 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -40,6 +40,10 @@ #include namespace grpc { + +namespace experimental { +void TestOnlyResetGlobalClientInterceptorFactory(); +} namespace testing { namespace { @@ -894,6 +898,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, DummyGlobalInterceptor) { MakeCall(channel); // Make sure all 20 dummy interceptors were run with the global interceptor EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 21); + experimental::TestOnlyResetGlobalClientInterceptorFactory(); } TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) { @@ -917,6 +922,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) { MakeCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); + experimental::TestOnlyResetGlobalClientInterceptorFactory(); } TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { @@ -940,6 +946,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) { MakeCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); + experimental::TestOnlyResetGlobalClientInterceptorFactory(); } } // namespace From 85d76b2888ddd19a743191d6676d4be17df6a584 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 8 Feb 2019 16:56:42 -0800 Subject: [PATCH 311/814] Add ApplicationCallbackExecCtx in other spots that may trigger application work --- .../ext/filters/client_channel/channel_connectivity.cc | 2 ++ .../ext/transport/cronet/transport/cronet_transport.cc | 8 ++++++++ src/core/lib/iomgr/cfstream_handle.cc | 2 ++ src/core/lib/security/credentials/jwt/jwt_credentials.cc | 1 + src/core/lib/security/credentials/jwt/jwt_verifier.cc | 1 + .../lib/security/credentials/plugin/plugin_credentials.cc | 1 + 6 files changed, 15 insertions(+) diff --git a/src/core/ext/filters/client_channel/channel_connectivity.cc b/src/core/ext/filters/client_channel/channel_connectivity.cc index c71d10274a8..9f970f6affa 100644 --- a/src/core/ext/filters/client_channel/channel_connectivity.cc +++ b/src/core/ext/filters/client_channel/channel_connectivity.cc @@ -35,6 +35,7 @@ grpc_connectivity_state grpc_channel_check_connectivity_state( /* forward through to the underlying client channel */ grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; grpc_connectivity_state state; GRPC_API_TRACE( @@ -202,6 +203,7 @@ void grpc_channel_watch_connectivity_state( gpr_timespec deadline, grpc_completion_queue* cq, void* tag) { grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel)); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; state_watcher* w = static_cast(gpr_malloc(sizeof(*w))); diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index ade88da4cb9..9551b4ba496 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -441,6 +441,7 @@ static void convert_cronet_array_to_metadata( */ static void on_failed(bidirectional_stream* stream, int net_error) { gpr_log(GPR_ERROR, "on_failed(%p, %d)", stream, net_error); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); @@ -467,6 +468,7 @@ static void on_failed(bidirectional_stream* stream, int net_error) { */ static void on_canceled(bidirectional_stream* stream) { CRONET_LOG(GPR_DEBUG, "on_canceled(%p)", stream); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); @@ -493,6 +495,7 @@ static void on_canceled(bidirectional_stream* stream) { */ static void on_succeeded(bidirectional_stream* stream) { CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); @@ -511,6 +514,7 @@ static void on_succeeded(bidirectional_stream* stream) { */ static void on_stream_ready(bidirectional_stream* stream) { CRONET_LOG(GPR_DEBUG, "W: on_stream_ready(%p)", stream); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); grpc_cronet_transport* t = s->curr_ct; @@ -541,6 +545,7 @@ static void on_response_headers_received( bidirectional_stream* stream, const bidirectional_stream_header_array* headers, const char* negotiated_protocol) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream, headers, negotiated_protocol); @@ -580,6 +585,7 @@ static void on_response_headers_received( Cronet callback */ static void on_write_completed(bidirectional_stream* stream, const char* data) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); CRONET_LOG(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data); @@ -598,6 +604,7 @@ static void on_write_completed(bidirectional_stream* stream, const char* data) { */ static void on_read_completed(bidirectional_stream* stream, char* data, int count) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; stream_obj* s = static_cast(stream->annotation); CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, @@ -640,6 +647,7 @@ static void on_read_completed(bidirectional_stream* stream, char* data, static void on_response_trailers_received( bidirectional_stream* stream, const bidirectional_stream_header_array* trailers) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; CRONET_LOG(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream, trailers); diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index 6cb9ca1a0d4..87b7b9fb334 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -52,6 +52,7 @@ CFStreamHandle* CFStreamHandle::CreateStreamHandle( void CFStreamHandle::ReadCallback(CFReadStreamRef stream, CFStreamEventType type, void* client_callback_info) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; CFStreamHandle* handle = static_cast(client_callback_info); if (grpc_tcp_trace.enabled()) { @@ -77,6 +78,7 @@ void CFStreamHandle::ReadCallback(CFReadStreamRef stream, void CFStreamHandle::WriteCallback(CFWriteStreamRef stream, CFStreamEventType type, void* clientCallBackInfo) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; CFStreamHandle* handle = static_cast(clientCallBackInfo); if (grpc_tcp_trace.enabled()) { diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.cc b/src/core/lib/security/credentials/jwt/jwt_credentials.cc index f2591a1ea5e..70fe45e56dc 100644 --- a/src/core/lib/security/credentials/jwt/jwt_credentials.cc +++ b/src/core/lib/security/credentials/jwt/jwt_credentials.cc @@ -174,6 +174,7 @@ grpc_call_credentials* grpc_service_account_jwt_access_credentials_create( gpr_free(clean_json); } GPR_ASSERT(reserved == nullptr); + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; return grpc_service_account_jwt_access_credentials_create_from_auth_json_key( grpc_auth_json_key_create_from_string(json_key), token_lifetime) diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc index cdef0f322a9..d887c354b41 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc @@ -353,6 +353,7 @@ static verifier_cb_ctx* verifier_cb_ctx_create( grpc_jwt_claims* claims, const char* audience, grpc_slice signature, const char* signed_jwt, size_t signed_jwt_len, void* user_data, grpc_jwt_verification_done_cb cb) { + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; verifier_cb_ctx* ctx = static_cast(gpr_zalloc(sizeof(verifier_cb_ctx))); diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc index 52982fdb8f1..59fecbca992 100644 --- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc +++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc @@ -114,6 +114,7 @@ static void plugin_md_request_metadata_ready(void* request, grpc_status_code status, const char* error_details) { /* called from application code */ + grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx(GRPC_EXEC_CTX_FLAG_IS_FINISHED | GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP); grpc_plugin_credentials::pending_request* r = From 30d8f7a6268b30f7b3b4d5657ce936d2f903f968 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 8 Feb 2019 17:14:45 -0800 Subject: [PATCH 312/814] Memset before setting length --- src/core/lib/iomgr/buffer_list.cc | 2 +- test/core/iomgr/buffer_list_test.cc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index 321de539934..73915933eee 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -188,8 +188,8 @@ void extract_opt_stats_from_cmsg(ConnectionMetrics* metrics, } static int get_socket_tcp_info(grpc_core::tcp_info* info, int fd) { - info->length = sizeof(*info) - sizeof(socklen_t); memset(info, 0, sizeof(*info)); + info->length = sizeof(*info) - sizeof(socklen_t); return getsockopt(fd, IPPROTO_TCP, TCP_INFO, info, &(info->length)); } } /* namespace */ diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index 61a81e31c2b..70e36940425 100644 --- a/test/core/iomgr/buffer_list_test.cc +++ b/test/core/iomgr/buffer_list_test.cc @@ -66,6 +66,7 @@ static void TestVerifierCalledOnAckVerifier(void* arg, GPR_ASSERT(ts->acked_time.time.clock_type == GPR_CLOCK_REALTIME); GPR_ASSERT(ts->acked_time.time.tv_sec == 123); GPR_ASSERT(ts->acked_time.time.tv_nsec == 456); + GPR_ASSERT(ts->info.length > 0); gpr_atm* done = reinterpret_cast(arg); gpr_atm_rel_store(done, static_cast(1)); } From d8947ae0731b4d474a8155c739181cf5cc460a91 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 8 Feb 2019 17:17:00 -0800 Subject: [PATCH 313/814] Fix internal build error --- test/cpp/end2end/channelz_service_test.cc | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index e7719b5c14e..fe52a64db48 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -35,8 +35,6 @@ #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" -#include - #include using grpc::channelz::v1::GetChannelRequest; @@ -54,14 +52,6 @@ using grpc::channelz::v1::GetSubchannelResponse; using grpc::channelz::v1::GetTopChannelsRequest; using grpc::channelz::v1::GetTopChannelsResponse; -// This code snippet can be used to print out any responses for -// visual debugging. -// -// -// string out_str; -// google::protobuf::TextFormat::PrintToString(resp, &out_str); -// std::cout << "resp: " << out_str << "\n"; - namespace grpc { namespace testing { namespace { From 40544bb112a87ed9738d92b4f2a4b3c39551a031 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 8 Feb 2019 17:33:47 -0800 Subject: [PATCH 314/814] Min deployment target change --- .../manual_tests/GrpcIosTest.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj b/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj index 00004e06cad..9063719aa2e 100644 --- a/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj +++ b/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj @@ -323,6 +323,7 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -342,6 +343,7 @@ CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", From 34965961cf15dfdb8cc2a6c290849704771b763e Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Sat, 9 Feb 2019 12:56:02 -0800 Subject: [PATCH 315/814] check grpc is init before creating execctx --- src/core/lib/iomgr/fork_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index 2eebe3f26f6..0918e7ae1ba 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -47,11 +47,11 @@ bool registered_handlers = false; } // namespace void grpc_prefork() { - grpc_core::ExecCtx exec_ctx; skipped_handler = true; if (!grpc_is_initialized()) { return; } + grpc_core::ExecCtx exec_ctx; if (!grpc_core::Fork::Enabled()) { gpr_log(GPR_ERROR, "Fork support not enabled; try running with the " From dc8bac54ad4a0b4aa8c3e14862ffee5b547dff9e Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sat, 9 Feb 2019 22:16:29 -0800 Subject: [PATCH 316/814] patch --- tools/internal_ci/helper_scripts/prepare_build_macos_rc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc index 2ecd39465d4..e9ec07cd0f9 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc @@ -48,11 +48,9 @@ set -ex # cocoapods export LANG=en_US.UTF-8 -# pre-fetch cocoapods master repo with HEAD only +# pre-fetch cocoapods master repo's most recent commit only mkdir -p ~/.cocoapods/repos -git clone --depth 1 https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/master - -time pod repo update # needed by python +time git clone --depth 1 https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/master # python time pip install virtualenv --user python From 1124c4edd98ee2c051ebf99f36c55a3ea41df616 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Sun, 10 Feb 2019 11:22:30 -0800 Subject: [PATCH 317/814] increase timeout of cfstream-tests --- tools/run_tests/run_tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 2556e777730..986e7cd58c2 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1126,7 +1126,7 @@ class ObjCLanguage(object): }), self.config.job_spec( ['test/core/iomgr/ios/CFStreamTests/run_tests.sh'], - timeout_seconds=10 * 60, + timeout_seconds=20 * 60, shortname='cfstream-tests', cpu_cost=1e6, environ=_FORCE_ENVIRON_FOR_WRAPPERS), From 5c85f5a1a001eab3f671d674a915d720347c8f3a Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Sat, 9 Feb 2019 01:09:13 -0800 Subject: [PATCH 318/814] Ruby: refactor init/shutdown logic to avoid using atexit; fix windows --- src/ruby/ext/grpc/rb_call_credentials.c | 13 ++++--- src/ruby/ext/grpc/rb_channel.c | 16 +++++--- src/ruby/ext/grpc/rb_channel_credentials.c | 12 ++++-- src/ruby/ext/grpc/rb_compression_options.c | 16 ++++---- src/ruby/ext/grpc/rb_event_thread.c | 2 + src/ruby/ext/grpc/rb_grpc.c | 45 +++++++++++----------- src/ruby/ext/grpc/rb_grpc.h | 6 ++- src/ruby/ext/grpc/rb_server.c | 12 ++++-- 8 files changed, 71 insertions(+), 51 deletions(-) diff --git a/src/ruby/ext/grpc/rb_call_credentials.c b/src/ruby/ext/grpc/rb_call_credentials.c index be325975920..cea9620081f 100644 --- a/src/ruby/ext/grpc/rb_call_credentials.c +++ b/src/ruby/ext/grpc/rb_call_credentials.c @@ -134,8 +134,7 @@ static void grpc_rb_call_credentials_plugin_destroy(void* state) { // Not sure what needs to be done here } -/* Destroys the credentials instances. */ -static void grpc_rb_call_credentials_free(void* p) { +static void grpc_rb_call_credentials_free_internal(void* p) { grpc_rb_call_credentials* wrapper; if (p == NULL) { return; @@ -143,10 +142,15 @@ static void grpc_rb_call_credentials_free(void* p) { wrapper = (grpc_rb_call_credentials*)p; grpc_call_credentials_release(wrapper->wrapped); wrapper->wrapped = NULL; - xfree(p); } +/* Destroys the credentials instances. */ +static void grpc_rb_call_credentials_free(void* p) { + grpc_rb_call_credentials_free_internal(p); + grpc_ruby_shutdown(); +} + /* Protects the mark object from GC */ static void grpc_rb_call_credentials_mark(void* p) { grpc_rb_call_credentials* wrapper = NULL; @@ -175,6 +179,7 @@ static rb_data_type_t grpc_rb_call_credentials_data_type = { /* Allocates CallCredentials instances. Provides safe initial defaults for the instance fields. */ static VALUE grpc_rb_call_credentials_alloc(VALUE cls) { + grpc_ruby_init(); grpc_rb_call_credentials* wrapper = ALLOC(grpc_rb_call_credentials); wrapper->wrapped = NULL; wrapper->mark = Qnil; @@ -212,8 +217,6 @@ static VALUE grpc_rb_call_credentials_init(VALUE self, VALUE proc) { grpc_call_credentials* creds = NULL; grpc_metadata_credentials_plugin plugin; - grpc_ruby_once_init(); - TypedData_Get_Struct(self, grpc_rb_call_credentials, &grpc_rb_call_credentials_data_type, wrapper); diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 5bde962f788..d789e5a4362 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -143,14 +143,12 @@ static void* channel_safe_destroy_without_gil(void* arg) { return NULL; } -/* Destroys Channel instances. */ -static void grpc_rb_channel_free(void* p) { +static void grpc_rb_channel_free_internal(void* p) { grpc_rb_channel* ch = NULL; if (p == NULL) { return; }; ch = (grpc_rb_channel*)p; - if (ch->bg_wrapped != NULL) { /* assumption made here: it's ok to directly gpr_mu_lock the global * connection polling mutex because we're in a finalizer, @@ -159,10 +157,15 @@ static void grpc_rb_channel_free(void* p) { grpc_rb_channel_safe_destroy(ch->bg_wrapped); ch->bg_wrapped = NULL; } - xfree(p); } +/* Destroys Channel instances. */ +static void grpc_rb_channel_free(void* p) { + grpc_rb_channel_free_internal(p); + grpc_ruby_shutdown(); +} + /* Protects the mark object from GC */ static void grpc_rb_channel_mark(void* p) { grpc_rb_channel* channel = NULL; @@ -189,6 +192,7 @@ static rb_data_type_t grpc_channel_data_type = {"grpc_channel", /* Allocates grpc_rb_channel instances. */ static VALUE grpc_rb_channel_alloc(VALUE cls) { + grpc_ruby_init(); grpc_rb_channel* wrapper = ALLOC(grpc_rb_channel); wrapper->bg_wrapped = NULL; wrapper->credentials = Qnil; @@ -216,7 +220,6 @@ static VALUE grpc_rb_channel_init(int argc, VALUE* argv, VALUE self) { int stop_waiting_for_thread_start = 0; MEMZERO(&args, grpc_channel_args, 1); - grpc_ruby_once_init(); grpc_ruby_fork_guard(); rb_thread_call_without_gvl( wait_until_channel_polling_thread_started_no_gil, @@ -682,9 +685,10 @@ static VALUE run_poll_channels_loop(VALUE arg) { gpr_log( GPR_DEBUG, "GRPC_RUBY: run_poll_channels_loop - create connection polling thread"); + grpc_ruby_init(); rb_thread_call_without_gvl(run_poll_channels_loop_no_gil, NULL, run_poll_channels_loop_unblocking_func, NULL); - + grpc_ruby_shutdown(); return Qnil; } diff --git a/src/ruby/ext/grpc/rb_channel_credentials.c b/src/ruby/ext/grpc/rb_channel_credentials.c index 178224c6e00..970bc4eeb11 100644 --- a/src/ruby/ext/grpc/rb_channel_credentials.c +++ b/src/ruby/ext/grpc/rb_channel_credentials.c @@ -48,8 +48,7 @@ typedef struct grpc_rb_channel_credentials { grpc_channel_credentials* wrapped; } grpc_rb_channel_credentials; -/* Destroys the credentials instances. */ -static void grpc_rb_channel_credentials_free(void* p) { +static void grpc_rb_channel_credentials_free_internal(void* p) { grpc_rb_channel_credentials* wrapper = NULL; if (p == NULL) { return; @@ -61,6 +60,12 @@ static void grpc_rb_channel_credentials_free(void* p) { xfree(p); } +/* Destroys the credentials instances. */ +static void grpc_rb_channel_credentials_free(void* p) { + grpc_rb_channel_credentials_free_internal(p); + grpc_ruby_shutdown(); +} + /* Protects the mark object from GC */ static void grpc_rb_channel_credentials_mark(void* p) { grpc_rb_channel_credentials* wrapper = NULL; @@ -90,6 +95,7 @@ static rb_data_type_t grpc_rb_channel_credentials_data_type = { /* Allocates ChannelCredential instances. Provides safe initial defaults for the instance fields. */ static VALUE grpc_rb_channel_credentials_alloc(VALUE cls) { + grpc_ruby_init(); grpc_rb_channel_credentials* wrapper = ALLOC(grpc_rb_channel_credentials); wrapper->wrapped = NULL; wrapper->mark = Qnil; @@ -147,8 +153,6 @@ static VALUE grpc_rb_channel_credentials_init(int argc, VALUE* argv, const char* pem_root_certs_cstr = NULL; MEMZERO(&key_cert_pair, grpc_ssl_pem_key_cert_pair, 1); - grpc_ruby_once_init(); - /* "03" == no mandatory arg, 3 optional */ rb_scan_args(argc, argv, "03", &pem_root_certs, &pem_private_key, &pem_cert_chain); diff --git a/src/ruby/ext/grpc/rb_compression_options.c b/src/ruby/ext/grpc/rb_compression_options.c index 4ba6991ef66..d10c603460c 100644 --- a/src/ruby/ext/grpc/rb_compression_options.c +++ b/src/ruby/ext/grpc/rb_compression_options.c @@ -52,23 +52,26 @@ typedef struct grpc_rb_compression_options { grpc_compression_options* wrapped; } grpc_rb_compression_options; -/* Destroys the compression options instances and free the - * wrapped grpc compression options. */ -static void grpc_rb_compression_options_free(void* p) { +static void grpc_rb_compression_options_free_internal(void* p) { grpc_rb_compression_options* wrapper = NULL; if (p == NULL) { return; }; wrapper = (grpc_rb_compression_options*)p; - if (wrapper->wrapped != NULL) { gpr_free(wrapper->wrapped); wrapper->wrapped = NULL; } - xfree(p); } +/* Destroys the compression options instances and free the + * wrapped grpc compression options. */ +static void grpc_rb_compression_options_free(void* p) { + grpc_rb_compression_options_free_internal(p); + grpc_ruby_shutdown(); +} + /* Ruby recognized data type for the CompressionOptions class. */ static rb_data_type_t grpc_rb_compression_options_data_type = { "grpc_compression_options", @@ -87,10 +90,9 @@ static rb_data_type_t grpc_rb_compression_options_data_type = { Allocate the wrapped grpc compression options and initialize it here too. */ static VALUE grpc_rb_compression_options_alloc(VALUE cls) { + grpc_ruby_init(); grpc_rb_compression_options* wrapper = NULL; - grpc_ruby_once_init(); - wrapper = gpr_malloc(sizeof(grpc_rb_compression_options)); wrapper->wrapped = NULL; wrapper->wrapped = gpr_malloc(sizeof(grpc_compression_options)); diff --git a/src/ruby/ext/grpc/rb_event_thread.c b/src/ruby/ext/grpc/rb_event_thread.c index 281e41c9a88..c9ca14ed06a 100644 --- a/src/ruby/ext/grpc/rb_event_thread.c +++ b/src/ruby/ext/grpc/rb_event_thread.c @@ -115,6 +115,7 @@ static void grpc_rb_event_unblocking_func(void* arg) { static VALUE grpc_rb_event_thread(VALUE arg) { grpc_rb_event* event; (void)arg; + grpc_ruby_init(); while (true) { event = (grpc_rb_event*)rb_thread_call_without_gvl( grpc_rb_wait_for_event_no_gil, NULL, grpc_rb_event_unblocking_func, @@ -128,6 +129,7 @@ static VALUE grpc_rb_event_thread(VALUE arg) { } } grpc_rb_event_queue_destroy(); + grpc_ruby_shutdown(); return Qnil; } diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c index 872aed0cfce..4916cee4f7c 100644 --- a/src/ruby/ext/grpc/rb_grpc.c +++ b/src/ruby/ext/grpc/rb_grpc.c @@ -276,10 +276,6 @@ static bool grpc_ruby_forked_after_init(void) { } #endif -static void grpc_rb_shutdown(void) { - if (!grpc_ruby_forked_after_init()) grpc_shutdown(); -} - /* Initialize the GRPC module structs */ /* grpc_rb_sNewServerRpc is the struct that holds new server rpc details. */ @@ -298,12 +294,6 @@ VALUE sym_metadata = Qundef; static gpr_once g_once_init = GPR_ONCE_INIT; -static void grpc_ruby_once_init_internal() { - grpc_ruby_set_init_pid(); - grpc_init(); - atexit(grpc_rb_shutdown); -} - void grpc_ruby_fork_guard() { if (grpc_ruby_forked_after_init()) { rb_raise(rb_eRuntimeError, "grpc cannot be used before and after forking"); @@ -313,19 +303,7 @@ void grpc_ruby_fork_guard() { static VALUE bg_thread_init_rb_mu = Qundef; static int bg_thread_init_done = 0; -void grpc_ruby_once_init() { - /* ruby_vm_at_exit doesn't seem to be working. It would crash once every - * blue moon, and some users are getting it repeatedly. See the discussions - * - https://github.com/grpc/grpc/pull/5337 - * - https://bugs.ruby-lang.org/issues/12095 - * - * In order to still be able to handle the (unlikely) situation where the - * extension is loaded by a first Ruby VM that is subsequently destroyed, - * then loaded again by another VM within the same process, we need to - * schedule our initialization and destruction only once. - */ - gpr_once_init(&g_once_init, grpc_ruby_once_init_internal); - +static void grpc_ruby_init_threads() { // Avoid calling calling into ruby library (when creating threads here) // in gpr_once_init. In general, it appears to be unsafe to call // into the ruby library while holding a non-ruby mutex, because a gil yield @@ -339,6 +317,27 @@ void grpc_ruby_once_init() { rb_mutex_unlock(bg_thread_init_rb_mu); } +static int64_t g_grpc_ruby_init_count; + +void grpc_ruby_init() { + gpr_once_init(&g_once_init, grpc_ruby_set_init_pid); + grpc_init(); + grpc_ruby_init_threads(); + // (only gpr_log after logging has been initialized) + gpr_log(GPR_DEBUG, + "GRPC_RUBY: grpc_ruby_init - prev g_grpc_ruby_init_count:%" PRId64, + g_grpc_ruby_init_count++); +} + +void grpc_ruby_shutdown() { + GPR_ASSERT(g_grpc_ruby_init_count > 0); + if (!grpc_ruby_forked_after_init()) grpc_shutdown(); + gpr_log( + GPR_DEBUG, + "GRPC_RUBY: grpc_ruby_shutdown - prev g_grpc_ruby_init_count:%" PRId64, + g_grpc_ruby_init_count--); +} + void Init_grpc_c() { if (!grpc_rb_load_core()) { rb_raise(rb_eLoadError, "Couldn't find or load gRPC's dynamic C core"); diff --git a/src/ruby/ext/grpc/rb_grpc.h b/src/ruby/ext/grpc/rb_grpc.h index 4118435ecf7..2c4675839ac 100644 --- a/src/ruby/ext/grpc/rb_grpc.h +++ b/src/ruby/ext/grpc/rb_grpc.h @@ -67,8 +67,10 @@ VALUE grpc_rb_cannot_init_copy(VALUE copy, VALUE self); /* grpc_rb_time_timeval creates a gpr_timespec from a ruby time object. */ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval); -void grpc_ruby_once_init(); - void grpc_ruby_fork_guard(); +void grpc_ruby_init(); + +void grpc_ruby_shutdown(); + #endif /* GRPC_RB_H_ */ diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c index 2931f344092..4396de1c335 100644 --- a/src/ruby/ext/grpc/rb_server.c +++ b/src/ruby/ext/grpc/rb_server.c @@ -86,8 +86,7 @@ static void grpc_rb_server_maybe_destroy(grpc_rb_server* server) { } } -/* Destroys server instances. */ -static void grpc_rb_server_free(void* p) { +static void grpc_rb_server_free_internal(void* p) { grpc_rb_server* svr = NULL; gpr_timespec deadline; if (p == NULL) { @@ -104,6 +103,12 @@ static void grpc_rb_server_free(void* p) { xfree(p); } +/* Destroys server instances. */ +static void grpc_rb_server_free(void* p) { + grpc_rb_server_free_internal(p); + grpc_ruby_shutdown(); +} + static const rb_data_type_t grpc_rb_server_data_type = { "grpc_server", {GRPC_RB_GC_NOT_MARKED, @@ -123,6 +128,7 @@ static const rb_data_type_t grpc_rb_server_data_type = { /* Allocates grpc_rb_server instances. */ static VALUE grpc_rb_server_alloc(VALUE cls) { + grpc_ruby_init(); grpc_rb_server* wrapper = ALLOC(grpc_rb_server); wrapper->wrapped = NULL; wrapper->destroy_done = 0; @@ -142,8 +148,6 @@ static VALUE grpc_rb_server_init(VALUE self, VALUE channel_args) { grpc_channel_args args; MEMZERO(&args, grpc_channel_args, 1); - grpc_ruby_once_init(); - cq = grpc_completion_queue_create_for_pluck(NULL); TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, wrapper); From 52695cae917e125c2717b58accb7cb1526b7a265 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Sun, 10 Feb 2019 23:59:47 -0800 Subject: [PATCH 319/814] Fix TSAN flake in time_change_test --- test/cpp/end2end/time_change_test.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/cpp/end2end/time_change_test.cc b/test/cpp/end2end/time_change_test.cc index 9fbd01299d0..7f4e3caf6f9 100644 --- a/test/cpp/end2end/time_change_test.cc +++ b/test/cpp/end2end/time_change_test.cc @@ -74,14 +74,18 @@ static gpr_timespec now_impl(gpr_clock_type clock) { // offset the value returned by gpr_now(GPR_CLOCK_REALTIME) by msecs // milliseconds static void set_now_offset(int msecs) { + gpr_mu_lock(&g_mu); g_time_shift_sec = msecs / 1000; g_time_shift_nsec = (msecs % 1000) * 1e6; + gpr_mu_unlock(&g_mu); } // restore the original implementation of gpr_now() static void reset_now_offset() { + gpr_mu_lock(&g_mu); g_time_shift_sec = 0; g_time_shift_nsec = 0; + gpr_mu_unlock(&g_mu); } namespace grpc { From a832d66b09d5ba295726058153bdf5df6abf4565 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 1 Oct 2018 15:41:03 +0200 Subject: [PATCH 320/814] upgrade System.Interactive.Async to 3.2.0 --- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 2 +- src/csharp/Grpc.Core/Grpc.Core.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index 0dc73576bf5..eec8fc56de0 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -21,7 +21,7 @@ - + diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index b99c23ae131..43ace08e52c 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -85,7 +85,7 @@ - + From 611857accbbaf20635d5847bf4f1dcc38b0789dd Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Mon, 11 Feb 2019 09:56:39 -0500 Subject: [PATCH 321/814] Address guantaol@'s comments on Pull #17964 --- src/core/lib/iomgr/ev_epollex_linux.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index b6d13b44d12..0e66bc56440 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -447,14 +447,12 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, // Otherwise, we will receive epoll events after we release the FD. epoll_event ev_fd; memset(&ev_fd, 0, sizeof(ev_fd)); - if (release_fd != nullptr) { - if (pollable_obj != nullptr) { // For PO_FD. - epoll_ctl(pollable_obj->epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); - } - for (size_t i = 0; i < fd->pollset_fds.size(); ++i) { // For PO_MULTI. - const int epfd = fd->pollset_fds[i]; - epoll_ctl(epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); - } + if (pollable_obj != nullptr) { // For PO_FD. + epoll_ctl(pollable_obj->epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); + } + for (size_t i = 0; i < fd->pollset_fds.size(); ++i) { // For PO_MULTI. + const int epfd = fd->pollset_fds[i]; + epoll_ctl(epfd, EPOLL_CTL_DEL, fd->fd, &ev_fd); } *release_fd = fd->fd; } else { @@ -1295,7 +1293,7 @@ static grpc_error* pollset_as_multipollable_locked(grpc_pollset* pollset, static void pollset_add_fd(grpc_pollset* pollset, grpc_fd* fd) { GPR_TIMER_SCOPE("pollset_add_fd", 0); - // We never transition from PO_MULTI to other modes (i.e., PO_FD or PO_EMOPTY) + // We never transition from PO_MULTI to other modes (i.e., PO_FD or PO_EMPTY) // and, thus, it is safe to simply store and check whether the FD has already // been added to the active pollable previously. if (gpr_atm_acq_load(&pollset->active_pollable_type) == PO_MULTI && From b90dd36270be2c0be8bbdf16f49c6ed61f5bdf7c Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 11 Feb 2019 08:13:06 -0800 Subject: [PATCH 322/814] add comment --- src/core/lib/iomgr/fork_posix.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index 0918e7ae1ba..7f8fb7e828b 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -48,6 +48,8 @@ bool registered_handlers = false; void grpc_prefork() { skipped_handler = true; + // This may be called after core shuts down, so verify initialized before + // instantiating an ExecCtx. if (!grpc_is_initialized()) { return; } From f96d630c33c07889a40009fa074365fe7b27d4ce Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 8 Feb 2019 09:01:27 -0800 Subject: [PATCH 323/814] Document ApplicationCallbackExecCtx, update ExecCtx comments --- src/core/lib/iomgr/exec_ctx.h | 66 ++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index 16ac14ba6c5..4a3d52e220e 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -58,8 +58,8 @@ grpc_millis grpc_timespec_to_millis_round_up(gpr_timespec timespec); namespace grpc_core { /** Execution context. * A bag of data that collects information along a callstack. - * It is created on the stack at public API entry points, and stored internally - * as a thread-local variable. + * It is created on the stack at core entry points (public API or iomgr), and + * stored internally as a thread-local variable. * * Generally, to create an exec_ctx instance, add the following line at the top * of the public API entry point or at the start of a thread's work function : @@ -70,7 +70,7 @@ namespace grpc_core { * grpc_core::ExecCtx::Get() * * Specific responsibilities (this may grow in the future): - * - track a list of work that needs to be delayed until the top of the + * - track a list of core work that needs to be delayed until the base of the * call stack (this provides a convenient mechanism to run callbacks * without worrying about locking issues) * - provide a decision maker (via IsReadyToFinish) that provides a @@ -80,10 +80,19 @@ namespace grpc_core { * CONVENTIONS: * - Instance of this must ALWAYS be constructed on the stack, never * heap allocated. - * - Exactly one instance of ExecCtx must be created per thread. Instances must - * always be called exec_ctx. * - Do not pass exec_ctx as a parameter to a function. Always access it using * grpc_core::ExecCtx::Get(). + * - NOTE: In the future, the convention is likely to change to allow only one + * ExecCtx on a thread's stack at the same time. The TODO below + * discusses this plan in more detail. + * + * TODO(yashykt): Only allow one "active" ExecCtx on a thread at the same time. + * Stage 1: If a new one is created on the stack, it should just + * pass-through to the underlying ExecCtx deeper in the thread's + * stack. + * Stage 2: Assert if a 2nd one is ever created on the stack + * since that implies a core re-entry outside of application + * callbacks. */ class ExecCtx { public: @@ -227,6 +236,53 @@ class ExecCtx { ExecCtx* last_exec_ctx_ = Get(); }; +/** Application-callback execution context. + * A bag of data that collects information along a callstack. + * It is created on the stack at core entry points, and stored internally + * as a thread-local variable. + * + * There are three key differences between this structure and ExecCtx: + * 1. ApplicationCallbackExecCtx builds a list of application-level + * callbacks, but ExecCtx builds a list of internal callbacks to invoke. + * 2. ApplicationCallbackExecCtx invokes its callbacks only at destruction; + * there is no explicit Flush method. + * 3. If more than one ApplicationCallbackExecCtx is created on the thread's + * stack, only the one closest to the base of the stack is actually + * active and this is the only one that enqueues application callbacks. + * (Unlike ExecCtx, it is not feasible to prevent multiple of these on the + * stack since the executing application callback may itself enter core. + * However, the new one created will just pass callbacks through to the + * base one and those will not be executed until the return to the + * destructor of the base one, preventing unlimited stack growth.) + * + * This structure exists because application callbacks may themselves cause a + * core re-entry (e.g., through a public API call) and if that call in turn + * causes another application-callback, there could be arbitrarily growing + * stacks of core re-entries. Instead, any application callbacks instead should + * not be invoked until other core work is done and other application callbacks + * have completed. To accomplish this, any application callback should be + * enqueued using grpc_core::ApplicationCallbackExecCtx::Enqueue . + * + * CONVENTIONS: + * - Instances of this must ALWAYS be constructed on the stack, never + * heap allocated. + * - Instances of this are generally constructed before ExecCtx when needed. + * The only exception is for ExecCtx's that are explicitly flushed and + * that survive beyond the scope of the function that can cause application + * callbacks to be invoked (e.g., in the timer thread). + * + * Generally, core entry points that may trigger application-level callbacks + * will have the following declarations: + * + * grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; + * grpc_core::ExecCtx exec_ctx; + * + * This ordering is important to make sure that the ApplicationCallbackExecCtx + * is destroyed after the ExecCtx (to prevent the re-entry problem described + * above, as well as making sure that ExecCtx core callbacks are invoked first) + * + */ + class ApplicationCallbackExecCtx { public: ApplicationCallbackExecCtx() { From 93b7acd9bf11f0df780ec3a106792911b337db92 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Sun, 10 Feb 2019 22:09:15 -0800 Subject: [PATCH 324/814] Disable service config resolution with c-ares by default --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 2 +- test/cpp/naming/gen_build_yaml.py | 1 + test/cpp/naming/resolver_component_test.cc | 27 ++++++++ .../naming/resolver_component_tests_runner.py | 61 +++++++++++++++++++ .../naming/resolver_test_record_groups.yaml | 60 ++++++++++++++++++ 5 files changed, 150 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index bf8b0ea5f62..69d4ee24368 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -151,7 +151,7 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args) // Disable service config option const grpc_arg* arg = grpc_channel_args_find( channel_args_, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION); - request_service_config_ = !grpc_channel_arg_get_bool(arg, false); + request_service_config_ = !grpc_channel_arg_get_bool(arg, true); // Min time b/t resolutions option arg = grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS); diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py index aeff927824d..9bf5ae9b2f8 100755 --- a/test/cpp/naming/gen_build_yaml.py +++ b/test/cpp/naming/gen_build_yaml.py @@ -49,6 +49,7 @@ def _resolver_test_cases(resolver_component_data): (test_case['expected_chosen_service_config'] or '')), ('expected_lb_policy', (test_case['expected_lb_policy'] or '')), ('enable_srv_queries', test_case['enable_srv_queries']), + ('enable_txt_queries', test_case['enable_txt_queries']), ], }) return out diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index ff9ebe70a8e..9532529e45d 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -99,6 +99,13 @@ DEFINE_string( "generate " "the python script runner doesn't allow us to pass a gflags bool to this " "binary."); +DEFINE_string( + enable_txt_queries, "", + "Whether or not to enable TXT queries for the ares resolver instance." + "It would be better if this arg could be bool, but the way that we " + "generate " + "the python script runner doesn't allow us to pass a gflags bool to this " + "binary."); DEFINE_string(expected_lb_policy, "", "Expected lb policy name that appears in resolver result channel " "arg. Empty for none."); @@ -461,6 +468,26 @@ void RunResolvesRelevantRecordsTest(void (*OnDoneLocked)(void* arg, gpr_log(GPR_DEBUG, "Invalid value for --enable_srv_queries."); abort(); } + gpr_log(GPR_DEBUG, "resolver_component_test: --enable_txt_queries: %s", + FLAGS_enable_txt_queries.c_str()); + // By default, TXT queries are disabled, so tests that expect no TXT query + // should avoid setting any channel arg. Test cases that do rely on the TXT + // query must explicitly enable TXT though. + if (FLAGS_enable_txt_queries == "True") { + // Unlike SRV queries, there isn't a channel arg specific to TXT records. + // Rather, we use the resolver-agnostic "service config" resolution option, + // for which c-ares has its own specific default value, which isn't + // necessarily shared by other resolvers. + grpc_arg txt_queries_arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), false); + grpc_channel_args* tmp_args = + grpc_channel_args_copy_and_add(resolver_args, &txt_queries_arg, 1); + grpc_channel_args_destroy(resolver_args); + resolver_args = tmp_args; + } else if (FLAGS_enable_txt_queries != "False") { + gpr_log(GPR_DEBUG, "Invalid value for --enable_txt_queries."); + abort(); + } // create resolver and resolve grpc_core::OrphanablePtr resolver = grpc_core::ResolverRegistry::CreateResolver(whole_uri, resolver_args, diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index a4438cb100e..a0eda79ec62 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -126,6 +126,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -139,6 +140,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -152,6 +154,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -165,6 +168,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -178,6 +182,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -191,6 +196,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}', '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -204,6 +210,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}', '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -217,6 +224,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -230,6 +238,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -243,6 +252,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}', '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -256,6 +266,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}', '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -269,6 +280,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -282,6 +294,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -295,6 +308,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}', '--expected_lb_policy', '', '--enable_srv_queries', 'True', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -308,6 +322,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'False', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -321,6 +336,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'False', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -334,6 +350,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'False', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -347,6 +364,7 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '', '--expected_lb_policy', '', '--enable_srv_queries', 'False', + '--enable_txt_queries', 'True', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: @@ -360,6 +378,49 @@ current_test_subprocess = subprocess.Popen([ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}', '--expected_lb_policy', 'round_robin', '--enable_srv_queries', 'False', + '--enable_txt_queries', 'True', + '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'srv-ipv4-simple-service-config-txt-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'srv-ipv4-simple-service-config-txt-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:1234,True', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'False', + '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'ipv4-cpp-config-has-zero-percentage-txt-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-cpp-config-has-zero-percentage-txt-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'False', + '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) +current_test_subprocess.communicate() +if current_test_subprocess.returncode != 0: + num_test_failures += 1 + +test_runner_log('Run test with target: %s' % 'ipv4-second-language-is-cpp-txt-disabled.resolver-tests-version-4.grpctestingexp.') +current_test_subprocess = subprocess.Popen([ + args.test_bin_path, + '--target_name', 'ipv4-second-language-is-cpp-txt-disabled.resolver-tests-version-4.grpctestingexp.', + '--expected_addrs', '1.2.3.4:443,False', + '--expected_chosen_service_config', '', + '--expected_lb_policy', '', + '--enable_srv_queries', 'True', + '--enable_txt_queries', 'False', '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port]) current_test_subprocess.communicate() if current_test_subprocess.returncode != 0: diff --git a/test/cpp/naming/resolver_test_record_groups.yaml b/test/cpp/naming/resolver_test_record_groups.yaml index 3d8811a36f7..738fe658939 100644 --- a/test/cpp/naming/resolver_test_record_groups.yaml +++ b/test/cpp/naming/resolver_test_record_groups.yaml @@ -6,6 +6,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: true + enable_txt_queries: true record_to_resolve: no-srv-ipv4-single-target records: no-srv-ipv4-single-target: @@ -15,6 +16,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: true + enable_txt_queries: true record_to_resolve: srv-ipv4-single-target records: _grpclb._tcp.srv-ipv4-single-target: @@ -28,6 +30,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: true + enable_txt_queries: true record_to_resolve: srv-ipv4-multi-target records: _grpclb._tcp.srv-ipv4-multi-target: @@ -41,6 +44,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: true + enable_txt_queries: true record_to_resolve: srv-ipv6-single-target records: _grpclb._tcp.srv-ipv6-single-target: @@ -54,6 +58,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: true + enable_txt_queries: true record_to_resolve: srv-ipv6-multi-target records: _grpclb._tcp.srv-ipv6-multi-target: @@ -67,6 +72,7 @@ resolver_component_tests: expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}' expected_lb_policy: round_robin enable_srv_queries: true + enable_txt_queries: true record_to_resolve: srv-ipv4-simple-service-config records: _grpclb._tcp.srv-ipv4-simple-service-config: @@ -81,6 +87,7 @@ resolver_component_tests: expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}' expected_lb_policy: round_robin enable_srv_queries: true + enable_txt_queries: true record_to_resolve: ipv4-no-srv-simple-service-config records: ipv4-no-srv-simple-service-config: @@ -93,6 +100,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: true + enable_txt_queries: true record_to_resolve: ipv4-no-config-for-cpp records: ipv4-no-config-for-cpp: @@ -105,6 +113,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: true + enable_txt_queries: true record_to_resolve: ipv4-cpp-config-has-zero-percentage records: ipv4-cpp-config-has-zero-percentage: @@ -117,6 +126,7 @@ resolver_component_tests: expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}' expected_lb_policy: round_robin enable_srv_queries: true + enable_txt_queries: true record_to_resolve: ipv4-second-language-is-cpp records: ipv4-second-language-is-cpp: @@ -129,6 +139,7 @@ resolver_component_tests: expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}' expected_lb_policy: round_robin enable_srv_queries: true + enable_txt_queries: true record_to_resolve: ipv4-config-with-percentages records: ipv4-config-with-percentages: @@ -142,6 +153,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: true + enable_txt_queries: true record_to_resolve: srv-ipv4-target-has-backend-and-balancer records: _grpclb._tcp.srv-ipv4-target-has-backend-and-balancer: @@ -156,6 +168,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: true + enable_txt_queries: true record_to_resolve: srv-ipv6-target-has-backend-and-balancer records: _grpclb._tcp.srv-ipv6-target-has-backend-and-balancer: @@ -169,6 +182,7 @@ resolver_component_tests: expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}' expected_lb_policy: null enable_srv_queries: true + enable_txt_queries: true record_to_resolve: ipv4-config-causing-fallback-to-tcp records: ipv4-config-causing-fallback-to-tcp: @@ -182,6 +196,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: false + enable_txt_queries: true record_to_resolve: srv-ipv4-single-target-srv-disabled records: _grpclb._tcp.srv-ipv4-single-target-srv-disabled: @@ -197,6 +212,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: false + enable_txt_queries: true record_to_resolve: srv-ipv4-multi-target-srv-disabled records: _grpclb._tcp.srv-ipv4-multi-target-srv-disabled: @@ -214,6 +230,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: false + enable_txt_queries: true record_to_resolve: srv-ipv6-single-target-srv-disabled records: _grpclb._tcp.srv-ipv6-single-target-srv-disabled: @@ -229,6 +246,7 @@ resolver_component_tests: expected_chosen_service_config: null expected_lb_policy: null enable_srv_queries: false + enable_txt_queries: true record_to_resolve: srv-ipv6-multi-target-srv-disabled records: _grpclb._tcp.srv-ipv6-multi-target-srv-disabled: @@ -246,6 +264,7 @@ resolver_component_tests: expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}' expected_lb_policy: round_robin enable_srv_queries: false + enable_txt_queries: true record_to_resolve: srv-ipv4-simple-service-config-srv-disabled records: _grpclb._tcp.srv-ipv4-simple-service-config-srv-disabled: @@ -257,3 +276,44 @@ resolver_component_tests: _grpc_config.srv-ipv4-simple-service-config-srv-disabled: - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}}]', type: TXT} +- expected_addrs: + - {address: '1.2.3.4:1234', is_balancer: true} + expected_chosen_service_config: null + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: false + record_to_resolve: srv-ipv4-simple-service-config-txt-disabled + records: + _grpclb._tcp.srv-ipv4-simple-service-config-txt-disabled: + - {TTL: '2100', data: 0 0 1234 ipv4-simple-service-config-txt-disabled, type: SRV} + ipv4-simple-service-config-txt-disabled: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.srv-ipv4-simple-service-config-txt-disabled: + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}}]', + type: TXT} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: false + record_to_resolve: ipv4-cpp-config-has-zero-percentage-txt-disabled + records: + ipv4-cpp-config-has-zero-percentage-txt-disabled: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-cpp-config-has-zero-percentage-txt-disabled: + - {TTL: '2100', data: 'grpc_config=[{"percentage":0,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}}]', + type: TXT} +- expected_addrs: + - {address: '1.2.3.4:443', is_balancer: false} + expected_chosen_service_config: null + expected_lb_policy: null + enable_srv_queries: true + enable_txt_queries: false + record_to_resolve: ipv4-second-language-is-cpp-txt-disabled + records: + ipv4-second-language-is-cpp-txt-disabled: + - {TTL: '2100', data: 1.2.3.4, type: A} + _grpc_config.ipv4-second-language-is-cpp-txt-disabled: + - {TTL: '2100', data: 'grpc_config=[{"clientLanguage":["go"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"GoService","waitForReady":true}]}]}},{"clientLanguage":["c++"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}}]', + type: TXT} From 195a30bb8bc05f7fb1c2873f639621d6fea2948d Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Wed, 16 Jan 2019 16:30:39 -0800 Subject: [PATCH 325/814] Grpc: Change grpc_handshake and grpc_handshake_mgr to use CPP implementations. grpc_handshake is renamed to GrpcHandshake, using C++ class definitions instead of C-style vtable classes. Update callers to use new interfaces. We use RefCountedPtr to simplify reference tracking. --- BUILD | 1 - CMakeLists.txt | 6 - Makefile | 6 - build.yaml | 1 - config.m4 | 1 - config.w32 | 1 - gRPC-Core.podspec | 1 - grpc.gemspec | 1 - grpc.gyp | 4 - package.xml | 1 - .../client_channel/http_connect_handshaker.cc | 302 +++++----- .../chttp2/client/chttp2_connector.cc | 22 +- .../transport/chttp2/server/chttp2_server.cc | 37 +- src/core/lib/channel/handshaker.cc | 389 +++++------- src/core/lib/channel/handshaker.h | 215 +++---- src/core/lib/channel/handshaker_factory.cc | 42 -- src/core/lib/channel/handshaker_factory.h | 26 +- src/core/lib/channel/handshaker_registry.cc | 118 ++-- src/core/lib/channel/handshaker_registry.h | 33 +- .../lib/http/httpcli_security_connector.cc | 27 +- .../alts/alts_security_connector.cc | 18 +- .../fake/fake_security_connector.cc | 16 +- .../local/local_security_connector.cc | 18 +- .../security_connector/security_connector.h | 4 +- .../ssl/ssl_security_connector.cc | 10 +- .../security/transport/security_handshaker.cc | 563 +++++++++--------- .../security/transport/security_handshaker.h | 13 +- src/core/lib/surface/init.cc | 4 +- src/core/lib/surface/init_secure.cc | 2 +- src/python/grpcio/grpc_core_dependencies.py | 1 - .../readahead_handshaker_server_ssl.cc | 65 +- test/core/security/ssl_server_fuzzer.cc | 15 +- tools/doxygen/Doxyfile.core.internal | 1 - .../generated/sources_and_headers.json | 1 - 34 files changed, 896 insertions(+), 1069 deletions(-) delete mode 100644 src/core/lib/channel/handshaker_factory.cc diff --git a/BUILD b/BUILD index 3f1e735466d..ebb03580bb4 100644 --- a/BUILD +++ b/BUILD @@ -701,7 +701,6 @@ grpc_cc_library( "src/core/lib/channel/channelz_registry.cc", "src/core/lib/channel/connected_channel.cc", "src/core/lib/channel/handshaker.cc", - "src/core/lib/channel/handshaker_factory.cc", "src/core/lib/channel/handshaker_registry.cc", "src/core/lib/channel/status_util.cc", "src/core/lib/compression/compression.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f1a0f6af9b..b2de3f6fde5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -971,7 +971,6 @@ add_library(grpc src/core/lib/channel/channelz_registry.cc src/core/lib/channel/connected_channel.cc src/core/lib/channel/handshaker.cc - src/core/lib/channel/handshaker_factory.cc src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc @@ -1397,7 +1396,6 @@ add_library(grpc_cronet src/core/lib/channel/channelz_registry.cc src/core/lib/channel/connected_channel.cc src/core/lib/channel/handshaker.cc - src/core/lib/channel/handshaker_factory.cc src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc @@ -1808,7 +1806,6 @@ add_library(grpc_test_util src/core/lib/channel/channelz_registry.cc src/core/lib/channel/connected_channel.cc src/core/lib/channel/handshaker.cc - src/core/lib/channel/handshaker_factory.cc src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc @@ -2134,7 +2131,6 @@ add_library(grpc_test_util_unsecure src/core/lib/channel/channelz_registry.cc src/core/lib/channel/connected_channel.cc src/core/lib/channel/handshaker.cc - src/core/lib/channel/handshaker_factory.cc src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc @@ -2436,7 +2432,6 @@ add_library(grpc_unsecure src/core/lib/channel/channelz_registry.cc src/core/lib/channel/connected_channel.cc src/core/lib/channel/handshaker.cc - src/core/lib/channel/handshaker_factory.cc src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc @@ -3324,7 +3319,6 @@ add_library(grpc++_cronet src/core/lib/channel/channelz_registry.cc src/core/lib/channel/connected_channel.cc src/core/lib/channel/handshaker.cc - src/core/lib/channel/handshaker_factory.cc src/core/lib/channel/handshaker_registry.cc src/core/lib/channel/status_util.cc src/core/lib/compression/compression.cc diff --git a/Makefile b/Makefile index e41c0584c7d..069d001d3be 100644 --- a/Makefile +++ b/Makefile @@ -3497,7 +3497,6 @@ LIBGRPC_SRC = \ src/core/lib/channel/channelz_registry.cc \ src/core/lib/channel/connected_channel.cc \ src/core/lib/channel/handshaker.cc \ - src/core/lib/channel/handshaker_factory.cc \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ @@ -3917,7 +3916,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/channel/channelz_registry.cc \ src/core/lib/channel/connected_channel.cc \ src/core/lib/channel/handshaker.cc \ - src/core/lib/channel/handshaker_factory.cc \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ @@ -4321,7 +4319,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/channel/channelz_registry.cc \ src/core/lib/channel/connected_channel.cc \ src/core/lib/channel/handshaker.cc \ - src/core/lib/channel/handshaker_factory.cc \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ @@ -4634,7 +4631,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/channel/channelz_registry.cc \ src/core/lib/channel/connected_channel.cc \ src/core/lib/channel/handshaker.cc \ - src/core/lib/channel/handshaker_factory.cc \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ @@ -4910,7 +4906,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/channel/channelz_registry.cc \ src/core/lib/channel/connected_channel.cc \ src/core/lib/channel/handshaker.cc \ - src/core/lib/channel/handshaker_factory.cc \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ @@ -5775,7 +5770,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/channel/channelz_registry.cc \ src/core/lib/channel/connected_channel.cc \ src/core/lib/channel/handshaker.cc \ - src/core/lib/channel/handshaker_factory.cc \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ diff --git a/build.yaml b/build.yaml index ec00450f28a..f96b0cbcf22 100644 --- a/build.yaml +++ b/build.yaml @@ -242,7 +242,6 @@ filegroups: - src/core/lib/channel/channelz_registry.cc - src/core/lib/channel/connected_channel.cc - src/core/lib/channel/handshaker.cc - - src/core/lib/channel/handshaker_factory.cc - src/core/lib/channel/handshaker_registry.cc - src/core/lib/channel/status_util.cc - src/core/lib/compression/compression.cc diff --git a/config.m4 b/config.m4 index 1874f3ba1b0..5746caf694a 100644 --- a/config.m4 +++ b/config.m4 @@ -94,7 +94,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/channel/channelz_registry.cc \ src/core/lib/channel/connected_channel.cc \ src/core/lib/channel/handshaker.cc \ - src/core/lib/channel/handshaker_factory.cc \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/status_util.cc \ src/core/lib/compression/compression.cc \ diff --git a/config.w32 b/config.w32 index 452e8fd18b1..5659d8b8408 100644 --- a/config.w32 +++ b/config.w32 @@ -69,7 +69,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\channel\\channelz_registry.cc " + "src\\core\\lib\\channel\\connected_channel.cc " + "src\\core\\lib\\channel\\handshaker.cc " + - "src\\core\\lib\\channel\\handshaker_factory.cc " + "src\\core\\lib\\channel\\handshaker_registry.cc " + "src\\core\\lib\\channel\\status_util.cc " + "src\\core\\lib\\compression\\compression.cc " + diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index da48fe7e953..625d1a9a50c 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -543,7 +543,6 @@ Pod::Spec.new do |s| 'src/core/lib/channel/channelz_registry.cc', 'src/core/lib/channel/connected_channel.cc', 'src/core/lib/channel/handshaker.cc', - 'src/core/lib/channel/handshaker_factory.cc', 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', diff --git a/grpc.gemspec b/grpc.gemspec index 9a3c657cc85..a4e25d7bb22 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -477,7 +477,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/channel/channelz_registry.cc ) s.files += %w( src/core/lib/channel/connected_channel.cc ) s.files += %w( src/core/lib/channel/handshaker.cc ) - s.files += %w( src/core/lib/channel/handshaker_factory.cc ) s.files += %w( src/core/lib/channel/handshaker_registry.cc ) s.files += %w( src/core/lib/channel/status_util.cc ) s.files += %w( src/core/lib/compression/compression.cc ) diff --git a/grpc.gyp b/grpc.gyp index 6a0a2718c8e..113c17f0d09 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -276,7 +276,6 @@ 'src/core/lib/channel/channelz_registry.cc', 'src/core/lib/channel/connected_channel.cc', 'src/core/lib/channel/handshaker.cc', - 'src/core/lib/channel/handshaker_factory.cc', 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', @@ -643,7 +642,6 @@ 'src/core/lib/channel/channelz_registry.cc', 'src/core/lib/channel/connected_channel.cc', 'src/core/lib/channel/handshaker.cc', - 'src/core/lib/channel/handshaker_factory.cc', 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', @@ -889,7 +887,6 @@ 'src/core/lib/channel/channelz_registry.cc', 'src/core/lib/channel/connected_channel.cc', 'src/core/lib/channel/handshaker.cc', - 'src/core/lib/channel/handshaker_factory.cc', 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', @@ -1111,7 +1108,6 @@ 'src/core/lib/channel/channelz_registry.cc', 'src/core/lib/channel/connected_channel.cc', 'src/core/lib/channel/handshaker.cc', - 'src/core/lib/channel/handshaker_factory.cc', 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', diff --git a/package.xml b/package.xml index 69b6fdfa671..aa2bf62411c 100644 --- a/package.xml +++ b/package.xml @@ -482,7 +482,6 @@ - diff --git a/src/core/ext/filters/client_channel/http_connect_handshaker.cc b/src/core/ext/filters/client_channel/http_connect_handshaker.cc index 0716e468181..fa5aaa9e7ce 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -33,151 +33,160 @@ #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/http/format_request.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/uri/uri_parser.h" -typedef struct http_connect_handshaker { - // Base class. Must be first. - grpc_handshaker base; +namespace grpc_core { - gpr_refcount refcount; - gpr_mu mu; +namespace { - bool shutdown; +class HttpConnectHandshaker : public Handshaker { + public: + HttpConnectHandshaker(); + void Shutdown(grpc_error* why) override; + void DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) override; + const char* name() const override { return "http_connect"; } + + private: + virtual ~HttpConnectHandshaker(); + void CleanupArgsForFailureLocked(); + void HandshakeFailedLocked(grpc_error* error); + static void OnWriteDone(void* arg, grpc_error* error); + static void OnReadDone(void* arg, grpc_error* error); + + gpr_mu mu_; + + bool is_shutdown_ = false; // Endpoint and read buffer to destroy after a shutdown. - grpc_endpoint* endpoint_to_destroy; - grpc_slice_buffer* read_buffer_to_destroy; + grpc_endpoint* endpoint_to_destroy_ = nullptr; + grpc_slice_buffer* read_buffer_to_destroy_ = nullptr; // State saved while performing the handshake. - grpc_handshaker_args* args; - grpc_closure* on_handshake_done; + HandshakerArgs* args_ = nullptr; + grpc_closure* on_handshake_done_ = nullptr; // Objects for processing the HTTP CONNECT request and response. - grpc_slice_buffer write_buffer; - grpc_closure request_done_closure; - grpc_closure response_read_closure; - grpc_http_parser http_parser; - grpc_http_response http_response; -} http_connect_handshaker; + grpc_slice_buffer write_buffer_; + grpc_closure request_done_closure_; + grpc_closure response_read_closure_; + grpc_http_parser http_parser_; + grpc_http_response http_response_; +}; -// Unref and clean up handshaker. -static void http_connect_handshaker_unref(http_connect_handshaker* handshaker) { - if (gpr_unref(&handshaker->refcount)) { - gpr_mu_destroy(&handshaker->mu); - if (handshaker->endpoint_to_destroy != nullptr) { - grpc_endpoint_destroy(handshaker->endpoint_to_destroy); - } - if (handshaker->read_buffer_to_destroy != nullptr) { - grpc_slice_buffer_destroy_internal(handshaker->read_buffer_to_destroy); - gpr_free(handshaker->read_buffer_to_destroy); - } - grpc_slice_buffer_destroy_internal(&handshaker->write_buffer); - grpc_http_parser_destroy(&handshaker->http_parser); - grpc_http_response_destroy(&handshaker->http_response); - gpr_free(handshaker); +HttpConnectHandshaker::~HttpConnectHandshaker() { + gpr_mu_destroy(&mu_); + if (endpoint_to_destroy_ != nullptr) { + grpc_endpoint_destroy(endpoint_to_destroy_); } + if (read_buffer_to_destroy_ != nullptr) { + grpc_slice_buffer_destroy_internal(read_buffer_to_destroy_); + gpr_free(read_buffer_to_destroy_); + } + grpc_slice_buffer_destroy_internal(&write_buffer_); + grpc_http_parser_destroy(&http_parser_); + grpc_http_response_destroy(&http_response_); } // Set args fields to nullptr, saving the endpoint and read buffer for // later destruction. -static void cleanup_args_for_failure_locked( - http_connect_handshaker* handshaker) { - handshaker->endpoint_to_destroy = handshaker->args->endpoint; - handshaker->args->endpoint = nullptr; - handshaker->read_buffer_to_destroy = handshaker->args->read_buffer; - handshaker->args->read_buffer = nullptr; - grpc_channel_args_destroy(handshaker->args->args); - handshaker->args->args = nullptr; +void HttpConnectHandshaker::CleanupArgsForFailureLocked() { + endpoint_to_destroy_ = args_->endpoint; + args_->endpoint = nullptr; + read_buffer_to_destroy_ = args_->read_buffer; + args_->read_buffer = nullptr; + grpc_channel_args_destroy(args_->args); + args_->args = nullptr; } // If the handshake failed or we're shutting down, clean up and invoke the // callback with the error. -static void handshake_failed_locked(http_connect_handshaker* handshaker, - grpc_error* error) { +void HttpConnectHandshaker::HandshakeFailedLocked(grpc_error* error) { if (error == GRPC_ERROR_NONE) { // If we were shut down after an endpoint operation succeeded but // before the endpoint callback was invoked, we need to generate our // own error. error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshaker shutdown"); } - if (!handshaker->shutdown) { + if (!is_shutdown_) { // TODO(ctiller): It is currently necessary to shutdown endpoints // before destroying them, even if we know that there are no // pending read/write callbacks. This should be fixed, at which // point this can be removed. - grpc_endpoint_shutdown(handshaker->args->endpoint, GRPC_ERROR_REF(error)); + grpc_endpoint_shutdown(args_->endpoint, GRPC_ERROR_REF(error)); // Not shutting down, so the handshake failed. Clean up before // invoking the callback. - cleanup_args_for_failure_locked(handshaker); + CleanupArgsForFailureLocked(); // Set shutdown to true so that subsequent calls to // http_connect_handshaker_shutdown() do nothing. - handshaker->shutdown = true; + is_shutdown_ = true; } // Invoke callback. - GRPC_CLOSURE_SCHED(handshaker->on_handshake_done, error); + GRPC_CLOSURE_SCHED(on_handshake_done_, error); } // Callback invoked when finished writing HTTP CONNECT request. -static void on_write_done(void* arg, grpc_error* error) { - http_connect_handshaker* handshaker = - static_cast(arg); - gpr_mu_lock(&handshaker->mu); - if (error != GRPC_ERROR_NONE || handshaker->shutdown) { +void HttpConnectHandshaker::OnWriteDone(void* arg, grpc_error* error) { + auto* handshaker = static_cast(arg); + gpr_mu_lock(&handshaker->mu_); + if (error != GRPC_ERROR_NONE || handshaker->is_shutdown_) { // If the write failed or we're shutting down, clean up and invoke the // callback with the error. - handshake_failed_locked(handshaker, GRPC_ERROR_REF(error)); - gpr_mu_unlock(&handshaker->mu); - http_connect_handshaker_unref(handshaker); + handshaker->HandshakeFailedLocked(GRPC_ERROR_REF(error)); + gpr_mu_unlock(&handshaker->mu_); + handshaker->Unref(); } else { // Otherwise, read the response. // The read callback inherits our ref to the handshaker. - grpc_endpoint_read(handshaker->args->endpoint, - handshaker->args->read_buffer, - &handshaker->response_read_closure); - gpr_mu_unlock(&handshaker->mu); + grpc_endpoint_read(handshaker->args_->endpoint, + handshaker->args_->read_buffer, + &handshaker->response_read_closure_); + gpr_mu_unlock(&handshaker->mu_); } } // Callback invoked for reading HTTP CONNECT response. -static void on_read_done(void* arg, grpc_error* error) { - http_connect_handshaker* handshaker = - static_cast(arg); - gpr_mu_lock(&handshaker->mu); - if (error != GRPC_ERROR_NONE || handshaker->shutdown) { +void HttpConnectHandshaker::OnReadDone(void* arg, grpc_error* error) { + auto* handshaker = static_cast(arg); + + gpr_mu_lock(&handshaker->mu_); + if (error != GRPC_ERROR_NONE || handshaker->is_shutdown_) { // If the read failed or we're shutting down, clean up and invoke the // callback with the error. - handshake_failed_locked(handshaker, GRPC_ERROR_REF(error)); + handshaker->HandshakeFailedLocked(GRPC_ERROR_REF(error)); goto done; } // Add buffer to parser. - for (size_t i = 0; i < handshaker->args->read_buffer->count; ++i) { - if (GRPC_SLICE_LENGTH(handshaker->args->read_buffer->slices[i]) > 0) { + for (size_t i = 0; i < handshaker->args_->read_buffer->count; ++i) { + if (GRPC_SLICE_LENGTH(handshaker->args_->read_buffer->slices[i]) > 0) { size_t body_start_offset = 0; - error = grpc_http_parser_parse(&handshaker->http_parser, - handshaker->args->read_buffer->slices[i], + error = grpc_http_parser_parse(&handshaker->http_parser_, + handshaker->args_->read_buffer->slices[i], &body_start_offset); if (error != GRPC_ERROR_NONE) { - handshake_failed_locked(handshaker, error); + handshaker->HandshakeFailedLocked(error); goto done; } - if (handshaker->http_parser.state == GRPC_HTTP_BODY) { + if (handshaker->http_parser_.state == GRPC_HTTP_BODY) { // Remove the data we've already read from the read buffer, // leaving only the leftover bytes (if any). grpc_slice_buffer tmp_buffer; grpc_slice_buffer_init(&tmp_buffer); if (body_start_offset < - GRPC_SLICE_LENGTH(handshaker->args->read_buffer->slices[i])) { + GRPC_SLICE_LENGTH(handshaker->args_->read_buffer->slices[i])) { grpc_slice_buffer_add( &tmp_buffer, - grpc_slice_split_tail(&handshaker->args->read_buffer->slices[i], + grpc_slice_split_tail(&handshaker->args_->read_buffer->slices[i], body_start_offset)); } grpc_slice_buffer_addn(&tmp_buffer, - &handshaker->args->read_buffer->slices[i + 1], - handshaker->args->read_buffer->count - i - 1); - grpc_slice_buffer_swap(handshaker->args->read_buffer, &tmp_buffer); + &handshaker->args_->read_buffer->slices[i + 1], + handshaker->args_->read_buffer->count - i - 1); + grpc_slice_buffer_swap(handshaker->args_->read_buffer, &tmp_buffer); grpc_slice_buffer_destroy_internal(&tmp_buffer); break; } @@ -194,64 +203,53 @@ static void on_read_done(void* arg, grpc_error* error) { // need to fix the HTTP parser to understand when the body is // complete (e.g., handling chunked transfer encoding or looking // at the Content-Length: header). - if (handshaker->http_parser.state != GRPC_HTTP_BODY) { - grpc_slice_buffer_reset_and_unref_internal(handshaker->args->read_buffer); - grpc_endpoint_read(handshaker->args->endpoint, - handshaker->args->read_buffer, - &handshaker->response_read_closure); - gpr_mu_unlock(&handshaker->mu); + if (handshaker->http_parser_.state != GRPC_HTTP_BODY) { + grpc_slice_buffer_reset_and_unref_internal(handshaker->args_->read_buffer); + grpc_endpoint_read(handshaker->args_->endpoint, + handshaker->args_->read_buffer, + &handshaker->response_read_closure_); + gpr_mu_unlock(&handshaker->mu_); return; } // Make sure we got a 2xx response. - if (handshaker->http_response.status < 200 || - handshaker->http_response.status >= 300) { + if (handshaker->http_response_.status < 200 || + handshaker->http_response_.status >= 300) { char* msg; gpr_asprintf(&msg, "HTTP proxy returned response code %d", - handshaker->http_response.status); + handshaker->http_response_.status); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); - handshake_failed_locked(handshaker, error); + handshaker->HandshakeFailedLocked(error); goto done; } // Success. Invoke handshake-done callback. - GRPC_CLOSURE_SCHED(handshaker->on_handshake_done, error); + GRPC_CLOSURE_SCHED(handshaker->on_handshake_done_, error); done: // Set shutdown to true so that subsequent calls to // http_connect_handshaker_shutdown() do nothing. - handshaker->shutdown = true; - gpr_mu_unlock(&handshaker->mu); - http_connect_handshaker_unref(handshaker); + handshaker->is_shutdown_ = true; + gpr_mu_unlock(&handshaker->mu_); + handshaker->Unref(); } // // Public handshaker methods // -static void http_connect_handshaker_destroy(grpc_handshaker* handshaker_in) { - http_connect_handshaker* handshaker = - reinterpret_cast(handshaker_in); - http_connect_handshaker_unref(handshaker); -} - -static void http_connect_handshaker_shutdown(grpc_handshaker* handshaker_in, - grpc_error* why) { - http_connect_handshaker* handshaker = - reinterpret_cast(handshaker_in); - gpr_mu_lock(&handshaker->mu); - if (!handshaker->shutdown) { - handshaker->shutdown = true; - grpc_endpoint_shutdown(handshaker->args->endpoint, GRPC_ERROR_REF(why)); - cleanup_args_for_failure_locked(handshaker); +void HttpConnectHandshaker::Shutdown(grpc_error* why) { + gpr_mu_lock(&mu_); + if (!is_shutdown_) { + is_shutdown_ = true; + grpc_endpoint_shutdown(args_->endpoint, GRPC_ERROR_REF(why)); + CleanupArgsForFailureLocked(); } - gpr_mu_unlock(&handshaker->mu); + gpr_mu_unlock(&mu_); GRPC_ERROR_UNREF(why); } -static void http_connect_handshaker_do_handshake( - grpc_handshaker* handshaker_in, grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, grpc_handshaker_args* args) { - http_connect_handshaker* handshaker = - reinterpret_cast(handshaker_in); +void HttpConnectHandshaker::DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) { // Check for HTTP CONNECT channel arg. // If not found, invoke on_handshake_done without doing anything. const grpc_arg* arg = @@ -260,9 +258,9 @@ static void http_connect_handshaker_do_handshake( if (server_name == nullptr) { // Set shutdown to true so that subsequent calls to // http_connect_handshaker_shutdown() do nothing. - gpr_mu_lock(&handshaker->mu); - handshaker->shutdown = true; - gpr_mu_unlock(&handshaker->mu); + gpr_mu_lock(&mu_); + is_shutdown_ = true; + gpr_mu_unlock(&mu_); GRPC_CLOSURE_SCHED(on_handshake_done, GRPC_ERROR_NONE); return; } @@ -280,6 +278,7 @@ static void http_connect_handshaker_do_handshake( gpr_malloc(sizeof(grpc_http_header) * num_header_strings)); for (size_t i = 0; i < num_header_strings; ++i) { char* sep = strchr(header_strings[i], ':'); + if (sep == nullptr) { gpr_log(GPR_ERROR, "skipping unparseable HTTP CONNECT header: %s", header_strings[i]); @@ -292,9 +291,9 @@ static void http_connect_handshaker_do_handshake( } } // Save state in the handshaker object. - gpr_mu_lock(&handshaker->mu); - handshaker->args = args; - handshaker->on_handshake_done = on_handshake_done; + MutexLock lock(&mu_); + args_ = args; + on_handshake_done_ = on_handshake_done; // Log connection via proxy. char* proxy_name = grpc_endpoint_get_peer(args->endpoint); gpr_log(GPR_INFO, "Connecting to server %s via HTTP proxy %s", server_name, @@ -302,15 +301,18 @@ static void http_connect_handshaker_do_handshake( gpr_free(proxy_name); // Construct HTTP CONNECT request. grpc_httpcli_request request; - memset(&request, 0, sizeof(request)); request.host = server_name; + request.ssl_host_override = nullptr; request.http.method = (char*)"CONNECT"; request.http.path = server_name; + request.http.version = GRPC_HTTP_HTTP10; // Set by OnReadDone request.http.hdrs = headers; request.http.hdr_count = num_headers; + request.http.body_length = 0; + request.http.body = nullptr; request.handshaker = &grpc_httpcli_plaintext; grpc_slice request_slice = grpc_httpcli_format_connect_request(&request); - grpc_slice_buffer_add(&handshaker->write_buffer, request_slice); + grpc_slice_buffer_add(&write_buffer_, request_slice); // Clean up. gpr_free(headers); for (size_t i = 0; i < num_header_strings; ++i) { @@ -318,54 +320,42 @@ static void http_connect_handshaker_do_handshake( } gpr_free(header_strings); // Take a new ref to be held by the write callback. - gpr_ref(&handshaker->refcount); - grpc_endpoint_write(args->endpoint, &handshaker->write_buffer, - &handshaker->request_done_closure, nullptr); - gpr_mu_unlock(&handshaker->mu); + Ref().release(); + grpc_endpoint_write(args->endpoint, &write_buffer_, &request_done_closure_, + nullptr); } -static const grpc_handshaker_vtable http_connect_handshaker_vtable = { - http_connect_handshaker_destroy, http_connect_handshaker_shutdown, - http_connect_handshaker_do_handshake, "http_connect"}; - -static grpc_handshaker* grpc_http_connect_handshaker_create() { - http_connect_handshaker* handshaker = - static_cast(gpr_malloc(sizeof(*handshaker))); - memset(handshaker, 0, sizeof(*handshaker)); - grpc_handshaker_init(&http_connect_handshaker_vtable, &handshaker->base); - gpr_mu_init(&handshaker->mu); - gpr_ref_init(&handshaker->refcount, 1); - grpc_slice_buffer_init(&handshaker->write_buffer); - GRPC_CLOSURE_INIT(&handshaker->request_done_closure, on_write_done, - handshaker, grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&handshaker->response_read_closure, on_read_done, - handshaker, grpc_schedule_on_exec_ctx); - grpc_http_parser_init(&handshaker->http_parser, GRPC_HTTP_RESPONSE, - &handshaker->http_response); - return &handshaker->base; +HttpConnectHandshaker::HttpConnectHandshaker() { + gpr_mu_init(&mu_); + grpc_slice_buffer_init(&write_buffer_); + GRPC_CLOSURE_INIT(&request_done_closure_, &HttpConnectHandshaker::OnWriteDone, + this, grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&response_read_closure_, &HttpConnectHandshaker::OnReadDone, + this, grpc_schedule_on_exec_ctx); + grpc_http_parser_init(&http_parser_, GRPC_HTTP_RESPONSE, &http_response_); } // // handshaker factory // -static void handshaker_factory_add_handshakers( - grpc_handshaker_factory* factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add(handshake_mgr, - grpc_http_connect_handshaker_create()); -} +class HttpConnectHandshakerFactory : public HandshakerFactory { + public: + void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) override { + handshake_mgr->Add(MakeRefCounted()); + } + ~HttpConnectHandshakerFactory() override = default; +}; -static void handshaker_factory_destroy(grpc_handshaker_factory* factory) {} +} // namespace -static const grpc_handshaker_factory_vtable handshaker_factory_vtable = { - handshaker_factory_add_handshakers, handshaker_factory_destroy}; - -static grpc_handshaker_factory handshaker_factory = { - &handshaker_factory_vtable}; +} // namespace grpc_core void grpc_http_connect_register_handshaker_factory() { - grpc_handshaker_factory_register(true /* at_start */, HANDSHAKER_CLIENT, - &handshaker_factory); + using namespace grpc_core; + HandshakerRegistry::RegisterHandshakerFactory( + true /* at_start */, HANDSHAKER_CLIENT, + UniquePtr(New())); } diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 1e9a75d0630..c324c2c9243 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -55,7 +55,7 @@ typedef struct { grpc_closure connected; - grpc_handshake_manager* handshake_mgr; + grpc_core::RefCountedPtr handshake_mgr; } chttp2_connector; static void chttp2_connector_ref(grpc_connector* con) { @@ -79,7 +79,7 @@ static void chttp2_connector_shutdown(grpc_connector* con, grpc_error* why) { gpr_mu_lock(&c->mu); c->shutdown = true; if (c->handshake_mgr != nullptr) { - grpc_handshake_manager_shutdown(c->handshake_mgr, GRPC_ERROR_REF(why)); + c->handshake_mgr->Shutdown(GRPC_ERROR_REF(why)); } // If handshaking is not yet in progress, shutdown the endpoint. // Otherwise, the handshaker will do this for us. @@ -91,7 +91,7 @@ static void chttp2_connector_shutdown(grpc_connector* con, grpc_error* why) { } static void on_handshake_done(void* arg, grpc_error* error) { - grpc_handshaker_args* args = static_cast(arg); + auto* args = static_cast(arg); chttp2_connector* c = static_cast(args->user_data); gpr_mu_lock(&c->mu); if (error != GRPC_ERROR_NONE || c->shutdown) { @@ -152,20 +152,20 @@ static void on_handshake_done(void* arg, grpc_error* error) { grpc_closure* notify = c->notify; c->notify = nullptr; GRPC_CLOSURE_SCHED(notify, error); - grpc_handshake_manager_destroy(c->handshake_mgr); - c->handshake_mgr = nullptr; + c->handshake_mgr.reset(); gpr_mu_unlock(&c->mu); chttp2_connector_unref(reinterpret_cast(c)); } static void start_handshake_locked(chttp2_connector* c) { - c->handshake_mgr = grpc_handshake_manager_create(); - grpc_handshakers_add(HANDSHAKER_CLIENT, c->args.channel_args, - c->args.interested_parties, c->handshake_mgr); + c->handshake_mgr = grpc_core::MakeRefCounted(); + grpc_core::HandshakerRegistry::AddHandshakers( + grpc_core::HANDSHAKER_CLIENT, c->args.channel_args, + c->args.interested_parties, c->handshake_mgr.get()); grpc_endpoint_add_to_pollset_set(c->endpoint, c->args.interested_parties); - grpc_handshake_manager_do_handshake( - c->handshake_mgr, c->endpoint, c->args.channel_args, c->args.deadline, - nullptr /* acceptor */, on_handshake_done, c); + c->handshake_mgr->DoHandshake(c->endpoint, c->args.channel_args, + c->args.deadline, nullptr /* acceptor */, + on_handshake_done, c); c->endpoint = nullptr; // Endpoint handed off to handshake manager. } diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 3d09187b9ba..040ea2044b1 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -54,7 +54,7 @@ typedef struct { bool shutdown; grpc_closure tcp_server_shutdown_complete; grpc_closure* server_destroy_listener_done; - grpc_handshake_manager* pending_handshake_mgrs; + grpc_core::HandshakeManager* pending_handshake_mgrs; grpc_core::RefCountedPtr channelz_listen_socket; } server_state; @@ -64,7 +64,7 @@ typedef struct { server_state* svr_state; grpc_pollset* accepting_pollset; grpc_tcp_server_acceptor* acceptor; - grpc_handshake_manager* handshake_mgr; + grpc_core::RefCountedPtr handshake_mgr; // State for enforcing handshake timeout on receiving HTTP/2 settings. grpc_chttp2_transport* transport; grpc_millis deadline; @@ -112,7 +112,7 @@ static void on_receive_settings(void* arg, grpc_error* error) { } static void on_handshake_done(void* arg, grpc_error* error) { - grpc_handshaker_args* args = static_cast(arg); + auto* args = static_cast(arg); server_connection_state* connection_state = static_cast(args->user_data); gpr_mu_lock(&connection_state->svr_state->mu); @@ -175,11 +175,10 @@ static void on_handshake_done(void* arg, grpc_error* error) { } } } - grpc_handshake_manager_pending_list_remove( - &connection_state->svr_state->pending_handshake_mgrs, - connection_state->handshake_mgr); + connection_state->handshake_mgr->RemoveFromPendingMgrList( + &connection_state->svr_state->pending_handshake_mgrs); gpr_mu_unlock(&connection_state->svr_state->mu); - grpc_handshake_manager_destroy(connection_state->handshake_mgr); + connection_state->handshake_mgr.reset(); gpr_free(connection_state->acceptor); grpc_tcp_server_unref(connection_state->svr_state->tcp_server); server_connection_state_unref(connection_state); @@ -211,9 +210,8 @@ static void on_accept(void* arg, grpc_endpoint* tcp, gpr_free(acceptor); return; } - grpc_handshake_manager* handshake_mgr = grpc_handshake_manager_create(); - grpc_handshake_manager_pending_list_add(&state->pending_handshake_mgrs, - handshake_mgr); + auto handshake_mgr = grpc_core::MakeRefCounted(); + handshake_mgr->AddToPendingMgrList(&state->pending_handshake_mgrs); grpc_tcp_server_ref(state->tcp_server); gpr_mu_unlock(&state->mu); server_connection_state* connection_state = @@ -227,19 +225,19 @@ static void on_accept(void* arg, grpc_endpoint* tcp, connection_state->interested_parties = grpc_pollset_set_create(); grpc_pollset_set_add_pollset(connection_state->interested_parties, connection_state->accepting_pollset); - grpc_handshakers_add(HANDSHAKER_SERVER, state->args, - connection_state->interested_parties, - connection_state->handshake_mgr); + grpc_core::HandshakerRegistry::AddHandshakers( + grpc_core::HANDSHAKER_SERVER, state->args, + connection_state->interested_parties, + connection_state->handshake_mgr.get()); const grpc_arg* timeout_arg = grpc_channel_args_find(state->args, GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS); connection_state->deadline = grpc_core::ExecCtx::Get()->Now() + grpc_channel_arg_get_integer(timeout_arg, {120 * GPR_MS_PER_SEC, 1, INT_MAX}); - grpc_handshake_manager_do_handshake(connection_state->handshake_mgr, tcp, - state->args, connection_state->deadline, - acceptor, on_handshake_done, - connection_state); + connection_state->handshake_mgr->DoHandshake( + tcp, state->args, connection_state->deadline, acceptor, on_handshake_done, + connection_state); } /* Server callback: start listening on our ports */ @@ -260,8 +258,9 @@ static void tcp_server_shutdown_complete(void* arg, grpc_error* error) { gpr_mu_lock(&state->mu); grpc_closure* destroy_done = state->server_destroy_listener_done; GPR_ASSERT(state->shutdown); - grpc_handshake_manager_pending_list_shutdown_all( - state->pending_handshake_mgrs, GRPC_ERROR_REF(error)); + if (state->pending_handshake_mgrs != nullptr) { + state->pending_handshake_mgrs->ShutdownAllPending(GRPC_ERROR_REF(error)); + } state->channelz_listen_socket.reset(); gpr_mu_unlock(&state->mu); // Flush queued work before destroying handshaker factory, since that diff --git a/src/core/lib/channel/handshaker.cc b/src/core/lib/channel/handshaker.cc index e516b56b743..6bb05cee24e 100644 --- a/src/core/lib/channel/handshaker.cc +++ b/src/core/lib/channel/handshaker.cc @@ -30,164 +30,13 @@ #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/slice/slice_internal.h" -grpc_core::TraceFlag grpc_handshaker_trace(false, "handshaker"); +namespace grpc_core { -// -// grpc_handshaker -// +TraceFlag grpc_handshaker_trace(false, "handshaker"); -void grpc_handshaker_init(const grpc_handshaker_vtable* vtable, - grpc_handshaker* handshaker) { - handshaker->vtable = vtable; -} +namespace { -void grpc_handshaker_destroy(grpc_handshaker* handshaker) { - handshaker->vtable->destroy(handshaker); -} - -void grpc_handshaker_shutdown(grpc_handshaker* handshaker, grpc_error* why) { - handshaker->vtable->shutdown(handshaker, why); -} - -void grpc_handshaker_do_handshake(grpc_handshaker* handshaker, - grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, - grpc_handshaker_args* args) { - handshaker->vtable->do_handshake(handshaker, acceptor, on_handshake_done, - args); -} - -const char* grpc_handshaker_name(grpc_handshaker* handshaker) { - return handshaker->vtable->name; -} - -// -// grpc_handshake_manager -// - -struct grpc_handshake_manager { - gpr_mu mu; - gpr_refcount refs; - bool shutdown; - // An array of handshakers added via grpc_handshake_manager_add(). - size_t count; - grpc_handshaker** handshakers; - // The index of the handshaker to invoke next and closure to invoke it. - size_t index; - grpc_closure call_next_handshaker; - // The acceptor to call the handshakers with. - grpc_tcp_server_acceptor* acceptor; - // Deadline timer across all handshakers. - grpc_timer deadline_timer; - grpc_closure on_timeout; - // The final callback and user_data to invoke after the last handshaker. - grpc_closure on_handshake_done; - void* user_data; - // Handshaker args. - grpc_handshaker_args args; - // Links to the previous and next managers in a list of all pending handshakes - // Used at server side only. - grpc_handshake_manager* prev; - grpc_handshake_manager* next; -}; - -grpc_handshake_manager* grpc_handshake_manager_create() { - grpc_handshake_manager* mgr = static_cast( - gpr_zalloc(sizeof(grpc_handshake_manager))); - gpr_mu_init(&mgr->mu); - gpr_ref_init(&mgr->refs, 1); - return mgr; -} - -void grpc_handshake_manager_pending_list_add(grpc_handshake_manager** head, - grpc_handshake_manager* mgr) { - GPR_ASSERT(mgr->prev == nullptr); - GPR_ASSERT(mgr->next == nullptr); - mgr->next = *head; - if (*head) { - (*head)->prev = mgr; - } - *head = mgr; -} - -void grpc_handshake_manager_pending_list_remove(grpc_handshake_manager** head, - grpc_handshake_manager* mgr) { - if (mgr->next != nullptr) { - mgr->next->prev = mgr->prev; - } - if (mgr->prev != nullptr) { - mgr->prev->next = mgr->next; - } else { - GPR_ASSERT(*head == mgr); - *head = mgr->next; - } -} - -void grpc_handshake_manager_pending_list_shutdown_all( - grpc_handshake_manager* head, grpc_error* why) { - while (head != nullptr) { - grpc_handshake_manager_shutdown(head, GRPC_ERROR_REF(why)); - head = head->next; - } - GRPC_ERROR_UNREF(why); -} - -static bool is_power_of_2(size_t n) { return (n & (n - 1)) == 0; } - -void grpc_handshake_manager_add(grpc_handshake_manager* mgr, - grpc_handshaker* handshaker) { - if (grpc_handshaker_trace.enabled()) { - gpr_log( - GPR_INFO, - "handshake_manager %p: adding handshaker %s [%p] at index %" PRIuPTR, - mgr, grpc_handshaker_name(handshaker), handshaker, mgr->count); - } - gpr_mu_lock(&mgr->mu); - // To avoid allocating memory for each handshaker we add, we double - // the number of elements every time we need more. - size_t realloc_count = 0; - if (mgr->count == 0) { - realloc_count = 2; - } else if (mgr->count >= 2 && is_power_of_2(mgr->count)) { - realloc_count = mgr->count * 2; - } - if (realloc_count > 0) { - mgr->handshakers = static_cast(gpr_realloc( - mgr->handshakers, realloc_count * sizeof(grpc_handshaker*))); - } - mgr->handshakers[mgr->count++] = handshaker; - gpr_mu_unlock(&mgr->mu); -} - -static void grpc_handshake_manager_unref(grpc_handshake_manager* mgr) { - if (gpr_unref(&mgr->refs)) { - for (size_t i = 0; i < mgr->count; ++i) { - grpc_handshaker_destroy(mgr->handshakers[i]); - } - gpr_free(mgr->handshakers); - gpr_mu_destroy(&mgr->mu); - gpr_free(mgr); - } -} - -void grpc_handshake_manager_destroy(grpc_handshake_manager* mgr) { - grpc_handshake_manager_unref(mgr); -} - -void grpc_handshake_manager_shutdown(grpc_handshake_manager* mgr, - grpc_error* why) { - gpr_mu_lock(&mgr->mu); - // Shutdown the handshaker that's currently in progress, if any. - if (!mgr->shutdown && mgr->index > 0) { - mgr->shutdown = true; - grpc_handshaker_shutdown(mgr->handshakers[mgr->index - 1], - GRPC_ERROR_REF(why)); - } - gpr_mu_unlock(&mgr->mu); - GRPC_ERROR_UNREF(why); -} - -static char* handshaker_args_string(grpc_handshaker_args* args) { +char* HandshakerArgsString(HandshakerArgs* args) { char* args_str = grpc_channel_args_string(args->args); size_t num_args = args->args != nullptr ? args->args->num_args : 0; size_t read_buffer_length = @@ -202,130 +51,208 @@ static char* handshaker_args_string(grpc_handshaker_args* args) { return str; } +} // namespace + +HandshakeManager::HandshakeManager() { gpr_mu_init(&mu_); } + +/// Add \a mgr to the server side list of all pending handshake managers, the +/// list starts with \a *head. +// Not thread-safe. Caller needs to synchronize. +void HandshakeManager::AddToPendingMgrList(HandshakeManager** head) { + GPR_ASSERT(prev_ == nullptr); + GPR_ASSERT(next_ == nullptr); + next_ = *head; + if (*head) { + (*head)->prev_ = this; + } + *head = this; +} + +/// Remove \a mgr from the server side list of all pending handshake managers. +// Not thread-safe. Caller needs to synchronize. +void HandshakeManager::RemoveFromPendingMgrList(HandshakeManager** head) { + if (next_ != nullptr) { + next_->prev_ = prev_; + } + if (prev_ != nullptr) { + prev_->next_ = next_; + } else { + GPR_ASSERT(*head == this); + *head = next_; + } +} + +/// Shutdown all pending handshake managers starting at head on the server +/// side. Not thread-safe. Caller needs to synchronize. +void HandshakeManager::ShutdownAllPending(grpc_error* why) { + auto* head = this; + while (head != nullptr) { + head->Shutdown(GRPC_ERROR_REF(why)); + head = head->next_; + } + GRPC_ERROR_UNREF(why); +} + +void HandshakeManager::Add(RefCountedPtr handshaker) { + if (grpc_handshaker_trace.enabled()) { + gpr_log( + GPR_INFO, + "handshake_manager %p: adding handshaker %s [%p] at index %" PRIuPTR, + this, handshaker->name(), handshaker.get(), handshakers_.size()); + } + MutexLock lock(&mu_); + handshakers_.push_back(std::move(handshaker)); +} + +HandshakeManager::~HandshakeManager() { + handshakers_.clear(); + gpr_mu_destroy(&mu_); +} + +void HandshakeManager::Shutdown(grpc_error* why) { + { + MutexLock lock(&mu_); + // Shutdown the handshaker that's currently in progress, if any. + if (!is_shutdown_ && index_ > 0) { + is_shutdown_ = true; + handshakers_[index_ - 1]->Shutdown(GRPC_ERROR_REF(why)); + } + } + GRPC_ERROR_UNREF(why); +} + // Helper function to call either the next handshaker or the // on_handshake_done callback. // Returns true if we've scheduled the on_handshake_done callback. -static bool call_next_handshaker_locked(grpc_handshake_manager* mgr, - grpc_error* error) { +bool HandshakeManager::CallNextHandshakerLocked(grpc_error* error) { if (grpc_handshaker_trace.enabled()) { - char* args_str = handshaker_args_string(&mgr->args); + char* args_str = HandshakerArgsString(&args_); gpr_log(GPR_INFO, "handshake_manager %p: error=%s shutdown=%d index=%" PRIuPTR ", args=%s", - mgr, grpc_error_string(error), mgr->shutdown, mgr->index, args_str); + this, grpc_error_string(error), is_shutdown_, index_, args_str); gpr_free(args_str); } - GPR_ASSERT(mgr->index <= mgr->count); + GPR_ASSERT(index_ <= handshakers_.size()); // If we got an error or we've been shut down or we're exiting early or // we've finished the last handshaker, invoke the on_handshake_done // callback. Otherwise, call the next handshaker. - if (error != GRPC_ERROR_NONE || mgr->shutdown || mgr->args.exit_early || - mgr->index == mgr->count) { - if (error == GRPC_ERROR_NONE && mgr->shutdown) { + if (error != GRPC_ERROR_NONE || is_shutdown_ || args_.exit_early || + index_ == handshakers_.size()) { + if (error == GRPC_ERROR_NONE && is_shutdown_) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("handshaker shutdown"); // It is possible that the endpoint has already been destroyed by // a shutdown call while this callback was sitting on the ExecCtx // with no error. - if (mgr->args.endpoint != nullptr) { + if (args_.endpoint != nullptr) { // TODO(roth): It is currently necessary to shutdown endpoints // before destroying then, even when we know that there are no // pending read/write callbacks. This should be fixed, at which // point this can be removed. - grpc_endpoint_shutdown(mgr->args.endpoint, GRPC_ERROR_REF(error)); - grpc_endpoint_destroy(mgr->args.endpoint); - mgr->args.endpoint = nullptr; - grpc_channel_args_destroy(mgr->args.args); - mgr->args.args = nullptr; - grpc_slice_buffer_destroy_internal(mgr->args.read_buffer); - gpr_free(mgr->args.read_buffer); - mgr->args.read_buffer = nullptr; + grpc_endpoint_shutdown(args_.endpoint, GRPC_ERROR_REF(error)); + grpc_endpoint_destroy(args_.endpoint); + args_.endpoint = nullptr; + grpc_channel_args_destroy(args_.args); + args_.args = nullptr; + grpc_slice_buffer_destroy_internal(args_.read_buffer); + gpr_free(args_.read_buffer); + args_.read_buffer = nullptr; } } if (grpc_handshaker_trace.enabled()) { gpr_log(GPR_INFO, "handshake_manager %p: handshaking complete -- scheduling " "on_handshake_done with error=%s", - mgr, grpc_error_string(error)); + this, grpc_error_string(error)); } // Cancel deadline timer, since we're invoking the on_handshake_done // callback now. - grpc_timer_cancel(&mgr->deadline_timer); - GRPC_CLOSURE_SCHED(&mgr->on_handshake_done, error); - mgr->shutdown = true; + grpc_timer_cancel(&deadline_timer_); + GRPC_CLOSURE_SCHED(&on_handshake_done_, error); + is_shutdown_ = true; } else { + auto handshaker = handshakers_[index_]; if (grpc_handshaker_trace.enabled()) { gpr_log( GPR_INFO, "handshake_manager %p: calling handshaker %s [%p] at index %" PRIuPTR, - mgr, grpc_handshaker_name(mgr->handshakers[mgr->index]), - mgr->handshakers[mgr->index], mgr->index); + this, handshaker->name(), handshaker.get(), index_); } - grpc_handshaker_do_handshake(mgr->handshakers[mgr->index], mgr->acceptor, - &mgr->call_next_handshaker, &mgr->args); + handshaker->DoHandshake(acceptor_, &call_next_handshaker_, &args_); } - ++mgr->index; - return mgr->shutdown; + ++index_; + return is_shutdown_; } -// A function used as the handshaker-done callback when chaining -// handshakers together. -static void call_next_handshaker(void* arg, grpc_error* error) { - grpc_handshake_manager* mgr = static_cast(arg); - gpr_mu_lock(&mgr->mu); - bool done = call_next_handshaker_locked(mgr, GRPC_ERROR_REF(error)); - gpr_mu_unlock(&mgr->mu); +void HandshakeManager::CallNextHandshakerFn(void* arg, grpc_error* error) { + auto* mgr = static_cast(arg); + bool done; + { + MutexLock lock(&mgr->mu_); + done = mgr->CallNextHandshakerLocked(GRPC_ERROR_REF(error)); + } // If we're invoked the final callback, we won't be coming back // to this function, so we can release our reference to the // handshake manager. if (done) { - grpc_handshake_manager_unref(mgr); + mgr->Unref(); } } -// Callback invoked when deadline is exceeded. -static void on_timeout(void* arg, grpc_error* error) { - grpc_handshake_manager* mgr = static_cast(arg); - if (error == GRPC_ERROR_NONE) { // Timer fired, rather than being cancelled. - grpc_handshake_manager_shutdown( - mgr, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake timed out")); +void HandshakeManager::OnTimeoutFn(void* arg, grpc_error* error) { + auto* mgr = static_cast(arg); + if (error == GRPC_ERROR_NONE) { // Timer fired, rather than being cancelled + mgr->Shutdown(GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshake timed out")); } - grpc_handshake_manager_unref(mgr); + mgr->Unref(); } -void grpc_handshake_manager_do_handshake(grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, - const grpc_channel_args* channel_args, - grpc_millis deadline, - grpc_tcp_server_acceptor* acceptor, - grpc_iomgr_cb_func on_handshake_done, - void* user_data) { - gpr_mu_lock(&mgr->mu); - GPR_ASSERT(mgr->index == 0); - GPR_ASSERT(!mgr->shutdown); - // Construct handshaker args. These will be passed through all - // handshakers and eventually be freed by the on_handshake_done callback. - mgr->args.endpoint = endpoint; - mgr->args.args = grpc_channel_args_copy(channel_args); - mgr->args.user_data = user_data; - mgr->args.read_buffer = static_cast( - gpr_malloc(sizeof(*mgr->args.read_buffer))); - grpc_slice_buffer_init(mgr->args.read_buffer); - // Initialize state needed for calling handshakers. - mgr->acceptor = acceptor; - GRPC_CLOSURE_INIT(&mgr->call_next_handshaker, call_next_handshaker, mgr, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&mgr->on_handshake_done, on_handshake_done, &mgr->args, - grpc_schedule_on_exec_ctx); - // Start deadline timer, which owns a ref. - gpr_ref(&mgr->refs); - GRPC_CLOSURE_INIT(&mgr->on_timeout, on_timeout, mgr, - grpc_schedule_on_exec_ctx); - grpc_timer_init(&mgr->deadline_timer, deadline, &mgr->on_timeout); - // Start first handshaker, which also owns a ref. - gpr_ref(&mgr->refs); - bool done = call_next_handshaker_locked(mgr, GRPC_ERROR_NONE); - gpr_mu_unlock(&mgr->mu); +void HandshakeManager::DoHandshake(grpc_endpoint* endpoint, + const grpc_channel_args* channel_args, + grpc_millis deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_iomgr_cb_func on_handshake_done, + void* user_data) { + bool done; + { + MutexLock lock(&mu_); + GPR_ASSERT(index_ == 0); + GPR_ASSERT(!is_shutdown_); + // Construct handshaker args. These will be passed through all + // handshakers and eventually be freed by the on_handshake_done callback. + args_.endpoint = endpoint; + args_.args = grpc_channel_args_copy(channel_args); + args_.user_data = user_data; + args_.read_buffer = + static_cast(gpr_malloc(sizeof(*args_.read_buffer))); + grpc_slice_buffer_init(args_.read_buffer); + // Initialize state needed for calling handshakers. + acceptor_ = acceptor; + GRPC_CLOSURE_INIT(&call_next_handshaker_, + &HandshakeManager::CallNextHandshakerFn, this, + grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&on_handshake_done_, on_handshake_done, &args_, + grpc_schedule_on_exec_ctx); + // Start deadline timer, which owns a ref. + Ref().release(); + GRPC_CLOSURE_INIT(&on_timeout_, &HandshakeManager::OnTimeoutFn, this, + grpc_schedule_on_exec_ctx); + grpc_timer_init(&deadline_timer_, deadline, &on_timeout_); + // Start first handshaker, which also owns a ref. + Ref().release(); + done = CallNextHandshakerLocked(GRPC_ERROR_NONE); + } if (done) { - grpc_handshake_manager_unref(mgr); + Unref(); } } + +} // namespace grpc_core + +void grpc_handshake_manager_add(grpc_handshake_manager* mgr, + grpc_handshaker* handshaker) { + // This is a transition method to aid the API change for handshakers. + using namespace grpc_core; + RefCountedPtr refd_hs(static_cast(handshaker)); + mgr->Add(refd_hs); +} diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index a65990fceb4..912d524c8db 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -21,12 +21,21 @@ #include +#include + #include +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/iomgr/timer.h" + +namespace grpc_core { /// Handshakers are used to perform initial handshakes on a connection /// before the client sends the initial request. Some examples of what @@ -35,12 +44,6 @@ /// /// In general, handshakers should be used via a handshake manager. -/// -/// grpc_handshaker -/// - -typedef struct grpc_handshaker grpc_handshaker; - /// Arguments passed through handshakers and to the on_handshake_done callback. /// /// For handshakers, all members are input/output parameters; for @@ -55,115 +58,121 @@ typedef struct grpc_handshaker grpc_handshaker; /// /// For the on_handshake_done callback, all members are input arguments, /// which the callback takes ownership of. -typedef struct { - grpc_endpoint* endpoint; - grpc_channel_args* args; - grpc_slice_buffer* read_buffer; +struct HandshakerArgs { + grpc_endpoint* endpoint = nullptr; + grpc_channel_args* args = nullptr; + grpc_slice_buffer* read_buffer = nullptr; // A handshaker may set this to true before invoking on_handshake_done // to indicate that subsequent handshakers should be skipped. - bool exit_early; + bool exit_early = false; // User data passed through the handshake manager. Not used by // individual handshakers. - void* user_data; -} grpc_handshaker_args; - -typedef struct { - /// Destroys the handshaker. - void (*destroy)(grpc_handshaker* handshaker); - - /// Shuts down the handshaker (e.g., to clean up when the operation is - /// aborted in the middle). - void (*shutdown)(grpc_handshaker* handshaker, grpc_error* why); - - /// Performs handshaking, modifying \a args as needed (e.g., to - /// replace \a endpoint with a wrapped endpoint). - /// When finished, invokes \a on_handshake_done. - /// \a acceptor will be NULL for client-side handshakers. - void (*do_handshake)(grpc_handshaker* handshaker, - grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, - grpc_handshaker_args* args); - - /// The name of the handshaker, for debugging purposes. - const char* name; -} grpc_handshaker_vtable; - -/// Base struct. To subclass, make this the first member of the -/// implementation struct. -struct grpc_handshaker { - const grpc_handshaker_vtable* vtable; + void* user_data = nullptr; }; -/// Called by concrete implementations to initialize the base struct. -void grpc_handshaker_init(const grpc_handshaker_vtable* vtable, - grpc_handshaker* handshaker); - -void grpc_handshaker_destroy(grpc_handshaker* handshaker); -void grpc_handshaker_shutdown(grpc_handshaker* handshaker, grpc_error* why); -void grpc_handshaker_do_handshake(grpc_handshaker* handshaker, - grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, - grpc_handshaker_args* args); -const char* grpc_handshaker_name(grpc_handshaker* handshaker); - /// -/// grpc_handshake_manager +/// Handshaker /// -typedef struct grpc_handshake_manager grpc_handshake_manager; +class Handshaker : public RefCounted { + public: + virtual ~Handshaker() = default; + virtual void Shutdown(grpc_error* why) GRPC_ABSTRACT; + virtual void DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) GRPC_ABSTRACT; + virtual const char* name() const GRPC_ABSTRACT; + GRPC_ABSTRACT_BASE_CLASS +}; -/// Creates a new handshake manager. Caller takes ownership. -grpc_handshake_manager* grpc_handshake_manager_create(); +// +// HandshakeManager +// -/// Adds a handshaker to the handshake manager. -/// Takes ownership of \a handshaker. +class HandshakeManager : public RefCounted { + public: + HandshakeManager(); + ~HandshakeManager(); + + /// Add \a mgr to the server side list of all pending handshake managers, the + /// list starts with \a *head. + // Not thread-safe. Caller needs to synchronize. + void AddToPendingMgrList(HandshakeManager** head); + + /// Remove \a mgr from the server side list of all pending handshake managers. + // Not thread-safe. Caller needs to synchronize. + void RemoveFromPendingMgrList(HandshakeManager** head); + + /// Shutdown all pending handshake managers starting at head on the server + /// side. Not thread-safe. Caller needs to synchronize. + void ShutdownAllPending(grpc_error* why); + + /// Adds a handshaker to the handshake manager. + /// Takes ownership of \a handshaker. + void Add(RefCountedPtr handshaker); + + /// Shuts down the handshake manager (e.g., to clean up when the operation is + /// aborted in the middle). + void Shutdown(grpc_error* why); + + /// Invokes handshakers in the order they were added. + /// Takes ownership of \a endpoint, and then passes that ownership to + /// the \a on_handshake_done callback. + /// Does NOT take ownership of \a channel_args. Instead, makes a copy before + /// invoking the first handshaker. + /// \a acceptor will be nullptr for client-side handshakers. + /// + /// When done, invokes \a on_handshake_done with a HandshakerArgs + /// object as its argument. If the callback is invoked with error != + /// GRPC_ERROR_NONE, then handshaking failed and the handshaker has done + /// the necessary clean-up. Otherwise, the callback takes ownership of + /// the arguments. + void DoHandshake(grpc_endpoint* endpoint, + const grpc_channel_args* channel_args, grpc_millis deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_iomgr_cb_func on_handshake_done, void* user_data); + + private: + bool CallNextHandshakerLocked(grpc_error* error); + + // A function used as the handshaker-done callback when chaining + // handshakers together. + static void CallNextHandshakerFn(void* arg, grpc_error* error); + + // Callback invoked when deadline is exceeded. + static void OnTimeoutFn(void* arg, grpc_error* error); + + static const size_t HANDSHAKERS_INIT_SIZE = 2; + + gpr_mu mu_; + bool is_shutdown_ = false; + // An array of handshakers added via grpc_handshake_manager_add(). + InlinedVector, HANDSHAKERS_INIT_SIZE> handshakers_; + // The index of the handshaker to invoke next and closure to invoke it. + size_t index_ = 0; + grpc_closure call_next_handshaker_; + // The acceptor to call the handshakers with. + grpc_tcp_server_acceptor* acceptor_; + // Deadline timer across all handshakers. + grpc_timer deadline_timer_; + grpc_closure on_timeout_; + // The final callback and user_data to invoke after the last handshaker. + grpc_closure on_handshake_done_; + // Handshaker args. + HandshakerArgs args_; + // Links to the previous and next managers in a list of all pending handshakes + // Used at server side only. + HandshakeManager* prev_ = nullptr; + HandshakeManager* next_ = nullptr; +}; + +} // namespace grpc_core + +// TODO(arjunroy): These are transitional to account for the new handshaker API +// and will eventually be removed entirely. +typedef grpc_core::HandshakeManager grpc_handshake_manager; +typedef grpc_core::Handshaker grpc_handshaker; void grpc_handshake_manager_add(grpc_handshake_manager* mgr, grpc_handshaker* handshaker); -/// Destroys the handshake manager. -void grpc_handshake_manager_destroy(grpc_handshake_manager* mgr); - -/// Shuts down the handshake manager (e.g., to clean up when the operation is -/// aborted in the middle). -/// The caller must still call grpc_handshake_manager_destroy() after -/// calling this function. -void grpc_handshake_manager_shutdown(grpc_handshake_manager* mgr, - grpc_error* why); - -/// Invokes handshakers in the order they were added. -/// Takes ownership of \a endpoint, and then passes that ownership to -/// the \a on_handshake_done callback. -/// Does NOT take ownership of \a channel_args. Instead, makes a copy before -/// invoking the first handshaker. -/// \a acceptor will be nullptr for client-side handshakers. -/// -/// When done, invokes \a on_handshake_done with a grpc_handshaker_args -/// object as its argument. If the callback is invoked with error != -/// GRPC_ERROR_NONE, then handshaking failed and the handshaker has done -/// the necessary clean-up. Otherwise, the callback takes ownership of -/// the arguments. -void grpc_handshake_manager_do_handshake(grpc_handshake_manager* mgr, - grpc_endpoint* endpoint, - const grpc_channel_args* channel_args, - grpc_millis deadline, - grpc_tcp_server_acceptor* acceptor, - grpc_iomgr_cb_func on_handshake_done, - void* user_data); - -/// Add \a mgr to the server side list of all pending handshake managers, the -/// list starts with \a *head. -// Not thread-safe. Caller needs to synchronize. -void grpc_handshake_manager_pending_list_add(grpc_handshake_manager** head, - grpc_handshake_manager* mgr); - -/// Remove \a mgr from the server side list of all pending handshake managers. -// Not thread-safe. Caller needs to synchronize. -void grpc_handshake_manager_pending_list_remove(grpc_handshake_manager** head, - grpc_handshake_manager* mgr); - -/// Shutdown all pending handshake managers on the server side. -// Not thread-safe. Caller needs to synchronize. -void grpc_handshake_manager_pending_list_shutdown_all( - grpc_handshake_manager* head, grpc_error* why); - #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ diff --git a/src/core/lib/channel/handshaker_factory.cc b/src/core/lib/channel/handshaker_factory.cc deleted file mode 100644 index 8ade8fe4e23..00000000000 --- a/src/core/lib/channel/handshaker_factory.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/lib/channel/handshaker_factory.h" - -#include - -void grpc_handshaker_factory_add_handshakers( - grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - if (handshaker_factory != nullptr) { - GPR_ASSERT(handshaker_factory->vtable != nullptr); - handshaker_factory->vtable->add_handshakers( - handshaker_factory, args, interested_parties, handshake_mgr); - } -} - -void grpc_handshaker_factory_destroy( - grpc_handshaker_factory* handshaker_factory) { - if (handshaker_factory != nullptr) { - GPR_ASSERT(handshaker_factory->vtable != nullptr); - handshaker_factory->vtable->destroy(handshaker_factory); - } -} diff --git a/src/core/lib/channel/handshaker_factory.h b/src/core/lib/channel/handshaker_factory.h index e17a6781798..3972af1f439 100644 --- a/src/core/lib/channel/handshaker_factory.h +++ b/src/core/lib/channel/handshaker_factory.h @@ -27,26 +27,18 @@ // A handshaker factory is used to create handshakers. -typedef struct grpc_handshaker_factory grpc_handshaker_factory; +namespace grpc_core { -typedef struct { - void (*add_handshakers)(grpc_handshaker_factory* handshaker_factory, - const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); - void (*destroy)(grpc_handshaker_factory* handshaker_factory); -} grpc_handshaker_factory_vtable; +class HandshakerFactory { + public: + virtual void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) GRPC_ABSTRACT; + virtual ~HandshakerFactory() = default; -struct grpc_handshaker_factory { - const grpc_handshaker_factory_vtable* vtable; + GRPC_ABSTRACT_BASE_CLASS }; -void grpc_handshaker_factory_add_handshakers( - grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); - -void grpc_handshaker_factory_destroy( - grpc_handshaker_factory* handshaker_factory); +} // namespace grpc_core #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_FACTORY_H */ diff --git a/src/core/lib/channel/handshaker_registry.cc b/src/core/lib/channel/handshaker_registry.cc index fbafc43e795..b65129a6ed6 100644 --- a/src/core/lib/channel/handshaker_registry.cc +++ b/src/core/lib/channel/handshaker_registry.cc @@ -19,8 +19,11 @@ #include #include "src/core/lib/channel/handshaker_registry.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/memory.h" #include +#include #include @@ -28,74 +31,83 @@ // grpc_handshaker_factory_list // -typedef struct { - grpc_handshaker_factory** list; - size_t num_factories; -} grpc_handshaker_factory_list; +namespace grpc_core { -static void grpc_handshaker_factory_list_register( - grpc_handshaker_factory_list* list, bool at_start, - grpc_handshaker_factory* factory) { - list->list = static_cast(gpr_realloc( - list->list, - (list->num_factories + 1) * sizeof(grpc_handshaker_factory*))); +namespace { + +class HandshakerFactoryList { + public: + void Register(bool at_start, UniquePtr factory); + void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr); + + private: + InlinedVector, 2> factories_; +}; + +HandshakerFactoryList* g_handshaker_factory_lists = nullptr; + +} // namespace + +void HandshakerFactoryList::Register(bool at_start, + UniquePtr factory) { + factories_.push_back(std::move(factory)); if (at_start) { - memmove(list->list + 1, list->list, - sizeof(grpc_handshaker_factory*) * list->num_factories); - list->list[0] = factory; - } else { - list->list[list->num_factories] = factory; - } - ++list->num_factories; -} - -static void grpc_handshaker_factory_list_add_handshakers( - grpc_handshaker_factory_list* list, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - for (size_t i = 0; i < list->num_factories; ++i) { - grpc_handshaker_factory_add_handshakers(list->list[i], args, - interested_parties, handshake_mgr); + auto* end = &factories_[factories_.size() - 1]; + std::rotate(&factories_[0], end, end + 1); } } -static void grpc_handshaker_factory_list_destroy( - grpc_handshaker_factory_list* list) { - for (size_t i = 0; i < list->num_factories; ++i) { - grpc_handshaker_factory_destroy(list->list[i]); +void HandshakerFactoryList::AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) { + for (size_t idx = 0; idx < factories_.size(); ++idx) { + auto& handshaker_factory = factories_[idx]; + handshaker_factory->AddHandshakers(args, interested_parties, handshake_mgr); } - gpr_free(list->list); } // // plugin // -static grpc_handshaker_factory_list - g_handshaker_factory_lists[NUM_HANDSHAKER_TYPES]; - -void grpc_handshaker_factory_registry_init() { - memset(g_handshaker_factory_lists, 0, sizeof(g_handshaker_factory_lists)); -} - -void grpc_handshaker_factory_registry_shutdown() { - for (size_t i = 0; i < NUM_HANDSHAKER_TYPES; ++i) { - grpc_handshaker_factory_list_destroy(&g_handshaker_factory_lists[i]); +void HandshakerRegistry::Init() { + GPR_ASSERT(g_handshaker_factory_lists == nullptr); + g_handshaker_factory_lists = static_cast( + gpr_malloc(sizeof(*g_handshaker_factory_lists) * NUM_HANDSHAKER_TYPES)); + GPR_ASSERT(g_handshaker_factory_lists != nullptr); + for (auto idx = 0; idx < NUM_HANDSHAKER_TYPES; ++idx) { + auto factory_list = g_handshaker_factory_lists + idx; + new (factory_list) HandshakerFactoryList(); } } -void grpc_handshaker_factory_register(bool at_start, - grpc_handshaker_type handshaker_type, - grpc_handshaker_factory* factory) { - grpc_handshaker_factory_list_register( - &g_handshaker_factory_lists[handshaker_type], at_start, factory); +void HandshakerRegistry::Shutdown() { + GPR_ASSERT(g_handshaker_factory_lists != nullptr); + for (auto idx = 0; idx < NUM_HANDSHAKER_TYPES; ++idx) { + auto factory_list = g_handshaker_factory_lists + idx; + factory_list->~HandshakerFactoryList(); + } + gpr_free(g_handshaker_factory_lists); + g_handshaker_factory_lists = nullptr; } -void grpc_handshakers_add(grpc_handshaker_type handshaker_type, - const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshaker_factory_list_add_handshakers( - &g_handshaker_factory_lists[handshaker_type], args, interested_parties, - handshake_mgr); +void HandshakerRegistry::RegisterHandshakerFactory( + bool at_start, HandshakerType handshaker_type, + UniquePtr factory) { + GPR_ASSERT(g_handshaker_factory_lists != nullptr); + auto& factory_list = g_handshaker_factory_lists[handshaker_type]; + factory_list.Register(at_start, std::move(factory)); } + +void HandshakerRegistry::AddHandshakers(HandshakerType handshaker_type, + const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) { + GPR_ASSERT(g_handshaker_factory_lists != nullptr); + auto& factory_list = g_handshaker_factory_lists[handshaker_type]; + factory_list.AddHandshakers(args, interested_parties, handshake_mgr); +} + +} // namespace grpc_core diff --git a/src/core/lib/channel/handshaker_registry.h b/src/core/lib/channel/handshaker_registry.h index 3dd4316de67..1b93a8dd47e 100644 --- a/src/core/lib/channel/handshaker_registry.h +++ b/src/core/lib/channel/handshaker_registry.h @@ -25,25 +25,30 @@ #include "src/core/lib/channel/handshaker_factory.h" +namespace grpc_core { + typedef enum { HANDSHAKER_CLIENT = 0, HANDSHAKER_SERVER, NUM_HANDSHAKER_TYPES, // Must be last. -} grpc_handshaker_type; +} HandshakerType; -void grpc_handshaker_factory_registry_init(); -void grpc_handshaker_factory_registry_shutdown(); +class HandshakerRegistry { + public: + /// Registers a new handshaker factory. Takes ownership. + /// If \a at_start is true, the new handshaker will be at the beginning of + /// the list. Otherwise, it will be added to the end. + static void RegisterHandshakerFactory(bool at_start, + HandshakerType handshaker_type, + UniquePtr factory); + static void AddHandshakers(HandshakerType handshaker_type, + const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr); + static void Init(); + static void Shutdown(); +}; -/// Registers a new handshaker factory. Takes ownership. -/// If \a at_start is true, the new handshaker will be at the beginning of -/// the list. Otherwise, it will be added to the end. -void grpc_handshaker_factory_register(bool at_start, - grpc_handshaker_type handshaker_type, - grpc_handshaker_factory* factory); - -void grpc_handshakers_add(grpc_handshaker_type handshaker_type, - const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr); +} // namespace grpc_core #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H */ diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index fdea7511cca..3f288e045a6 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -67,7 +67,7 @@ class grpc_httpcli_ssl_channel_security_connector final } void add_handshakers(grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) override { + grpc_core::HandshakeManager* handshake_mgr) override { tsi_handshaker* handshaker = nullptr; if (handshaker_factory_ != nullptr) { tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( @@ -77,8 +77,7 @@ class grpc_httpcli_ssl_channel_security_connector final tsi_result_to_string(result)); } } - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(handshaker, this)); + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(handshaker, this)); } tsi_ssl_client_handshaker_factory* handshaker_factory() const { @@ -155,11 +154,11 @@ httpcli_ssl_channel_security_connector_create( typedef struct { void (*func)(void* arg, grpc_endpoint* endpoint); void* arg; - grpc_handshake_manager* handshake_mgr; + grpc_core::RefCountedPtr handshake_mgr; } on_done_closure; static void on_handshake_done(void* arg, grpc_error* error) { - grpc_handshaker_args* args = static_cast(arg); + auto* args = static_cast(arg); on_done_closure* c = static_cast(args->user_data); if (error != GRPC_ERROR_NONE) { const char* msg = grpc_error_string(error); @@ -172,14 +171,13 @@ static void on_handshake_done(void* arg, grpc_error* error) { gpr_free(args->read_buffer); c->func(c->arg, args->endpoint); } - grpc_handshake_manager_destroy(c->handshake_mgr); - gpr_free(c); + grpc_core::Delete(c); } static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, grpc_millis deadline, void (*on_done)(void* arg, grpc_endpoint* endpoint)) { - on_done_closure* c = static_cast(gpr_malloc(sizeof(*c))); + auto* c = grpc_core::New(); const char* pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); const tsi_ssl_root_certs_store* root_store = @@ -198,12 +196,13 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, GPR_ASSERT(sc != nullptr); grpc_arg channel_arg = grpc_security_connector_to_arg(sc.get()); grpc_channel_args args = {1, &channel_arg}; - c->handshake_mgr = grpc_handshake_manager_create(); - grpc_handshakers_add(HANDSHAKER_CLIENT, &args, - nullptr /* interested_parties */, c->handshake_mgr); - grpc_handshake_manager_do_handshake( - c->handshake_mgr, tcp, nullptr /* channel_args */, deadline, - nullptr /* acceptor */, on_handshake_done, c /* user_data */); + c->handshake_mgr = grpc_core::MakeRefCounted(); + grpc_core::HandshakerRegistry::AddHandshakers( + grpc_core::HANDSHAKER_CLIENT, &args, /*interested_parties=*/nullptr, + c->handshake_mgr.get()); + c->handshake_mgr->DoHandshake(tcp, /*channel_args=*/nullptr, deadline, + /*acceptor=*/nullptr, on_handshake_done, + /*user_data=*/c); sc.reset(DEBUG_LOCATION, "httpcli"); } diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc index 3ad0cc353cb..38b1f856d52 100644 --- a/src/core/lib/security/security_connector/alts/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc @@ -80,8 +80,9 @@ class grpc_alts_channel_security_connector final ~grpc_alts_channel_security_connector() override { gpr_free(target_name_); } - void add_handshakers(grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) override { + void add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_manager) override { tsi_handshaker* handshaker = nullptr; const grpc_alts_credentials* creds = static_cast(channel_creds()); @@ -89,8 +90,8 @@ class grpc_alts_channel_security_connector final creds->handshaker_service_url(), true, interested_parties, &handshaker) == TSI_OK); - grpc_handshake_manager_add( - handshake_manager, grpc_security_handshaker_create(handshaker, this)); + handshake_manager->Add( + grpc_core::SecurityHandshakerCreate(handshaker, this)); } void check_peer(tsi_peer peer, grpc_endpoint* ep, @@ -139,16 +140,17 @@ class grpc_alts_server_security_connector final } ~grpc_alts_server_security_connector() override = default; - void add_handshakers(grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) override { + void add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_manager) override { tsi_handshaker* handshaker = nullptr; const grpc_alts_server_credentials* creds = static_cast(server_creds()); GPR_ASSERT(alts_tsi_handshaker_create( creds->options(), nullptr, creds->handshaker_service_url(), false, interested_parties, &handshaker) == TSI_OK); - grpc_handshake_manager_add( - handshake_manager, grpc_security_handshaker_create(handshaker, this)); + handshake_manager->Add( + grpc_core::SecurityHandshakerCreate(handshaker, this)); } void check_peer(tsi_peer peer, grpc_endpoint* ep, diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.cc b/src/core/lib/security/security_connector/fake/fake_security_connector.cc index e3b8affb360..a0e2e6f030b 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.cc +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc @@ -92,11 +92,9 @@ class grpc_fake_channel_security_connector final } void add_handshakers(grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) override { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(/*is_client=*/true), this)); + grpc_core::HandshakeManager* handshake_mgr) override { + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate( + tsi_create_fake_handshaker(/*is_client=*/true), this)); } bool check_call_host(const char* host, grpc_auth_context* auth_context, @@ -273,11 +271,9 @@ class grpc_fake_server_security_connector } void add_handshakers(grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) override { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(/*=is_client*/ false), this)); + grpc_core::HandshakeManager* handshake_mgr) override { + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate( + tsi_create_fake_handshaker(/*=is_client*/ false), this)); } int cmp(const grpc_security_connector* other) const override { diff --git a/src/core/lib/security/security_connector/local/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc index 7cc482c16c5..c1a101d4ab8 100644 --- a/src/core/lib/security/security_connector/local/local_security_connector.cc +++ b/src/core/lib/security/security_connector/local/local_security_connector.cc @@ -128,13 +128,14 @@ class grpc_local_channel_security_connector final ~grpc_local_channel_security_connector() override { gpr_free(target_name_); } - void add_handshakers(grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) override { + void add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_manager) override { tsi_handshaker* handshaker = nullptr; GPR_ASSERT(local_tsi_handshaker_create(true /* is_client */, &handshaker) == TSI_OK); - grpc_handshake_manager_add( - handshake_manager, grpc_security_handshaker_create(handshaker, this)); + handshake_manager->Add( + grpc_core::SecurityHandshakerCreate(handshaker, this)); } int cmp(const grpc_security_connector* other_sc) const override { @@ -184,13 +185,14 @@ class grpc_local_server_security_connector final : grpc_server_security_connector(nullptr, std::move(server_creds)) {} ~grpc_local_server_security_connector() override = default; - void add_handshakers(grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_manager) override { + void add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_manager) override { tsi_handshaker* handshaker = nullptr; GPR_ASSERT(local_tsi_handshaker_create(false /* is_client */, &handshaker) == TSI_OK); - grpc_handshake_manager_add( - handshake_manager, grpc_security_handshaker_create(handshaker, this)); + handshake_manager->Add( + grpc_core::SecurityHandshakerCreate(handshaker, this)); } void check_peer(tsi_peer peer, grpc_endpoint* ep, diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index 74b0ef21a62..4c74c5cfea0 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -109,7 +109,7 @@ class grpc_channel_security_connector : public grpc_security_connector { grpc_error* error) GRPC_ABSTRACT; /// Registers handshakers with \a handshake_mgr. virtual void add_handshakers(grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) + grpc_core::HandshakeManager* handshake_mgr) GRPC_ABSTRACT; const grpc_channel_credentials* channel_creds() const { @@ -150,7 +150,7 @@ class grpc_server_security_connector : public grpc_security_connector { ~grpc_server_security_connector() override = default; virtual void add_handshakers(grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) + grpc_core::HandshakeManager* handshake_mgr) GRPC_ABSTRACT; const grpc_server_credentials* server_creds() const { diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index 7414ab1a37f..37cb41b9637 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -128,7 +128,7 @@ class grpc_ssl_channel_security_connector final } void add_handshakers(grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) override { + grpc_core::HandshakeManager* handshake_mgr) override { // Instantiate TSI handshaker. tsi_handshaker* tsi_hs = nullptr; tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( @@ -142,8 +142,7 @@ class grpc_ssl_channel_security_connector final return; } // Create handshakers. - grpc_handshake_manager_add(handshake_mgr, - grpc_security_handshaker_create(tsi_hs, this)); + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this)); } void check_peer(tsi_peer peer, grpc_endpoint* ep, @@ -283,7 +282,7 @@ class grpc_ssl_server_security_connector } void add_handshakers(grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) override { + grpc_core::HandshakeManager* handshake_mgr) override { // Instantiate TSI handshaker. try_fetch_ssl_server_credentials(); tsi_handshaker* tsi_hs = nullptr; @@ -295,8 +294,7 @@ class grpc_ssl_server_security_connector return; } // Create handshakers. - grpc_handshake_manager_add(handshake_mgr, - grpc_security_handshaker_create(tsi_hs, this)); + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this)); } void check_peer(tsi_peer peer, grpc_endpoint* ep, diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index 01831dab10f..a6fd2481a4a 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -39,74 +39,113 @@ #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256 +namespace grpc_core { + namespace { -struct security_handshaker { - security_handshaker(tsi_handshaker* handshaker, - grpc_security_connector* connector); - ~security_handshaker() { - gpr_mu_destroy(&mu); - tsi_handshaker_destroy(handshaker); - tsi_handshaker_result_destroy(handshaker_result); - if (endpoint_to_destroy != nullptr) { - grpc_endpoint_destroy(endpoint_to_destroy); - } - if (read_buffer_to_destroy != nullptr) { - grpc_slice_buffer_destroy_internal(read_buffer_to_destroy); - gpr_free(read_buffer_to_destroy); - } - gpr_free(handshake_buffer); - grpc_slice_buffer_destroy_internal(&outgoing); - auth_context.reset(DEBUG_LOCATION, "handshake"); - connector.reset(DEBUG_LOCATION, "handshake"); - } - void Ref() { refs.Ref(); } - void Unref() { - if (refs.Unref()) { - grpc_core::Delete(this); - } - } +class SecurityHandshaker : public Handshaker { + public: + SecurityHandshaker(tsi_handshaker* handshaker, + grpc_security_connector* connector); + ~SecurityHandshaker() override; + void Shutdown(grpc_error* why) override; + void DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) override; + const char* name() const override { return "security"; } - grpc_handshaker base; + private: + grpc_error* DoHandshakerNextLocked(const unsigned char* bytes_received, + size_t bytes_received_size); + + grpc_error* OnHandshakeNextDoneLocked( + tsi_result result, const unsigned char* bytes_to_send, + size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result); + void HandshakeFailedLocked(grpc_error* error); + void CleanupArgsForFailureLocked(); + + static void OnHandshakeDataReceivedFromPeerFn(void* arg, grpc_error* error); + static void OnHandshakeDataSentToPeerFn(void* arg, grpc_error* error); + static void OnHandshakeNextDoneGrpcWrapper( + tsi_result result, void* user_data, const unsigned char* bytes_to_send, + size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result); + static void OnPeerCheckedFn(void* arg, grpc_error* error); + void OnPeerCheckedInner(grpc_error* error); + size_t MoveReadBufferIntoHandshakeBuffer(); + grpc_error* CheckPeerLocked(); // State set at creation time. - tsi_handshaker* handshaker; - grpc_core::RefCountedPtr connector; + tsi_handshaker* handshaker_; + RefCountedPtr connector_; - gpr_mu mu; - grpc_core::RefCount refs; + gpr_mu mu_; - bool shutdown = false; + bool is_shutdown_ = false; // Endpoint and read buffer to destroy after a shutdown. - grpc_endpoint* endpoint_to_destroy = nullptr; - grpc_slice_buffer* read_buffer_to_destroy = nullptr; + grpc_endpoint* endpoint_to_destroy_ = nullptr; + grpc_slice_buffer* read_buffer_to_destroy_ = nullptr; // State saved while performing the handshake. - grpc_handshaker_args* args = nullptr; - grpc_closure* on_handshake_done = nullptr; + HandshakerArgs* args_ = nullptr; + grpc_closure* on_handshake_done_ = nullptr; - size_t handshake_buffer_size; - unsigned char* handshake_buffer; - grpc_slice_buffer outgoing; - grpc_closure on_handshake_data_sent_to_peer; - grpc_closure on_handshake_data_received_from_peer; - grpc_closure on_peer_checked; - grpc_core::RefCountedPtr auth_context; - tsi_handshaker_result* handshaker_result = nullptr; + size_t handshake_buffer_size_; + unsigned char* handshake_buffer_; + grpc_slice_buffer outgoing_; + grpc_closure on_handshake_data_sent_to_peer_; + grpc_closure on_handshake_data_received_from_peer_; + grpc_closure on_peer_checked_; + RefCountedPtr auth_context_; + tsi_handshaker_result* handshaker_result_ = nullptr; }; -} // namespace -static size_t move_read_buffer_into_handshake_buffer(security_handshaker* h) { - size_t bytes_in_read_buffer = h->args->read_buffer->length; - if (h->handshake_buffer_size < bytes_in_read_buffer) { - h->handshake_buffer = static_cast( - gpr_realloc(h->handshake_buffer, bytes_in_read_buffer)); - h->handshake_buffer_size = bytes_in_read_buffer; +SecurityHandshaker::SecurityHandshaker(tsi_handshaker* handshaker, + grpc_security_connector* connector) + : handshaker_(handshaker), + connector_(connector->Ref(DEBUG_LOCATION, "handshake")), + handshake_buffer_size_(GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE), + handshake_buffer_( + static_cast(gpr_malloc(handshake_buffer_size_))) { + gpr_mu_init(&mu_); + grpc_slice_buffer_init(&outgoing_); + GRPC_CLOSURE_INIT(&on_handshake_data_sent_to_peer_, + &SecurityHandshaker::OnHandshakeDataSentToPeerFn, this, + grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&on_handshake_data_received_from_peer_, + &SecurityHandshaker::OnHandshakeDataReceivedFromPeerFn, + this, grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&on_peer_checked_, &SecurityHandshaker::OnPeerCheckedFn, + this, grpc_schedule_on_exec_ctx); +} + +SecurityHandshaker::~SecurityHandshaker() { + gpr_mu_destroy(&mu_); + tsi_handshaker_destroy(handshaker_); + tsi_handshaker_result_destroy(handshaker_result_); + if (endpoint_to_destroy_ != nullptr) { + grpc_endpoint_destroy(endpoint_to_destroy_); + } + if (read_buffer_to_destroy_ != nullptr) { + grpc_slice_buffer_destroy_internal(read_buffer_to_destroy_); + gpr_free(read_buffer_to_destroy_); + } + gpr_free(handshake_buffer_); + grpc_slice_buffer_destroy_internal(&outgoing_); + auth_context_.reset(DEBUG_LOCATION, "handshake"); + connector_.reset(DEBUG_LOCATION, "handshake"); +} + +size_t SecurityHandshaker::MoveReadBufferIntoHandshakeBuffer() { + size_t bytes_in_read_buffer = args_->read_buffer->length; + if (handshake_buffer_size_ < bytes_in_read_buffer) { + handshake_buffer_ = static_cast( + gpr_realloc(handshake_buffer_, bytes_in_read_buffer)); + handshake_buffer_size_ = bytes_in_read_buffer; } size_t offset = 0; - while (h->args->read_buffer->count > 0) { - grpc_slice next_slice = grpc_slice_buffer_take_first(h->args->read_buffer); - memcpy(h->handshake_buffer + offset, GRPC_SLICE_START_PTR(next_slice), + while (args_->read_buffer->count > 0) { + grpc_slice next_slice = grpc_slice_buffer_take_first(args_->read_buffer); + memcpy(handshake_buffer_ + offset, GRPC_SLICE_START_PTR(next_slice), GRPC_SLICE_LENGTH(next_slice)); offset += GRPC_SLICE_LENGTH(next_slice); grpc_slice_unref_internal(next_slice); @@ -114,21 +153,20 @@ static size_t move_read_buffer_into_handshake_buffer(security_handshaker* h) { return bytes_in_read_buffer; } -// Set args fields to NULL, saving the endpoint and read buffer for +// Set args_ fields to NULL, saving the endpoint and read buffer for // later destruction. -static void cleanup_args_for_failure_locked(security_handshaker* h) { - h->endpoint_to_destroy = h->args->endpoint; - h->args->endpoint = nullptr; - h->read_buffer_to_destroy = h->args->read_buffer; - h->args->read_buffer = nullptr; - grpc_channel_args_destroy(h->args->args); - h->args->args = nullptr; +void SecurityHandshaker::CleanupArgsForFailureLocked() { + endpoint_to_destroy_ = args_->endpoint; + args_->endpoint = nullptr; + read_buffer_to_destroy_ = args_->read_buffer; + args_->read_buffer = nullptr; + grpc_channel_args_destroy(args_->args); + args_->args = nullptr; } // If the handshake failed or we're shutting down, clean up and invoke the // callback with the error. -static void security_handshake_failed_locked(security_handshaker* h, - grpc_error* error) { +void SecurityHandshaker::HandshakeFailedLocked(grpc_error* error) { if (error == GRPC_ERROR_NONE) { // If we were shut down after the handshake succeeded but before an // endpoint callback was invoked, we need to generate our own error. @@ -137,50 +175,51 @@ static void security_handshake_failed_locked(security_handshaker* h, const char* msg = grpc_error_string(error); gpr_log(GPR_DEBUG, "Security handshake failed: %s", msg); - if (!h->shutdown) { + if (!is_shutdown_) { // TODO(ctiller): It is currently necessary to shutdown endpoints // before destroying them, even if we know that there are no // pending read/write callbacks. This should be fixed, at which // point this can be removed. - grpc_endpoint_shutdown(h->args->endpoint, GRPC_ERROR_REF(error)); + grpc_endpoint_shutdown(args_->endpoint, GRPC_ERROR_REF(error)); // Not shutting down, so the write failed. Clean up before // invoking the callback. - cleanup_args_for_failure_locked(h); + CleanupArgsForFailureLocked(); // Set shutdown to true so that subsequent calls to // security_handshaker_shutdown() do nothing. - h->shutdown = true; + is_shutdown_ = true; } // Invoke callback. - GRPC_CLOSURE_SCHED(h->on_handshake_done, error); + GRPC_CLOSURE_SCHED(on_handshake_done_, error); } -static void on_peer_checked_inner(security_handshaker* h, grpc_error* error) { - if (error != GRPC_ERROR_NONE || h->shutdown) { - security_handshake_failed_locked(h, GRPC_ERROR_REF(error)); +void SecurityHandshaker::OnPeerCheckedInner(grpc_error* error) { + MutexLock lock(&mu_); + if (error != GRPC_ERROR_NONE || is_shutdown_) { + HandshakeFailedLocked(GRPC_ERROR_REF(error)); return; } // Create zero-copy frame protector, if implemented. tsi_zero_copy_grpc_protector* zero_copy_protector = nullptr; tsi_result result = tsi_handshaker_result_create_zero_copy_grpc_protector( - h->handshaker_result, nullptr, &zero_copy_protector); + handshaker_result_, nullptr, &zero_copy_protector); if (result != TSI_OK && result != TSI_UNIMPLEMENTED) { error = grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Zero-copy frame protector creation failed"), result); - security_handshake_failed_locked(h, error); + HandshakeFailedLocked(error); return; } // Create frame protector if zero-copy frame protector is NULL. tsi_frame_protector* protector = nullptr; if (zero_copy_protector == nullptr) { - result = tsi_handshaker_result_create_frame_protector(h->handshaker_result, + result = tsi_handshaker_result_create_frame_protector(handshaker_result_, nullptr, &protector); if (result != TSI_OK) { error = grpc_set_tsi_error_result(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Frame protector creation failed"), result); - security_handshake_failed_locked(h, error); + HandshakeFailedLocked(error); return; } } @@ -188,68 +227,63 @@ static void on_peer_checked_inner(security_handshaker* h, grpc_error* error) { const unsigned char* unused_bytes = nullptr; size_t unused_bytes_size = 0; result = tsi_handshaker_result_get_unused_bytes( - h->handshaker_result, &unused_bytes, &unused_bytes_size); + handshaker_result_, &unused_bytes, &unused_bytes_size); // Create secure endpoint. if (unused_bytes_size > 0) { grpc_slice slice = grpc_slice_from_copied_buffer((char*)unused_bytes, unused_bytes_size); - h->args->endpoint = grpc_secure_endpoint_create( - protector, zero_copy_protector, h->args->endpoint, &slice, 1); + args_->endpoint = grpc_secure_endpoint_create( + protector, zero_copy_protector, args_->endpoint, &slice, 1); grpc_slice_unref_internal(slice); } else { - h->args->endpoint = grpc_secure_endpoint_create( - protector, zero_copy_protector, h->args->endpoint, nullptr, 0); + args_->endpoint = grpc_secure_endpoint_create( + protector, zero_copy_protector, args_->endpoint, nullptr, 0); } - tsi_handshaker_result_destroy(h->handshaker_result); - h->handshaker_result = nullptr; + tsi_handshaker_result_destroy(handshaker_result_); + handshaker_result_ = nullptr; // Add auth context to channel args. - grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context.get()); - grpc_channel_args* tmp_args = h->args->args; - h->args->args = - grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1); + grpc_arg auth_context_arg = grpc_auth_context_to_arg(auth_context_.get()); + grpc_channel_args* tmp_args = args_->args; + args_->args = grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1); grpc_channel_args_destroy(tmp_args); // Invoke callback. - GRPC_CLOSURE_SCHED(h->on_handshake_done, GRPC_ERROR_NONE); + GRPC_CLOSURE_SCHED(on_handshake_done_, GRPC_ERROR_NONE); // Set shutdown to true so that subsequent calls to // security_handshaker_shutdown() do nothing. - h->shutdown = true; + is_shutdown_ = true; } -static void on_peer_checked(void* arg, grpc_error* error) { - security_handshaker* h = static_cast(arg); - gpr_mu_lock(&h->mu); - on_peer_checked_inner(h, error); - gpr_mu_unlock(&h->mu); - h->Unref(); +void SecurityHandshaker::OnPeerCheckedFn(void* arg, grpc_error* error) { + RefCountedPtr(static_cast(arg)) + ->OnPeerCheckedInner(error); } -static grpc_error* check_peer_locked(security_handshaker* h) { +grpc_error* SecurityHandshaker::CheckPeerLocked() { tsi_peer peer; tsi_result result = - tsi_handshaker_result_extract_peer(h->handshaker_result, &peer); + tsi_handshaker_result_extract_peer(handshaker_result_, &peer); if (result != TSI_OK) { return grpc_set_tsi_error_result( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), result); } - h->connector->check_peer(peer, h->args->endpoint, &h->auth_context, - &h->on_peer_checked); + connector_->check_peer(peer, args_->endpoint, &auth_context_, + &on_peer_checked_); return GRPC_ERROR_NONE; } -static grpc_error* on_handshake_next_done_locked( - security_handshaker* h, tsi_result result, - const unsigned char* bytes_to_send, size_t bytes_to_send_size, - tsi_handshaker_result* handshaker_result) { +grpc_error* SecurityHandshaker::OnHandshakeNextDoneLocked( + tsi_result result, const unsigned char* bytes_to_send, + size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result) { grpc_error* error = GRPC_ERROR_NONE; // Handshaker was shutdown. - if (h->shutdown) { + if (is_shutdown_) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Handshaker shutdown"); } // Read more if we need to. if (result == TSI_INCOMPLETE_DATA) { GPR_ASSERT(bytes_to_send_size == 0); - grpc_endpoint_read(h->args->endpoint, h->args->read_buffer, - &h->on_handshake_data_received_from_peer); + grpc_endpoint_read(args_->endpoint, args_->read_buffer, + &on_handshake_data_received_from_peer_); return error; } if (result != TSI_OK) { @@ -258,55 +292,52 @@ static grpc_error* on_handshake_next_done_locked( } // Update handshaker result. if (handshaker_result != nullptr) { - GPR_ASSERT(h->handshaker_result == nullptr); - h->handshaker_result = handshaker_result; + GPR_ASSERT(handshaker_result_ == nullptr); + handshaker_result_ = handshaker_result; } if (bytes_to_send_size > 0) { // Send data to peer, if needed. grpc_slice to_send = grpc_slice_from_copied_buffer( reinterpret_cast(bytes_to_send), bytes_to_send_size); - grpc_slice_buffer_reset_and_unref_internal(&h->outgoing); - grpc_slice_buffer_add(&h->outgoing, to_send); - grpc_endpoint_write(h->args->endpoint, &h->outgoing, - &h->on_handshake_data_sent_to_peer, nullptr); + grpc_slice_buffer_reset_and_unref_internal(&outgoing_); + grpc_slice_buffer_add(&outgoing_, to_send); + grpc_endpoint_write(args_->endpoint, &outgoing_, + &on_handshake_data_sent_to_peer_, nullptr); } else if (handshaker_result == nullptr) { // There is nothing to send, but need to read from peer. - grpc_endpoint_read(h->args->endpoint, h->args->read_buffer, - &h->on_handshake_data_received_from_peer); + grpc_endpoint_read(args_->endpoint, args_->read_buffer, + &on_handshake_data_received_from_peer_); } else { // Handshake has finished, check peer and so on. - error = check_peer_locked(h); + error = CheckPeerLocked(); } return error; } -static void on_handshake_next_done_grpc_wrapper( +void SecurityHandshaker::OnHandshakeNextDoneGrpcWrapper( tsi_result result, void* user_data, const unsigned char* bytes_to_send, size_t bytes_to_send_size, tsi_handshaker_result* handshaker_result) { - security_handshaker* h = static_cast(user_data); - gpr_mu_lock(&h->mu); - grpc_error* error = on_handshake_next_done_locked( - h, result, bytes_to_send, bytes_to_send_size, handshaker_result); + RefCountedPtr h( + static_cast(user_data)); + MutexLock lock(&h->mu_); + grpc_error* error = h->OnHandshakeNextDoneLocked( + result, bytes_to_send, bytes_to_send_size, handshaker_result); if (error != GRPC_ERROR_NONE) { - security_handshake_failed_locked(h, error); - gpr_mu_unlock(&h->mu); - h->Unref(); + h->HandshakeFailedLocked(error); } else { - gpr_mu_unlock(&h->mu); + h.release(); // Avoid unref } } -static grpc_error* do_handshaker_next_locked( - security_handshaker* h, const unsigned char* bytes_received, - size_t bytes_received_size) { +grpc_error* SecurityHandshaker::DoHandshakerNextLocked( + const unsigned char* bytes_received, size_t bytes_received_size) { // Invoke TSI handshaker. const unsigned char* bytes_to_send = nullptr; size_t bytes_to_send_size = 0; - tsi_handshaker_result* handshaker_result = nullptr; + tsi_handshaker_result* hs_result = nullptr; tsi_result result = tsi_handshaker_next( - h->handshaker, bytes_received, bytes_received_size, &bytes_to_send, - &bytes_to_send_size, &handshaker_result, - &on_handshake_next_done_grpc_wrapper, h); + handshaker_, bytes_received, bytes_received_size, &bytes_to_send, + &bytes_to_send_size, &hs_result, &OnHandshakeNextDoneGrpcWrapper, this); if (result == TSI_ASYNC) { // Handshaker operating asynchronously. Nothing else to do here; // callback will be invoked in a TSI thread. @@ -314,233 +345,169 @@ static grpc_error* do_handshaker_next_locked( } // Handshaker returned synchronously. Invoke callback directly in // this thread with our existing exec_ctx. - return on_handshake_next_done_locked(h, result, bytes_to_send, - bytes_to_send_size, handshaker_result); + return OnHandshakeNextDoneLocked(result, bytes_to_send, bytes_to_send_size, + hs_result); } -static void on_handshake_data_received_from_peer(void* arg, grpc_error* error) { - security_handshaker* h = static_cast(arg); - gpr_mu_lock(&h->mu); - if (error != GRPC_ERROR_NONE || h->shutdown) { - security_handshake_failed_locked( - h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Handshake read failed", &error, 1)); - gpr_mu_unlock(&h->mu); - h->Unref(); +void SecurityHandshaker::OnHandshakeDataReceivedFromPeerFn(void* arg, + grpc_error* error) { + RefCountedPtr h(static_cast(arg)); + MutexLock lock(&h->mu_); + if (error != GRPC_ERROR_NONE || h->is_shutdown_) { + h->HandshakeFailedLocked(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Handshake read failed", &error, 1)); return; } // Copy all slices received. - size_t bytes_received_size = move_read_buffer_into_handshake_buffer(h); + size_t bytes_received_size = h->MoveReadBufferIntoHandshakeBuffer(); // Call TSI handshaker. - error = - do_handshaker_next_locked(h, h->handshake_buffer, bytes_received_size); + error = h->DoHandshakerNextLocked(h->handshake_buffer_, bytes_received_size); if (error != GRPC_ERROR_NONE) { - security_handshake_failed_locked(h, error); - gpr_mu_unlock(&h->mu); - h->Unref(); + h->HandshakeFailedLocked(error); } else { - gpr_mu_unlock(&h->mu); + h.release(); // Avoid unref } } -static void on_handshake_data_sent_to_peer(void* arg, grpc_error* error) { - security_handshaker* h = static_cast(arg); - gpr_mu_lock(&h->mu); - if (error != GRPC_ERROR_NONE || h->shutdown) { - security_handshake_failed_locked( - h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Handshake write failed", &error, 1)); - gpr_mu_unlock(&h->mu); - h->Unref(); +void SecurityHandshaker::OnHandshakeDataSentToPeerFn(void* arg, + grpc_error* error) { + RefCountedPtr h(static_cast(arg)); + MutexLock lock(&h->mu_); + if (error != GRPC_ERROR_NONE || h->is_shutdown_) { + h->HandshakeFailedLocked(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Handshake write failed", &error, 1)); return; } // We may be done. - if (h->handshaker_result == nullptr) { - grpc_endpoint_read(h->args->endpoint, h->args->read_buffer, - &h->on_handshake_data_received_from_peer); + if (h->handshaker_result_ == nullptr) { + grpc_endpoint_read(h->args_->endpoint, h->args_->read_buffer, + &h->on_handshake_data_received_from_peer_); } else { - error = check_peer_locked(h); + error = h->CheckPeerLocked(); if (error != GRPC_ERROR_NONE) { - security_handshake_failed_locked(h, error); - gpr_mu_unlock(&h->mu); - h->Unref(); + h->HandshakeFailedLocked(error); return; } } - gpr_mu_unlock(&h->mu); + h.release(); // Avoid unref } // // public handshaker API // -static void security_handshaker_destroy(grpc_handshaker* handshaker) { - security_handshaker* h = reinterpret_cast(handshaker); - h->Unref(); -} - -static void security_handshaker_shutdown(grpc_handshaker* handshaker, - grpc_error* why) { - security_handshaker* h = reinterpret_cast(handshaker); - gpr_mu_lock(&h->mu); - if (!h->shutdown) { - h->shutdown = true; - tsi_handshaker_shutdown(h->handshaker); - grpc_endpoint_shutdown(h->args->endpoint, GRPC_ERROR_REF(why)); - cleanup_args_for_failure_locked(h); +void SecurityHandshaker::Shutdown(grpc_error* why) { + MutexLock lock(&mu_); + if (!is_shutdown_) { + is_shutdown_ = true; + tsi_handshaker_shutdown(handshaker_); + grpc_endpoint_shutdown(args_->endpoint, GRPC_ERROR_REF(why)); + CleanupArgsForFailureLocked(); } - gpr_mu_unlock(&h->mu); GRPC_ERROR_UNREF(why); } -static void security_handshaker_do_handshake(grpc_handshaker* handshaker, - grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, - grpc_handshaker_args* args) { - security_handshaker* h = reinterpret_cast(handshaker); - gpr_mu_lock(&h->mu); - h->args = args; - h->on_handshake_done = on_handshake_done; - h->Ref(); - size_t bytes_received_size = move_read_buffer_into_handshake_buffer(h); +void SecurityHandshaker::DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) { + auto ref = Ref(); + MutexLock lock(&mu_); + args_ = args; + on_handshake_done_ = on_handshake_done; + size_t bytes_received_size = MoveReadBufferIntoHandshakeBuffer(); grpc_error* error = - do_handshaker_next_locked(h, h->handshake_buffer, bytes_received_size); + DoHandshakerNextLocked(handshake_buffer_, bytes_received_size); if (error != GRPC_ERROR_NONE) { - security_handshake_failed_locked(h, error); - gpr_mu_unlock(&h->mu); - h->Unref(); - return; + HandshakeFailedLocked(error); + } else { + ref.release(); // Avoid unref } - gpr_mu_unlock(&h->mu); -} - -static const grpc_handshaker_vtable security_handshaker_vtable = { - security_handshaker_destroy, security_handshaker_shutdown, - security_handshaker_do_handshake, "security"}; - -namespace { -security_handshaker::security_handshaker(tsi_handshaker* handshaker, - grpc_security_connector* connector) - : handshaker(handshaker), - connector(connector->Ref(DEBUG_LOCATION, "handshake")), - handshake_buffer_size(GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE), - handshake_buffer( - static_cast(gpr_malloc(handshake_buffer_size))) { - grpc_handshaker_init(&security_handshaker_vtable, &base); - gpr_mu_init(&mu); - grpc_slice_buffer_init(&outgoing); - GRPC_CLOSURE_INIT(&on_handshake_data_sent_to_peer, - ::on_handshake_data_sent_to_peer, this, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&on_handshake_data_received_from_peer, - ::on_handshake_data_received_from_peer, this, - grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&on_peer_checked, ::on_peer_checked, this, - grpc_schedule_on_exec_ctx); -} -} // namespace - -static grpc_handshaker* security_handshaker_create( - tsi_handshaker* handshaker, grpc_security_connector* connector) { - security_handshaker* h = - grpc_core::New(handshaker, connector); - return &h->base; } // -// fail_handshaker +// FailHandshaker // -static void fail_handshaker_destroy(grpc_handshaker* handshaker) { - gpr_free(handshaker); -} +class FailHandshaker : public Handshaker { + public: + const char* name() const override { return "security_fail"; } + void Shutdown(grpc_error* why) override { GRPC_ERROR_UNREF(why); } + void DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) override { + GRPC_CLOSURE_SCHED(on_handshake_done, + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Failed to create security handshaker")); + } -static void fail_handshaker_shutdown(grpc_handshaker* handshaker, - grpc_error* why) { - GRPC_ERROR_UNREF(why); -} - -static void fail_handshaker_do_handshake(grpc_handshaker* handshaker, - grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, - grpc_handshaker_args* args) { - GRPC_CLOSURE_SCHED(on_handshake_done, - GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Failed to create security handshaker")); -} - -static const grpc_handshaker_vtable fail_handshaker_vtable = { - fail_handshaker_destroy, fail_handshaker_shutdown, - fail_handshaker_do_handshake, "security_fail"}; - -static grpc_handshaker* fail_handshaker_create() { - grpc_handshaker* h = static_cast(gpr_malloc(sizeof(*h))); - grpc_handshaker_init(&fail_handshaker_vtable, h); - return h; -} + private: + virtual ~FailHandshaker() = default; +}; // // handshaker factories // -static void client_handshaker_factory_add_handshakers( - grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_channel_security_connector* security_connector = - reinterpret_cast( - grpc_security_connector_find_in_args(args)); - if (security_connector) { - security_connector->add_handshakers(interested_parties, handshake_mgr); +class ClientSecurityHandshakerFactory : public HandshakerFactory { + public: + void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) override { + auto* security_connector = + reinterpret_cast( + grpc_security_connector_find_in_args(args)); + if (security_connector) { + security_connector->add_handshakers(interested_parties, handshake_mgr); + } } -} + ~ClientSecurityHandshakerFactory() override = default; +}; -static void server_handshaker_factory_add_handshakers( - grpc_handshaker_factory* hf, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_server_security_connector* security_connector = - reinterpret_cast( - grpc_security_connector_find_in_args(args)); - if (security_connector) { - security_connector->add_handshakers(interested_parties, handshake_mgr); +class ServerSecurityHandshakerFactory : public HandshakerFactory { + public: + void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) override { + auto* security_connector = + reinterpret_cast( + grpc_security_connector_find_in_args(args)); + if (security_connector) { + security_connector->add_handshakers(interested_parties, handshake_mgr); + } } -} + ~ServerSecurityHandshakerFactory() override = default; +}; -static void handshaker_factory_destroy( - grpc_handshaker_factory* handshaker_factory) {} - -static const grpc_handshaker_factory_vtable client_handshaker_factory_vtable = { - client_handshaker_factory_add_handshakers, handshaker_factory_destroy}; - -static grpc_handshaker_factory client_handshaker_factory = { - &client_handshaker_factory_vtable}; - -static const grpc_handshaker_factory_vtable server_handshaker_factory_vtable = { - server_handshaker_factory_add_handshakers, handshaker_factory_destroy}; - -static grpc_handshaker_factory server_handshaker_factory = { - &server_handshaker_factory_vtable}; +} // namespace // // exported functions // -grpc_handshaker* grpc_security_handshaker_create( +RefCountedPtr SecurityHandshakerCreate( tsi_handshaker* handshaker, grpc_security_connector* connector) { // If no TSI handshaker was created, return a handshaker that always fails. // Otherwise, return a real security handshaker. if (handshaker == nullptr) { - return fail_handshaker_create(); + return MakeRefCounted(); } else { - return security_handshaker_create(handshaker, connector); + return MakeRefCounted(handshaker, connector); } } -void grpc_security_register_handshaker_factories() { - grpc_handshaker_factory_register(false /* at_start */, HANDSHAKER_CLIENT, - &client_handshaker_factory); - grpc_handshaker_factory_register(false /* at_start */, HANDSHAKER_SERVER, - &server_handshaker_factory); +grpc_handshaker* grpc_security_handshaker_create( + tsi_handshaker* handshaker, grpc_security_connector* connector) { + return SecurityHandshakerCreate(handshaker, connector).release(); } + +void SecurityRegisterHandshakerFactories() { + HandshakerRegistry::RegisterHandshakerFactory( + false /* at_start */, HANDSHAKER_CLIENT, + UniquePtr(New())); + HandshakerRegistry::RegisterHandshakerFactory( + false /* at_start */, HANDSHAKER_SERVER, + UniquePtr(New())); +} + +} // namespace grpc_core diff --git a/src/core/lib/security/transport/security_handshaker.h b/src/core/lib/security/transport/security_handshaker.h index 88483b02e74..263fe555967 100644 --- a/src/core/lib/security/transport/security_handshaker.h +++ b/src/core/lib/security/transport/security_handshaker.h @@ -24,11 +24,20 @@ #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/security/security_connector/security_connector.h" +namespace grpc_core { + /// Creates a security handshaker using \a handshaker. -grpc_handshaker* grpc_security_handshaker_create( +RefCountedPtr SecurityHandshakerCreate( tsi_handshaker* handshaker, grpc_security_connector* connector); /// Registers security handshaker factories. -void grpc_security_register_handshaker_factories(); +void SecurityRegisterHandshakerFactories(); + +} // namespace grpc_core + +// TODO(arjunroy): This is transitional to account for the new handshaker API +// and will eventually be removed entirely. +grpc_handshaker* grpc_security_handshaker_create( + tsi_handshaker* handshaker, grpc_security_connector* connector); #endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_HANDSHAKER_H */ diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index f704a64b1c9..e507de87c2a 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -134,7 +134,7 @@ void grpc_init(void) { grpc_core::ExecCtx::GlobalInit(); grpc_iomgr_init(); gpr_timers_global_init(); - grpc_handshaker_factory_registry_init(); + grpc_core::HandshakerRegistry::Init(); grpc_security_init(); for (i = 0; i < g_number_of_plugins; i++) { if (g_all_of_the_plugins[i].init != nullptr) { @@ -177,7 +177,7 @@ void grpc_shutdown(void) { gpr_timers_global_destroy(); grpc_tracer_shutdown(); grpc_mdctx_global_shutdown(); - grpc_handshaker_factory_registry_shutdown(); + grpc_core::HandshakerRegistry::Shutdown(); grpc_slice_intern_shutdown(); grpc_core::channelz::ChannelzRegistry::Shutdown(); grpc_stats_shutdown(); diff --git a/src/core/lib/surface/init_secure.cc b/src/core/lib/surface/init_secure.cc index 765350cced0..0e83a11a5f0 100644 --- a/src/core/lib/surface/init_secure.cc +++ b/src/core/lib/surface/init_secure.cc @@ -78,4 +78,4 @@ void grpc_register_security_filters(void) { maybe_prepend_server_auth_filter, nullptr); } -void grpc_security_init() { grpc_security_register_handshaker_factories(); } +void grpc_security_init() { grpc_core::SecurityRegisterHandshakerFactories(); } diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 19d27412205..71de0c4abe0 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -68,7 +68,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/channel/channelz_registry.cc', 'src/core/lib/channel/connected_channel.cc', 'src/core/lib/channel/handshaker.cc', - 'src/core/lib/channel/handshaker_factory.cc', 'src/core/lib/channel/handshaker_registry.cc', 'src/core/lib/channel/status_util.cc', 'src/core/lib/compression/compression.cc', diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc index 14d96b5d89c..e4584105e65 100644 --- a/test/core/handshake/readahead_handshaker_server_ssl.cc +++ b/test/core/handshake/readahead_handshaker_server_ssl.cc @@ -49,51 +49,38 @@ * to the security_handshaker). This test is meant to protect code relying on * this functionality that lives outside of this repo. */ -static void readahead_handshaker_destroy(grpc_handshaker* handshaker) { - gpr_free(handshaker); -} +namespace grpc_core { -static void readahead_handshaker_shutdown(grpc_handshaker* handshaker, - grpc_error* error) {} +class ReadAheadHandshaker : public Handshaker { + public: + virtual ~ReadAheadHandshaker() {} + const char* name() const override { return "read_ahead"; } + void Shutdown(grpc_error* why) override {} + void DoHandshake(grpc_tcp_server_acceptor* acceptor, + grpc_closure* on_handshake_done, + HandshakerArgs* args) override { + grpc_endpoint_read(args->endpoint, args->read_buffer, on_handshake_done); + } +}; -static void readahead_handshaker_do_handshake( - grpc_handshaker* handshaker, grpc_tcp_server_acceptor* acceptor, - grpc_closure* on_handshake_done, grpc_handshaker_args* args) { - grpc_endpoint_read(args->endpoint, args->read_buffer, on_handshake_done); -} +class ReadAheadHandshakerFactory : public HandshakerFactory { + public: + void AddHandshakers(const grpc_channel_args* args, + grpc_pollset_set* interested_parties, + HandshakeManager* handshake_mgr) override { + handshake_mgr->Add(MakeRefCounted()); + } + ~ReadAheadHandshakerFactory() override = default; +}; -const grpc_handshaker_vtable readahead_handshaker_vtable = { - readahead_handshaker_destroy, readahead_handshaker_shutdown, - readahead_handshaker_do_handshake, "read_ahead"}; - -static grpc_handshaker* readahead_handshaker_create() { - grpc_handshaker* h = - static_cast(gpr_zalloc(sizeof(grpc_handshaker))); - grpc_handshaker_init(&readahead_handshaker_vtable, h); - return h; -} - -static void readahead_handshaker_factory_add_handshakers( - grpc_handshaker_factory* hf, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add(handshake_mgr, readahead_handshaker_create()); -} - -static void readahead_handshaker_factory_destroy( - grpc_handshaker_factory* handshaker_factory) {} - -static const grpc_handshaker_factory_vtable - readahead_handshaker_factory_vtable = { - readahead_handshaker_factory_add_handshakers, - readahead_handshaker_factory_destroy}; +} // namespace grpc_core int main(int argc, char* argv[]) { - grpc_handshaker_factory readahead_handshaker_factory = { - &readahead_handshaker_factory_vtable}; + using namespace grpc_core; grpc_init(); - grpc_handshaker_factory_register(true /* at_start */, HANDSHAKER_SERVER, - &readahead_handshaker_factory); + HandshakerRegistry::RegisterHandshakerFactory( + true /* at_start */, HANDSHAKER_SERVER, + UniquePtr(New())); const char* full_alpn_list[] = {"grpc-exp", "h2"}; GPR_ASSERT(server_ssl_test(full_alpn_list, 2, "grpc-exp")); grpc_shutdown(); diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc index c9380126dd0..8533644aceb 100644 --- a/test/core/security/ssl_server_fuzzer.cc +++ b/test/core/security/ssl_server_fuzzer.cc @@ -41,7 +41,8 @@ struct handshake_state { }; static void on_handshake_done(void* arg, grpc_error* error) { - grpc_handshaker_args* args = static_cast(arg); + grpc_core::HandshakerArgs* args = + static_cast(arg); struct handshake_state* state = static_cast(args->user_data); GPR_ASSERT(state->done_callback_called == false); @@ -89,11 +90,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { struct handshake_state state; state.done_callback_called = false; - grpc_handshake_manager* handshake_mgr = grpc_handshake_manager_create(); - sc->add_handshakers(nullptr, handshake_mgr); - grpc_handshake_manager_do_handshake( - handshake_mgr, mock_endpoint, nullptr /* channel_args */, deadline, - nullptr /* acceptor */, on_handshake_done, &state); + auto handshake_mgr = + grpc_core::MakeRefCounted(); + sc->add_handshakers(nullptr, handshake_mgr.get()); + handshake_mgr->DoHandshake(mock_endpoint, nullptr /* channel_args */, + deadline, nullptr /* acceptor */, + on_handshake_done, &state); grpc_core::ExecCtx::Get()->Flush(); // If the given string happens to be part of the correct client hello, the @@ -108,7 +110,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { GPR_ASSERT(state.done_callback_called); - grpc_handshake_manager_destroy(handshake_mgr); sc.reset(DEBUG_LOCATION, "test"); grpc_server_credentials_release(creds); grpc_slice_unref(cert_slice); diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 2aced414218..86b57b23d9a 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1080,7 +1080,6 @@ src/core/lib/channel/connected_channel.h \ src/core/lib/channel/context.h \ src/core/lib/channel/handshaker.cc \ src/core/lib/channel/handshaker.h \ -src/core/lib/channel/handshaker_factory.cc \ src/core/lib/channel/handshaker_factory.h \ src/core/lib/channel/handshaker_registry.cc \ src/core/lib/channel/handshaker_registry.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index ab01b8fca6a..84d5c45095f 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9440,7 +9440,6 @@ "src/core/lib/channel/channelz_registry.cc", "src/core/lib/channel/connected_channel.cc", "src/core/lib/channel/handshaker.cc", - "src/core/lib/channel/handshaker_factory.cc", "src/core/lib/channel/handshaker_registry.cc", "src/core/lib/channel/status_util.cc", "src/core/lib/compression/compression.cc", From a47c979ba07937cd6f5e67b0763a0908502f9b28 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 14 Jan 2019 14:29:27 -0800 Subject: [PATCH 326/814] Enable TCP callback tests if the event engine allows --- src/core/lib/iomgr/iomgr.h | 5 ++ src/core/lib/iomgr/iomgr_posix.cc | 4 + src/core/lib/iomgr/iomgr_windows.cc | 2 + .../end2end/client_callback_end2end_test.cc | 66 +++++++++++++- test/cpp/end2end/end2end_test.cc | 86 ++++++++++++++++++- test/cpp/end2end/test_service_impl.cc | 17 +++- 6 files changed, 173 insertions(+), 7 deletions(-) diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h index 6261aa550c3..74775de8146 100644 --- a/src/core/lib/iomgr/iomgr.h +++ b/src/core/lib/iomgr/iomgr.h @@ -39,6 +39,11 @@ void grpc_iomgr_shutdown(); * background poller. */ void grpc_iomgr_shutdown_background_closure(); +/* Returns true if polling engine runs in the background, false otherwise. + * Currently only 'epollbg' runs in the background. + */ +bool grpc_iomgr_run_in_background(); + /** Returns true if the caller is a worker thread for any background poller. */ bool grpc_iomgr_is_any_background_poller_thread(); diff --git a/src/core/lib/iomgr/iomgr_posix.cc b/src/core/lib/iomgr/iomgr_posix.cc index 278c8de6886..690e81f3b1d 100644 --- a/src/core/lib/iomgr/iomgr_posix.cc +++ b/src/core/lib/iomgr/iomgr_posix.cc @@ -74,4 +74,8 @@ void grpc_set_default_iomgr_platform() { grpc_set_iomgr_platform_vtable(&vtable); } +bool grpc_iomgr_run_in_background() { + return grpc_event_engine_run_in_background(); +} + #endif /* GRPC_POSIX_SOCKET_IOMGR */ diff --git a/src/core/lib/iomgr/iomgr_windows.cc b/src/core/lib/iomgr/iomgr_windows.cc index 0579e16aa76..e517a6caee4 100644 --- a/src/core/lib/iomgr/iomgr_windows.cc +++ b/src/core/lib/iomgr/iomgr_windows.cc @@ -92,4 +92,6 @@ void grpc_set_default_iomgr_platform() { grpc_set_iomgr_platform_vtable(&vtable); } +bool grpc_iomgr_run_in_background() { return false; } + #endif /* GRPC_WINSOCK_SOCKET */ diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index a999321992f..30db5b8c01c 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -30,7 +31,9 @@ #include #include +#include "src/core/lib/iomgr/iomgr.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" #include "test/cpp/util/byte_buffer_proto_helper.h" @@ -38,15 +41,30 @@ #include +// MAYBE_SKIP_TEST is a macro to determine if this particular test configuration +// should be skipped based on a decision made at SetUp time. In particular, any +// callback tests can only be run if the iomgr can run in the background or if +// the transport is in-process. +#define MAYBE_SKIP_TEST \ + do { \ + if (do_not_test_) { \ + return; \ + } \ + } while (0) + namespace grpc { namespace testing { namespace { +enum class Protocol { INPROC, TCP }; + class TestScenario { public: - TestScenario(bool serve_callback) : callback_server(serve_callback) {} + TestScenario(bool serve_callback, Protocol protocol) + : callback_server(serve_callback), protocol(protocol) {} void Log() const; bool callback_server; + Protocol protocol; }; static std::ostream& operator<<(std::ostream& out, @@ -69,6 +87,16 @@ class ClientCallbackEnd2endTest void SetUp() override { ServerBuilder builder; + if (GetParam().protocol == Protocol::TCP) { + if (!grpc_iomgr_run_in_background()) { + do_not_test_ = true; + return; + } + int port = grpc_pick_unused_port_or_die(); + server_address_ << "localhost:" << port; + builder.AddListeningPort(server_address_.str(), + InsecureServerCredentials()); + } if (!GetParam().callback_server) { builder.RegisterService(&service_); } else { @@ -81,7 +109,17 @@ class ClientCallbackEnd2endTest void ResetStub() { ChannelArguments args; - channel_ = server_->InProcessChannel(args); + switch (GetParam().protocol) { + case Protocol::TCP: + channel_ = + CreateChannel(server_address_.str(), InsecureChannelCredentials()); + break; + case Protocol::INPROC: + channel_ = server_->InProcessChannel(args); + break; + default: + assert(false); + } stub_ = grpc::testing::EchoTestService::NewStub(channel_); generic_stub_.reset(new GenericStub(channel_)); } @@ -243,26 +281,31 @@ class ClientCallbackEnd2endTest rpc.Await(); } } - bool is_server_started_; + bool do_not_test_{false}; + bool is_server_started_{false}; std::shared_ptr channel_; std::unique_ptr stub_; std::unique_ptr generic_stub_; TestServiceImpl service_; CallbackTestServiceImpl callback_service_; std::unique_ptr server_; + std::ostringstream server_address_; }; TEST_P(ClientCallbackEnd2endTest, SimpleRpc) { + MAYBE_SKIP_TEST; ResetStub(); SendRpcs(1, false); } TEST_P(ClientCallbackEnd2endTest, SequentialRpcs) { + MAYBE_SKIP_TEST; ResetStub(); SendRpcs(10, false); } TEST_P(ClientCallbackEnd2endTest, SendClientInitialMetadata) { + MAYBE_SKIP_TEST; ResetStub(); SimpleRequest request; SimpleResponse response; @@ -289,38 +332,45 @@ TEST_P(ClientCallbackEnd2endTest, SendClientInitialMetadata) { } TEST_P(ClientCallbackEnd2endTest, SimpleRpcWithBinaryMetadata) { + MAYBE_SKIP_TEST; ResetStub(); SendRpcs(1, true); } TEST_P(ClientCallbackEnd2endTest, SequentialRpcsWithVariedBinaryMetadataValue) { + MAYBE_SKIP_TEST; ResetStub(); SendRpcs(10, true); } TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcs) { + MAYBE_SKIP_TEST; ResetStub(); SendRpcsGeneric(10, false); } TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidi) { + MAYBE_SKIP_TEST; ResetStub(); SendGenericEchoAsBidi(10, 1); } TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidiWithReactorReuse) { + MAYBE_SKIP_TEST; ResetStub(); SendGenericEchoAsBidi(10, 10); } #if GRPC_ALLOW_EXCEPTIONS TEST_P(ClientCallbackEnd2endTest, ExceptingRpc) { + MAYBE_SKIP_TEST; ResetStub(); SendRpcsGeneric(10, true); } #endif TEST_P(ClientCallbackEnd2endTest, MultipleRpcsWithVariedBinaryMetadataValue) { + MAYBE_SKIP_TEST; ResetStub(); std::vector threads; threads.reserve(10); @@ -333,6 +383,7 @@ TEST_P(ClientCallbackEnd2endTest, MultipleRpcsWithVariedBinaryMetadataValue) { } TEST_P(ClientCallbackEnd2endTest, MultipleRpcs) { + MAYBE_SKIP_TEST; ResetStub(); std::vector threads; threads.reserve(10); @@ -345,6 +396,7 @@ TEST_P(ClientCallbackEnd2endTest, MultipleRpcs) { } TEST_P(ClientCallbackEnd2endTest, CancelRpcBeforeStart) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -370,6 +422,7 @@ TEST_P(ClientCallbackEnd2endTest, CancelRpcBeforeStart) { } TEST_P(ClientCallbackEnd2endTest, RequestStream) { + MAYBE_SKIP_TEST; ResetStub(); class Client : public grpc::experimental::ClientWriteReactor { public: @@ -416,6 +469,7 @@ TEST_P(ClientCallbackEnd2endTest, RequestStream) { } TEST_P(ClientCallbackEnd2endTest, ResponseStream) { + MAYBE_SKIP_TEST; ResetStub(); class Client : public grpc::experimental::ClientReadReactor { public: @@ -463,6 +517,7 @@ TEST_P(ClientCallbackEnd2endTest, ResponseStream) { } TEST_P(ClientCallbackEnd2endTest, BidiStream) { + MAYBE_SKIP_TEST; ResetStub(); class Client : public grpc::experimental::ClientBidiReactor { @@ -519,7 +574,10 @@ TEST_P(ClientCallbackEnd2endTest, BidiStream) { test.Await(); } -TestScenario scenarios[] = {TestScenario{false}, TestScenario{true}}; +TestScenario scenarios[]{{false, Protocol::INPROC}, + {false, Protocol::TCP}, + {true, Protocol::INPROC}, + {true, Protocol::TCP}}; INSTANTIATE_TEST_CASE_P(ClientCallbackEnd2endTest, ClientCallbackEnd2endTest, ::testing::ValuesIn(scenarios)); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 4bddbb4bdf2..f58a472bfaf 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -35,6 +35,7 @@ #include #include "src/core/lib/gpr/env.h" +#include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" @@ -52,6 +53,17 @@ using grpc::testing::EchoResponse; using grpc::testing::kTlsCredentialsType; using std::chrono::system_clock; +// MAYBE_SKIP_TEST is a macro to determine if this particular test configuration +// should be skipped based on a decision made at SetUp time. In particular, +// tests that use the callback server can only be run if the iomgr can run in +// the background or if the transport is in-process. +#define MAYBE_SKIP_TEST \ + do { \ + if (do_not_test_) { \ + return; \ + } \ + } while (0) + namespace grpc { namespace testing { namespace { @@ -237,6 +249,14 @@ class End2endTest : public ::testing::TestWithParam { GetParam().Log(); } + void SetUp() override { + if (GetParam().callback_server && !GetParam().inproc && + !grpc_iomgr_run_in_background()) { + do_not_test_ = true; + return; + } + } + void TearDown() override { if (is_server_started_) { server_->Shutdown(); @@ -361,6 +381,7 @@ class End2endTest : public ::testing::TestWithParam { DummyInterceptor::Reset(); } + bool do_not_test_{false}; bool is_server_started_; std::shared_ptr channel_; std::unique_ptr stub_; @@ -416,6 +437,7 @@ class End2endServerTryCancelTest : public End2endTest { // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL. void TestRequestStreamServerCancel( ServerTryCancelRequestPhase server_try_cancel, int num_msgs_to_send) { + MAYBE_SKIP_TEST; RestartServer(std::shared_ptr()); ResetStub(); EchoRequest request; @@ -494,6 +516,7 @@ class End2endServerTryCancelTest : public End2endTest { // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL. void TestResponseStreamServerCancel( ServerTryCancelRequestPhase server_try_cancel) { + MAYBE_SKIP_TEST; RestartServer(std::shared_ptr()); ResetStub(); EchoRequest request; @@ -575,6 +598,7 @@ class End2endServerTryCancelTest : public End2endTest { // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL. void TestBidiStreamServerCancel(ServerTryCancelRequestPhase server_try_cancel, int num_messages) { + MAYBE_SKIP_TEST; RestartServer(std::shared_ptr()); ResetStub(); EchoRequest request; @@ -650,6 +674,7 @@ class End2endServerTryCancelTest : public End2endTest { }; TEST_P(End2endServerTryCancelTest, RequestEchoServerCancel) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -712,6 +737,7 @@ TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelAfter) { } TEST_P(End2endTest, SimpleRpcWithCustomUserAgentPrefix) { + MAYBE_SKIP_TEST; // User-Agent is an HTTP header for HTTP transports only if (GetParam().inproc) { return; @@ -735,6 +761,7 @@ TEST_P(End2endTest, SimpleRpcWithCustomUserAgentPrefix) { } TEST_P(End2endTest, MultipleRpcsWithVariedBinaryMetadataValue) { + MAYBE_SKIP_TEST; ResetStub(); std::vector threads; threads.reserve(10); @@ -747,6 +774,7 @@ TEST_P(End2endTest, MultipleRpcsWithVariedBinaryMetadataValue) { } TEST_P(End2endTest, MultipleRpcs) { + MAYBE_SKIP_TEST; ResetStub(); std::vector threads; threads.reserve(10); @@ -759,6 +787,7 @@ TEST_P(End2endTest, MultipleRpcs) { } TEST_P(End2endTest, EmptyBinaryMetadata) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -771,6 +800,7 @@ TEST_P(End2endTest, EmptyBinaryMetadata) { } TEST_P(End2endTest, ReconnectChannel) { + MAYBE_SKIP_TEST; if (GetParam().inproc) { return; } @@ -796,6 +826,7 @@ TEST_P(End2endTest, ReconnectChannel) { } TEST_P(End2endTest, RequestStreamOneRequest) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -812,6 +843,7 @@ TEST_P(End2endTest, RequestStreamOneRequest) { } TEST_P(End2endTest, RequestStreamOneRequestWithCoalescingApi) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -827,6 +859,7 @@ TEST_P(End2endTest, RequestStreamOneRequestWithCoalescingApi) { } TEST_P(End2endTest, RequestStreamTwoRequests) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -843,6 +876,7 @@ TEST_P(End2endTest, RequestStreamTwoRequests) { } TEST_P(End2endTest, RequestStreamTwoRequestsWithWriteThrough) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -859,6 +893,7 @@ TEST_P(End2endTest, RequestStreamTwoRequestsWithWriteThrough) { } TEST_P(End2endTest, RequestStreamTwoRequestsWithCoalescingApi) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -875,6 +910,7 @@ TEST_P(End2endTest, RequestStreamTwoRequestsWithCoalescingApi) { } TEST_P(End2endTest, ResponseStream) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -893,6 +929,7 @@ TEST_P(End2endTest, ResponseStream) { } TEST_P(End2endTest, ResponseStreamWithCoalescingApi) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -914,6 +951,7 @@ TEST_P(End2endTest, ResponseStreamWithCoalescingApi) { // This was added to prevent regression from issue: // https://github.com/grpc/grpc/issues/11546 TEST_P(End2endTest, ResponseStreamWithEverythingCoalesced) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -935,6 +973,7 @@ TEST_P(End2endTest, ResponseStreamWithEverythingCoalesced) { } TEST_P(End2endTest, BidiStream) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -959,6 +998,7 @@ TEST_P(End2endTest, BidiStream) { } TEST_P(End2endTest, BidiStreamWithCoalescingApi) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -994,6 +1034,7 @@ TEST_P(End2endTest, BidiStreamWithCoalescingApi) { // This was added to prevent regression from issue: // https://github.com/grpc/grpc/issues/11546 TEST_P(End2endTest, BidiStreamWithEverythingCoalesced) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1019,6 +1060,7 @@ TEST_P(End2endTest, BidiStreamWithEverythingCoalesced) { // Talk to the two services with the same name but different package names. // The two stubs are created on the same channel. TEST_P(End2endTest, DiffPackageServices) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1047,6 +1089,7 @@ void CancelRpc(ClientContext* context, int delay_us, ServiceType* service) { } TEST_P(End2endTest, CancelRpcBeforeStart) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1063,6 +1106,7 @@ TEST_P(End2endTest, CancelRpcBeforeStart) { // Client cancels request stream after sending two messages TEST_P(End2endTest, ClientCancelsRequestStream) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1086,6 +1130,7 @@ TEST_P(End2endTest, ClientCancelsRequestStream) { // Client cancels server stream after sending some messages TEST_P(End2endTest, ClientCancelsResponseStream) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1121,6 +1166,7 @@ TEST_P(End2endTest, ClientCancelsResponseStream) { // Client cancels bidi stream after sending some messages TEST_P(End2endTest, ClientCancelsBidi) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1156,6 +1202,7 @@ TEST_P(End2endTest, ClientCancelsBidi) { } TEST_P(End2endTest, RpcMaxMessageSize) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1178,6 +1225,7 @@ void ReaderThreadFunc(ClientReaderWriter* stream, // Run a Read and a WritesDone simultaneously. TEST_P(End2endTest, SimultaneousReadWritesDone) { + MAYBE_SKIP_TEST; ResetStub(); ClientContext context; gpr_event ev; @@ -1192,6 +1240,7 @@ TEST_P(End2endTest, SimultaneousReadWritesDone) { } TEST_P(End2endTest, ChannelState) { + MAYBE_SKIP_TEST; if (GetParam().inproc) { return; } @@ -1242,6 +1291,7 @@ TEST_P(End2endTest, ChannelStateTimeout) { // Talking to a non-existing service. TEST_P(End2endTest, NonExistingService) { + MAYBE_SKIP_TEST; ResetChannel(); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel_); @@ -1259,6 +1309,7 @@ TEST_P(End2endTest, NonExistingService) { // Ask the server to send back a serialized proto in trailer. // This is an example of setting error details. TEST_P(End2endTest, BinaryTrailerTest) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1285,6 +1336,7 @@ TEST_P(End2endTest, BinaryTrailerTest) { } TEST_P(End2endTest, ExpectErrorTest) { + MAYBE_SKIP_TEST; ResetStub(); std::vector expected_status; @@ -1336,11 +1388,13 @@ class ProxyEnd2endTest : public End2endTest { }; TEST_P(ProxyEnd2endTest, SimpleRpc) { + MAYBE_SKIP_TEST; ResetStub(); SendRpc(stub_.get(), 1, false); } TEST_P(ProxyEnd2endTest, SimpleRpcWithEmptyMessages) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1351,6 +1405,7 @@ TEST_P(ProxyEnd2endTest, SimpleRpcWithEmptyMessages) { } TEST_P(ProxyEnd2endTest, MultipleRpcs) { + MAYBE_SKIP_TEST; ResetStub(); std::vector threads; threads.reserve(10); @@ -1364,6 +1419,7 @@ TEST_P(ProxyEnd2endTest, MultipleRpcs) { // Set a 10us deadline and make sure proper error is returned. TEST_P(ProxyEnd2endTest, RpcDeadlineExpires) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1389,6 +1445,7 @@ TEST_P(ProxyEnd2endTest, RpcDeadlineExpires) { // Set a long but finite deadline. TEST_P(ProxyEnd2endTest, RpcLongDeadline) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1405,6 +1462,7 @@ TEST_P(ProxyEnd2endTest, RpcLongDeadline) { // Ask server to echo back the deadline it sees. TEST_P(ProxyEnd2endTest, EchoDeadline) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1430,6 +1488,7 @@ TEST_P(ProxyEnd2endTest, EchoDeadline) { // Ask server to echo back the deadline it sees. The rpc has no deadline. TEST_P(ProxyEnd2endTest, EchoDeadlineForNoDeadlineRpc) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1445,6 +1504,7 @@ TEST_P(ProxyEnd2endTest, EchoDeadlineForNoDeadlineRpc) { } TEST_P(ProxyEnd2endTest, UnimplementedRpc) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1460,6 +1520,7 @@ TEST_P(ProxyEnd2endTest, UnimplementedRpc) { // Client cancels rpc after 10ms TEST_P(ProxyEnd2endTest, ClientCancelsRpc) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1494,6 +1555,7 @@ TEST_P(ProxyEnd2endTest, ClientCancelsRpc) { // Server cancels rpc after 1ms TEST_P(ProxyEnd2endTest, ServerCancelsRpc) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1508,6 +1570,7 @@ TEST_P(ProxyEnd2endTest, ServerCancelsRpc) { // Make the response larger than the flow control window. TEST_P(ProxyEnd2endTest, HugeResponse) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1525,6 +1588,7 @@ TEST_P(ProxyEnd2endTest, HugeResponse) { } TEST_P(ProxyEnd2endTest, Peer) { + MAYBE_SKIP_TEST; // Peer is not meaningful for inproc if (GetParam().inproc) { return; @@ -1553,6 +1617,7 @@ class SecureEnd2endTest : public End2endTest { }; TEST_P(SecureEnd2endTest, SimpleRpcWithHost) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; @@ -1584,6 +1649,7 @@ bool MetadataContains( } TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) { + MAYBE_SKIP_TEST; auto* processor = new TestAuthMetadataProcessor(true); StartServer(std::shared_ptr(processor)); ResetStub(); @@ -1609,6 +1675,7 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) { } TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorFailure) { + MAYBE_SKIP_TEST; auto* processor = new TestAuthMetadataProcessor(true); StartServer(std::shared_ptr(processor)); ResetStub(); @@ -1624,6 +1691,7 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorFailure) { } TEST_P(SecureEnd2endTest, SetPerCallCredentials) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1646,6 +1714,7 @@ TEST_P(SecureEnd2endTest, SetPerCallCredentials) { } TEST_P(SecureEnd2endTest, OverridePerCallCredentials) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1677,6 +1746,7 @@ TEST_P(SecureEnd2endTest, OverridePerCallCredentials) { } TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1694,6 +1764,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { } TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1711,6 +1782,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { } TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1732,6 +1804,7 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { } TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) { + MAYBE_SKIP_TEST; auto* processor = new TestAuthMetadataProcessor(false); StartServer(std::shared_ptr(processor)); ResetStub(); @@ -1757,6 +1830,7 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) { } TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) { + MAYBE_SKIP_TEST; auto* processor = new TestAuthMetadataProcessor(false); StartServer(std::shared_ptr(processor)); ResetStub(); @@ -1772,6 +1846,7 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) { } TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1793,6 +1868,7 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { } TEST_P(SecureEnd2endTest, CompositeCallCreds) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1821,6 +1897,7 @@ TEST_P(SecureEnd2endTest, CompositeCallCreds) { } TEST_P(SecureEnd2endTest, ClientAuthContext) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; EchoResponse response; @@ -1865,6 +1942,7 @@ class ResourceQuotaEnd2endTest : public End2endTest { }; TEST_P(ResourceQuotaEnd2endTest, SimpleRequest) { + MAYBE_SKIP_TEST; ResetStub(); EchoRequest request; @@ -1899,11 +1977,17 @@ std::vector CreateTestScenarios(bool use_proxy, credentials_types.push_back(kInsecureCredentialsType); } - // For now test callback server only with inproc + // Test callback with inproc or if the event-engine allows it GPR_ASSERT(!credentials_types.empty()); for (const auto& cred : credentials_types) { scenarios.emplace_back(false, false, false, cred, false); scenarios.emplace_back(true, false, false, cred, false); + if (test_callback_server) { + // Note that these scenarios will be dynamically disabled if the event + // engine doesn't run in the background + scenarios.emplace_back(false, false, false, cred, true); + scenarios.emplace_back(true, false, false, cred, true); + } if (use_proxy) { scenarios.emplace_back(false, true, false, cred, false); scenarios.emplace_back(true, true, false, cred, false); diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 6729ad14f4a..8c2df1acc33 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -670,6 +670,8 @@ CallbackTestServiceImpl::ResponseStream() { void OnWriteDone(bool ok) override { if (num_msgs_sent_ < server_responses_to_send_) { NextWrite(); + } else if (server_coalescing_api_ != 0) { + // We would have already done Finish just after the WriteLast } else if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { // Let OnCancel recover this } else if (server_try_cancel_ == CANCEL_AFTER_PROCESSING) { @@ -695,6 +697,8 @@ CallbackTestServiceImpl::ResponseStream() { server_coalescing_api_ != 0) { num_msgs_sent_++; StartWriteLast(&response_, WriteOptions()); + // If we use WriteLast, we shouldn't wait before attempting Finish + FinishOnce(Status::OK); } else { num_msgs_sent_++; StartWrite(&response_); @@ -753,10 +757,14 @@ CallbackTestServiceImpl::BidiStream() { response_.set_message(request_.message()); if (num_msgs_read_ == server_write_last_) { StartWriteLast(&response_, WriteOptions()); + // If we use WriteLast, we shouldn't wait before attempting Finish } else { StartWrite(&response_); + return; } - } else if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { + } + + if (server_try_cancel_ == CANCEL_DURING_PROCESSING) { // Let OnCancel handle this } else if (server_try_cancel_ == CANCEL_AFTER_PROCESSING) { ServerTryCancelNonblocking(ctx_); @@ -764,7 +772,12 @@ CallbackTestServiceImpl::BidiStream() { FinishOnce(Status::OK); } } - void OnWriteDone(bool ok) override { StartRead(&request_); } + void OnWriteDone(bool ok) override { + std::lock_guard l(finish_mu_); + if (!finished_) { + StartRead(&request_); + } + } private: void FinishOnce(const Status& s) { From 5a44f700bb687f21e89ebf337f2a4170c45db36c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 11 Feb 2019 16:23:16 -0800 Subject: [PATCH 327/814] Increase allocated space for cmsgs --- src/core/lib/iomgr/tcp_posix.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 61db36bd99e..fb56e15295c 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -715,11 +715,13 @@ static void process_errors(grpc_tcp* tcp) { msg.msg_iovlen = 0; msg.msg_flags = 0; - // Allocate aligned space for cmsgs received along with a timestamps + /* Allocate aligned space for cmsgs received along with timestamps */ union { - char rbuf[CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + + /* Allocate enough space so we don't need to keep increasing this as size + * of OPT_STATS increase */ + char rbuf[1024 /*CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in)) + - CMSG_SPACE(16 * NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t)))]; + CMSG_SPACE(16 * NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t)))*/]; struct cmsghdr align; } aligned_buf; memset(&aligned_buf, 0, sizeof(aligned_buf)); @@ -739,10 +741,8 @@ static void process_errors(grpc_tcp* tcp) { if (r == -1) { return; } - if (grpc_tcp_trace.enabled()) { - if ((msg.msg_flags & MSG_CTRUNC) == 1) { - gpr_log(GPR_INFO, "Error message was truncated."); - } + if ((msg.msg_flags & MSG_CTRUNC) == 1) { + gpr_log(GPR_ERROR, "Error message was truncated."); } if (msg.msg_controllen == 0) { From 6a372ff4426b0be01e1198ef2b4e60dd382d2b5f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 11 Feb 2019 16:58:24 -0800 Subject: [PATCH 328/814] Use constexpr --- src/core/lib/iomgr/tcp_posix.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index fb56e15295c..b850b907ff6 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -715,13 +715,15 @@ static void process_errors(grpc_tcp* tcp) { msg.msg_iovlen = 0; msg.msg_flags = 0; + /* Allocate enough space so we don't need to keep increasing this as size + * of OPT_STATS increase */ + constexpr size_t cmsg_alloc_space = + 1024 /*CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + + CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in)) + + CMSG_SPACE(16 * NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t)))*/; /* Allocate aligned space for cmsgs received along with timestamps */ union { - /* Allocate enough space so we don't need to keep increasing this as size - * of OPT_STATS increase */ - char rbuf[1024 /*CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + - CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in)) + - CMSG_SPACE(16 * NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t)))*/]; + char rbuf[cmsg_alloc_space]; struct cmsghdr align; } aligned_buf; memset(&aligned_buf, 0, sizeof(aligned_buf)); From 5eeb651a5fd91de85ba30b2063aa8b8f82a33c55 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 11 Feb 2019 17:16:15 -0800 Subject: [PATCH 329/814] Add extra space for opt_stats as part of the formula as opposed to 1024 --- src/core/lib/iomgr/tcp_posix.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index b850b907ff6..13ceffc6960 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -718,9 +718,9 @@ static void process_errors(grpc_tcp* tcp) { /* Allocate enough space so we don't need to keep increasing this as size * of OPT_STATS increase */ constexpr size_t cmsg_alloc_space = - 1024 /*CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + - CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in)) + - CMSG_SPACE(16 * NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t)))*/; + CMSG_SPACE(sizeof(grpc_core::scm_timestamping)) + + CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in)) + + CMSG_SPACE(32 * NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t))); /* Allocate aligned space for cmsgs received along with timestamps */ union { char rbuf[cmsg_alloc_space]; From db34fd2a94c47c69a62355c5a512d75ba327394f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Feb 2019 19:09:11 +0100 Subject: [PATCH 330/814] update Xamarin README.md --- examples/csharp/HelloworldXamarin/README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/csharp/HelloworldXamarin/README.md b/examples/csharp/HelloworldXamarin/README.md index e47855de5e1..153a4f1b4dc 100644 --- a/examples/csharp/HelloworldXamarin/README.md +++ b/examples/csharp/HelloworldXamarin/README.md @@ -4,11 +4,6 @@ gRPC C# on Xamarin EXPERIMENTAL ONLY ------------- Support of the Xamarin platform is currently experimental. -The example depends on experimental Grpc.Core nuget package that hasn't -been officially released and is only available via the [daily builds](https://packages.grpc.io/) -source. - -HINT: To download the package, please manually download the latest `.nupkg` packages from "Daily Builds" in [packages.grpc.io](https://packages.grpc.io/) into a local directory. Then add a nuget source that points to that directory (That can be [done in Visual Studio](https://docs.microsoft.com/en-us/nuget/tools/package-manager-ui#package-sources) or Visual Studio for Mac via "Configure nuget sources"). After that, nuget will also explore that directory when looking for packages. BACKGROUND ------------- From a8a6e925b88d561ca5054bc7db13bda29ff74dbb Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 12 Feb 2019 11:44:36 +0100 Subject: [PATCH 331/814] update Grpc.Core in Xamarin example --- .../Droid/HelloworldXamarin.Droid.csproj | 8 ++++---- examples/csharp/HelloworldXamarin/Droid/packages.config | 2 +- .../HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj | 8 ++++---- examples/csharp/HelloworldXamarin/iOS/packages.config | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj b/examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj index b5ca8490a48..991fa0c9bcc 100644 --- a/examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj +++ b/examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj @@ -50,12 +50,12 @@ ..\packages\System.Interactive.Async.3.1.1\lib\netstandard1.3\System.Interactive.Async.dll - - ..\packages\Grpc.Core.1.15.0-dev\lib\netstandard1.5\Grpc.Core.dll - ..\packages\Google.Protobuf.3.6.0\lib\netstandard1.0\Google.Protobuf.dll + + ..\packages\Grpc.Core.1.18.0\lib\netstandard1.5\Grpc.Core.dll + @@ -79,5 +79,5 @@ - + \ No newline at end of file diff --git a/examples/csharp/HelloworldXamarin/Droid/packages.config b/examples/csharp/HelloworldXamarin/Droid/packages.config index 3574b6782b3..29201117298 100644 --- a/examples/csharp/HelloworldXamarin/Droid/packages.config +++ b/examples/csharp/HelloworldXamarin/Droid/packages.config @@ -1,7 +1,7 @@  - + diff --git a/examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj b/examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj index b5c0d1d1192..9154bf33527 100644 --- a/examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj +++ b/examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj @@ -89,12 +89,12 @@ ..\packages\System.Interactive.Async.3.1.1\lib\netstandard1.3\System.Interactive.Async.dll - - ..\packages\Grpc.Core.1.15.0-dev\lib\netstandard1.5\Grpc.Core.dll - ..\packages\Google.Protobuf.3.6.0\lib\netstandard1.0\Google.Protobuf.dll + + ..\packages\Grpc.Core.1.18.0\lib\netstandard1.5\Grpc.Core.dll + @@ -122,5 +122,5 @@ - + \ No newline at end of file diff --git a/examples/csharp/HelloworldXamarin/iOS/packages.config b/examples/csharp/HelloworldXamarin/iOS/packages.config index ce4bceb62a8..055222ba48f 100644 --- a/examples/csharp/HelloworldXamarin/iOS/packages.config +++ b/examples/csharp/HelloworldXamarin/iOS/packages.config @@ -1,7 +1,7 @@  - + From d9b508c896081582ee9db0d64be5d9baff4fd2d2 Mon Sep 17 00:00:00 2001 From: xichengliudui <1693291525@qq.com> Date: Tue, 12 Feb 2019 11:11:43 -0500 Subject: [PATCH 332/814] Fix various typos in .cc and .md and .py files --- src/cpp/codegen/codegen_init.cc | 2 +- src/ruby/pb/README.md | 2 +- test/core/end2end/fixtures/http_proxy_fixture.cc | 2 +- test/cpp/util/proto_reflection_descriptor_database.h | 2 +- tools/run_tests/run_interop_tests.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpp/codegen/codegen_init.cc b/src/cpp/codegen/codegen_init.cc index 684d7218b93..e1e47cbb17b 100644 --- a/src/cpp/codegen/codegen_init.cc +++ b/src/cpp/codegen/codegen_init.cc @@ -20,7 +20,7 @@ #include /// Null-initializes the global gRPC variables for the codegen library. These -/// stay null in the absence of of grpc++ library. In this case, no gRPC +/// stay null in the absence of grpc++ library. In this case, no gRPC /// features such as the ability to perform calls will be available. Trying to /// perform them would result in a segmentation fault when trying to deference /// the following nulled globals. These should be associated with actual diff --git a/src/ruby/pb/README.md b/src/ruby/pb/README.md index d9e30bbc854..49327fe31e7 100644 --- a/src/ruby/pb/README.md +++ b/src/ruby/pb/README.md @@ -7,7 +7,7 @@ code to them. PREREQUISITES ------------- -The code is is generated using the protoc (> 3.0.0.alpha.1) and the +The code is generated using the protoc (> 3.0.0.alpha.1) and the grpc_ruby_plugin. These must be installed to regenerate the IDL defined classes, but that's not necessary just to use them. diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index b235c101652..e6fc5dfcfca 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -78,7 +78,7 @@ struct grpc_end2end_http_proxy { // // proxy_connection structure is only accessed in the closures which are all -// scheduled under the same combiner lock. So there is is no need for a mutex to +// scheduled under the same combiner lock. So there is no need for a mutex to // protect this structure. typedef struct proxy_connection { grpc_end2end_http_proxy* proxy; diff --git a/test/cpp/util/proto_reflection_descriptor_database.h b/test/cpp/util/proto_reflection_descriptor_database.h index 46190b32179..e91546ff3a0 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.h +++ b/test/cpp/util/proto_reflection_descriptor_database.h @@ -44,7 +44,7 @@ class ProtoReflectionDescriptorDatabase : public protobuf::DescriptorDatabase { // The following four methods implement DescriptorDatabase interfaces. // - // Find a file by file name. Fills in in *output and returns true if found. + // Find a file by file name. Fills in *output and returns true if found. // Otherwise, returns false, leaving the contents of *output undefined. bool FindFileByName(const string& filename, protobuf::FileDescriptorProto* output) override; diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index fe691fdbf5e..f6303982cee 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -759,7 +759,7 @@ def _job_kill_handler(job): # When the job times out and we decide to kill it, # we need to wait a before restarting the job # to prevent "container name already in use" error. - # TODO(jtattermusch): figure out a cleaner way to to this. + # TODO(jtattermusch): figure out a cleaner way to this. time.sleep(2) From 8fd9b02bec38dcad4b500f00d91fd05033dcf5ed Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 12 Feb 2019 10:06:12 -0800 Subject: [PATCH 333/814] added fieldmask to resultstore upload for RBE --- tools/run_tests/python_utils/upload_rbe_results.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index 3f3bd382bb6..6ae8af7787e 100644 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -122,7 +122,7 @@ def _get_resultstore_data(api_key, invocation_id): while True: req = urllib2.Request( url= - 'https://resultstore.googleapis.com/v2/invocations/%s/targets/-/configuredTargets/-/actions?key=%s&pageToken=%s' + 'https://resultstore.googleapis.com/v2/invocations/%s/targets/-/configuredTargets/-/actions?key=%s&pageToken=%s&fields=id,status_attributes,timing,test_action' % (invocation_id, api_key, page_token), headers={ 'Content-Type': 'application/json' From 6d14987f09a494dc57416046c6df1aa3bab39a4c Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Tue, 29 Jan 2019 18:00:32 -0800 Subject: [PATCH 334/814] Fixed cast in endpoint_cfstream.cc --- src/core/lib/iomgr/endpoint_cfstream.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index 7c4bc1ace2a..25146e7861c 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -182,7 +182,7 @@ static void ReadAction(void* arg, grpc_error* error) { GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), ep)); EP_UNREF(ep, "read"); } else { - if (read_size < len) { + if (read_size < static_cast(len)) { grpc_slice_buffer_trim_end(ep->read_slices, len - read_size, nullptr); } CallReadCb(ep, GRPC_ERROR_NONE); @@ -217,7 +217,7 @@ static void WriteAction(void* arg, grpc_error* error) { CallWriteCb(ep, error); EP_UNREF(ep, "write"); } else { - if (write_size < GRPC_SLICE_LENGTH(slice)) { + if (write_size < static_cast(GRPC_SLICE_LENGTH(slice))) { grpc_slice_buffer_undo_take_first( ep->write_slices, grpc_slice_sub(slice, write_size, slice_len)); } From 2f0f522423c15394307e0abd066c7213eed23185 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Thu, 7 Feb 2019 17:40:47 -0800 Subject: [PATCH 335/814] Add end2end test for cfstream --- BUILD | 18 ++ bazel/grpc_build_system.bzl | 16 +- test/cpp/end2end/BUILD | 32 ++ test/cpp/end2end/cfstream_test.cc | 275 ++++++++++++++++++ tools/internal_ci/macos/grpc_cfstream.cfg | 18 ++ .../internal_ci/macos/grpc_run_bazel_tests.sh | 28 ++ 6 files changed, 379 insertions(+), 8 deletions(-) create mode 100644 test/cpp/end2end/cfstream_test.cc create mode 100644 tools/internal_ci/macos/grpc_cfstream.cfg create mode 100644 tools/internal_ci/macos/grpc_run_bazel_tests.sh diff --git a/BUILD b/BUILD index ebb03580bb4..11d40710f22 100644 --- a/BUILD +++ b/BUILD @@ -63,6 +63,21 @@ config_setting( values = {"cpu": "x64_windows_msvc"}, ) +config_setting( + name = "mac_x86_64", + values = {"cpu": "darwin"}, +) + +COPTS = select({ + ":mac_x86_64": ["-DGRPC_CFSTREAM"], + "//conditions:default": [], +}) + +LINK_OPTS = select({ + ":mac_x86_64": ["-framework CoreFoundation"], + "//conditions:default": [], +}) + # This should be updated along with build.yaml g_stands_for = "gold" @@ -980,6 +995,7 @@ grpc_cc_library( "zlib", ], language = "c++", + copts = COPTS, public_hdrs = GRPC_PUBLIC_HDRS, deps = [ "gpr_base", @@ -1039,6 +1055,8 @@ grpc_cc_library( "src/core/lib/iomgr/iomgr_posix_cfstream.cc", "src/core/lib/iomgr/tcp_client_cfstream.cc", ], + copts = COPTS, + linkopts = LINK_OPTS, hdrs = [ "src/core/lib/iomgr/cfstream_handle.h", "src/core/lib/iomgr/endpoint_cfstream.h", diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index be85bc87324..5d5f75073af 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -73,10 +73,11 @@ def grpc_cc_library( testonly = False, visibility = None, alwayslink = 0, - data = []): - copts = [] + data = [], + copts = [], + linkopts = []): if language.upper() == "C": - copts = if_not_windows(["-std=c99"]) + copts = copts + if_not_windows(["-std=c99"]) native.cc_library( name = name, srcs = srcs, @@ -98,7 +99,7 @@ def grpc_cc_library( copts = copts, visibility = visibility, testonly = testonly, - linkopts = if_not_windows(["-pthread"]), + linkopts = linkopts + if_not_windows(["-pthread"]), includes = [ "include", ], @@ -132,10 +133,9 @@ def grpc_proto_library( generate_mocks = generate_mocks, ) -def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = None, tags = [], exec_compatible_with = []): - copts = [] +def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = None, tags = [], exec_compatible_with = [], copts = [], linkopts = []): if language.upper() == "C": - copts = if_not_windows(["-std=c99"]) + copts = copts + if_not_windows(["-std=c99"]) args = { "name": name, "srcs": srcs, @@ -143,7 +143,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data "data": data, "deps": deps + _get_external_deps(external_deps), "copts": copts, - "linkopts": if_not_windows(["-pthread"]), + "linkopts": linkopts + if_not_windows(["-pthread"]), "size": size, "timeout": timeout, "exec_compatible_with": exec_compatible_with, diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index cbf09354a03..b3ebefc68b9 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -16,6 +16,16 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library", "grpc_cc_test", "grpc_package") +config_setting( + name = "mac_x86_64", + values = {"cpu": "darwin"}, +) + +COPTS = select({ + ":mac_x86_64": ["-DGRPC_CFSTREAM"], + "//conditions:default": [], +}) + grpc_package( name = "test/cpp/end2end", visibility = "public", @@ -606,3 +616,25 @@ grpc_cc_test( "//test/cpp/util:test_util", ], ) + +grpc_cc_test( + name = "cfstream_test", + srcs = ["cfstream_test.cc"], + external_deps = [ + "gtest", + ], + tags = ["manual"], # test requires root, won't work with bazel RBE + copts = COPTS, + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//:grpc_cfstream", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing:simple_messages_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) diff --git a/test/cpp/end2end/cfstream_test.cc b/test/cpp/end2end/cfstream_test.cc new file mode 100644 index 00000000000..8d4cec55515 --- /dev/null +++ b/test/cpp/end2end/cfstream_test.cc @@ -0,0 +1,275 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "src/core/lib/iomgr/port.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/gpr/env.h" + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#ifdef GRPC_CFSTREAM +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +class CFStreamTest : public ::testing::Test { + protected: + CFStreamTest() + : server_host_("grpctest"), + interface_("lo0"), + ipv4_address_("10.0.0.1"), + netmask_("/32"), + kRequestMessage_("🖖") {} + + void DNSUp() { + std::ostringstream cmd; + // Add DNS entry for server_host_ in /etc/hosts + cmd << "echo '" << ipv4_address_ << " " << server_host_ + << " ' | sudo tee -a /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DNSDown() { + std::ostringstream cmd; + // Remove DNS entry for server_host_ in /etc/hosts + cmd << "sudo sed -i '.bak' '/" << server_host_ << "/d' /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void InterfaceUp() { + std::ostringstream cmd; + cmd << "sudo /sbin/ifconfig " << interface_ << " alias " << ipv4_address_; + std::system(cmd.str().c_str()); + } + + void InterfaceDown() { + std::ostringstream cmd; + cmd << "sudo /sbin/ifconfig " << interface_ << " -alias " << ipv4_address_; + std::system(cmd.str().c_str()); + } + + void NetworkUp() { + InterfaceUp(); + DNSUp(); + } + + void NetworkDown() { + InterfaceDown(); + DNSDown(); + } + + void SetUp() override { + NetworkUp(); + grpc_init(); + StartServer(); + } + + void TearDown() override { + NetworkDown(); + StopServer(); + grpc_shutdown(); + } + + void StartServer() { + port_ = grpc_pick_unused_port_or_die(); + server_.reset(new ServerData(port_)); + server_->Start(server_host_); + } + void StopServer() { server_->Shutdown(); } + + std::unique_ptr BuildStub( + const std::shared_ptr& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr BuildChannel() { + std::ostringstream server_address; + server_address << server_host_ << ":" << port_; + return CreateCustomChannel( + server_address.str(), InsecureChannelCredentials(), ChannelArguments()); + } + + void SendRpc( + const std::unique_ptr& stub, + bool expect_success = false) { + auto response = std::unique_ptr(new EchoResponse()); + EchoRequest request; + request.set_message(kRequestMessage_); + ClientContext context; + Status status = stub->Echo(&context, request, response.get()); + if (status.ok()) { + gpr_log(GPR_DEBUG, "RPC returned %s\n", response->message().c_str()); + } else { + gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); + } + if (expect_success) { + EXPECT_TRUE(status.ok()); + } + } + + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 10) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + private: + struct ServerData { + int port_; + std::unique_ptr server_; + TestServiceImpl service_; + std::unique_ptr thread_; + bool server_ready_ = false; + + explicit ServerData(int port) { port_ = port; } + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting server on port %d", port_); + std::mutex mu; + std::unique_lock lock(mu); + std::condition_variable cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.wait(lock, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + + void Serve(const grpc::string& server_host, std::mutex* mu, + std::condition_variable* cond) { + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + builder.AddListeningPort(server_address.str(), + InsecureServerCredentials()); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + std::lock_guard lock(*mu); + server_ready_ = true; + cond->notify_one(); + } + + void Shutdown(bool join = true) { + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + if (join) thread_->join(); + } + }; + + const grpc::string server_host_; + const grpc::string interface_; + const grpc::string ipv4_address_; + const grpc::string netmask_; + std::unique_ptr stub_; + std::unique_ptr server_; + int port_; + const grpc::string kRequestMessage_; +}; + +// gRPC should automatically detech network flaps (without enabling keepalives) +// when CFStream is enabled +TEST_F(CFStreamTest, NetworkTransition) { + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + SendRpc(stub, /*expect_success=*/true); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // bring down network + NetworkDown(); + + // network going down should be detected by cfstream + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + + // bring network interface back up + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + NetworkUp(); + + // channel should reconnect + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); +} + +} // namespace +} // namespace testing +} // namespace grpc +#endif // GRPC_CFSTREAM + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_test_init(argc, argv); + gpr_setenv("grpc_cfstream", "1"); + const auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/tools/internal_ci/macos/grpc_cfstream.cfg b/tools/internal_ci/macos/grpc_cfstream.cfg new file mode 100644 index 00000000000..b911bbe6c69 --- /dev/null +++ b/tools/internal_ci/macos/grpc_cfstream.cfg @@ -0,0 +1,18 @@ +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_bazel_tests.sh" diff --git a/tools/internal_ci/macos/grpc_run_bazel_tests.sh b/tools/internal_ci/macos/grpc_run_bazel_tests.sh new file mode 100644 index 00000000000..3dfa182d7c6 --- /dev/null +++ b/tools/internal_ci/macos/grpc_run_bazel_tests.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -ex + +# change to grpc repo root +cd $(dirname $0)/../../.. + + +./tools/run_tests/start_port_server.py + +# run cfstream_test separately because it messes with the network +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all //test/cpp/end2end:cfstream_test + +# kill port_server.py to prevent the build from hanging +ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9 From 485bc78ba325ce0b3a4ce55187a7560f4d6732d3 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Thu, 7 Feb 2019 16:53:24 -0800 Subject: [PATCH 336/814] Added flaky_network_test --- test/cpp/end2end/BUILD | 19 + test/cpp/end2end/flaky_network_test.cc | 441 ++++++++++++++++++ .../linux/grpc_bazel_privileged_docker.sh | 26 ++ .../internal_ci/linux/grpc_flaky_network.cfg | 2 +- .../linux/grpc_flaky_network_in_docker.sh | 8 +- 5 files changed, 491 insertions(+), 5 deletions(-) create mode 100644 test/cpp/end2end/flaky_network_test.cc create mode 100755 tools/internal_ci/linux/grpc_bazel_privileged_docker.sh diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index cbf09354a03..64b3eae60da 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -553,6 +553,25 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "flaky_network_test", + srcs = ["flaky_network_test.cc"], + external_deps = [ + "gtest", + ], + tags = ["manual"], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + grpc_cc_test( name = "shutdown_test", srcs = ["shutdown_test.cc"], diff --git a/test/cpp/end2end/flaky_network_test.cc b/test/cpp/end2end/flaky_network_test.cc new file mode 100644 index 00000000000..06eaf9e74ad --- /dev/null +++ b/test/cpp/end2end/flaky_network_test.cc @@ -0,0 +1,441 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/gpr/env.h" + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#include + +#ifdef GPR_LINUX +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; + +namespace grpc { +namespace testing { +namespace { + +class FlakyNetworkTest : public ::testing::Test { + protected: + FlakyNetworkTest() + : server_host_("grpctest"), + interface_("lo:1"), + ipv4_address_("10.0.0.1"), + netmask_("/32"), + kRequestMessage_("🖖") {} + + void InterfaceUp() { + std::ostringstream cmd; + // create interface_ with address ipv4_address_ + cmd << "ip addr add " << ipv4_address_ << netmask_ << " dev " << interface_; + std::system(cmd.str().c_str()); + } + + void InterfaceDown() { + std::ostringstream cmd; + // remove interface_ + cmd << "ip addr del " << ipv4_address_ << netmask_ << " dev " << interface_; + std::system(cmd.str().c_str()); + } + + void DNSUp() { + std::ostringstream cmd; + // Add DNS entry for server_host_ in /etc/hosts + cmd << "echo '" << ipv4_address_ << " " << server_host_ + << "' >> /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DNSDown() { + std::ostringstream cmd; + // Remove DNS entry for server_host_ from /etc/hosts + // NOTE: we can't do this in one step with sed -i because when we are + // running under docker, the file is mounted by docker so we can't change + // its inode from within the container (sed -i creates a new file and + // replaces the old file, which changes the inode) + cmd << "sed '/" << server_host_ << "/d' /etc/hosts > /etc/hosts.orig"; + std::system(cmd.str().c_str()); + + // clear the stream + cmd.str(""); + + cmd << "cat /etc/hosts.orig > /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DropPackets() { + std::ostringstream cmd; + // drop packets with src IP = ipv4_address_ + cmd << "iptables -A INPUT -s " << ipv4_address_ << " -j DROP"; + + std::system(cmd.str().c_str()); + // clear the stream + cmd.str(""); + + // drop packets with dst IP = ipv4_address_ + cmd << "iptables -A INPUT -d " << ipv4_address_ << " -j DROP"; + } + + void RestoreNetwork() { + std::ostringstream cmd; + // remove iptables rule to drop packets with src IP = ipv4_address_ + cmd << "iptables -D INPUT -s " << ipv4_address_ << " -j DROP"; + std::system(cmd.str().c_str()); + // clear the stream + cmd.str(""); + // remove iptables rule to drop packets with dest IP = ipv4_address_ + cmd << "iptables -D INPUT -d " << ipv4_address_ << " -j DROP"; + } + + void FlakeNetwork() { + std::ostringstream cmd; + // Emulate a flaky network connection over interface_. Add a delay of 100ms + // +/- 590ms, 3% packet loss, 1% duplicates and 0.1% corrupt packets. + cmd << "tc qdisc replace dev " << interface_ + << " root netem delay 100ms 50ms distribution normal loss 3% duplicate " + "1% corrupt 0.1% "; + std::system(cmd.str().c_str()); + } + + void UnflakeNetwork() { + // Remove simulated network flake on interface_ + std::ostringstream cmd; + cmd << "tc qdisc del dev " << interface_ << " root netem"; + std::system(cmd.str().c_str()); + } + + void NetworkUp() { + InterfaceUp(); + DNSUp(); + } + + void NetworkDown() { + InterfaceDown(); + DNSDown(); + } + + void SetUp() override { + NetworkUp(); + grpc_init(); + StartServer(); + } + + void TearDown() override { + NetworkDown(); + StopServer(); + grpc_shutdown(); + } + + void StartServer() { + // TODO (pjaikumar): Ideally, we should allocate the port dynamically using + // grpc_pick_unused_port_or_die(). That doesn't work inside some docker + // containers because port_server listens on localhost which maps to + // ip6-looopback, but ipv6 support is not enabled by default in docker. + port_ = SERVER_PORT; + + server_.reset(new ServerData(port_)); + server_->Start(server_host_); + } + void StopServer() { server_->Shutdown(); } + + std::unique_ptr BuildStub( + const std::shared_ptr& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr BuildChannel( + const grpc::string& lb_policy_name, + ChannelArguments args = ChannelArguments()) { + if (lb_policy_name.size() > 0) { + args.SetLoadBalancingPolicyName(lb_policy_name); + } // else, default to pick first + std::ostringstream server_address; + server_address << server_host_ << ":" << port_; + return CreateCustomChannel(server_address.str(), + InsecureChannelCredentials(), args); + } + + bool SendRpc( + const std::unique_ptr& stub, + int timeout_ms = 0, bool wait_for_ready = false) { + auto response = std::unique_ptr(new EchoResponse()); + EchoRequest request; + request.set_message(kRequestMessage_); + ClientContext context; + if (timeout_ms > 0) { + context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); + } + // See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md for + // details of wait-for-ready semantics + if (wait_for_ready) { + context.set_wait_for_ready(true); + } + Status status = stub->Echo(&context, request, response.get()); + auto ok = status.ok(); + if (ok) { + gpr_log(GPR_DEBUG, "RPC returned %s\n", response->message().c_str()); + } else { + gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); + } + return ok; + } + + struct ServerData { + int port_; + std::unique_ptr server_; + TestServiceImpl service_; + std::unique_ptr thread_; + bool server_ready_ = false; + + explicit ServerData(int port) { port_ = port; } + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting server on port %d", port_); + std::mutex mu; + std::unique_lock lock(mu); + std::condition_variable cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.wait(lock, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + + void Serve(const grpc::string& server_host, std::mutex* mu, + std::condition_variable* cond) { + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + builder.AddListeningPort(server_address.str(), + InsecureServerCredentials()); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + std::lock_guard lock(*mu); + server_ready_ = true; + cond->notify_one(); + } + + void Shutdown(bool join = true) { + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + if (join) thread_->join(); + } + }; + + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + private: + const grpc::string server_host_; + const grpc::string interface_; + const grpc::string ipv4_address_; + const grpc::string netmask_; + std::unique_ptr stub_; + std::unique_ptr server_; + const int SERVER_PORT = 32750; + int port_; + const grpc::string kRequestMessage_; +}; + +// Network interface connected to server flaps +TEST_F(FlakyNetworkTest, NetworkTransition) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // bring down network + NetworkDown(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + // bring network interface back up + InterfaceUp(); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + // Restore DNS entry for server + DNSUp(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); +} + +// Traffic to server server is blackholed temporarily with keepalives enabled +TEST_F(FlakyNetworkTest, ServerUnreachableWithKeepalive) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // break network connectivity + DropPackets(); + std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + // bring network interface back up + RestoreNetwork(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); +} + +// +// Traffic to server server is blackholed temporarily with keepalives disabled +TEST_F(FlakyNetworkTest, ServerUnreachableNoKeepalive) { + auto channel = BuildChannel("pick_first", ChannelArguments()); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // break network connectivity + DropPackets(); + + std::thread sender = std::thread([this, &stub]() { + // RPC with deadline should timeout + EXPECT_FALSE(SendRpc(stub, /*timeout_ms=*/500, /*wait_for_ready=*/true)); + // RPC without deadline forever until call finishes + EXPECT_TRUE(SendRpc(stub, /*timeout_ms=*/0, /*wait_for_ready=*/true)); + }); + + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + // bring network interface back up + RestoreNetwork(); + + // wait for RPC to finish + sender.join(); +} + +// Send RPCs over a flaky network connection +TEST_F(FlakyNetworkTest, FlakyNetwork) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + const int kMessageCount = 100; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // simulate flaky network (packet loss, corruption and delays) + FlakeNetwork(); + for (int i = 0; i < kMessageCount; ++i) { + EXPECT_TRUE(SendRpc(stub)); + } + // remove network flakiness + UnflakeNetwork(); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); +} + +} // namespace +} // namespace testing +} // namespace grpc +#endif // GPR_LINUX + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_test_init(argc, argv); + auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh b/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh new file mode 100755 index 00000000000..ae1056d7c3d --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -ex + +# change to grpc repo root +cd $(dirname $0)/../../.. + +source tools/internal_ci/helper_scripts/prepare_build_linux_rc + +export DOCKERFILE_DIR=tools/dockerfile/test/bazel +export DOCKER_RUN_SCRIPT=$BAZEL_SCRIPT +# NET_ADMIN capability allows tests to manipulate network interfaces +exec tools/run_tests/dockerize/build_and_run_docker.sh --cap-add NET_ADMIN diff --git a/tools/internal_ci/linux/grpc_flaky_network.cfg b/tools/internal_ci/linux/grpc_flaky_network.cfg index de7a3b9cd8f..07bedd79f94 100644 --- a/tools/internal_ci/linux/grpc_flaky_network.cfg +++ b/tools/internal_ci/linux/grpc_flaky_network.cfg @@ -15,7 +15,7 @@ # Config file for the internal CI (in protobuf text format) # Location of the continuous shell script in repository. -build_file: "grpc/tools/internal_ci/linux/grpc_bazel.sh" +build_file: "grpc/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh" timeout_mins: 240 env_vars { key: "BAZEL_SCRIPT" diff --git a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh index 42b6d44c1cb..60bb49b639a 100755 --- a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh +++ b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh @@ -23,9 +23,9 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc (cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \ && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') -cd /var/local/git/grpc +cd /var/local/git/grpc/test/cpp/end2end -# TODO(jtattermusch): install prerequsites if needed +# iptables is used to drop traffic between client and server +apt-get install -y iptables -# TODO(jtattermusch): run the flaky network test instead -bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/... +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all :flaky_network_test From 593852c2ba39abd4194c498695a02a2426cf357c Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Tue, 12 Feb 2019 11:58:24 -0800 Subject: [PATCH 337/814] grpc handshaker linkage fixup --- src/core/lib/security/transport/security_handshaker.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index a6fd2481a4a..5369574b854 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -496,11 +496,6 @@ RefCountedPtr SecurityHandshakerCreate( } } -grpc_handshaker* grpc_security_handshaker_create( - tsi_handshaker* handshaker, grpc_security_connector* connector) { - return SecurityHandshakerCreate(handshaker, connector).release(); -} - void SecurityRegisterHandshakerFactories() { HandshakerRegistry::RegisterHandshakerFactory( false /* at_start */, HANDSHAKER_CLIENT, @@ -511,3 +506,8 @@ void SecurityRegisterHandshakerFactories() { } } // namespace grpc_core + +grpc_handshaker* grpc_security_handshaker_create( + tsi_handshaker* handshaker, grpc_security_connector* connector) { + return SecurityHandshakerCreate(handshaker, connector).release(); +} From c78d456e0804265bc4b101e6f86ffa22862f8361 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Feb 2019 13:20:35 +0100 Subject: [PATCH 338/814] add scaffolding for HelloworldUnity --- examples/csharp/HelloworldUnity/.gitignore | 52 ++ .../HelloworldUnity/Assets/Plugins.meta | 8 + .../csharp/HelloworldUnity/Assets/Scenes.meta | 8 + .../Assets/Scenes/SampleScene.unity | 586 ++++++++++++++++ .../Assets/Scenes/SampleScene.unity.meta | 7 + .../HelloworldUnity/Assets/Scripts.meta | 8 + .../Assets/Scripts/HelloWorldScript.cs | 92 +++ .../Assets/Scripts/HelloWorldScript.cs.meta | 11 + .../Assets/Scripts/Helloworld.cs | 286 ++++++++ .../Assets/Scripts/Helloworld.cs.meta | 11 + .../Assets/Scripts/HelloworldGrpc.cs | 150 ++++ .../Assets/Scripts/HelloworldGrpc.cs.meta | 11 + .../ProjectSettings/AudioManager.asset | 17 + .../ProjectSettings/ClusterInputManager.asset | 6 + .../ProjectSettings/DynamicsManager.asset | 29 + .../ProjectSettings/EditorBuildSettings.asset | 11 + .../ProjectSettings/EditorSettings.asset | 21 + .../ProjectSettings/GraphicsSettings.asset | 60 ++ .../ProjectSettings/InputManager.asset | 295 ++++++++ .../ProjectSettings/NavMeshAreas.asset | 91 +++ .../ProjectSettings/NetworkManager.asset | 8 + .../ProjectSettings/Physics2DSettings.asset | 55 ++ .../ProjectSettings/PresetManager.asset | 13 + .../ProjectSettings/ProjectSettings.asset | 656 ++++++++++++++++++ .../ProjectSettings/ProjectVersion.txt | 1 + .../ProjectSettings/QualitySettings.asset | 191 +++++ .../ProjectSettings/TagManager.asset | 43 ++ .../ProjectSettings/TimeManager.asset | 9 + .../UnityConnectSettings.asset | 34 + .../ProjectSettings/VFXManager.asset | 11 + .../UIElementsSchema/UIElements.xsd | 6 + .../UnityEditor.Experimental.UIElements.xsd | 228 ++++++ .../UnityEditor.PackageManager.UI.xsd | 116 ++++ .../UnityEngine.Experimental.UIElements.xsd | 269 +++++++ 34 files changed, 3400 insertions(+) create mode 100644 examples/csharp/HelloworldUnity/.gitignore create mode 100644 examples/csharp/HelloworldUnity/Assets/Plugins.meta create mode 100644 examples/csharp/HelloworldUnity/Assets/Scenes.meta create mode 100644 examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity create mode 100644 examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity.meta create mode 100644 examples/csharp/HelloworldUnity/Assets/Scripts.meta create mode 100644 examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs create mode 100644 examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs.meta create mode 100644 examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs create mode 100644 examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs.meta create mode 100644 examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs create mode 100644 examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs.meta create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/AudioManager.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/ClusterInputManager.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/DynamicsManager.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/EditorBuildSettings.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/EditorSettings.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/GraphicsSettings.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/InputManager.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/NavMeshAreas.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/NetworkManager.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/Physics2DSettings.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/PresetManager.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/ProjectSettings.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/QualitySettings.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/TagManager.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/TimeManager.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/UnityConnectSettings.asset create mode 100644 examples/csharp/HelloworldUnity/ProjectSettings/VFXManager.asset create mode 100644 examples/csharp/HelloworldUnity/UIElementsSchema/UIElements.xsd create mode 100644 examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.Experimental.UIElements.xsd create mode 100644 examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.PackageManager.UI.xsd create mode 100644 examples/csharp/HelloworldUnity/UIElementsSchema/UnityEngine.Experimental.UIElements.xsd diff --git a/examples/csharp/HelloworldUnity/.gitignore b/examples/csharp/HelloworldUnity/.gitignore new file mode 100644 index 00000000000..6245af922f6 --- /dev/null +++ b/examples/csharp/HelloworldUnity/.gitignore @@ -0,0 +1,52 @@ +[Ll]ibrary/ +[Tt]emp/ +[Oo]bj/ +[Bb]uild/ +[Bb]uilds/ +[Ll]ogs/ + +# Never ignore Asset meta data +![Aa]ssets/**/*.meta + +# Uncomment this line if you wish to ignore the asset store tools plugin +# [Aa]ssets/AssetStoreTools* + +# Visual Studio cache directory +.vs/ + +# Gradle cache directory +.gradle/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.mdb +*.opendb +*.VC.db + +# Unity3D generated meta files +*.pidb.meta +*.pdb.meta +*.mdb.meta + +# Unity3D generated file on crash reports +sysinfo.txt + +# Builds +*.apk +*.unitypackage + +# Crashlytics generated file +crashlytics-build.properties + diff --git a/examples/csharp/HelloworldUnity/Assets/Plugins.meta b/examples/csharp/HelloworldUnity/Assets/Plugins.meta new file mode 100644 index 00000000000..31c915a8752 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9e39cea189b0245c4a39113ff6459d24 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/Assets/Scenes.meta b/examples/csharp/HelloworldUnity/Assets/Scenes.meta new file mode 100644 index 00000000000..7fe8e109da3 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 131a6b21c8605f84396be9f6751fb6e3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity b/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity new file mode 100644 index 00000000000..8c5947d0f7b --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity @@ -0,0 +1,586 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &519420028 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 519420032} + - component: {fileID: 519420031} + - component: {fileID: 519420029} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &519420029 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 +--- !u!20 &519420031 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 0 + m_HDR: 1 + m_AllowMSAA: 0 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 0 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &519420032 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &785253852 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 785253855} + - component: {fileID: 785253854} + - component: {fileID: 785253853} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &785253853 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 785253852} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &785253854 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 785253852} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &785253855 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 785253852} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1639505844 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1639505846} + - component: {fileID: 1639505845} + m_Layer: 0 + m_Name: UIManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1639505845 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1639505844} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d62381e23356a4203b3e54cc6c2e3a4f, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &1639505846 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1639505844} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1729899994 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1729899995} + - component: {fileID: 1729899997} + - component: {fileID: 1729899996} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1729899995 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1729899994} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2040475500} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1729899996 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1729899994} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Hello gRPC!!! +--- !u!222 &1729899997 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 1729899994} + m_CullTransparentMesh: 0 +--- !u!1 &2040475499 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2040475500} + - component: {fileID: 2040475503} + - component: {fileID: 2040475502} + - component: {fileID: 2040475501} + m_Layer: 5 + m_Name: Button + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2040475500 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2040475499} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1729899995} + m_Father: {fileID: 2066701619} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 500, y: 150} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2040475501 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2040475499} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2040475502} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1639505845} + m_MethodName: RunHelloWorld + m_Mode: 2 + m_Arguments: + m_ObjectArgument: {fileID: 1729899996} + m_ObjectArgumentAssemblyTypeName: UnityEngine.UI.Text, UnityEngine.UI + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, + Culture=neutral, PublicKeyToken=null +--- !u!114 &2040475502 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2040475499} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.34157702, g: 0.6037736, b: 0.093983635, a: 1} + m_RaycastTarget: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 +--- !u!222 &2040475503 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2040475499} + m_CullTransparentMesh: 0 +--- !u!1 &2066701615 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2066701619} + - component: {fileID: 2066701618} + - component: {fileID: 2066701617} + - component: {fileID: 2066701616} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2066701616 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2066701615} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &2066701617 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2066701615} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!223 &2066701618 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2066701615} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &2066701619 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 2066701615} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 2040475500} + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} diff --git a/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity.meta b/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity.meta new file mode 100644 index 00000000000..c1e3c88e1cf --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scenes/SampleScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2cda990e2423bbf4892e6590ba056729 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts.meta b/examples/csharp/HelloworldUnity/Assets/Scripts.meta new file mode 100644 index 00000000000..49e35f97956 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 55598493aa3774a6dad4b7a4974826ff +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs new file mode 100644 index 00000000000..6d318bcc348 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs @@ -0,0 +1,92 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +using Helloworld; +using System.Threading.Tasks; + +using System; + +using UnityEngine.SceneManagement; + +using Grpc.Core; + +public class HelloWorldScript : MonoBehaviour { + const int Port = 50051; + int counter = 1; + // Use this for initialization + void Start () { + //Console.WriteLine("dfsdfadfffa dfasfa"); + + + } + + public void RunHelloWorld(Text text) + { + //Debug.Log("dfasfa"); + //var channel = new Channel("localhost:12345", ChannelCredentials.Insecure); + //SceneManager.LoadScene("RocketMouse"); + + + //var unityApplicationClass = Type.GetType("UnityEngine.Application, UnityEngine"); + // Consult value of Application.platform via reflection + // https://docs.unity3d.com/ScriptReference/Application-platform.html + // var platformProperty = unityApplicationClass.GetTypeInfo().GetProperty("platform"); + // var unityRuntimePlatform = platformProperty?.GetValue(null)?.ToString(); + //var isUnityIOS = (unityRuntimePlatform == "IPhonePlayer"); + + var t = Type.GetType("UnityEngine.Application, UnityEngine"); + var propInfo = t.GetProperty("platform"); + var reflPlatform = propInfo.GetValue(null).ToString(); + + + Debug.Log("Appl. platform:" + Application.platform); + Debug.Log("Appl. platform:" + reflPlatform); + Debug.Log("Environment.OSVersion: " + Environment.OSVersion); + + + Server server = new Server + { + Services = { Greeter.BindService(new GreeterImpl()) }, + Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } + }; + server.Start(); + + Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure); + + var client = new Greeter.GreeterClient(channel); + String user = "Unity " + counter; + + var reply = client.SayHello(new HelloRequest { Name = user }); + + + text.text = "Greeting: " + reply.Message; + + channel.ShutdownAsync().Wait(); + + server.ShutdownAsync().Wait(); + + counter ++; + + + + //Debug.Log("channel: created channel"); + + + } + + // Update is called once per frame + void Update () { + + } + + class GreeterImpl : Greeter.GreeterBase + { + // Server side handler of the SayHello RPC + public override Task SayHello(HelloRequest request, ServerCallContext context) + { + return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); + } + } +} diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs.meta b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs.meta new file mode 100644 index 00000000000..60b0ea38c08 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d62381e23356a4203b3e54cc6c2e3a4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs b/examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs new file mode 100644 index 00000000000..ecfc8e131cb --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs @@ -0,0 +1,286 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Helloworld { + + /// Holder for reflection information generated from helloworld.proto + public static partial class HelloworldReflection { + + #region Descriptor + /// File descriptor for helloworld.proto + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static HelloworldReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz", + "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo", + "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl", + "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4", + "YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw", + "cm90bzM=")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null) + })); + } + #endregion + + } + #region Messages + /// + /// The request message containing the user's name. + /// + public sealed partial class HelloRequest : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloRequest()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public HelloRequest() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public HelloRequest(HelloRequest other) : this() { + name_ = other.name_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public HelloRequest Clone() { + return new HelloRequest(this); + } + + /// Field number for the "name" field. + public const int NameFieldNumber = 1; + private string name_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string Name { + get { return name_; } + set { + name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as HelloRequest); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(HelloRequest other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Name != other.Name) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Name.Length != 0) hash ^= Name.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Name.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(HelloRequest other) { + if (other == null) { + return; + } + if (other.Name.Length != 0) { + Name = other.Name; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + Name = input.ReadString(); + break; + } + } + } + } + + } + + /// + /// The response message containing the greetings + /// + public sealed partial class HelloReply : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloReply()); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public HelloReply() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public HelloReply(HelloReply other) : this() { + message_ = other.message_; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public HelloReply Clone() { + return new HelloReply(this); + } + + /// Field number for the "message" field. + public const int MessageFieldNumber = 1; + private string message_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string Message { + get { return message_; } + set { + message_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as HelloReply); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(HelloReply other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Message != other.Message) return false; + return true; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (Message.Length != 0) hash ^= Message.GetHashCode(); + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + if (Message.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Message); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (Message.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(HelloReply other) { + if (other == null) { + return; + } + if (other.Message.Length != 0) { + Message = other.Message; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + Message = input.ReadString(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs.meta b/examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs.meta new file mode 100644 index 00000000000..7a43df02a17 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/Helloworld.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8bfcdd9a5979d4cc7b76d17be585e778 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs new file mode 100644 index 00000000000..c808884e579 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs @@ -0,0 +1,150 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +// Original file comments: +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#pragma warning disable 1591 +#region Designer generated code + +using System; +using System.Threading; +using System.Threading.Tasks; +using grpc = global::Grpc.Core; + +namespace Helloworld { + /// + /// The greeting service definition. + /// + public static partial class Greeter + { + static readonly string __ServiceName = "helloworld.Greeter"; + + static readonly grpc::Marshaller __Marshaller_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); + + static readonly grpc::Method __Method_SayHello = new grpc::Method( + grpc::MethodType.Unary, + __ServiceName, + "SayHello", + __Marshaller_HelloRequest, + __Marshaller_HelloReply); + + /// Service descriptor + public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor + { + get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; } + } + + /// Base class for server-side implementations of Greeter + public abstract partial class GreeterBase + { + /// + /// Sends a greeting + /// + /// The request received from the client. + /// The context of the server-side call handler being invoked. + /// The response to send back to the client (wrapped by a task). + public virtual global::System.Threading.Tasks.Task SayHello(global::Helloworld.HelloRequest request, grpc::ServerCallContext context) + { + throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, "")); + } + + } + + /// Client for Greeter + public partial class GreeterClient : grpc::ClientBase + { + /// Creates a new client for Greeter + /// The channel to use to make remote calls. + public GreeterClient(grpc::Channel channel) : base(channel) + { + } + /// Creates a new client for Greeter that uses a custom CallInvoker. + /// The callInvoker to use to make remote calls. + public GreeterClient(grpc::CallInvoker callInvoker) : base(callInvoker) + { + } + /// Protected parameterless constructor to allow creation of test doubles. + protected GreeterClient() : base() + { + } + /// Protected constructor to allow creation of configured clients. + /// The client configuration. + protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration) + { + } + + /// + /// Sends a greeting + /// + /// The request to send to the server. + /// The initial metadata to send with the call. This parameter is optional. + /// An optional deadline for the call. The call will be cancelled if deadline is hit. + /// An optional token for canceling the call. + /// The response received from the server. + public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + { + return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken)); + } + /// + /// Sends a greeting + /// + /// The request to send to the server. + /// The options for the call. + /// The response received from the server. + public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::CallOptions options) + { + return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request); + } + /// + /// Sends a greeting + /// + /// The request to send to the server. + /// The initial metadata to send with the call. This parameter is optional. + /// An optional deadline for the call. The call will be cancelled if deadline is hit. + /// An optional token for canceling the call. + /// The call object. + public virtual grpc::AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + { + return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken)); + } + /// + /// Sends a greeting + /// + /// The request to send to the server. + /// The options for the call. + /// The call object. + public virtual grpc::AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, grpc::CallOptions options) + { + return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request); + } + /// Creates a new instance of client from given ClientBaseConfiguration. + protected override GreeterClient NewInstance(ClientBaseConfiguration configuration) + { + return new GreeterClient(configuration); + } + } + + /// Creates service definition that can be registered with a server + /// An object implementing the server-side handling logic. + public static grpc::ServerServiceDefinition BindService(GreeterBase serviceImpl) + { + return grpc::ServerServiceDefinition.CreateBuilder() + .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build(); + } + + } +} +#endregion diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs.meta b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs.meta new file mode 100644 index 00000000000..e6a26fca3dc --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloworldGrpc.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf9b820c371a143ce96df8edaebb3fe2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/AudioManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/AudioManager.asset new file mode 100644 index 00000000000..304925ebde5 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/AudioManager.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 1024 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/ClusterInputManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 00000000000..a84cf4e6fe7 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/DynamicsManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/DynamicsManager.asset new file mode 100644 index 00000000000..78992f08c7a --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,29 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/EditorBuildSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 00000000000..62c5a75b293 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,11 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: + - enabled: 1 + path: Assets/Scenes/SampleScene.unity + guid: 2cda990e2423bbf4892e6590ba056729 + m_configObjects: {} diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/EditorSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/EditorSettings.asset new file mode 100644 index 00000000000..3376fd8b501 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/EditorSettings.asset @@ -0,0 +1,21 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_ExternalVersionControlSupport: Visible Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 2 + m_DefaultBehaviorMode: 1 + m_SpritePackerMode: 4 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd + m_ProjectGenerationRootNamespace: + m_UserGeneratedProjectSuffix: + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/GraphicsSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 00000000000..b35e28eaf0f --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,60 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 16002, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/InputManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/InputManager.asset new file mode 100644 index 00000000000..25966468fff --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/InputManager.asset @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/NavMeshAreas.asset b/examples/csharp/HelloworldUnity/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 00000000000..c8fa1b5bd1e --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/NetworkManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/NetworkManager.asset new file mode 100644 index 00000000000..e9cd5781b1a --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/NetworkManager.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!149 &1 +NetworkManager: + m_ObjectHideFlags: 0 + m_DebugLevel: 0 + m_Sendrate: 15 + m_AssetToPrefab: {} diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/Physics2DSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 00000000000..8e9e0210986 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,55 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 3 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_VelocityThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_JobOptions: + serializedVersion: 2 + useMultithreading: 0 + useConsistencySorting: 0 + m_InterpolationPosesPerJob: 100 + m_NewContactsPerJob: 30 + m_CollideContactsPerJob: 100 + m_ClearFlagsPerJob: 200 + m_ClearBodyForcesPerJob: 200 + m_SyncDiscreteFixturesPerJob: 50 + m_SyncContinuousFixturesPerJob: 50 + m_FindNearestContactsPerJob: 100 + m_UpdateTriggerContactsPerJob: 100 + m_IslandSolverCostThreshold: 100 + m_IslandSolverBodyCostScale: 1 + m_IslandSolverContactCostScale: 10 + m_IslandSolverJointCostScale: 10 + m_IslandSolverBodiesPerJob: 50 + m_IslandSolverContactsPerJob: 50 + m_AutoSimulation: 1 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_CallbacksOnDisable: 1 + m_AutoSyncTransforms: 1 + m_AlwaysShowColliders: 0 + m_ShowColliderSleep: 1 + m_ShowColliderContacts: 0 + m_ShowColliderAABB: 0 + m_ContactArrowScale: 0.2 + m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} + m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} + m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} + m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/PresetManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/PresetManager.asset new file mode 100644 index 00000000000..0832099de85 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/PresetManager.asset @@ -0,0 +1,13 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + m_DefaultList: + - type: + m_NativeTypeID: 20 + m_ManagedTypePPtr: {fileID: 0} + m_ManagedTypeFallback: + defaultPresets: + - m_Preset: {fileID: 2655988077585873504, guid: bfcfc320427f8224bbb7a96f3d3aebad, + type: 2} diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/ProjectSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/ProjectSettings.asset new file mode 100644 index 00000000000..b1e2fb0a430 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,656 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 15 + productGUID: 2ed9f077cb8c7421b9d7c7fa18f3c25d + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: com.grpc.examples + productName: HelloworldUnity + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1024 + defaultScreenHeight: 768 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + m_MTRendering: 1 + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + iosAppInBackgroundBehavior: 0 + displayResolutionDialog: 1 + iosAllowHTTPDownload: 1 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidStartInFullscreen: 1 + androidRenderOutsideSafeArea: 0 + androidBlitType: 0 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 1 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 0 + graphicsJobs: 0 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + graphicsJobMode: 0 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 0 + vulkanEnableSetSRGBWrite: 0 + m_SupportedAspectRatios: + 4:3: 1 + 5:4: 1 + 16:10: 1 + 16:9: 1 + Others: 1 + bundleVersion: 0.1 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 0 + xboxOneEnable7thCore: 0 + isWsaHolographicRemotingEnabled: 0 + vrSettings: + cardboard: + depthFormat: 0 + enableTransitionView: 0 + daydream: + depthFormat: 0 + useSustainedPerformanceMode: 0 + enableVideoLayer: 0 + useProtectedVideoMemory: 0 + minimumSupportedHeadTracking: 0 + maximumSupportedHeadTracking: 1 + hololens: + depthFormat: 1 + depthBufferSharingEnabled: 0 + oculus: + sharedDepthBuffer: 0 + dashSupport: 0 + enable360StereoCapture: 0 + protectGraphicsMemory: 0 + enableFrameTimingStats: 0 + useHDRDisplay: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: + Android: com.grpc.examples + Standalone: com.Company.ProductName + iOS: com.jattermusch.grpc.example + buildNumber: {} + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 16 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 1 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 989 + iOSTargetOSVersionString: 9.0 + tvOSSdkVersion: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 9.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + iPhoneSplashScreen: {fileID: 0} + iPhoneHighResSplashScreen: {fileID: 0} + iPhoneTallHighResSplashScreen: {fileID: 0} + iPhone47inSplashScreen: {fileID: 0} + iPhone55inPortraitSplashScreen: {fileID: 0} + iPhone55inLandscapeSplashScreen: {fileID: 0} + iPhone58inPortraitSplashScreen: {fileID: 0} + iPhone58inLandscapeSplashScreen: {fileID: 0} + iPadPortraitSplashScreen: {fileID: 0} + iPadHighResPortraitSplashScreen: {fileID: 0} + iPadLandscapeSplashScreen: {fileID: 0} + iPadHighResLandscapeSplashScreen: {fileID: 0} + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSUseLaunchScreenStoryboard: 0 + iOSLaunchScreenCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + iOSRenderExtraFrameOnPause: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + appleEnableProMotion: 0 + clonedFromGUID: 5f34be1353de5cf4398729fda238591b + templatePackageId: com.unity.template.2d@1.0.1 + templateDefaultScene: Assets/Scenes/SampleScene.unity + AndroidTargetArchitectures: 5 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: + AndroidKeyaliasName: + AndroidBuildApkPerCpuArchitecture: 0 + AndroidTVCompatibility: 1 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + resolutionDialogBanner: {fileID: 0} + m_BuildTargetIcons: [] + m_BuildTargetPlatformIcons: + - m_BuildTarget: Android + m_Icons: + - m_Textures: [] + m_Width: 432 + m_Height: 432 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 324 + m_Height: 324 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 216 + m_Height: 216 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 162 + m_Height: 162 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 108 + m_Height: 108 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 81 + m_Height: 81 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 1 + m_SubKind: + m_BuildTargetBatching: [] + m_BuildTargetGraphicsAPIs: [] + m_BuildTargetVRSettings: [] + m_BuildTargetEnableVuforiaSettings: [] + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: [] + m_BuildTargetGroupLightmapSettings: [] + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchTouchScreenUsage: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSupportedNpadStyles: 3 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 0 + switchSupportedNpadCount: 8 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchPlayerConnectionEnabled: 1 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + resetTempFolder: 1 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + monoEnv: + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + spritePackerPolicy: + webGLMemorySize: 256 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLDataCaching: 1 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLLinkerTarget: 1 + webGLThreadsSupport: 0 + scriptingDefineSymbols: {} + platformArchitecture: {} + scriptingBackend: + Android: 1 + il2cppCompilerConfiguration: {} + managedStrippingLevel: {} + incrementalIl2cppBuild: {} + allowUnsafeCode: 0 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + apiCompatibilityLevelPerPlatform: + Android: 3 + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: Template_2D + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: Template_2D + wsaImages: {} + metroTileShortName: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroSupportStreamingInstall: 0 + metroLastRequiredScene: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, + a: 1} + metroSplashScreenUseBackgroundColor: 0 + platformCapabilities: {} + metroTargetDeviceFamilies: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + metroCompilationOverrides: 1 + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnableGPUVariability: 0 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + xboxOneScriptCompiler: 0 + XboxOneOverrideIdentityName: + vrEditorSettings: + daydream: + daydreamIconForeground: {fileID: 0} + daydreamIconBackground: {fileID: 0} + cloudServicesEnabled: + UNet: 1 + luminIcon: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: + luminCert: + m_CertPath: + m_PrivateKeyPath: + luminIsChannelApp: 0 + luminVersion: + m_VersionCode: 1 + m_VersionName: + facebookSdkVersion: 7.9.4 + facebookAppId: + facebookCookies: 1 + facebookLogging: 1 + facebookStatus: 1 + facebookXfbml: 0 + facebookFrictionlessRequests: 1 + apiCompatibilityLevel: 3 + cloudProjectId: + framebufferDepthMemorylessMode: 0 + projectName: + organizationId: + cloudEnabled: 0 + enableNativePlatformBackendsForNewInputSystem: 0 + disableOldInputManagerSupport: 0 + legacyClampBlendShapeWeights: 1 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt b/examples/csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt new file mode 100644 index 00000000000..acd2ceba1e4 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt @@ -0,0 +1 @@ +m_EditorVersion: 2018.3.3f1 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/QualitySettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/QualitySettings.asset new file mode 100644 index 00000000000..b055962bcac --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/QualitySettings.asset @@ -0,0 +1,191 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 3 + m_QualitySettings: + - serializedVersion: 2 + name: Very Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 1 + textureQuality: 1 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.3 + maximumLODLevel: 0 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.4 + maximumLODLevel: 0 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Medium + pixelLightCount: 1 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 0.7 + maximumLODLevel: 0 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: High + pixelLightCount: 2 + shadows: 0 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 1 + maximumLODLevel: 0 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Very High + pixelLightCount: 3 + shadows: 0 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 70 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 1.5 + maximumLODLevel: 0 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Ultra + pixelLightCount: 4 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 4 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: + Android: 2 + Nintendo 3DS: 5 + Nintendo Switch: 5 + PS4: 5 + PSM: 5 + PSP2: 2 + Standalone: 5 + Tizen: 2 + WebGL: 3 + WiiU: 5 + Windows Store Apps: 5 + XboxOne: 5 + iPhone: 2 + tvOS: 2 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/TagManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/TagManager.asset new file mode 100644 index 00000000000..3281f1b528b --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/TagManager.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/TimeManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/TimeManager.asset new file mode 100644 index 00000000000..06bcc6d2953 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.1 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/UnityConnectSettings.asset b/examples/csharp/HelloworldUnity/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 00000000000..06db74a9444 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 1 + m_Enabled: 1 + m_TestMode: 0 + m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events + m_EventUrl: https://cdp.cloud.unity3d.com/v1/events + m_ConfigUrl: https://config.uca.cloud.unity3d.com + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com + m_Enabled: 0 + m_LogBufferSize: 10 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 1 + m_TestMode: 0 + m_InitializeOnStartup: 1 + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/VFXManager.asset b/examples/csharp/HelloworldUnity/ProjectSettings/VFXManager.asset new file mode 100644 index 00000000000..6e0eaca40d5 --- /dev/null +++ b/examples/csharp/HelloworldUnity/ProjectSettings/VFXManager.asset @@ -0,0 +1,11 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!937362698 &1 +VFXManager: + m_ObjectHideFlags: 0 + m_IndirectShader: {fileID: 0} + m_CopyBufferShader: {fileID: 0} + m_SortShader: {fileID: 0} + m_RenderPipeSettingsPath: + m_FixedTimeStep: 0.016666668 + m_MaxDeltaTime: 0.05 diff --git a/examples/csharp/HelloworldUnity/UIElementsSchema/UIElements.xsd b/examples/csharp/HelloworldUnity/UIElementsSchema/UIElements.xsd new file mode 100644 index 00000000000..1131a5105bf --- /dev/null +++ b/examples/csharp/HelloworldUnity/UIElementsSchema/UIElements.xsd @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.Experimental.UIElements.xsd b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.Experimental.UIElements.xsd new file mode 100644 index 00000000000..f2374e87007 --- /dev/null +++ b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.Experimental.UIElements.xsd @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.PackageManager.UI.xsd b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.PackageManager.UI.xsd new file mode 100644 index 00000000000..117194aa38a --- /dev/null +++ b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEditor.PackageManager.UI.xsd @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEngine.Experimental.UIElements.xsd b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEngine.Experimental.UIElements.xsd new file mode 100644 index 00000000000..0c074b23ba9 --- /dev/null +++ b/examples/csharp/HelloworldUnity/UIElementsSchema/UnityEngine.Experimental.UIElements.xsd @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From db598a6cd0ccee801d5d415630a58c1f2104f89c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Feb 2019 19:10:42 +0100 Subject: [PATCH 339/814] Add HelloworldUnity readme --- examples/csharp/HelloworldUnity/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 examples/csharp/HelloworldUnity/README.md diff --git a/examples/csharp/HelloworldUnity/README.md b/examples/csharp/HelloworldUnity/README.md new file mode 100644 index 00000000000..ec489e94998 --- /dev/null +++ b/examples/csharp/HelloworldUnity/README.md @@ -0,0 +1,19 @@ +gRPC C# on Unity +======================== + +EXPERIMENTAL ONLY +------------- +Support of the Unity platform is currently experimental. + +PREREQUISITES +------------- + +- Unity 2018.3.5f1 + +BUILD +------- + +- Follow instructions in https://github.com/grpc/grpc/tree/master/src/csharp/experimental#unity to obtain the grpc_csharp_unity.zip + that contains gRPC C# for Unity. Unzip it under `Assets/Plugins` directory. +- Open the `HelloworldUnity.sln` in Unity Editor. +- Build using Unity Editor. From 022d71ecc5209b0b39335845df63949b808a6c1d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 12 Feb 2019 11:20:31 +0100 Subject: [PATCH 340/814] Unity example improvements --- .../Assets/Scripts/HelloWorldScript.cs | 98 +++---------------- .../Assets/Scripts/HelloWorldTest.cs | 63 ++++++++++++ .../Assets/Scripts/HelloWorldTest.cs.meta | 11 +++ 3 files changed, 87 insertions(+), 85 deletions(-) create mode 100644 examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs create mode 100644 examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs.meta diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs index 6d318bcc348..df3ce8929e1 100644 --- a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs @@ -1,92 +1,20 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; +using UnityEngine; using UnityEngine.UI; -using Helloworld; -using System.Threading.Tasks; - -using System; - -using UnityEngine.SceneManagement; - -using Grpc.Core; - public class HelloWorldScript : MonoBehaviour { - const int Port = 50051; - int counter = 1; - // Use this for initialization - void Start () { - //Console.WriteLine("dfsdfadfffa dfasfa"); - - - } + int counter = 1; - public void RunHelloWorld(Text text) - { - //Debug.Log("dfasfa"); - //var channel = new Channel("localhost:12345", ChannelCredentials.Insecure); - //SceneManager.LoadScene("RocketMouse"); + // Use this for initialization + void Start () {} + // Update is called once per frame + void Update() {} - //var unityApplicationClass = Type.GetType("UnityEngine.Application, UnityEngine"); - // Consult value of Application.platform via reflection - // https://docs.unity3d.com/ScriptReference/Application-platform.html - // var platformProperty = unityApplicationClass.GetTypeInfo().GetProperty("platform"); - // var unityRuntimePlatform = platformProperty?.GetValue(null)?.ToString(); - //var isUnityIOS = (unityRuntimePlatform == "IPhonePlayer"); - - var t = Type.GetType("UnityEngine.Application, UnityEngine"); - var propInfo = t.GetProperty("platform"); - var reflPlatform = propInfo.GetValue(null).ToString(); - - - Debug.Log("Appl. platform:" + Application.platform); - Debug.Log("Appl. platform:" + reflPlatform); - Debug.Log("Environment.OSVersion: " + Environment.OSVersion); - - - Server server = new Server - { - Services = { Greeter.BindService(new GreeterImpl()) }, - Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } - }; - server.Start(); - - Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure); - - var client = new Greeter.GreeterClient(channel); - String user = "Unity " + counter; - - var reply = client.SayHello(new HelloRequest { Name = user }); - - - text.text = "Greeting: " + reply.Message; - - channel.ShutdownAsync().Wait(); - - server.ShutdownAsync().Wait(); - - counter ++; - - - - //Debug.Log("channel: created channel"); - - - } - - // Update is called once per frame - void Update () { - - } - - class GreeterImpl : Greeter.GreeterBase - { - // Server side handler of the SayHello RPC - public override Task SayHello(HelloRequest request, ServerCallContext context) - { - return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); - } - } + // Ran when button is clicked + public void RunHelloWorld(Text text) + { + var reply = HelloWorldTest.Greet("Unity " + counter); + text.text = "Greeting: " + reply.Message; + counter++; + } } diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs new file mode 100644 index 00000000000..7138da751b5 --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs @@ -0,0 +1,63 @@ +using UnityEngine; +using System.Threading.Tasks; +using System; +using Grpc.Core; +using Helloworld; + +class HelloWorldTest +{ + // Can be run from commandline. + // Example command: + // "/Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -nographics -executeMethod HelloWorldTest.RunHelloWorld -logfile" + public static void RunHelloWorld() + { + Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None); + + Debug.Log("=============================================================="); + Debug.Log("Starting tests"); + Debug.Log("=============================================================="); + + Debug.Log("Application.platform: " + Application.platform); + Debug.Log("Environment.OSVersion: " + Environment.OSVersion); + + var reply = Greet("Unity"); + Debug.Log("Greeting: " + reply.Message); + + Debug.Log("=============================================================="); + Debug.Log("Tests finished successfully."); + Debug.Log("=============================================================="); + } + + public static HelloReply Greet(string greeting) + { + const int Port = 50051; + + Server server = new Server + { + Services = { Greeter.BindService(new GreeterImpl()) }, + Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } + }; + server.Start(); + + Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure); + + var client = new Greeter.GreeterClient(channel); + + var reply = client.SayHello(new HelloRequest { Name = greeting }); + + channel.ShutdownAsync().Wait(); + + server.ShutdownAsync().Wait(); + + return reply; + } + + class GreeterImpl : Greeter.GreeterBase + { + // Server side handler of the SayHello RPC + public override Task SayHello(HelloRequest request, ServerCallContext context) + { + return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); + } + } +} diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs.meta b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs.meta new file mode 100644 index 00000000000..f511815254a --- /dev/null +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c088e5dee11c45fc95e41b9281d55e2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From bf175db9ad0b0962a3a03f010b4a93e8ba5ead55 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 12 Feb 2019 11:27:51 +0100 Subject: [PATCH 341/814] upgrade ProjectVersion --- .../csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt b/examples/csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt index acd2ceba1e4..6128d74131b 100644 --- a/examples/csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt +++ b/examples/csharp/HelloworldUnity/ProjectSettings/ProjectVersion.txt @@ -1 +1 @@ -m_EditorVersion: 2018.3.3f1 +m_EditorVersion: 2018.3.5f1 From 623702da6e509b802e26eaa10f96f1d6380c2649 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 12 Feb 2019 16:56:43 +0100 Subject: [PATCH 342/814] add copyright headers --- .../Assets/Scripts/HelloWorldScript.cs | 58 ++++--- .../Assets/Scripts/HelloWorldTest.cs | 144 ++++++++++-------- 2 files changed, 119 insertions(+), 83 deletions(-) diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs index df3ce8929e1..0dad0f6a5ad 100644 --- a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldScript.cs @@ -1,20 +1,38 @@ -using UnityEngine; -using UnityEngine.UI; - -public class HelloWorldScript : MonoBehaviour { - int counter = 1; - - // Use this for initialization - void Start () {} - - // Update is called once per frame - void Update() {} - - // Ran when button is clicked - public void RunHelloWorld(Text text) - { - var reply = HelloWorldTest.Greet("Unity " + counter); - text.text = "Greeting: " + reply.Message; - counter++; - } -} +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using UnityEngine; +using UnityEngine.UI; + +public class HelloWorldScript : MonoBehaviour { + int counter = 1; + + // Use this for initialization + void Start () {} + + // Update is called once per frame + void Update() {} + + // Ran when button is clicked + public void RunHelloWorld(Text text) + { + var reply = HelloWorldTest.Greet("Unity " + counter); + text.text = "Greeting: " + reply.Message; + counter++; + } +} diff --git a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs index 7138da751b5..2c10f10a144 100644 --- a/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs +++ b/examples/csharp/HelloworldUnity/Assets/Scripts/HelloWorldTest.cs @@ -1,63 +1,81 @@ -using UnityEngine; -using System.Threading.Tasks; -using System; -using Grpc.Core; -using Helloworld; - -class HelloWorldTest -{ - // Can be run from commandline. - // Example command: - // "/Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -nographics -executeMethod HelloWorldTest.RunHelloWorld -logfile" - public static void RunHelloWorld() - { - Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None); - - Debug.Log("=============================================================="); - Debug.Log("Starting tests"); - Debug.Log("=============================================================="); - - Debug.Log("Application.platform: " + Application.platform); - Debug.Log("Environment.OSVersion: " + Environment.OSVersion); - - var reply = Greet("Unity"); - Debug.Log("Greeting: " + reply.Message); - - Debug.Log("=============================================================="); - Debug.Log("Tests finished successfully."); - Debug.Log("=============================================================="); - } - - public static HelloReply Greet(string greeting) - { - const int Port = 50051; - - Server server = new Server - { - Services = { Greeter.BindService(new GreeterImpl()) }, - Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } - }; - server.Start(); - - Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure); - - var client = new Greeter.GreeterClient(channel); - - var reply = client.SayHello(new HelloRequest { Name = greeting }); - - channel.ShutdownAsync().Wait(); - - server.ShutdownAsync().Wait(); - - return reply; - } - - class GreeterImpl : Greeter.GreeterBase - { - // Server side handler of the SayHello RPC - public override Task SayHello(HelloRequest request, ServerCallContext context) - { - return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); - } - } -} +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using UnityEngine; +using System.Threading.Tasks; +using System; +using Grpc.Core; +using Helloworld; + +class HelloWorldTest +{ + // Can be run from commandline. + // Example command: + // "/Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -nographics -executeMethod HelloWorldTest.RunHelloWorld -logfile" + public static void RunHelloWorld() + { + Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None); + + Debug.Log("=============================================================="); + Debug.Log("Starting tests"); + Debug.Log("=============================================================="); + + Debug.Log("Application.platform: " + Application.platform); + Debug.Log("Environment.OSVersion: " + Environment.OSVersion); + + var reply = Greet("Unity"); + Debug.Log("Greeting: " + reply.Message); + + Debug.Log("=============================================================="); + Debug.Log("Tests finished successfully."); + Debug.Log("=============================================================="); + } + + public static HelloReply Greet(string greeting) + { + const int Port = 50051; + + Server server = new Server + { + Services = { Greeter.BindService(new GreeterImpl()) }, + Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } + }; + server.Start(); + + Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure); + + var client = new Greeter.GreeterClient(channel); + + var reply = client.SayHello(new HelloRequest { Name = greeting }); + + channel.ShutdownAsync().Wait(); + + server.ShutdownAsync().Wait(); + + return reply; + } + + class GreeterImpl : Greeter.GreeterBase + { + // Server side handler of the SayHello RPC + public override Task SayHello(HelloRequest request, ServerCallContext context) + { + return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); + } + } +} From 1af046e7239a295d9c16823c98cfae52f936898b Mon Sep 17 00:00:00 2001 From: Jean de Klerk Date: Mon, 11 Feb 2019 10:29:57 -0700 Subject: [PATCH 343/814] docs: enumerate status codes in statuscodes.md statuscodes.md is one of the top search results for "grpc status codes", right behind codes.proto. Since this is a landing page for many people*, and since the title and description of this page purports to be the generic status codes documentation page, it seems like a good idea to define terms before using them. * Many people who are new to grpc/protobuf, for example, will be more accustomed to and choose markdown files over .proto files. --- doc/statuscodes.md | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/doc/statuscodes.md b/doc/statuscodes.md index 547da054951..3d4d87e931a 100644 --- a/doc/statuscodes.md +++ b/doc/statuscodes.md @@ -1,13 +1,35 @@ # Status codes and their use in gRPC -gRPC uses a set of well defined status codes as part of the RPC API. All -RPCs started at a client return a `status` object composed of an integer +gRPC uses a set of well defined status codes as part of the RPC API. These +statuses are defined as such: + +| Code | Number | Description | Closest HTTP Mapping | +|------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------| +| OK | 0 | Not an error; returned on success. | 200 OK | +| CANCELLED | 1 | The operation was cancelled, typically by the caller. | 499 Client Closed Request | +| UNKNOWN | 2 | Unknown error. For example, this error may be returned when a `Status` value received from another address space belongs to an error space that is not known in this address space. Also errors raised by APIs that do not return enough error information may be converted to this error. | 500 Internal Server Error | +| INVALID_ARGUMENT | 3 | The client specified an invalid argument. Note that this differs from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments that are problematic regardless of the state of the system (e.g., a malformed file name). | 400 Bad Request | +| DEADLINE_EXCEEDED | 4 | The deadline expired before the operation could complete. For operations that change the state of the system, this error may be returned even if the operation has completed successfully. For example, a successful response from a server could have been delayed long | 504 Gateway Timeout | +| NOT_FOUND | 5 | Some requested entity (e.g., file or directory) was not found. Note to server developers: if a request is denied for an entire class of users, such as gradual feature rollout or undocumented whitelist, `NOT_FOUND` may be used. If a request is denied for some users within a class of users, such as user-based access control, `PERMISSION_DENIED` must be used. | 404 Not Found | +| ALREADY_EXISTS | 6 | The entity that a client attempted to create (e.g., file or directory) already exists. | 409 Conflict | +| PERMISSION_DENIED | 7 | The caller does not have permission to execute the specified operation. `PERMISSION_DENIED` must not be used for rejections caused by exhausting some resource (use `RESOURCE_EXHAUSTED` instead for those errors). `PERMISSION_DENIED` must not be used if the caller can not be identified (use `UNAUTHENTICATED` instead for those errors). This error code does not imply the request is valid or the requested entity exists or satisfies other pre-conditions. | 403 Forbidden | +| UNAUTHENTICATED | 16 | The request does not have valid authentication credentials for the operation. | 401 Unauthorized | +| RESOURCE_EXHAUSTED | 8 | Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space. | 429 Too Many Requests | +| FAILED_PRECONDITION | 9 | The operation was rejected because the system is not in a state required for the operation's execution. For example, the directory to be deleted is non-empty, an rmdir operation is applied to a non-directory, etc. Service implementors can use the following guidelines to decide between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`: (a) Use `UNAVAILABLE` if the client can retry just the failing call. (b) Use `ABORTED` if the client should retry at a higher level (e.g., when a client-specified test-and-set fails, indicating the client should restart a read-modify-write sequence). (c) Use `FAILED_PRECONDITION` if the client should not retry until the system state has been explicitly fixed. E.g., if an "rmdir" fails because the directory is non-empty, `FAILED_PRECONDITION` should be returned since the client should not retry unless the files are deleted from the directory. | 400 Bad Request | +| ABORTED | 10 | The operation was aborted, typically due to a concurrency issue such as a sequencer check failure or transaction abort. See the guidelines above for deciding between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`. | 409 Conflict | +| OUT_OF_RANGE | 11 | The operation was attempted past the valid range. E.g., seeking or reading past end-of-file. Unlike `INVALID_ARGUMENT`, this error indicates a problem that may be fixed if the system state changes. For example, a 32-bit file system will generate `INVALID_ARGUMENT` if asked to read at an offset that is not in the range [0,2^32-1], but it will generate `OUT_OF_RANGE` if asked to read from an offset past the current file size. There is a fair bit of overlap between `FAILED_PRECONDITION` and `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific error) when it applies so that callers who are iterating through a space can easily look for an `OUT_OF_RANGE` error to detect when they are done. | 400 Bad Request | +| UNIMPLEMENTED | 12 | The operation is not implemented or is not supported/enabled in this service. | 501 Not Implemented | +| INTERNAL | 13 | Internal errors. This means that some invariants expected by the underlying system have been broken. This error code is reserved for serious errors. | 500 Internal Server Error | +| UNAVAILABLE | 14 | The service is currently unavailable. This is most likely a transient condition, which can be corrected by retrying with a backoff. | 503 Service Unavailable | +| DATA_LOSS | 15 | Unrecoverable data loss or corruption. | 500 Internal Server Error | + +All RPCs started at a client return a `status` object composed of an integer `code` and a string `message`. The server-side can choose the status it returns for a given RPC. The gRPC client and server-side implementations may also generate and -return `status` on their own when errors happen. Only a subset of -the pre-defined status codes are generated by the gRPC libraries. This +return `status` on their own when errors happen. Only a subset of +the pre-defined status codes are generated by the gRPC libraries. This allows applications to be sure that any other code it sees was actually returned by the application (although it is also possible for the server-side to return one of the codes generated by the gRPC libraries). @@ -49,4 +71,4 @@ The following status codes are never generated by the library: - OUT_OF_RANGE - DATA_LOSS -Applications that may wish to [retry](https://github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried. +Applications that may wish to [retry](https:github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried. From ea3fd88ecad973a262293b4f7086d8c8150a9fc3 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 12 Feb 2019 14:12:04 -0800 Subject: [PATCH 344/814] debug printout for testing --- tools/run_tests/python_utils/upload_rbe_results.py | 3 +++ 1 file changed, 3 insertions(+) mode change 100644 => 100755 tools/run_tests/python_utils/upload_rbe_results.py diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py old mode 100644 new mode 100755 index 6ae8af7787e..fa8a2612bda --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -120,6 +120,9 @@ def _get_resultstore_data(api_key, invocation_id): # that limit, the 'nextPageToken' field is included in the request to get # subsequent data, so keep requesting until 'nextPageToken' field is omitted. while True: + print(invocation_id) + print(api_key) + print(page_token) req = urllib2.Request( url= 'https://resultstore.googleapis.com/v2/invocations/%s/targets/-/configuredTargets/-/actions?key=%s&pageToken=%s&fields=id,status_attributes,timing,test_action' From bf8bef9c78b5ba70cbeadbb835dbe6bfe1357f90 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 12 Feb 2019 15:10:53 -0800 Subject: [PATCH 345/814] Add retries for check_on_pr --- tools/run_tests/python_utils/check_on_pr.py | 32 ++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index 3f335c8ea93..62ea9a873e8 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -14,6 +14,7 @@ from __future__ import print_function import os +import sys import json import time import datetime @@ -27,6 +28,8 @@ _GITHUB_APP_ID = 22338 _INSTALLATION_ID = 519109 _ACCESS_TOKEN_CACHE = None +_ACCESS_TOKEN_FETCH_RETRIES = 5 +_ACCESS_TOKEN_FETCH_RETRIES_INTERVAL_S = 1 def _jwt_token(): @@ -46,13 +49,28 @@ def _jwt_token(): def _access_token(): global _ACCESS_TOKEN_CACHE if _ACCESS_TOKEN_CACHE == None or _ACCESS_TOKEN_CACHE['exp'] < time.time(): - resp = requests.post( - url='https://api.github.com/app/installations/%s/access_tokens' % - _INSTALLATION_ID, - headers={ - 'Authorization': 'Bearer %s' % _jwt_token().decode('ASCII'), - 'Accept': 'application/vnd.github.machine-man-preview+json', - }) + for i in range(_ACCESS_TOKEN_FETCH_RETRIES): + resp = requests.post( + url='https://api.github.com/app/installations/%s/access_tokens' + % _INSTALLATION_ID, + headers={ + 'Authorization': 'Bearer %s' % _jwt_token().decode('ASCII'), + 'Accept': 'application/vnd.github.machine-man-preview+json', + }) + if resp.status_code == 200: + break + else: + print("Fetch access token from Github API failed:") + print(resp.json()) + if i != _ACCESS_TOKEN_FETCH_RETRIES - 1: + print('Retrying after %.2f second.' % + _ACCESS_TOKEN_FETCH_RETRIES_INTERVAL_S) + time.sleep(_ACCESS_TOKEN_FETCH_RETRIES_INTERVAL_S) + + if resp.status_code != 200: + print("error: Unable to fetch access token, exiting...") + sys.exit(1) + _ACCESS_TOKEN_CACHE = { 'token': resp.json()['token'], 'exp': time.time() + 60 From 3e30c38f1cc4a6f522b0487efef5119ccbb8954d Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 13 Feb 2019 00:20:50 +0100 Subject: [PATCH 346/814] Adressing comments. --- include/grpcpp/channel.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h index a2eba75c891..05a45680916 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -21,8 +21,6 @@ #include -struct grpc_channel; - namespace grpc { typedef ::grpc_impl::Channel Channel; From 63aa8e1d7361cd9d3b96319eb299391d6581946b Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 12 Feb 2019 15:27:50 -0800 Subject: [PATCH 347/814] clang-format --- src/core/lib/surface/init.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 7708f6495fe..fca85ac876a 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -178,8 +178,7 @@ void grpc_shutdown_internal(void* ignored) { grpc_core::ExecCtx exec_ctx(0); grpc_iomgr_shutdown_background_closure(); { - grpc_timer_manager_set_threading( - false); // shutdown timer_manager thread + grpc_timer_manager_set_threading(false); // shutdown timer_manager thread grpc_core::Executor::ShutdownAll(); for (i = g_number_of_plugins; i >= 0; i--) { if (g_all_of_the_plugins[i].destroy != nullptr) { From b2bec4aa0c05b424339e6c791997da227d0317a7 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 12 Feb 2019 15:36:50 -0800 Subject: [PATCH 348/814] Add environment markers to python2-only dependencies --- setup.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 7f58e7ca070..f533e7b77cf 100644 --- a/setup.py +++ b/setup.py @@ -298,12 +298,11 @@ PACKAGE_DIRECTORIES = { } INSTALL_REQUIRES = ( - 'six>=1.5.2', + "six>=1.5.2", + "futures>=2.2.0; python_version<'3.2'", + "enum34>=1.0.4; python_version<'3.4'", ) -if not PY3: - INSTALL_REQUIRES += ('futures>=2.2.0', 'enum34>=1.0.4') - SETUP_REQUIRES = INSTALL_REQUIRES + ( 'Sphinx~=1.8.1', 'six>=1.10', From 63544ea3aed728ad5c70fad2c1fdfcfb1ddf63e4 Mon Sep 17 00:00:00 2001 From: Jerry Date: Tue, 29 Jan 2019 12:59:54 -0800 Subject: [PATCH 349/814] memory leak test for php --- src/php/bin/run_tests.sh | 7 + .../tests/MemoryLeakTest/MemoryLeakTest.php | 2300 +++++++++++++++++ src/php/tests/unit_tests/CallTest.php | 10 + .../tools/dockerfile/php_valgrind.include | 7 + .../test/php7_jessie_x64/Dockerfile.template | 1 + .../test/php_jessie_x64/Dockerfile.template | 1 + .../test/php7_jessie_x64/Dockerfile | 7 + .../dockerfile/test/php_jessie_x64/Dockerfile | 7 + 8 files changed, 2340 insertions(+) create mode 100644 src/php/tests/MemoryLeakTest/MemoryLeakTest.php create mode 100644 templates/tools/dockerfile/php_valgrind.include diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh index 295bcb2430c..39ef669190e 100755 --- a/src/php/bin/run_tests.sh +++ b/src/php/bin/run_tests.sh @@ -28,3 +28,10 @@ php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ ../tests/unit_tests/PersistentChannelTests +export ZEND_DONT_UNLOAD_MODULES=1 +export USE_ZEND_ALLOC=0 +# Detect whether valgrind is executable +if [ -x "$(command -v valgrind)" ]; then + valgrind --error-exitcode=10 --leak-check=yes php $extension_dir -d max_execution_time=300 \ + ../tests/MemoryLeakTest/MemoryLeakTest.php +fi diff --git a/src/php/tests/MemoryLeakTest/MemoryLeakTest.php b/src/php/tests/MemoryLeakTest/MemoryLeakTest.php new file mode 100644 index 00000000000..62ba3295504 --- /dev/null +++ b/src/php/tests/MemoryLeakTest/MemoryLeakTest.php @@ -0,0 +1,2300 @@ + "v1"]; +} + +function assertConnecting($state) +{ + assert(($state == GRPC\CHANNEL_CONNECTING || $state == GRPC\CHANNEL_TRANSIENT_FAILURE) == true); +} + +function waitUntilNotIdle($channel) { + for ($i = 0; $i < 10; $i++) { + $now = Grpc\Timeval::now(); + $deadline = $now->add(new Grpc\Timeval(10000)); + if ($channel->watchConnectivityState(GRPC\CHANNEL_IDLE, + $deadline)) { + return true; + } + } + assert(true == false); +} + +// Set up +$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + +// Test InsecureCredentials +assert('Grpc\Channel' == get_class($channel)); + +// Test ConnectivityState +$state = $channel->getConnectivityState(); +assert(0 == $state); + +// Test GetConnectivityStateWithInt +$state = $channel->getConnectivityState(123); +assert(0 == $state); + +// Test GetConnectivityStateWithString +$state = $channel->getConnectivityState('hello'); +assert(0 == $state); + +// Test GetConnectivityStateWithBool +$state = $channel->getConnectivityState(true); +assert(0 == $state); + +$channel->close(); + +// Test GetTarget +$channel = new Grpc\Channel('localhost:8888', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); +$target = $channel->getTarget(); +assert(is_string($target) == true); +$channel->close(); + +// Test WatchConnectivityState +$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); +$now = Grpc\Timeval::now(); +$deadline = $now->add(new Grpc\Timeval(100*1000)); + +$state = $channel->watchConnectivityState(1, $deadline); +assert($state == true); + +unset($now); +unset($deadline); + +$channel->close(); + +// Test InvalidConstructorWithNull +try { + $channel = new Grpc\Channel(); + assert($channel == NULL); +} +catch (\Exception $e) { +} + +// Test InvalidConstructorWith +try { + $channel = new Grpc\Channel('localhost:0', 'invalid'); + assert($channel == NULL); +} +catch (\Exception $e) { +} + +// Test InvalideCredentials +try { + $channel = new Grpc\Channel('localhost:0', ['credentials' => new Grpc\Timeval(100)]); +} +catch (\Exception $e) { +} + +// Test InvalidOptionsArrray +try { + $channel = new Grpc\Channel('localhost:0', ['abc' => []]); +} +catch (\Exception $e) { +} + +// Test InvalidGetConnectivityStateWithArray +$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); +try { + $channel->getConnectivityState([]); +} +catch (\Exception $e) { +} + +// Test InvalidWatchConnectivityState +try { + $channel->watchConnectivityState([]); +} +catch (\Exception $e) { +} + +// Test InvalidWatchConnectivityState2 +try { + $channel->watchConnectivityState(1, 'hi'); +} +catch (\Exception $e) { +} + +$channel->close(); + +// Test PersistentChannelSameHost +$channel1 = new Grpc\Channel('localhost:1', []); +$channel2 = new Grpc\Channel('localhost:1', []); +$state = $channel1->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelDifferentHost +$channel1 = new Grpc\Channel('localhost:1', ["grpc_target_persist_bound" => 3,]); +$channel2 = new Grpc\Channel('localhost:2', []); +$state = $channel1->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelSameArgs +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 3, + "abc" => "def", + ]); +$channel2 = new Grpc\Channel('localhost:1', ["abc" => "def"]); +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelDifferentArgs +$channel1 = new Grpc\Channel('localhost:1', []); +$channel2 = new Grpc\Channel('localhost:1', ["abc" => "def"]); +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelSameChannelCredentials +$creds1 = Grpc\ChannelCredentials::createSsl(); +$creds2 = Grpc\ChannelCredentials::createSsl(); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => $creds1, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => $creds2]); + +$state = $channel1->getConnectivityState(true); +print "state: ".$state."......................"; +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelDifferentChannelCredentials +$creds1 = Grpc\ChannelCredentials::createSsl(); +$creds2 = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => $creds1, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => $creds2]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + + +// Test PersistentChannelSameChannelCredentialsRootCerts +$creds1 = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); +$creds2 = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => $creds1, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => $creds2]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelDifferentSecureChannelCredentials +$creds1 = Grpc\ChannelCredentials::createSsl(); +$creds2 = Grpc\ChannelCredentials::createInsecure(); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => $creds1, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => $creds2]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelSharedChannelClose1 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 3, +]); +$channel2 = new Grpc\Channel('localhost:1', []); + +$channel1->close(); + +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$channel2->close(); + +// Test PersistentChannelSharedChannelClose2 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 3, +]); +$channel2 = new Grpc\Channel('localhost:1', []); + +$channel1->close(); + +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +try{ + $state = $channel1->getConnectivityState(); +} +catch(\Exception $e){ +} + +$channel2->close(); + +//Test PersistentChannelCreateAfterClose +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 3, +]); + +$channel1->close(); + +$channel2 = new Grpc\Channel('localhost:1', []); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel2->close(); + +//Test PersistentChannelSharedMoreThanTwo +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 3, +]); +$channel2 = new Grpc\Channel('localhost:1', []); +$channel3 = new Grpc\Channel('localhost:1', []); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); +$state = $channel3->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); + +//Test PersistentChannelWithCallCredentials +$creds = Grpc\ChannelCredentials::createSsl(); +$callCreds = Grpc\CallCredentials::createFromPlugin( + 'callbackFunc'); +$credsWithCallCreds = Grpc\ChannelCredentials::createComposite( + $creds, $callCreds); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => + $credsWithCallCreds, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => + $credsWithCallCreds]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelWithDifferentCallCredentials +$callCreds1 = Grpc\CallCredentials::createFromPlugin('callbackFunc'); +$callCreds2 = Grpc\CallCredentials::createFromPlugin('callbackFunc2'); + +$creds1 = Grpc\ChannelCredentials::createSsl(); +$creds2 = Grpc\ChannelCredentials::createComposite( + $creds1, $callCreds1); +$creds3 = Grpc\ChannelCredentials::createComposite( + $creds1, $callCreds2); + +$channel1 = new Grpc\Channel('localhost:1', + ["credentials" => $creds1, + "grpc_target_persist_bound" => 3, + ]); +$channel2 = new Grpc\Channel('localhost:1', + ["credentials" => $creds2]); +$channel3 = new Grpc\Channel('localhost:1', + ["credentials" => $creds3]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$state = $channel3->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); +$channel3->close(); + +// Test PersistentChannelForceNew +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', + ["force_new" => true]); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelForceNewOldChannelIdle1 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', + ["force_new" => true]); +$channel3 = new Grpc\Channel('localhost:1', []); + +$state = $channel2->getConnectivityState(true); +waitUntilNotIdle($channel2); +$state = $channel1->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); +$state = $channel3->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelForceNewOldChannelIdle2 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', []); + +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel2); +$state = $channel1->getConnectivityState(); +assertConnecting($state); +$state = $channel2->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); +$channel2->close(); + +// Test PersistentChannelForceNewOldChannelClose1 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', + ["force_new" => true]); +$channel3 = new Grpc\Channel('localhost:1', []); + +$channel1->close(); + +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); +$state = $channel3->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +$channel2->close(); +$channel3->close(); + +// Test PersistentChannelForceNewOldChannelClose2 +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', + ["force_new" => true]); +// channel3 shares with channel1 +$channel3 = new Grpc\Channel('localhost:1', []); + +$channel1->close(); + +$state = $channel2->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +// channel3 is still usable +$state = $channel3->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +// channel 1 is closed +try{ + $channel1->getConnectivityState(); +} +catch(\Exception $e){ +} + +$channel2->close(); +$channel3->close(); + +// Test PersistentChannelForceNewNewChannelClose +$channel1 = new Grpc\Channel('localhost:1', [ + "grpc_target_persist_bound" => 2, +]); +$channel2 = new Grpc\Channel('localhost:1', + ["force_new" => true]); +$channel3 = new Grpc\Channel('localhost:1', []); + +$channel2->close(); + +$state = $channel1->getConnectivityState(); +assert(GRPC\CHANNEL_IDLE == $state); + +// can still connect on channel1 +$state = $channel1->getConnectivityState(true); +waitUntilNotIdle($channel1); + +$state = $channel1->getConnectivityState(); +assertConnecting($state); + +$channel1->close(); + +//============== Call Test ==================== +$server = new Grpc\Server([]); +$port = $server->addHttp2Port('0.0.0.0:53000'); +$channel = new Grpc\Channel('localhost:'.$port, []); +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); + +// Test AddEmptyMetadata +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => [], +]; +$result = $call->startBatch($batch); +assert($result->send_metadata == true); + +// Test testAddSingleMetadata +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value']], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +$result = $call->startBatch($batch); +assert($result->send_metadata == true); + +// Test AddMultiValue +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value1', 'value2']], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +$result = $call->startBatch($batch); +assert($result->send_metadata == true); + +// Test AddSingleAndMultiValueMetadata +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], + 'key2' => ['value2', + 'value3', ], ], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +$result = $call->startBatch($batch); +assert($result->send_metadata == true); + +// Test AddMultiAndMultiValueMetadata +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], + 'key2' => ['value2', + 'value3', ], ], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +$result = $call->startBatch($batch); +assert($result->send_metadata == true); + +// Test GetPeer +assert(is_string($call->getPeer()) == true); + +// Test Cancel +assert($call->cancel == NULL); + +// Test InvalidStartBatchKey +$batch = [ + 'invalid' => ['key1' => 'value1'], +]; +try{ + $result = $call->startBatch($batch); +} +catch(\Exception $e){ +} + +// Test InvalideMetadataStrKey +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['Key' => ['value1', 'value2']], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +try{ + $result = $call->startBatch($batch); +} +catch(\Exception $e){ +} + +// Test InvalidMetadataIntKey +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => [1 => ['value1', 'value2']], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +try{ + $result = $call->startBatch($batch); +} +catch(\Exception $e){ +} + +// Test InvalidMetadataInnerValue +$batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key1' => 'value1'], +]; +$call = new Grpc\Call($channel, + '/foo', + Grpc\Timeval::infFuture()); +try{ + $result = $call->startBatch($batch); +} +catch(\Exception $e){ +} + +// Test InvalidConstuctor +try { + $call = new Grpc\Call(); +} catch (\Exception $e) {} + +// Test InvalidConstuctor2 +try { + $call = new Grpc\Call('hi', 'hi', 'hi'); +} catch (\Exception $e) {} + +// Test InvalidSetCredentials +try{ + $call->setCredentials('hi'); +} +catch(\Exception $e){ +} + +// Test InvalidSetCredentials2 +try { + $call->setCredentials([]); +} catch (\Exception $e) {} + + +//============== CallCredentials Test 2 ==================== +// Set Up +$credentials = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); +$server_credentials = Grpc\ServerCredentials::createSsl( + null, + file_get_contents(dirname(__FILE__).'/../data/server1.key'), + file_get_contents(dirname(__FILE__).'/../data/server1.pem')); +$server = new Grpc\Server(); +$port = $server->addSecureHttp2Port('0.0.0.0:0', + $server_credentials); +$server->start(); +$host_override = 'foo.test.google.fr'; +$channel = new Grpc\Channel( + 'localhost:'.$port, + [ + 'grpc.ssl_target_name_override' => $host_override, + 'grpc.default_authority' => $host_override, + 'credentials' => $credentials, + ] +); +function callCredscallbackFunc($context) +{ + is_string($context->service_url); + is_string($context->method_name); + return ['k1' => ['v1'], 'k2' => ['v2']]; +} + +// Test CreateFromPlugin +$deadline = Grpc\Timeval::infFuture(); +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + '/abc/dummy_method', + $deadline, + $host_override); + $call_credentials = Grpc\CallCredentials::createFromPlugin( + 'callCredscallbackFunc'); +$call->setCredentials($call_credentials); + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); + +$event = $server->requestCall(); +assert(is_array($event->metadata) == true); + +$metadata = $event->metadata; +assert(array_key_exists('k1', $metadata) == true); +assert(array_key_exists('k2', $metadata) == true); +assert($metadata['k1'] == ['v1']); +assert($metadata['k2'] == ['v2']); +assert('/abc/dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert($event->send_metadata == true); +assert($event->send_status == true); +assert($event->cancelled == false); + +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert([] == $event->metadata); + +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +function invalidKeyCallbackFunc($context) +{ + is_string($context->service_url); + is_string($context->method_name); + return ['K1' => ['v1']]; +} + +// Test CallbackWithInvalidKey +$deadline = Grpc\Timeval::infFuture(); +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + '/abc/dummy_method', + $deadline, + $host_override); + $call_credentials = Grpc\CallCredentials::createFromPlugin( + 'invalidKeyCallbackFunc'); +$call->setCredentials($call_credentials); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); +assert(($event->status->code == Grpc\STATUS_UNAVAILABLE) == true); + +function invalidReturnCallbackFunc($context) +{ + is_string($context->service_url); + is_string($context->method_name); + return 'a string'; +} + +// Test CallbackWithInvalidReturnValue +$deadline = Grpc\Timeval::infFuture(); +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + '/abc/dummy_method', + $deadline, + $host_override); + $call_credentials = Grpc\CallCredentials::createFromPlugin( + 'invalidReturnCallbackFunc'); +$call->setCredentials($call_credentials); + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); + +assert($event->send_metadata == true); +assert($event->send_close == true); +assert(($event->status->code == Grpc\STATUS_UNAVAILABLE) == true); + +unset($channel); +unset($server); + +//============== CallCredentials Test ==================== +//Set Up +$credentials = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); +$call_credentials = Grpc\CallCredentials::createFromPlugin('callbackFunc'); +$credentials = Grpc\ChannelCredentials::createComposite( + $credentials, + $call_credentials +); +$server_credentials = Grpc\ServerCredentials::createSsl( + null, + file_get_contents(dirname(__FILE__).'/../data/server1.key'), + file_get_contents(dirname(__FILE__).'/../data/server1.pem')); +$server = new Grpc\Server(); +$port = $server->addSecureHttp2Port('0.0.0.0:0', + $server_credentials); +$server->start(); +$host_override = 'foo.test.google.fr'; +$channel = new Grpc\Channel( + 'localhost:'.$port, + [ + 'grpc.ssl_target_name_override' => $host_override, + 'grpc.default_authority' => $host_override, + 'credentials' => $credentials, + ] +); + +// Test CreateComposite +$call_credentials2 = Grpc\CallCredentials::createFromPlugin('callbackFunc'); +$call_credentials3 = Grpc\CallCredentials::createComposite( + $call_credentials, + $call_credentials2 +); +assert('Grpc\CallCredentials' == get_class($call_credentials3)); + +// Test CreateFromPluginInvalidParam +try{ + $call_credentials = Grpc\CallCredentials::createFromPlugin( + 'callbackFunc' + ); +} +catch(\Exception $e){} + +// Test CreateCompositeInvalidParam +try{ + $call_credentials3 = Grpc\CallCredentials::createComposite( + $call_credentials, + $credentials + ); +} +catch(\Exception $e){} + +unset($channel); +unset($server); + + +//============== EndToEnd Test ==================== +// Set Up +$server = new Grpc\Server([]); +$port = $server->addHttp2Port('0.0.0.0:0'); +$channel = new Grpc\Channel('localhost:'.$port, []); +$server->start(); + +// Test SimpleRequestBody +$deadline = Grpc\Timeval::infFuture(); +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert($event->send_metadata == true); +assert($event->send_status == true); +assert($event->cancelled == false) +; + $event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +// Test MessageWriteFlags +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'message_write_flags_test'; +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $req_text, + 'flags' => Grpc\WRITE_NO_COMPRESS, ], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], +]); +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +$status = $event->status; + +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +// Test ClientServerFullRequestResponse +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +assert($event->send_metadata == true); +assert($event->send_close == true); +assert($event->send_message == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); +$server_call = $event->call; + +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert($event->send_metadata == true); +assert($event->send_status == true); +assert($event->send_message == true); +assert($event->cancelled == false); +assert($req_text == $event->message); + +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert([] == $event->metadata); +assert($reply_text == $event->message); +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +// Test InvalidClientMessageArray +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +try { + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => 'invalid', + ]); +} catch (\Exception $e) {} + +// Test InvalidClientMessageString +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +try{ + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => 0], + ]); +} catch (\Exception $e) {} + +// Test InvalidClientMessageFlags +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +try{ + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => 'abc', + 'flags' => 'invalid', + ], + ]); +} catch (\Exception $e) {} + +// Test InvalidServerStatusMetadata +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +assert($event->send_metadata == true); +assert($event->send_close == true); +assert($event->send_message == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); +$server_call = $event->call; +try { + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => 'invalid', + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); +} catch (\Exception $e) {} + +// Test InvalidServerStatusCode +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +assert($event->send_metadata == true); +assert($event->send_close == true); +assert($event->send_message == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); +$server_call = $event->call; +try { + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => 'invalid', + 'details' => $status_text, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); +} catch (\Exception $e) {} + +// Test MissingServerStatusCode +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +$event = $server->requestCall(); +$server_call = $event->call; +try { + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'details' => $status_text, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); +} catch (\Exception $e) {} + +// Test InvalidServerStatusDetails +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +$event = $server->requestCall(); +$server_call = $event->call; +try { + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => 0, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); +} catch (\Exception $e) {} + +// Test MissingServerStatusDetails +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +$event = $server->requestCall(); +$server_call = $event->call; +try { + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); +} catch (\Exception $e) {} + +// Test InvalidStartBatchKey +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +try { + $event = $call->startBatch([ + 9999999 => [], + ]); +} catch (\Exception $e) {} + +// Test InvalidStartBatch +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline); +try { + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => 'abc', + ], + ]); +} catch (\Exception $e) {} + +// Test GetTarget +assert(is_string($channel->getTarget()) == true); + +// Test GetConnectivityState +assert(($channel->getConnectivityState() == + Grpc\CHANNEL_IDLE) == true); + +// Test WatchConnectivityStateFailed +$idle_state = $channel->getConnectivityState(); +assert(($idle_state == Grpc\CHANNEL_IDLE) == true); + +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(50000); // should timeout +$deadline = $now->add($delta); +assert($channel->watchConnectivityState( + $idle_state, $deadline) == false); + +// Test WatchConnectivityStateSuccess() +$idle_state = $channel->getConnectivityState(true); +assert(($idle_state == Grpc\CHANNEL_IDLE) == true); + +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(3000000); // should finish well before +$deadline = $now->add($delta); +$new_state = $channel->getConnectivityState(); +assert($new_state != $idle_state); + +// Test WatchConnectivityStateDoNothing +$idle_state = $channel->getConnectivityState(); +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(50000); +$deadline = $now->add($delta); +assert(!$channel->watchConnectivityState( + $idle_state, $deadline)); + +$new_state = $channel->getConnectivityState(); +assert($new_state == Grpc\CHANNEL_IDLE); + +// Test GetConnectivityStateInvalidParam +try { + $channel->getConnectivityState(new Grpc\Timeval()); +} catch (\Exception $e) {} +// Test WatchConnectivityStateInvalidParam +try { + $channel->watchConnectivityState(0, 1000); +} catch (\Exception $e) {} +// Test ChannelConstructorInvalidParam +try { + $channel = new Grpc\Channel('localhost:'.$port, null); +} catch (\Exception $e) {} +// testClose() +$channel->close(); + + +//============== SecureEndToEnd Test ==================== +// Set Up + +$credentials = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); +$server_credentials = Grpc\ServerCredentials::createSsl( + null, + file_get_contents(dirname(__FILE__).'/../data/server1.key'), + file_get_contents(dirname(__FILE__).'/../data/server1.pem')); +$server = new Grpc\Server(); +$port = $server->addSecureHttp2Port('0.0.0.0:0', + $server_credentials); +$server->start(); +$host_override = 'foo.test.google.fr'; +$channel = new Grpc\Channel( + 'localhost:'.$port, + [ + 'grpc.ssl_target_name_override' => $host_override, + 'grpc.default_authority' => $host_override, + 'credentials' => $credentials, + ] +); + +// Test SimpleRequestBody +$deadline = Grpc\Timeval::infFuture(); +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline, + $host_override); + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert($event->send_metadata == true); +assert($event->send_status == true); +assert($event->cancelled == false); + +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert([] == $event->metadata); +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +// Test MessageWriteFlags +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'message_write_flags_test'; +$status_text = 'xyz'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline, + $host_override); + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $req_text, + 'flags' => Grpc\WRITE_NO_COMPRESS, ], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, +]); +assert($event->send_metadata == true); +assert($event->send_close == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], +]); +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert([] == $event->metadata); +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details);unset($call); + +unset($call); +unset($server_call); + +// Test ClientServerFullRequestResponse +$deadline = Grpc\Timeval::infFuture(); +$req_text = 'client_server_full_request_response'; +$reply_text = 'reply:client_server_full_request_response'; +$status_text = 'status:client_server_full_response_text'; +$call = new Grpc\Call($channel, + 'dummy_method', + $deadline, + $host_override); +$event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => ['message' => $req_text], +]); +assert($event->send_metadata == true); +assert($event->send_close == true); +assert($event->send_message == true); + +$event = $server->requestCall(); +assert('dummy_method' == $event->method); + +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert($event->send_metadata); +assert($event->send_status); +assert($event->send_message); +assert(!$event->cancelled); +assert($req_text == $event->message); + +$event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, +]); +assert([] == $event->metadata); +assert($reply_text == $event->message); +$status = $event->status; +assert([] == $status->metadata); +assert(Grpc\STATUS_OK == $status->code); +assert($status_text == $status->details); + +unset($call); +unset($server_call); + +$channel->close(); + + +//============== Timeval Test ==================== +// Test ConstructorWithInt +$time = new Grpc\Timeval(1234); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test ConstructorWithNegative +$time = new Grpc\Timeval(-123); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test ConstructorWithZero +$time = new Grpc\Timeval(0); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test ConstructorWithOct +$time = new Grpc\Timeval(0123); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test ConstructorWithHex +$time = new Grpc\Timeval(0x1A); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test ConstructorWithFloat +$time = new Grpc\Timeval(123.456); +assert($time != NULL); +assert('Grpc\Timeval' == get_class($time)); + +// Test CompareSame +$zero = Grpc\Timeval::zero(); +assert(0 == Grpc\Timeval::compare($zero, $zero)); + +// Test PastIsLessThanZero +$zero = Grpc\Timeval::zero(); +$past = Grpc\Timeval::infPast(); +assert(0 > Grpc\Timeval::compare($past, $zero)); +assert(0 < Grpc\Timeval::compare($zero, $past)); + +// Test FutureIsGreaterThanZero +$zero = Grpc\Timeval::zero(); +$future = Grpc\Timeval::infFuture(); +assert(0 > Grpc\Timeval::compare($zero, $future)); +assert(0 < Grpc\Timeval::compare($future, $zero)); + +// Test NowIsBetweenZeroAndFuture +$zero = Grpc\Timeval::zero(); +$future = Grpc\Timeval::infFuture(); +$now = Grpc\Timeval::now(); +assert(0 > Grpc\Timeval::compare($zero, $now)); +assert(0 > Grpc\Timeval::compare($now, $future)); + +// Test NowAndAdd +$now = Grpc\Timeval::now(); +assert($now != NULL); +$delta = new Grpc\Timeval(1000); +$deadline = $now->add($delta); +assert(0 < Grpc\Timeval::compare($deadline, $now)); + +// Test NowAndSubtract +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(1000); +$deadline = $now->subtract($delta); +assert(0 > Grpc\Timeval::compare($deadline, $now)); + +// Test AddAndSubtract +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(1000); +$deadline = $now->add($delta); +$back_to_now = $deadline->subtract($delta); +assert(0 == Grpc\Timeval::compare($back_to_now, $now)); + +// Test Similar +$a = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(1000); +$b = $a->add($delta); +$thresh = new Grpc\Timeval(1100); +assert(Grpc\Timeval::similar($a, $b, $thresh)); +$thresh = new Grpc\Timeval(900); +assert(!Grpc\Timeval::similar($a, $b, $thresh)); + +// Test SleepUntil +$curr_microtime = microtime(true); +$now = Grpc\Timeval::now(); +$delta = new Grpc\Timeval(1000); +$deadline = $now->add($delta); +$deadline->sleepUntil(); +$done_microtime = microtime(true); +assert(($done_microtime - $curr_microtime) > 0.0009); + +// Test ConstructorInvalidParam +try { + $delta = new Grpc\Timeval('abc'); +} catch (\Exception $e) {} +// Test AddInvalidParam +$a = Grpc\Timeval::now(); +try { + $a->add(1000); +} catch (\Exception $e) {} +// Test SubtractInvalidParam +$a = Grpc\Timeval::now(); +try { + $a->subtract(1000); +} catch (\Exception $e) {} +// Test CompareInvalidParam +try { + $a = Grpc\Timeval::compare(1000, 1100); +} catch (\Exception $e) {} +// Test SimilarInvalidParam +try { + $a = Grpc\Timeval::similar(1000, 1100, 1200); +} catch (\Exception $e) {} + unset($time); + + //============== Server Test ==================== + //Set Up + $server = NULL; + + // Test ConstructorWithNull +$server = new Grpc\Server(); +assert($server != NULL); + +// Test ConstructorWithNullArray +$server = new Grpc\Server([]); +assert($server != NULL); + +// Test ConstructorWithArray +$server = new Grpc\Server(['ip' => '127.0.0.1', + 'port' => '8080', ]); +assert($server != NULL); + +// Test RequestCall +$server = new Grpc\Server(); +$port = $server->addHttp2Port('0.0.0.0:0'); +$server->start(); +$channel = new Grpc\Channel('localhost:'.$port, + [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure() + ]); + +$deadline = Grpc\Timeval::infFuture(); +$call = new Grpc\Call($channel, 'dummy_method', $deadline); + +$event = $call->startBatch([Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + ]); + +$c = $server->requestCall(); +assert('dummy_method' == $c->method); +assert(is_string($c->host)); + +unset($call); +unset($channel); + +// Test InvalidConstructorWithNumKeyOfArray +try{ + $server = new Grpc\Server([10 => '127.0.0.1', + 20 => '8080', ]); +} +catch(\Exception $e){} + +// Test Invalid ArgumentException +try{ + $server = new Grpc\Server(['127.0.0.1', '8080']); +} +catch(\Exception $e){} + +// Test InvalidAddHttp2Port +$server = new Grpc\Server([]); +try{ + $port = $server->addHttp2Port(['0.0.0.0:0']); +} +catch(\Exception $e){} + +// Test InvalidAddSecureHttp2Port +$server = new Grpc\Server([]); +try{ + $port = $server->addSecureHttp2Port(['0.0.0.0:0']); +} +catch(\Exception $e){} + +// Test InvalidAddSecureHttp2Port2 +$server = new Grpc\Server(); +try{ + $port = $server->addSecureHttp2Port('0.0.0.0:0'); +} +catch(\Exception $e){} + +// Test InvalidAddSecureHttp2Port3 +$server = new Grpc\Server(); +try{ + $port = $server->addSecureHttp2Port('0.0.0.0:0', 'invalid'); +} +catch(\Exception $e){} +unset($server); + + +//============== ChannelCredential Test ==================== +// Test CreateSslWith3Null +$channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, + null); +assert($channel_credentials != NULL); + +// Test CreateSslWith3NullString +$channel_credentials = Grpc\ChannelCredentials::createSsl('', '', ''); +assert($channel_credentials != NULL); + +// Test CreateInsecure +$channel_credentials = Grpc\ChannelCredentials::createInsecure(); +assert($channel_credentials == NULL); + +// Test InvalidCreateSsl() +try { + $channel_credentials = Grpc\ChannelCredentials::createSsl([]); +} +catch (\Exception $e) { +} +try { + $channel_credentials = Grpc\ChannelCredentials::createComposite( + 'something', 'something'); +} +catch (\Exception $e) { +} + +//============== Interceptor Test ==================== +require_once(dirname(__FILE__).'/../../lib/Grpc/BaseStub.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/AbstractCall.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/CallInvoker.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/DefaultCallInvoker.php'); +require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php'); + +class SimpleRequest +{ + private $data; + public function __construct($data) + { + $this->data = $data; + } + public function setData($data) + { + $this->data = $data; + } + public function serializeToString() + { + return $this->data; + } +} + +class InterceptorClient extends Grpc\BaseStub +{ + + /** + * @param string $hostname hostname + * @param array $opts channel options + * @param Channel|InterceptorChannel $channel (optional) re-use channel object + */ + public function __construct($hostname, $opts, $channel = null) + { + parent::__construct($hostname, $opts, $channel); + } + + /** + * A simple RPC. + * @param SimpleRequest $argument input argument + * @param array $metadata metadata + * @param array $options call options + */ + public function UnaryCall( + SimpleRequest $argument, + $metadata = [], + $options = [] + ) { + return $this->_simpleRequest( + '/dummy_method', + $argument, + [], + $metadata, + $options + ); + } + + /** + * A client-to-server streaming RPC. + * @param array $metadata metadata + * @param array $options call options + */ + public function StreamCall( + $metadata = [], + $options = [] + ) { + return $this->_clientStreamRequest('/dummy_method', [], $metadata, $options); + } +} + +class ChangeMetadataInterceptor extends Grpc\Interceptor +{ + public function interceptUnaryUnary($method, + $argument, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) + { + $metadata["foo"] = array('interceptor_from_unary_request'); + return $continuation($method, $argument, $deserialize, $metadata, $options); + } + public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) + { + $metadata["foo"] = array('interceptor_from_stream_request'); + return $continuation($method, $deserialize, $metadata, $options); + } +} + +class ChangeMetadataInterceptor2 extends Grpc\Interceptor +{ + public function interceptUnaryUnary($method, + $argument, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) + { + if (array_key_exists('foo', $metadata)) { + $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first'); + } else { + $metadata["bar"] = array('interceptor_from_unary_request'); + } + return $continuation($method, $argument, $deserialize, $metadata, $options); + } + public function interceptStreamUnary($method, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) + { + if (array_key_exists('foo', $metadata)) { + $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first'); + } else { + $metadata["bar"] = array('interceptor_from_stream_request'); + } + return $continuation($method, $deserialize, $metadata, $options); + } +} + +class ChangeRequestCall +{ + private $call; + + public function __construct($call) + { + $this->call = $call; + } + public function getCall() + { + return $this->call; + } + + public function write($request) + { + $request->setData('intercepted_stream_request'); + $this->getCall()->write($request); + } + + public function wait() + { + return $this->getCall()->wait(); + } +} + +class ChangeRequestInterceptor extends Grpc\Interceptor +{ + public function interceptUnaryUnary($method, + $argument, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) + { + $argument->setData('intercepted_unary_request'); + return $continuation($method, $argument, $deserialize, $metadata, $options); + } + public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) + { + return new ChangeRequestCall( + $continuation($method, $deserialize, $metadata, $options) + ); + } +} + +class StopCallInterceptor extends Grpc\Interceptor +{ + public function interceptUnaryUnary($method, + $argument, + array $metadata = [], + array $options = [], + $continuation) + { + $metadata["foo"] = array('interceptor_from_request_response'); + } + public function interceptStreamUnary($method, + array $metadata = [], + array $options = [], + $continuation) + { + $metadata["foo"] = array('interceptor_from_request_response'); + } +} + +// Set Up +$server = new Grpc\Server([]); +$port = $server->addHttp2Port('0.0.0.0:0'); +$channel = new Grpc\Channel('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure()]); +$server->start(); + +// Test ClientChangeMetadataOneInterceptor +$req_text = 'client_request'; +$channel_matadata_interceptor = new ChangeMetadataInterceptor(); +$intercept_channel = Grpc\Interceptor::intercept($channel, $channel_matadata_interceptor); +$client = new InterceptorClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), +], $intercept_channel); +$req = new SimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_unary_request'] == $event->metadata['foo']); + +$stream_call = $client->StreamCall(); +$stream_call->write($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_stream_request'] == $event->metadata['foo']); + +unset($unary_call); +unset($stream_call); +unset($server_call); + +// Test ClientChangeMetadataTwoInterceptor +$req_text = 'client_request'; +$channel_matadata_interceptor = new ChangeMetadataInterceptor(); +$channel_matadata_intercepto2 = new ChangeMetadataInterceptor2(); +// test intercept separately. +$intercept_channel1 = Grpc\Interceptor::intercept($channel, $channel_matadata_interceptor); +$intercept_channel2 = Grpc\Interceptor::intercept($intercept_channel1, $channel_matadata_intercepto2); +$client = new InterceptorClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), +], $intercept_channel2); + +$req = new SimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_unary_request'] == $event->metadata['foo']); +assert(['interceptor_from_unary_request'] == $event->metadata['bar']); + +$stream_call = $client->StreamCall(); +$stream_call->write($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_stream_request'] == $event->metadata['foo']); +assert(['interceptor_from_stream_request'] == $event->metadata['bar']); + +unset($unary_call); +unset($stream_call); +unset($server_call); + +// test intercept by array. +$intercept_channel3 = Grpc\Interceptor::intercept($channel, + [$channel_matadata_intercepto2, $channel_matadata_interceptor]); +$client = new InterceptorClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), +], $intercept_channel3); + +$req = new SimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_unary_request'] == $event->metadata['foo']); +assert(['interceptor_from_unary_request'] == $event->metadata['bar']); + +$stream_call = $client->StreamCall(); +$stream_call->write($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +assert(['interceptor_from_stream_request'] == $event->metadata['foo']); +assert(['interceptor_from_stream_request'] == $event->metadata['bar']); + +unset($unary_call); +unset($stream_call); +unset($server_call); + + +// Test ClientChangeRequestInterceptor +$req_text = 'client_request'; +$change_request_interceptor = new ChangeRequestInterceptor(); +$intercept_channel = Grpc\Interceptor::intercept($channel, + $change_request_interceptor); +$client = new InterceptorClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), +], $intercept_channel); + +$req = new SimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); + +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => '', + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert('intercepted_unary_request' == $event->message); + +$stream_call = $client->StreamCall(); +$stream_call->write($req); +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => '', + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert('intercepted_stream_request' == $event->message); + +unset($unary_call); +unset($stream_call); +unset($server_call); + +// Test ClientChangeStopCallInterceptor +$req_text = 'client_request'; +$channel_request_interceptor = new StopCallInterceptor(); +$intercept_channel = Grpc\Interceptor::intercept($channel, + $channel_request_interceptor); +$client = new InterceptorClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), +], $intercept_channel); + +$req = new SimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); +assert($unary_call == NULL); + + +$stream_call = $client->StreamCall(); +assert($stream_call == NULL); + +unset($unary_call); +unset($stream_call); +unset($server_call); + +// Test GetInterceptorChannelConnectivityState +$channel = new Grpc\Channel( + 'localhost:0', + [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure() + ] +); +$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); +$state = $interceptor_channel->getConnectivityState(); +assert(0 == $state); +$channel->close(); + +// Test InterceptorChannelWatchConnectivityState +$channel = new Grpc\Channel( + 'localhost:0', + [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure() + ] +); +$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); +$now = Grpc\Timeval::now(); +$deadline = $now->add(new Grpc\Timeval(100*1000)); +$state = $interceptor_channel->watchConnectivityState(1, $deadline); +assert($state); +unset($time); +unset($deadline); +$channel->close(); + +// Test InterceptorChannelClose +$channel = new Grpc\Channel( + 'localhost:0', + [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure() + ] +); +$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); +assert($interceptor_channel != NULL); +$channel->close(); + +// Test InterceptorChannelGetTarget +$channel = new Grpc\Channel( + 'localhost:8888', + [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure() + ] +); +$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); +$target = $interceptor_channel->getTarget(); +assert(is_string($target)); + +$channel->close(); +unset($server); + + +//============== CallInvoker Test ==================== +class CallInvokerSimpleRequest +{ + private $data; + public function __construct($data) + { + $this->data = $data; + } + public function setData($data) + { + $this->data = $data; + } + public function serializeToString() + { + return $this->data; + } +} + +class CallInvokerClient extends Grpc\BaseStub +{ + + /** + * @param string $hostname hostname + * @param array $opts channel options + * @param Channel|InterceptorChannel $channel (optional) re-use channel object + */ + public function __construct($hostname, $opts, $channel = null) + { + parent::__construct($hostname, $opts, $channel); + } + + /** + * A simple RPC. + * @param SimpleRequest $argument input argument + * @param array $metadata metadata + * @param array $options call options + */ + public function UnaryCall( + CallInvokerSimpleRequest $argument, + $metadata = [], + $options = [] + ) { + return $this->_simpleRequest( + '/dummy_method', + $argument, + [], + $metadata, + $options + ); + } +} + +class CallInvokerUpdateChannel implements \Grpc\CallInvoker +{ + private $channel; + + public function getChannel() { + return $this->channel; + } + + public function createChannelFactory($hostname, $opts) { + $this->channel = new \Grpc\Channel('localhost:50050', $opts); + return $this->channel; + } + + public function UnaryCall($channel, $method, $deserialize, $options) { + return new UnaryCall($channel, $method, $deserialize, $options); + } + + public function ClientStreamingCall($channel, $method, $deserialize, $options) { + return new ClientStreamingCall($channel, $method, $deserialize, $options); + } + + public function ServerStreamingCall($channel, $method, $deserialize, $options) { + return new ServerStreamingCall($channel, $method, $deserialize, $options); + } + + public function BidiStreamingCall($channel, $method, $deserialize, $options) { + return new BidiStreamingCall($channel, $method, $deserialize, $options); + } +} + +class CallInvokerChangeRequest implements \Grpc\CallInvoker +{ + private $channel; + + public function getChannel() { + return $this->channel; + } + public function createChannelFactory($hostname, $opts) { + $this->channel = new \Grpc\Channel($hostname, $opts); + return $this->channel; + } + + public function UnaryCall($channel, $method, $deserialize, $options) { + return new CallInvokerChangeRequestCall($channel, $method, $deserialize, $options); + } + + public function ClientStreamingCall($channel, $method, $deserialize, $options) { + return new ClientStreamingCall($channel, $method, $deserialize, $options); + } + + public function ServerStreamingCall($channel, $method, $deserialize, $options) { + return new ServerStreamingCall($channel, $method, $deserialize, $options); + } + + public function BidiStreamingCall($channel, $method, $deserialize, $options) { + return new BidiStreamingCall($channel, $method, $deserialize, $options); + } +} + +class CallInvokerChangeRequestCall +{ + private $call; + + public function __construct($channel, $method, $deserialize, $options) + { + $this->call = new \Grpc\UnaryCall($channel, $method, $deserialize, $options); + } + + public function start($argument, $metadata, $options) { + $argument->setData('intercepted_unary_request'); + $this->call->start($argument, $metadata, $options); + } + + public function wait() + { + return $this->call->wait(); + } +} + +// Set Up +$server = new Grpc\Server([]); +$port = $server->addHttp2Port('0.0.0.0:0'); +$server->start(); + +// Test CreateDefaultCallInvoker +$call_invoker = new \Grpc\DefaultCallInvoker(); + +// Test CreateCallInvoker +$call_invoker = new CallInvokerUpdateChannel(); + +// Test CallInvokerAccessChannel +$call_invoker = new CallInvokerUpdateChannel(); +$stub = new \Grpc\BaseStub('localhost:50051', + ['credentials' => \Grpc\ChannelCredentials::createInsecure(), + 'grpc_call_invoker' => $call_invoker]); +assert($call_invoker->getChannel()->getTarget() == 'localhost:50050'); +$call_invoker->getChannel()->close(); + +// Test ClientChangeRequestCallInvoker +$req_text = 'client_request'; +$call_invoker = new CallInvokerChangeRequest(); +$client = new CallInvokerClient('localhost:'.$port, [ + 'force_new' => true, + 'credentials' => Grpc\ChannelCredentials::createInsecure(), + 'grpc_call_invoker' => $call_invoker, +]); + +$req = new CallInvokerSimpleRequest($req_text); +$unary_call = $client->UnaryCall($req); + +$event = $server->requestCall(); +assert('/dummy_method' == $event->method); +$server_call = $event->call; +$event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => '', + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, +]); +assert('intercepted_unary_request' == $event->message); +$call_invoker->getChannel()->close(); +unset($unary_call); +unset($server_call); + +unset($server); + + diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php index be1d77fe7ad..927fac6622b 100644 --- a/src/php/tests/unit_tests/CallTest.php +++ b/src/php/tests/unit_tests/CallTest.php @@ -86,6 +86,16 @@ class CallTest extends PHPUnit_Framework_TestCase $this->assertTrue($result->send_metadata); } + public function testAddMultiAndMultiValueMetadata() + { + $batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1', 'value2'], + 'key2' => ['value3', 'value4'],], + ]; + $result = $this->call->startBatch($batch); + $this->assertTrue($result->send_metadata); + } + public function testGetPeer() { $this->assertTrue(is_string($this->call->getPeer())); diff --git a/templates/tools/dockerfile/php_valgrind.include b/templates/tools/dockerfile/php_valgrind.include new file mode 100644 index 00000000000..aa2ed883f39 --- /dev/null +++ b/templates/tools/dockerfile/php_valgrind.include @@ -0,0 +1,7 @@ +#================= +# PHP Test dependencies + + # Install dependencies + + RUN apt-get update && apt-get install -y ${'\\'} + valgrind \ No newline at end of file diff --git a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template index e7b6c0d5f9c..0b2290b741c 100644 --- a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template @@ -19,6 +19,7 @@ <%include file="../../php7_deps.include"/> <%include file="../../gcp_api_libraries.include"/> <%include file="../../python_deps.include"/> + <%include file="../../php_valgrind.include"/> <%include file="../../run_tests_addons.include"/> # Define the default command. CMD ["bash"] diff --git a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template index fdbad53c391..329205363e3 100644 --- a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template @@ -20,6 +20,7 @@ <%include file="../../gcp_api_libraries.include"/> <%include file="../../python_deps.include"/> <%include file="../../php_deps.include"/> + <%include file="../../php_valgrind.include"/> <%include file="../../run_tests_addons.include"/> # Define the default command. CMD ["bash"] diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile index 0dff8399047..0c84ed3fe4c 100644 --- a/tools/dockerfile/test/php7_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile @@ -79,6 +79,13 @@ RUN pip install --upgrade pip==10.0.1 RUN pip install virtualenv RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 +#================= +# PHP Test dependencies + + # Install dependencies + + RUN apt-get update && apt-get install -y \ + valgrind RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile index ed59e569956..c2c37d3b438 100644 --- a/tools/dockerfile/test/php_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php_jessie_x64/Dockerfile @@ -76,6 +76,13 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t RUN apt-get update && apt-get install -y \ git php5 php5-dev phpunit unzip +#================= +# PHP Test dependencies + + # Install dependencies + + RUN apt-get update && apt-get install -y \ + valgrind RUN mkdir /var/local/jenkins From 684690c2d734eb7f4cb702194ac2df5e67a1cb0a Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 12 Feb 2019 16:04:21 -0800 Subject: [PATCH 350/814] Adopt reviewers' advice --- tools/run_tests/python_utils/check_on_pr.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index 62ea9a873e8..8250dd76e02 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -18,6 +18,7 @@ import sys import json import time import datetime +import traceback import requests import jwt @@ -57,24 +58,26 @@ def _access_token(): 'Authorization': 'Bearer %s' % _jwt_token().decode('ASCII'), 'Accept': 'application/vnd.github.machine-man-preview+json', }) - if resp.status_code == 200: + + try: + _ACCESS_TOKEN_CACHE = { + 'token': resp.json()['token'], + 'exp': time.time() + 60 + } break - else: + except (KeyError, ValueError) as e: + traceback.print_exc(e) + print('HTTP Status %d %s' % (resp.status_code, resp.reason)) print("Fetch access token from Github API failed:") - print(resp.json()) + print(resp.text) if i != _ACCESS_TOKEN_FETCH_RETRIES - 1: print('Retrying after %.2f second.' % _ACCESS_TOKEN_FETCH_RETRIES_INTERVAL_S) time.sleep(_ACCESS_TOKEN_FETCH_RETRIES_INTERVAL_S) - - if resp.status_code != 200: + else: print("error: Unable to fetch access token, exiting...") sys.exit(1) - _ACCESS_TOKEN_CACHE = { - 'token': resp.json()['token'], - 'exp': time.time() + 60 - } return _ACCESS_TOKEN_CACHE['token'] From 37c1f0bd546dcbf5801e173f6e296a8528b7bea1 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 12 Feb 2019 15:47:29 -0500 Subject: [PATCH 351/814] Reorder code to set num_frequently_polled_cqs correctly. When there num_frequently_polled_cqs is non-zero (aka hybrid server), we create non-polling CQs for the sync methods. But, since we increase num_frequently_polled_cqs for callback methods after creating the sync CQs, the sync CQs would not detect a hyprid server, and will create a polling CQ. This commit reorders the logic, so that we increment num_frequently_polled_cqs upon detecting a callback service. This lowers the context switches by double digit percentage when using callback API. --- src/cpp/server/server_builder.cc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 64210a2f8d1..b7fad558abb 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -243,15 +243,25 @@ std::unique_ptr ServerBuilder::BuildAndStart() { sync_server_cqs(std::make_shared< std::vector>>()); - int num_frequently_polled_cqs = 0; + bool has_frequently_polled_cqs = false; for (auto it = cqs_.begin(); it != cqs_.end(); ++it) { if ((*it)->IsFrequentlyPolled()) { - num_frequently_polled_cqs++; + has_frequently_polled_cqs = true; + break; } } - const bool is_hybrid_server = - has_sync_methods && num_frequently_polled_cqs > 0; + // == Determine if the server has any callback methods == + bool has_callback_methods = false; + for (auto it = services_.begin(); it != services_.end(); ++it) { + if ((*it)->service->has_callback_methods()) { + has_callback_methods = true; + has_frequently_polled_cqs = true; + break; + } + } + + const bool is_hybrid_server = has_sync_methods && has_frequently_polled_cqs; if (has_sync_methods) { grpc_cq_polling_type polling_type = @@ -264,15 +274,6 @@ std::unique_ptr ServerBuilder::BuildAndStart() { } } - // == Determine if the server has any callback methods == - bool has_callback_methods = false; - for (auto it = services_.begin(); it != services_.end(); ++it) { - if ((*it)->service->has_callback_methods()) { - has_callback_methods = true; - break; - } - } - // TODO(vjpai): Add a section here for plugins once they can support callback // methods @@ -306,13 +307,12 @@ std::unique_ptr ServerBuilder::BuildAndStart() { for (auto it = sync_server_cqs->begin(); it != sync_server_cqs->end(); ++it) { grpc_server_register_completion_queue(server->server_, (*it)->cq(), nullptr); - num_frequently_polled_cqs++; + has_frequently_polled_cqs = true; } if (has_callback_methods) { auto* cq = server->CallbackCQ(); grpc_server_register_completion_queue(server->server_, cq->cq(), nullptr); - num_frequently_polled_cqs++; } // cqs_ contains the completion queue added by calling the ServerBuilder's @@ -325,7 +325,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { nullptr); } - if (num_frequently_polled_cqs == 0) { + if (!has_frequently_polled_cqs) { gpr_log(GPR_ERROR, "At least one of the completion queues must be frequently polled"); return nullptr; From fb4ba978036a5e6d67a789e763bfa91ec575b489 Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Tue, 12 Feb 2019 21:03:51 -0800 Subject: [PATCH 352/814] Bump version to v1.20.x --- BUILD | 6 +++--- build.yaml | 6 +++--- doc/g_stands_for.md | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/BUILD b/BUILD index ebb03580bb4..a566057e926 100644 --- a/BUILD +++ b/BUILD @@ -64,11 +64,11 @@ config_setting( ) # This should be updated along with build.yaml -g_stands_for = "gold" +g_stands_for = "godric" -core_version = "7.0.0-dev" +core_version = "7.0.0" -version = "1.19.0-dev" +version = "1.20.0-dev" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index f96b0cbcf22..77ad81ddda2 100644 --- a/build.yaml +++ b/build.yaml @@ -12,9 +12,9 @@ settings: '#08': Use "-preN" suffixes to identify pre-release versions '#09': Per-language overrides are possible with (eg) ruby_version tag here '#10': See the expand_version.py for all the quirks here - core_version: 7.0.0-dev - g_stands_for: gold - version: 1.19.0-dev + core_version: 7.0.0 + g_stands_for: godric + version: 1.20.0-dev filegroups: - name: alts_proto headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index 7bc8a003b5d..423d8c2fd9a 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -18,4 +18,5 @@ - 1.16 'g' stands for ['gao'](https://github.com/grpc/grpc/tree/v1.16.x) - 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/v1.17.x) - 1.18 'g' stands for ['goose'](https://github.com/grpc/grpc/tree/v1.18.x) -- 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/master) +- 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/v1.19.x) +- 1.20 'g' stands for ['godric'](https://github.com/grpc/grpc/tree/master) From b0efc103e34065571832f5838c2e839e671a44e8 Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Tue, 12 Feb 2019 21:07:42 -0800 Subject: [PATCH 353/814] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 6 +++--- gRPC-C++.podspec | 4 ++-- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/core/lib/surface/version.cc | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 4 ++-- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 4 ++-- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- tools/doxygen/Doxyfile.core | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- 33 files changed, 40 insertions(+), 40 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2de3f6fde5..f494ef0094c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.19.0-dev") +set(PACKAGE_VERSION "1.20.0-dev") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 069d001d3be..7cfe37384aa 100644 --- a/Makefile +++ b/Makefile @@ -437,9 +437,9 @@ E = @echo Q = @ endif -CORE_VERSION = 7.0.0-dev -CPP_VERSION = 1.19.0-dev -CSHARP_VERSION = 1.19.0-dev +CORE_VERSION = 7.0.0 +CPP_VERSION = 1.20.0-dev +CSHARP_VERSION = 1.20.0-dev CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index e1b1cf1564e..15ce090bd9b 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,7 +23,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.19.0-dev' + # version = '1.20.0-dev' version = '0.0.8-dev' s.version = version s.summary = 'gRPC C++ library' @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.19.0-dev' + grpc_version = '1.20.0-dev' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 625d1a9a50c..92626f3e84b 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.19.0-dev' + version = '1.20.0-dev' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index fe00b492236..3de74e49033 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.19.0-dev' + version = '1.20.0-dev' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index a16a3985211..6121f67ae29 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.19.0-dev' + version = '1.20.0-dev' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index a2e216ba2f7..c19419f1857 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.19.0-dev' + version = '1.20.0-dev' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index aa2bf62411c..7a1d26c47c5 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.19.0dev - 1.19.0dev + 1.20.0dev + 1.20.0dev beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 70d7580becb..bf2e6c90846 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -23,6 +23,6 @@ #include -const char* grpc_version_string(void) { return "7.0.0-dev"; } +const char* grpc_version_string(void) { return "7.0.0"; } -const char* grpc_g_stands_for(void) { return "gold"; } +const char* grpc_g_stands_for(void) { return "godric"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 358131c7c4c..930ec534fd4 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.19.0-dev"; } +grpc::string Version() { return "1.20.0-dev"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 52ab2215ebe..de933448b96 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.19.0-dev + 1.20.0-dev 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 8f3be310ee7..10efb17a678 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.19.0.0"; + public const string CurrentAssemblyFileVersion = "1.20.0.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.19.0-dev"; + public const string CurrentVersion = "1.20.0-dev"; } } diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index e304c6e4cf1..7d403d1338a 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.19.0-dev +set VERSION=1.20.0-dev @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 73e1a4046f6..cf2062c19bb 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.19.0-dev' + v = '1.20.0-dev' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 5e089fde316..4d4431ee365 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.19.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.20.0-dev" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 54f95ad16a8..b3c4788f496 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.19.0-dev" -#define GRPC_C_VERSION_STRING @"7.0.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.20.0-dev" +#define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index 75fab483f14..e8106db7288 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.19.0", + "version": "1.20.0", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index c85ee4d315b..fac3e85d849 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.19.0dev" +#define PHP_GRPC_VERSION "1.20.0dev" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index dd9d436c3fe..069dbf1a1c5 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.19.0.dev0""" +__version__ = """1.20.0.dev0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 8e2f4d30bbc..9e7af710f49 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.20.0.dev0' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 5f3a894a2ae..9a33dc35b26 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.20.0.dev0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 4c2d434066e..eeacbe23bfd 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.20.0.dev0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 6b88b2dfc50..c76cbbd7a95 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.20.0.dev0' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 2e58eb3b26c..40d823ed0cd 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.20.0.dev0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index d4c5d94ecbe..df40ba743a6 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.20.0.dev0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index e1645ab1b86..b2db0d0949d 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.20.0.dev0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 3b7f62d9f55..0e20b361b7d 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.19.0.dev' + VERSION = '1.20.0.dev' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 2ad685a7eb3..79201ad1e6e 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.19.0.dev' + VERSION = '1.20.0.dev' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index e5d9daef38f..950b2e2d111 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.20.0.dev0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index b0415fd4f64..9f17a25298a 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.19.0-dev +PROJECT_NUMBER = 1.20.0-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 8aec165a339..2c194c420f3 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.19.0-dev +PROJECT_NUMBER = 1.20.0-dev # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 8c557383b2e..7235c7b1539 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 7.0.0-dev +PROJECT_NUMBER = 7.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 86b57b23d9a..d1a2debd7e3 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 7.0.0-dev +PROJECT_NUMBER = 7.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From d3313adecf8d454836b73562f2a197aa1bbc1738 Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Tue, 12 Feb 2019 21:26:30 -0800 Subject: [PATCH 354/814] Bump version to v1.19.0-pre1 --- BUILD | 4 ++-- build.yaml | 4 ++-- doc/g_stands_for.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BUILD b/BUILD index ebb03580bb4..d18530bddc4 100644 --- a/BUILD +++ b/BUILD @@ -66,9 +66,9 @@ config_setting( # This should be updated along with build.yaml g_stands_for = "gold" -core_version = "7.0.0-dev" +core_version = "7.0.0" -version = "1.19.0-dev" +version = "1.19.0-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index f96b0cbcf22..fccc88afeb3 100644 --- a/build.yaml +++ b/build.yaml @@ -12,9 +12,9 @@ settings: '#08': Use "-preN" suffixes to identify pre-release versions '#09': Per-language overrides are possible with (eg) ruby_version tag here '#10': See the expand_version.py for all the quirks here - core_version: 7.0.0-dev + core_version: 7.0.0 g_stands_for: gold - version: 1.19.0-dev + version: 1.19.0-pre1 filegroups: - name: alts_proto headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index 7bc8a003b5d..ce28c208aa9 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -18,4 +18,4 @@ - 1.16 'g' stands for ['gao'](https://github.com/grpc/grpc/tree/v1.16.x) - 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/v1.17.x) - 1.18 'g' stands for ['goose'](https://github.com/grpc/grpc/tree/v1.18.x) -- 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/master) +- 1.19 'g' stands for ['gold'](https://github.com/grpc/grpc/tree/v1.19.x) From 8d237ea703ce822b1abb2b12f1f22d344983395e Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Tue, 12 Feb 2019 21:29:53 -0800 Subject: [PATCH 355/814] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 6 +++--- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 4 ++-- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- tools/doxygen/Doxyfile.core | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- 32 files changed, 38 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2de3f6fde5..23811c5b116 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.19.0-dev") +set(PACKAGE_VERSION "1.19.0-pre1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 069d001d3be..8166dcf3a1d 100644 --- a/Makefile +++ b/Makefile @@ -437,9 +437,9 @@ E = @echo Q = @ endif -CORE_VERSION = 7.0.0-dev -CPP_VERSION = 1.19.0-dev -CSHARP_VERSION = 1.19.0-dev +CORE_VERSION = 7.0.0 +CPP_VERSION = 1.19.0-pre1 +CSHARP_VERSION = 1.19.0-pre1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index e1b1cf1564e..07b02cf8dfb 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.19.0-dev' - version = '0.0.8-dev' + # version = '1.19.0-pre1' + version = '0.0.8-pre1' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.19.0-dev' + grpc_version = '1.19.0-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 625d1a9a50c..6ac7c7e586e 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.19.0-dev' + version = '1.19.0-pre1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index fe00b492236..9b4cd5a5568 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.19.0-dev' + version = '1.19.0-pre1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index a16a3985211..4ea2ff2e127 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.19.0-dev' + version = '1.19.0-pre1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index a2e216ba2f7..1882471af68 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.19.0-dev' + version = '1.19.0-pre1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index aa2bf62411c..2aea1a5bc4e 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.19.0dev - 1.19.0dev + 1.19.0RC1 + 1.19.0RC1 beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 70d7580becb..3ad52aee571 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -23,6 +23,6 @@ #include -const char* grpc_version_string(void) { return "7.0.0-dev"; } +const char* grpc_version_string(void) { return "7.0.0"; } const char* grpc_g_stands_for(void) { return "gold"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 358131c7c4c..49359fa4fbb 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.19.0-dev"; } +grpc::string Version() { return "1.19.0-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 52ab2215ebe..e967fb59e5c 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.19.0-dev + 1.19.0-pre1 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 8f3be310ee7..9885928f68a 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.19.0-dev"; + public const string CurrentVersion = "1.19.0-pre1"; } } diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index e304c6e4cf1..636211ad360 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.19.0-dev +set VERSION=1.19.0-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 73e1a4046f6..e214b3980b5 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.19.0-dev' + v = '1.19.0-pre1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index 5e089fde316..c47780fb0b4 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.19.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.19.0-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 54f95ad16a8..962b699b38f 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.19.0-dev" -#define GRPC_C_VERSION_STRING @"7.0.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.19.0-pre1" +#define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index c85ee4d315b..cf7761eb724 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.19.0dev" +#define PHP_GRPC_VERSION "1.19.0RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index dd9d436c3fe..17f82a81ce1 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.19.0.dev0""" +__version__ = """1.19.0rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 8e2f4d30bbc..6cf1234a392 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.19.0rc1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 5f3a894a2ae..922abf2ec70 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.19.0rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 4c2d434066e..d9eb56c5e9c 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.19.0rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 6b88b2dfc50..28fef1dc56b 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.19.0rc1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 2e58eb3b26c..efa6ff2c508 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.19.0rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index d4c5d94ecbe..0e593340ab2 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.19.0rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index e1645ab1b86..c8f6940e1a4 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.19.0rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 3b7f62d9f55..630d064fa05 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.19.0.dev' + VERSION = '1.19.0.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 2ad685a7eb3..a4a115ac2c9 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.19.0.dev' + VERSION = '1.19.0.pre1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index e5d9daef38f..a58218b3718 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.19.0.dev0' +VERSION = '1.19.0rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index b0415fd4f64..ae4e398051e 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.19.0-dev +PROJECT_NUMBER = 1.19.0-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 8aec165a339..e19fd05c0c1 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.19.0-dev +PROJECT_NUMBER = 1.19.0-pre1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 8c557383b2e..7235c7b1539 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 7.0.0-dev +PROJECT_NUMBER = 7.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 86b57b23d9a..d1a2debd7e3 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 7.0.0-dev +PROJECT_NUMBER = 7.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 596d1b056340c250b911771aeee2a4f4fa63f54f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 13 Feb 2019 12:56:11 +0100 Subject: [PATCH 356/814] refactor native_methods stub generator --- .../NativeMethods.Generated.cs.template | 122 ++---------------- .../Grpc.Core/Internal/native_methods.include | 109 ++++++++++++++++ 2 files changed, 117 insertions(+), 114 deletions(-) create mode 100644 templates/src/csharp/Grpc.Core/Internal/native_methods.include diff --git a/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template b/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template index 774fc2c56fe..4e6913803dd 100644 --- a/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template +++ b/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template @@ -1,112 +1,6 @@ %YAML 1.2 --- | - <% - native_method_signatures = [ - 'void grpcsharp_init()', - 'void grpcsharp_shutdown()', - 'IntPtr grpcsharp_version_string() // returns not-owned const char*', - 'BatchContextSafeHandle grpcsharp_batch_context_create()', - 'IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx)', - 'IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx)', - 'void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen)', - 'StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx)', - 'IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandle ctx, out UIntPtr detailsLength)', - 'IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata(BatchContextSafeHandle ctx)', - 'int grpcsharp_batch_context_recv_close_on_server_cancelled(BatchContextSafeHandle ctx)', - 'void grpcsharp_batch_context_reset(BatchContextSafeHandle ctx)', - 'void grpcsharp_batch_context_destroy(IntPtr ctx)', - 'RequestCallContextSafeHandle grpcsharp_request_call_context_create()', - 'CallSafeHandle grpcsharp_request_call_context_call(RequestCallContextSafeHandle ctx)', - 'IntPtr grpcsharp_request_call_context_method(RequestCallContextSafeHandle ctx, out UIntPtr methodLength)', - 'IntPtr grpcsharp_request_call_context_host(RequestCallContextSafeHandle ctx, out UIntPtr hostLength)', - 'Timespec grpcsharp_request_call_context_deadline(RequestCallContextSafeHandle ctx)', - 'IntPtr grpcsharp_request_call_context_request_metadata(RequestCallContextSafeHandle ctx)', - 'void grpcsharp_request_call_context_reset(RequestCallContextSafeHandle ctx)', - 'void grpcsharp_request_call_context_destroy(IntPtr ctx)', - 'CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2)', - 'void grpcsharp_call_credentials_release(IntPtr credentials)', - 'CallError grpcsharp_call_cancel(CallSafeHandle call)', - 'CallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description)', - 'CallError grpcsharp_call_start_unary(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', - 'CallError grpcsharp_call_start_client_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', - 'CallError grpcsharp_call_start_server_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', - 'CallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', - 'CallError grpcsharp_call_send_message(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, int sendEmptyInitialMetadata)', - 'CallError grpcsharp_call_send_close_from_client(CallSafeHandle call, BatchContextSafeHandle ctx)', - 'CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags)', - 'CallError grpcsharp_call_recv_message(CallSafeHandle call, BatchContextSafeHandle ctx)', - 'CallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call, BatchContextSafeHandle ctx)', - 'CallError grpcsharp_call_start_serverside(CallSafeHandle call, BatchContextSafeHandle ctx)', - 'CallError grpcsharp_call_send_initial_metadata(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray)', - 'CallError grpcsharp_call_set_credentials(CallSafeHandle call, CallCredentialsSafeHandle credentials)', - 'CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call)', - 'void grpcsharp_call_destroy(IntPtr call)', - 'ChannelArgsSafeHandle grpcsharp_channel_args_create(UIntPtr numArgs)', - 'void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value)', - 'void grpcsharp_channel_args_set_integer(ChannelArgsSafeHandle args, UIntPtr index, string key, int value)', - 'void grpcsharp_channel_args_destroy(IntPtr args)', - 'void grpcsharp_override_default_ssl_roots(string pemRootCerts)', - 'ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey)', - 'ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds)', - 'void grpcsharp_channel_credentials_release(IntPtr credentials)', - 'ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs)', - 'ChannelSafeHandle grpcsharp_secure_channel_create(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)', - 'CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline)', - 'ChannelState grpcsharp_channel_check_connectivity_state(ChannelSafeHandle channel, int tryToConnect)', - 'void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx)', - 'CStringSafeHandle grpcsharp_channel_get_target(ChannelSafeHandle call)', - 'void grpcsharp_channel_destroy(IntPtr channel)', - 'int grpcsharp_sizeof_grpc_event()', - 'CompletionQueueSafeHandle grpcsharp_completion_queue_create_async()', - 'CompletionQueueSafeHandle grpcsharp_completion_queue_create_sync()', - 'void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq)', - 'CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq)', - 'CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag)', - 'void grpcsharp_completion_queue_destroy(IntPtr cq)', - 'void gprsharp_free(IntPtr ptr)', - 'MetadataArraySafeHandle grpcsharp_metadata_array_create(UIntPtr capacity)', - 'void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength)', - 'UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray)', - 'IntPtr grpcsharp_metadata_array_get_key(IntPtr metadataArray, UIntPtr index, out UIntPtr keyLength)', - 'IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index, out UIntPtr valueLength)', - 'void grpcsharp_metadata_array_destroy_full(IntPtr array)', - 'void grpcsharp_redirect_log(GprLogDelegate callback)', - 'CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor)', - 'void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails)', - 'ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, SslClientCertificateRequestType clientCertificateRequest)', - 'void grpcsharp_server_credentials_release(IntPtr credentials)', - 'ServerSafeHandle grpcsharp_server_create(ChannelArgsSafeHandle args)', - 'void grpcsharp_server_register_completion_queue(ServerSafeHandle server, CompletionQueueSafeHandle cq)', - 'int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr)', - 'int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds)', - 'void grpcsharp_server_start(ServerSafeHandle server)', - 'CallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, RequestCallContextSafeHandle ctx)', - 'void grpcsharp_server_cancel_all_calls(ServerSafeHandle server)', - 'void grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx)', - 'void grpcsharp_server_destroy(IntPtr server)', - 'AuthContextSafeHandle grpcsharp_call_auth_context(CallSafeHandle call)', - 'IntPtr grpcsharp_auth_context_peer_identity_property_name(AuthContextSafeHandle authContext) // returns const char*', - 'AuthContextSafeHandle.NativeAuthPropertyIterator grpcsharp_auth_context_property_iterator(AuthContextSafeHandle authContext)', - 'IntPtr grpcsharp_auth_property_iterator_next(ref AuthContextSafeHandle.NativeAuthPropertyIterator iterator) // returns const auth_property*', - 'void grpcsharp_auth_context_release(IntPtr authContext)', - 'Timespec gprsharp_now(ClockType clockType)', - 'Timespec gprsharp_inf_future(ClockType clockType)', - 'Timespec gprsharp_inf_past(ClockType clockType)', - 'Timespec gprsharp_convert_clock_type(Timespec t, ClockType targetClock)', - 'int gprsharp_sizeof_timespec()', - 'CallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] NativeCallbackTestDelegate callback)', - 'IntPtr grpcsharp_test_nop(IntPtr ptr)', - 'void grpcsharp_test_override_method(string methodName, string variant)', - ] - - import re - native_methods = [] - for signature in native_method_signatures: - match = re.match('([A-Za-z0-9_.]+) +([A-Za-z0-9_]+)\\((.*)\\)(.*)', signature) - if not match: - raise Exception('Malformed signature "%s"' % signature) - native_methods.append({'returntype': match.group(1), 'name': match.group(2), 'params': match.group(3), 'comment': match.group(4)}) - %> + <%namespace file="native_methods.include" import="get_native_methods"/> #region Copyright notice and license // Copyright 2015 gRPC authors. @@ -142,7 +36,7 @@ { #region Native methods - % for method in native_methods: + % for method in get_native_methods(): public readonly Delegates.${method['name']}_delegate ${method['name']}; % endfor @@ -150,21 +44,21 @@ public NativeMethods(UnmanagedLibrary library) { - % for method in native_methods: + % for method in get_native_methods(): this.${method['name']} = GetMethodDelegate(library); % endfor } public NativeMethods(DllImportsFromStaticLib unusedInstance) { - % for method in native_methods: + % for method in get_native_methods(): this.${method['name']} = DllImportsFromStaticLib.${method['name']}; % endfor } public NativeMethods(DllImportsFromSharedLib unusedInstance) { - % for method in native_methods: + % for method in get_native_methods(): this.${method['name']} = DllImportsFromSharedLib.${method['name']}; % endfor } @@ -174,7 +68,7 @@ /// public class Delegates { - % for method in native_methods: + % for method in get_native_methods(): public delegate ${method['returntype']} ${method['name']}_delegate(${method['params']});${method['comment']} % endfor } @@ -185,7 +79,7 @@ internal class DllImportsFromStaticLib { private const string ImportName = "__Internal"; - % for method in native_methods: + % for method in get_native_methods(): [DllImport(ImportName)] public static extern ${method['returntype']} ${method['name']}(${method['params']}); @@ -198,7 +92,7 @@ internal class DllImportsFromSharedLib { private const string ImportName = "grpc_csharp_ext"; - % for method in native_methods: + % for method in get_native_methods(): [DllImport(ImportName)] public static extern ${method['returntype']} ${method['name']}(${method['params']}); diff --git a/templates/src/csharp/Grpc.Core/Internal/native_methods.include b/templates/src/csharp/Grpc.Core/Internal/native_methods.include new file mode 100644 index 00000000000..2afffd03720 --- /dev/null +++ b/templates/src/csharp/Grpc.Core/Internal/native_methods.include @@ -0,0 +1,109 @@ +<%def name="get_native_methods()"><% +native_method_signatures = [ + 'void grpcsharp_init()', + 'void grpcsharp_shutdown()', + 'IntPtr grpcsharp_version_string() // returns not-owned const char*', + 'BatchContextSafeHandle grpcsharp_batch_context_create()', + 'IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx)', + 'IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx)', + 'void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen)', + 'StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx)', + 'IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandle ctx, out UIntPtr detailsLength)', + 'IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata(BatchContextSafeHandle ctx)', + 'int grpcsharp_batch_context_recv_close_on_server_cancelled(BatchContextSafeHandle ctx)', + 'void grpcsharp_batch_context_reset(BatchContextSafeHandle ctx)', + 'void grpcsharp_batch_context_destroy(IntPtr ctx)', + 'RequestCallContextSafeHandle grpcsharp_request_call_context_create()', + 'CallSafeHandle grpcsharp_request_call_context_call(RequestCallContextSafeHandle ctx)', + 'IntPtr grpcsharp_request_call_context_method(RequestCallContextSafeHandle ctx, out UIntPtr methodLength)', + 'IntPtr grpcsharp_request_call_context_host(RequestCallContextSafeHandle ctx, out UIntPtr hostLength)', + 'Timespec grpcsharp_request_call_context_deadline(RequestCallContextSafeHandle ctx)', + 'IntPtr grpcsharp_request_call_context_request_metadata(RequestCallContextSafeHandle ctx)', + 'void grpcsharp_request_call_context_reset(RequestCallContextSafeHandle ctx)', + 'void grpcsharp_request_call_context_destroy(IntPtr ctx)', + 'CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2)', + 'void grpcsharp_call_credentials_release(IntPtr credentials)', + 'CallError grpcsharp_call_cancel(CallSafeHandle call)', + 'CallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description)', + 'CallError grpcsharp_call_start_unary(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', + 'CallError grpcsharp_call_start_client_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', + 'CallError grpcsharp_call_start_server_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', + 'CallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags)', + 'CallError grpcsharp_call_send_message(CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, int sendEmptyInitialMetadata)', + 'CallError grpcsharp_call_send_close_from_client(CallSafeHandle call, BatchContextSafeHandle ctx)', + 'CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, int sendEmptyInitialMetadata, byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags)', + 'CallError grpcsharp_call_recv_message(CallSafeHandle call, BatchContextSafeHandle ctx)', + 'CallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call, BatchContextSafeHandle ctx)', + 'CallError grpcsharp_call_start_serverside(CallSafeHandle call, BatchContextSafeHandle ctx)', + 'CallError grpcsharp_call_send_initial_metadata(CallSafeHandle call, BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray)', + 'CallError grpcsharp_call_set_credentials(CallSafeHandle call, CallCredentialsSafeHandle credentials)', + 'CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call)', + 'void grpcsharp_call_destroy(IntPtr call)', + 'ChannelArgsSafeHandle grpcsharp_channel_args_create(UIntPtr numArgs)', + 'void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value)', + 'void grpcsharp_channel_args_set_integer(ChannelArgsSafeHandle args, UIntPtr index, string key, int value)', + 'void grpcsharp_channel_args_destroy(IntPtr args)', + 'void grpcsharp_override_default_ssl_roots(string pemRootCerts)', + 'ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey)', + 'ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds)', + 'void grpcsharp_channel_credentials_release(IntPtr credentials)', + 'ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs)', + 'ChannelSafeHandle grpcsharp_secure_channel_create(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)', + 'CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline)', + 'ChannelState grpcsharp_channel_check_connectivity_state(ChannelSafeHandle channel, int tryToConnect)', + 'void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx)', + 'CStringSafeHandle grpcsharp_channel_get_target(ChannelSafeHandle call)', + 'void grpcsharp_channel_destroy(IntPtr channel)', + 'int grpcsharp_sizeof_grpc_event()', + 'CompletionQueueSafeHandle grpcsharp_completion_queue_create_async()', + 'CompletionQueueSafeHandle grpcsharp_completion_queue_create_sync()', + 'void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq)', + 'CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq)', + 'CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag)', + 'void grpcsharp_completion_queue_destroy(IntPtr cq)', + 'void gprsharp_free(IntPtr ptr)', + 'MetadataArraySafeHandle grpcsharp_metadata_array_create(UIntPtr capacity)', + 'void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength)', + 'UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray)', + 'IntPtr grpcsharp_metadata_array_get_key(IntPtr metadataArray, UIntPtr index, out UIntPtr keyLength)', + 'IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index, out UIntPtr valueLength)', + 'void grpcsharp_metadata_array_destroy_full(IntPtr array)', + 'void grpcsharp_redirect_log(GprLogDelegate callback)', + 'CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor)', + 'void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails)', + 'ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, SslClientCertificateRequestType clientCertificateRequest)', + 'void grpcsharp_server_credentials_release(IntPtr credentials)', + 'ServerSafeHandle grpcsharp_server_create(ChannelArgsSafeHandle args)', + 'void grpcsharp_server_register_completion_queue(ServerSafeHandle server, CompletionQueueSafeHandle cq)', + 'int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr)', + 'int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds)', + 'void grpcsharp_server_start(ServerSafeHandle server)', + 'CallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, RequestCallContextSafeHandle ctx)', + 'void grpcsharp_server_cancel_all_calls(ServerSafeHandle server)', + 'void grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx)', + 'void grpcsharp_server_destroy(IntPtr server)', + 'AuthContextSafeHandle grpcsharp_call_auth_context(CallSafeHandle call)', + 'IntPtr grpcsharp_auth_context_peer_identity_property_name(AuthContextSafeHandle authContext) // returns const char*', + 'AuthContextSafeHandle.NativeAuthPropertyIterator grpcsharp_auth_context_property_iterator(AuthContextSafeHandle authContext)', + 'IntPtr grpcsharp_auth_property_iterator_next(ref AuthContextSafeHandle.NativeAuthPropertyIterator iterator) // returns const auth_property*', + 'void grpcsharp_auth_context_release(IntPtr authContext)', + 'Timespec gprsharp_now(ClockType clockType)', + 'Timespec gprsharp_inf_future(ClockType clockType)', + 'Timespec gprsharp_inf_past(ClockType clockType)', + 'Timespec gprsharp_convert_clock_type(Timespec t, ClockType targetClock)', + 'int gprsharp_sizeof_timespec()', + 'CallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] NativeCallbackTestDelegate callback)', + 'IntPtr grpcsharp_test_nop(IntPtr ptr)', + 'void grpcsharp_test_override_method(string methodName, string variant)', +] + +import re +native_methods = [] +for signature in native_method_signatures: + match = re.match('([A-Za-z0-9_.]+) +([A-Za-z0-9_]+)\\((.*)\\)(.*)', signature) + if not match: + raise Exception('Malformed signature "%s"' % signature) + native_methods.append({'returntype': match.group(1), 'name': match.group(2), 'params': match.group(3), 'comment': match.group(4)}) + +return list(native_methods) +%> \ No newline at end of file From 1599fd5f7027f7fc9296b8fc6787361cb4c7998a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 13 Feb 2019 13:19:15 +0100 Subject: [PATCH 357/814] unity android: add dummy stubs to fix il2cpp build --- .../grpc_csharp_ext_dummy_stubs.c.meta | 93 +++++++++++++++++++ .../grpc_csharp_ext_dummy_stubs.c.template | 26 ++++++ 2 files changed, 119 insertions(+) create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.meta create mode 100644 templates/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.template diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.meta new file mode 100644 index 00000000000..d93af38e48a --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.meta @@ -0,0 +1,93 @@ +fileFormatVersion: 2 +guid: 576b78662f1f8af4fa751f709b620f52 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + isPreloaded: 0 + isOverridable: 0 + platformData: + - first: + '': Any + second: + enabled: 0 + settings: + Exclude Android: 0 + Exclude Editor: 1 + Exclude Linux: 1 + Exclude Linux64: 1 + Exclude LinuxUniversal: 1 + Exclude OSXUniversal: 1 + Exclude Win: 0 + Exclude Win64: 0 + - first: + Android: Android + second: + enabled: 1 + settings: + CPU: ARMv7 + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + CPU: AnyCPU + DefaultValueInitialized: true + OS: AnyOS + - first: + Facebook: Win + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Facebook: Win64 + second: + enabled: 0 + settings: + CPU: AnyCPU + - first: + Standalone: Linux + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Linux64 + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: LinuxUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: OSXUniversal + second: + enabled: 0 + settings: + CPU: None + - first: + Standalone: Win + second: + enabled: 1 + settings: + CPU: AnyCPU + - first: + Standalone: Win64 + second: + enabled: 1 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/templates/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.template b/templates/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.template new file mode 100644 index 00000000000..318113d18a7 --- /dev/null +++ b/templates/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.template @@ -0,0 +1,26 @@ +%YAML 1.2 +--- | + <%namespace file="../../../../../Grpc.Core/Internal/native_methods.include" import="get_native_methods"/> + // Copyright 2019 The gRPC Authors + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + + // When building for Unity Android with il2cpp backend, Unity tries to link + // the __Internal PInvoke definitions (which are required by iOS) even though + // the .so/.dll will be actually used. This file provides dummy stubs to + // make il2cpp happy. + // See https://github.com/grpc/grpc/issues/16012 + + % for method in get_native_methods(): + void ${method['name']}() {} + % endfor From 53b6b363d10b500224c2e8edd65d757290fdf392 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 13 Feb 2019 13:19:59 +0100 Subject: [PATCH 358/814] generate dummy stubs for Unity Android il2cpp --- .../runtimes/grpc_csharp_ext_dummy_stubs.c | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c new file mode 100644 index 00000000000..f7e622ab5f1 --- /dev/null +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c @@ -0,0 +1,116 @@ + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// When building for Unity Android with il2cpp backend, Unity tries to link +// the __Internal PInvoke definitions (which are required by iOS) even though +// the .so/.dll will be actually used. This file provides dummy stubs to +// make il2cpp happy. +// See https://github.com/grpc/grpc/issues/16012 + +void grpcsharp_init() {} +void grpcsharp_shutdown() {} +void grpcsharp_version_string() {} +void grpcsharp_batch_context_create() {} +void grpcsharp_batch_context_recv_initial_metadata() {} +void grpcsharp_batch_context_recv_message_length() {} +void grpcsharp_batch_context_recv_message_to_buffer() {} +void grpcsharp_batch_context_recv_status_on_client_status() {} +void grpcsharp_batch_context_recv_status_on_client_details() {} +void grpcsharp_batch_context_recv_status_on_client_trailing_metadata() {} +void grpcsharp_batch_context_recv_close_on_server_cancelled() {} +void grpcsharp_batch_context_reset() {} +void grpcsharp_batch_context_destroy() {} +void grpcsharp_request_call_context_create() {} +void grpcsharp_request_call_context_call() {} +void grpcsharp_request_call_context_method() {} +void grpcsharp_request_call_context_host() {} +void grpcsharp_request_call_context_deadline() {} +void grpcsharp_request_call_context_request_metadata() {} +void grpcsharp_request_call_context_reset() {} +void grpcsharp_request_call_context_destroy() {} +void grpcsharp_composite_call_credentials_create() {} +void grpcsharp_call_credentials_release() {} +void grpcsharp_call_cancel() {} +void grpcsharp_call_cancel_with_status() {} +void grpcsharp_call_start_unary() {} +void grpcsharp_call_start_client_streaming() {} +void grpcsharp_call_start_server_streaming() {} +void grpcsharp_call_start_duplex_streaming() {} +void grpcsharp_call_send_message() {} +void grpcsharp_call_send_close_from_client() {} +void grpcsharp_call_send_status_from_server() {} +void grpcsharp_call_recv_message() {} +void grpcsharp_call_recv_initial_metadata() {} +void grpcsharp_call_start_serverside() {} +void grpcsharp_call_send_initial_metadata() {} +void grpcsharp_call_set_credentials() {} +void grpcsharp_call_get_peer() {} +void grpcsharp_call_destroy() {} +void grpcsharp_channel_args_create() {} +void grpcsharp_channel_args_set_string() {} +void grpcsharp_channel_args_set_integer() {} +void grpcsharp_channel_args_destroy() {} +void grpcsharp_override_default_ssl_roots() {} +void grpcsharp_ssl_credentials_create() {} +void grpcsharp_composite_channel_credentials_create() {} +void grpcsharp_channel_credentials_release() {} +void grpcsharp_insecure_channel_create() {} +void grpcsharp_secure_channel_create() {} +void grpcsharp_channel_create_call() {} +void grpcsharp_channel_check_connectivity_state() {} +void grpcsharp_channel_watch_connectivity_state() {} +void grpcsharp_channel_get_target() {} +void grpcsharp_channel_destroy() {} +void grpcsharp_sizeof_grpc_event() {} +void grpcsharp_completion_queue_create_async() {} +void grpcsharp_completion_queue_create_sync() {} +void grpcsharp_completion_queue_shutdown() {} +void grpcsharp_completion_queue_next() {} +void grpcsharp_completion_queue_pluck() {} +void grpcsharp_completion_queue_destroy() {} +void gprsharp_free() {} +void grpcsharp_metadata_array_create() {} +void grpcsharp_metadata_array_add() {} +void grpcsharp_metadata_array_count() {} +void grpcsharp_metadata_array_get_key() {} +void grpcsharp_metadata_array_get_value() {} +void grpcsharp_metadata_array_destroy_full() {} +void grpcsharp_redirect_log() {} +void grpcsharp_metadata_credentials_create_from_plugin() {} +void grpcsharp_metadata_credentials_notify_from_plugin() {} +void grpcsharp_ssl_server_credentials_create() {} +void grpcsharp_server_credentials_release() {} +void grpcsharp_server_create() {} +void grpcsharp_server_register_completion_queue() {} +void grpcsharp_server_add_insecure_http2_port() {} +void grpcsharp_server_add_secure_http2_port() {} +void grpcsharp_server_start() {} +void grpcsharp_server_request_call() {} +void grpcsharp_server_cancel_all_calls() {} +void grpcsharp_server_shutdown_and_notify_callback() {} +void grpcsharp_server_destroy() {} +void grpcsharp_call_auth_context() {} +void grpcsharp_auth_context_peer_identity_property_name() {} +void grpcsharp_auth_context_property_iterator() {} +void grpcsharp_auth_property_iterator_next() {} +void grpcsharp_auth_context_release() {} +void gprsharp_now() {} +void gprsharp_inf_future() {} +void gprsharp_inf_past() {} +void gprsharp_convert_clock_type() {} +void gprsharp_sizeof_timespec() {} +void grpcsharp_test_callback() {} +void grpcsharp_test_nop() {} +void grpcsharp_test_override_method() {} From 520dc0461c7f0e94f4117e486761ab00cbb90297 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 13 Feb 2019 06:38:16 -0800 Subject: [PATCH 359/814] fix resolve_address_test --- test/core/iomgr/resolve_address_test.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index b041a15ff34..f59a992416d 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -323,7 +323,11 @@ static bool mock_ipv6_disabled_source_addr_factory_get_source_addr( } void mock_ipv6_disabled_source_addr_factory_destroy( - address_sorting_source_addr_factory* factory) {} + address_sorting_source_addr_factory* factory) { + mock_ipv6_disabled_source_addr_factory* f = + reinterpret_cast(factory); + gpr_free(f); +} const address_sorting_source_addr_factory_vtable kMockIpv6DisabledSourceAddrFactoryVtable = { @@ -390,9 +394,11 @@ int main(int argc, char** argv) { // Run a test case in which c-ares's address sorter // thinks that IPv4 is available and IPv6 isn't. grpc_init(); - mock_ipv6_disabled_source_addr_factory factory; - factory.base.vtable = &kMockIpv6DisabledSourceAddrFactoryVtable; - address_sorting_override_source_addr_factory_for_testing(&factory.base); + mock_ipv6_disabled_source_addr_factory* factory = + static_cast( + gpr_malloc(sizeof(mock_ipv6_disabled_source_addr_factory))); + factory->base.vtable = &kMockIpv6DisabledSourceAddrFactoryVtable; + address_sorting_override_source_addr_factory_for_testing(&factory->base); test_localhost_result_has_ipv4_first_when_ipv6_isnt_available(); grpc_shutdown(); } From bab812376331ac90b714d342667eb941c9e8a4ab Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 13 Feb 2019 08:30:04 -0800 Subject: [PATCH 360/814] LB policy picker API --- BUILD | 4 +- CMakeLists.txt | 12 +- Makefile | 12 +- build.yaml | 4 +- config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 2 +- gRPC-Core.podspec | 6 +- grpc.gemspec | 4 +- grpc.gyp | 8 +- package.xml | 4 +- .../filters/client_channel/client_channel.cc | 683 +++++++++---- .../ext/filters/client_channel/lb_policy.cc | 26 +- .../ext/filters/client_channel/lb_policy.h | 298 ++++-- .../client_channel/lb_policy/grpclb/grpclb.cc | 851 ++++++---------- .../lb_policy/grpclb/grpclb_client_stats.cc | 2 +- .../lb_policy/grpclb/grpclb_client_stats.h | 2 +- .../lb_policy/pick_first/pick_first.cc | 228 ++--- .../lb_policy/round_robin/round_robin.cc | 345 ++----- .../lb_policy/subchannel_list.h | 13 +- .../client_channel/lb_policy/xds/xds.cc | 539 +++------- .../filters/client_channel/request_routing.cc | 946 ------------------ .../filters/client_channel/request_routing.h | 181 ---- .../client_channel/resolving_lb_policy.cc | 460 +++++++++ .../client_channel/resolving_lb_policy.h | 137 +++ .../ext/filters/client_channel/subchannel.cc | 23 +- src/core/lib/gprpp/orphanable.h | 5 +- src/core/lib/gprpp/ref_counted.h | 5 +- src/python/grpcio/grpc_core_dependencies.py | 2 +- .../channel/channel_stack_builder_test.cc | 18 +- test/core/util/test_lb_policies.cc | 146 ++- test/cpp/microbenchmarks/bm_call_create.cc | 1 + tools/doxygen/Doxyfile.core.internal | 4 +- .../generated/sources_and_headers.json | 6 +- 34 files changed, 2043 insertions(+), 2938 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/request_routing.cc delete mode 100644 src/core/ext/filters/client_channel/request_routing.h create mode 100644 src/core/ext/filters/client_channel/resolving_lb_policy.cc create mode 100644 src/core/ext/filters/client_channel/resolving_lb_policy.h diff --git a/BUILD b/BUILD index ebb03580bb4..e464b1854d0 100644 --- a/BUILD +++ b/BUILD @@ -1070,10 +1070,10 @@ grpc_cc_library( "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/proxy_mapper.cc", "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", - "src/core/ext/filters/client_channel/request_routing.cc", "src/core/ext/filters/client_channel/resolver.cc", "src/core/ext/filters/client_channel/resolver_registry.cc", "src/core/ext/filters/client_channel/resolver_result_parsing.cc", + "src/core/ext/filters/client_channel/resolving_lb_policy.cc", "src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/server_address.cc", "src/core/ext/filters/client_channel/subchannel.cc", @@ -1096,11 +1096,11 @@ grpc_cc_library( "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", - "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index b2de3f6fde5..676f18660cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1232,10 +1232,10 @@ add_library(grpc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -1587,10 +1587,10 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -1965,10 +1965,10 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -2290,10 +2290,10 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -2626,10 +2626,10 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -3483,10 +3483,10 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc diff --git a/Makefile b/Makefile index 069d001d3be..3fc9f44cc63 100644 --- a/Makefile +++ b/Makefile @@ -3758,10 +3758,10 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -4107,10 +4107,10 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -4478,10 +4478,10 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -4790,10 +4790,10 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -5100,10 +5100,10 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -5934,10 +5934,10 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ diff --git a/build.yaml b/build.yaml index f96b0cbcf22..c6cbe0470e9 100644 --- a/build.yaml +++ b/build.yaml @@ -587,11 +587,11 @@ filegroups: - src/core/ext/filters/client_channel/parse_address.h - src/core/ext/filters/client_channel/proxy_mapper.h - src/core/ext/filters/client_channel/proxy_mapper_registry.h - - src/core/ext/filters/client_channel/request_routing.h - src/core/ext/filters/client_channel/resolver.h - src/core/ext/filters/client_channel/resolver_factory.h - src/core/ext/filters/client_channel/resolver_registry.h - src/core/ext/filters/client_channel/resolver_result_parsing.h + - src/core/ext/filters/client_channel/resolving_lb_policy.h - src/core/ext/filters/client_channel/retry_throttle.h - src/core/ext/filters/client_channel/server_address.h - src/core/ext/filters/client_channel/subchannel.h @@ -614,10 +614,10 @@ filegroups: - src/core/ext/filters/client_channel/parse_address.cc - src/core/ext/filters/client_channel/proxy_mapper.cc - src/core/ext/filters/client_channel/proxy_mapper_registry.cc - - src/core/ext/filters/client_channel/request_routing.cc - src/core/ext/filters/client_channel/resolver.cc - src/core/ext/filters/client_channel/resolver_registry.cc - src/core/ext/filters/client_channel/resolver_result_parsing.cc + - src/core/ext/filters/client_channel/resolving_lb_policy.cc - src/core/ext/filters/client_channel/retry_throttle.cc - src/core/ext/filters/client_channel/server_address.cc - src/core/ext/filters/client_channel/subchannel.cc diff --git a/config.m4 b/config.m4 index 5746caf694a..2616803d9b0 100644 --- a/config.m4 +++ b/config.m4 @@ -355,10 +355,10 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ diff --git a/config.w32 b/config.w32 index 5659d8b8408..64eca2a8472 100644 --- a/config.w32 +++ b/config.w32 @@ -330,10 +330,10 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\parse_address.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " + - "src\\core\\ext\\filters\\client_channel\\request_routing.cc " + "src\\core\\ext\\filters\\client_channel\\resolver.cc " + "src\\core\\ext\\filters\\client_channel\\resolver_registry.cc " + "src\\core\\ext\\filters\\client_channel\\resolver_result_parsing.cc " + + "src\\core\\ext\\filters\\client_channel\\resolving_lb_policy.cc " + "src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " + "src\\core\\ext\\filters\\client_channel\\server_address.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index e1b1cf1564e..d03fe56660b 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -360,11 +360,11 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', - 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', + 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 625d1a9a50c..c18acea2337 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -354,11 +354,11 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', - 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', + 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', @@ -801,10 +801,10 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -984,11 +984,11 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', - 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', + 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', diff --git a/grpc.gemspec b/grpc.gemspec index a4e25d7bb22..0ab718a0668 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -288,11 +288,11 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/parse_address.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h ) - s.files += %w( src/core/ext/filters/client_channel/request_routing.h ) s.files += %w( src/core/ext/filters/client_channel/resolver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_factory.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.h ) + s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.h ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h ) s.files += %w( src/core/ext/filters/client_channel/server_address.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel.h ) @@ -738,10 +738,10 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/parse_address.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.cc ) - s.files += %w( src/core/ext/filters/client_channel/request_routing.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver_registry.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.cc ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc ) s.files += %w( src/core/ext/filters/client_channel/server_address.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel.cc ) diff --git a/grpc.gyp b/grpc.gyp index 113c17f0d09..ca9d017dbbe 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -537,10 +537,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -801,10 +801,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -1046,10 +1046,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -1302,10 +1302,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', diff --git a/package.xml b/package.xml index aa2bf62411c..1bb1354480d 100644 --- a/package.xml +++ b/package.xml @@ -293,11 +293,11 @@ - + @@ -743,10 +743,10 @@ - + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 38525dbf97e..6de27369ea4 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -32,12 +32,14 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" -#include "src/core/ext/filters/client_channel/request_routing.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" +#include "src/core/ext/filters/client_channel/resolving_lb_policy.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/deadline/deadline_filter.h" @@ -68,6 +70,8 @@ using grpc_core::internal::ClientChannelMethodParamsTable; using grpc_core::internal::ProcessedResolverResult; using grpc_core::internal::ServerRetryThrottleData; +using grpc_core::LoadBalancingPolicy; + /* Client channel implementation */ // By default, we buffer 256 KiB per RPC for retries. @@ -86,44 +90,171 @@ grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel"); struct external_connectivity_watcher; -typedef struct client_channel_channel_data { - grpc_core::ManualConstructor request_router; +struct QueuedPick { + LoadBalancingPolicy::PickState pick; + grpc_call_element* elem; + QueuedPick* next = nullptr; +}; +typedef struct client_channel_channel_data { bool deadline_checking_enabled; bool enable_retries; size_t per_rpc_retry_buffer_size; /** combiner protecting all variables below in this data structure */ grpc_combiner* combiner; - /** retry throttle data */ - grpc_core::RefCountedPtr retry_throttle_data; - /** maps method names to method_parameters structs */ - grpc_core::RefCountedPtr method_params_table; /** owning stack */ grpc_channel_stack* owning_stack; /** interested parties (owned) */ grpc_pollset_set* interested_parties; + // Client channel factory. Holds a ref. + grpc_client_channel_factory* client_channel_factory; + // Subchannel pool. + grpc_core::RefCountedPtr subchannel_pool; - /* external_connectivity_watcher_list head is guarded by its own mutex, since - * counts need to be grabbed immediately without polling on a cq */ - gpr_mu external_connectivity_watcher_list_mu; - struct external_connectivity_watcher* external_connectivity_watcher_list_head; + grpc_core::channelz::ClientChannelNode* channelz_node; + + // Resolving LB policy. + grpc_core::OrphanablePtr resolving_lb_policy; + // Subchannel picker from LB policy. + grpc_core::UniquePtr picker; + // Linked list of queued picks. + QueuedPick* queued_picks; + + bool have_service_config; + /** retry throttle data from service config */ + grpc_core::RefCountedPtr retry_throttle_data; + /** per-method service config data */ + grpc_core::RefCountedPtr method_params_table; /* the following properties are guarded by a mutex since APIs require them to be instantaneously available */ gpr_mu info_mu; grpc_core::UniquePtr info_lb_policy_name; - /** service config in JSON form */ grpc_core::UniquePtr info_service_config_json; + + grpc_connectivity_state_tracker state_tracker; + grpc_error* disconnect_error; + + /* external_connectivity_watcher_list head is guarded by its own mutex, since + * counts need to be grabbed immediately without polling on a cq */ + gpr_mu external_connectivity_watcher_list_mu; + struct external_connectivity_watcher* external_connectivity_watcher_list_head; } channel_data; -// Synchronous callback from chand->request_router to process a resolver +// Forward declarations. +static void start_pick_locked(void* arg, grpc_error* ignored); +static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem); + +static const char* get_channel_connectivity_state_change_string( + grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "Channel state change to IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "Channel state change to CONNECTING"; + case GRPC_CHANNEL_READY: + return "Channel state change to READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "Channel state change to TRANSIENT_FAILURE"; + case GRPC_CHANNEL_SHUTDOWN: + return "Channel state change to SHUTDOWN"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +static void set_connectivity_state_and_picker_locked( + channel_data* chand, grpc_connectivity_state state, grpc_error* state_error, + const char* reason, + grpc_core::UniquePtr picker) { + // Update connectivity state. + grpc_connectivity_state_set(&chand->state_tracker, state, state_error, + reason); + if (chand->channelz_node != nullptr) { + chand->channelz_node->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + get_channel_connectivity_state_change_string(state))); + } + // Update picker. + chand->picker = std::move(picker); + // Re-process queued picks. + for (QueuedPick* pick = chand->queued_picks; pick != nullptr; + pick = pick->next) { + start_pick_locked(pick->elem, GRPC_ERROR_NONE); + } +} + +namespace grpc_core { +namespace { + +class ClientChannelControlHelper + : public LoadBalancingPolicy::ChannelControlHelper { + public: + explicit ClientChannelControlHelper(channel_data* chand) : chand_(chand) { + GRPC_CHANNEL_STACK_REF(chand_->owning_stack, "ClientChannelControlHelper"); + } + + ~ClientChannelControlHelper() override { + GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack, + "ClientChannelControlHelper"); + } + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + grpc_arg arg = SubchannelPoolInterface::CreateChannelArg( + chand_->subchannel_pool.get()); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(&args, &arg, 1); + Subchannel* subchannel = grpc_client_channel_factory_create_subchannel( + chand_->client_channel_factory, new_args); + grpc_channel_args_destroy(new_args); + return subchannel; + } + + grpc_channel* CreateChannel(const char* target, grpc_client_channel_type type, + const grpc_channel_args& args) override { + return grpc_client_channel_factory_create_channel( + chand_->client_channel_factory, target, type, &args); + } + + void UpdateState( + grpc_connectivity_state state, grpc_error* state_error, + UniquePtr picker) override { + if (grpc_client_channel_trace.enabled()) { + const char* extra = chand_->disconnect_error == GRPC_ERROR_NONE + ? "" + : " (ignoring -- channel shutting down)"; + gpr_log(GPR_INFO, "chand=%p: update: state=%s error=%s picker=%p%s", + chand_, grpc_connectivity_state_name(state), + grpc_error_string(state_error), picker.get(), extra); + } + // Do update only if not shutting down. + if (chand_->disconnect_error == GRPC_ERROR_NONE) { + set_connectivity_state_and_picker_locked(chand_, state, state_error, + "helper", std::move(picker)); + } else { + GRPC_ERROR_UNREF(state_error); + } + } + + // No-op -- we should never get this from ResolvingLoadBalancingPolicy. + void RequestReresolution() override {} + + private: + channel_data* chand_; +}; + +} // namespace +} // namespace grpc_core + +// Synchronous callback from chand->resolving_lb_policy to process a resolver // result update. static bool process_resolver_result_locked(void* arg, const grpc_channel_args& args, const char** lb_policy_name, grpc_json** lb_policy_config) { channel_data* chand = static_cast(arg); + chand->have_service_config = true; ProcessedResolverResult resolver_result(args, chand->enable_retries); grpc_core::UniquePtr service_config_json = resolver_result.service_config_json(); @@ -148,9 +279,38 @@ static bool process_resolver_result_locked(void* arg, // Return results. *lb_policy_name = chand->info_lb_policy_name.get(); *lb_policy_config = resolver_result.lb_policy_config(); + // Apply service config to queued picks. + for (QueuedPick* pick = chand->queued_picks; pick != nullptr; + pick = pick->next) { + maybe_apply_service_config_to_call_locked(pick->elem); + } return service_config_changed; } +static grpc_error* do_ping_locked(channel_data* chand, grpc_transport_op* op) { + grpc_error* error = GRPC_ERROR_NONE; + grpc_connectivity_state state = + grpc_connectivity_state_get(&chand->state_tracker, &error); + if (state != GRPC_CHANNEL_READY) { + grpc_error* new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "channel not connected", &error, 1); + GRPC_ERROR_UNREF(error); + return new_error; + } + LoadBalancingPolicy::PickState pick; + chand->picker->Pick(&pick, &error); + if (pick.connected_subchannel != nullptr) { + pick.connected_subchannel->Ping(op->send_ping.on_initiate, + op->send_ping.on_ack); + } else { + if (error == GRPC_ERROR_NONE) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "LB policy dropped call on ping"); + } + } + return error; +} + static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { grpc_transport_op* op = static_cast(arg); grpc_channel_element* elem = @@ -158,47 +318,40 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { channel_data* chand = static_cast(elem->channel_data); if (op->on_connectivity_state_change != nullptr) { - chand->request_router->NotifyOnConnectivityStateChange( - op->connectivity_state, op->on_connectivity_state_change); + grpc_connectivity_state_notify_on_state_change( + &chand->state_tracker, op->connectivity_state, + op->on_connectivity_state_change); op->on_connectivity_state_change = nullptr; op->connectivity_state = nullptr; } if (op->send_ping.on_initiate != nullptr || op->send_ping.on_ack != nullptr) { - if (chand->request_router->lb_policy() == nullptr) { - grpc_error* error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"); + grpc_error* error = do_ping_locked(chand, op); + if (error != GRPC_ERROR_NONE) { GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error)); GRPC_CLOSURE_SCHED(op->send_ping.on_ack, error); - } else { - grpc_error* error = GRPC_ERROR_NONE; - grpc_core::LoadBalancingPolicy::PickState pick_state; - // Pick must return synchronously, because pick_state.on_complete is null. - GPR_ASSERT( - chand->request_router->lb_policy()->PickLocked(&pick_state, &error)); - if (pick_state.connected_subchannel != nullptr) { - pick_state.connected_subchannel->Ping(op->send_ping.on_initiate, - op->send_ping.on_ack); - } else { - if (error == GRPC_ERROR_NONE) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "LB policy dropped call on ping"); - } - GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error)); - GRPC_CLOSURE_SCHED(op->send_ping.on_ack, error); - } - op->bind_pollset = nullptr; } + op->bind_pollset = nullptr; op->send_ping.on_initiate = nullptr; op->send_ping.on_ack = nullptr; } - if (op->disconnect_with_error != GRPC_ERROR_NONE) { - chand->request_router->ShutdownLocked(op->disconnect_with_error); + if (op->reset_connect_backoff) { + chand->resolving_lb_policy->ResetBackoffLocked(); } - if (op->reset_connect_backoff) { - chand->request_router->ResetConnectionBackoffLocked(); + if (op->disconnect_with_error != GRPC_ERROR_NONE) { + chand->disconnect_error = op->disconnect_with_error; + grpc_pollset_set_del_pollset_set( + chand->resolving_lb_policy->interested_parties(), + chand->interested_parties); + chand->resolving_lb_policy.reset(); + set_connectivity_state_and_picker_locked( + chand, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(op->disconnect_with_error), + "shutdown from API", + grpc_core::UniquePtr( + grpc_core::New( + GRPC_ERROR_REF(op->disconnect_with_error)))); } GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "start_transport_op"); @@ -244,6 +397,9 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, GPR_ASSERT(elem->filter == &grpc_client_channel_filter); // Initialize data members. chand->combiner = grpc_combiner_create(); + grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, + "client_channel"); + chand->disconnect_error = GRPC_ERROR_NONE; gpr_mu_init(&chand->info_mu); gpr_mu_init(&chand->external_connectivity_watcher_list_mu); @@ -275,8 +431,9 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "client channel factory arg must be a pointer"); } - grpc_client_channel_factory* client_channel_factory = + chand->client_channel_factory = static_cast(arg->value.pointer.p); + grpc_client_channel_factory_ref(chand->client_channel_factory); // Get server name to resolve, using proxy mapper if needed. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI); if (arg == nullptr) { @@ -291,26 +448,71 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, grpc_channel_args* new_args = nullptr; grpc_proxy_mappers_map_name(arg->value.string, args->channel_args, &proxy_name, &new_args); - // Instantiate request router. - grpc_client_channel_factory_ref(client_channel_factory); + grpc_core::UniquePtr target_uri( + proxy_name != nullptr ? proxy_name : gpr_strdup(arg->value.string)); + // Instantiate subchannel pool. + arg = grpc_channel_args_find(args->channel_args, + GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL); + if (grpc_channel_arg_get_bool(arg, false)) { + chand->subchannel_pool = + grpc_core::MakeRefCounted(); + } else { + chand->subchannel_pool = grpc_core::GlobalSubchannelPool::instance(); + } + // Instantiate resolving LB policy. + LoadBalancingPolicy::Args lb_args; + lb_args.combiner = chand->combiner; + lb_args.channel_control_helper = + grpc_core::UniquePtr( + grpc_core::New(chand)); + lb_args.args = new_args != nullptr ? new_args : args->channel_args; grpc_error* error = GRPC_ERROR_NONE; - chand->request_router.Init( - chand->owning_stack, chand->combiner, client_channel_factory, - chand->interested_parties, &grpc_client_channel_trace, - process_resolver_result_locked, chand, - proxy_name != nullptr ? proxy_name : arg->value.string /* target_uri */, - new_args != nullptr ? new_args : args->channel_args, &error); - gpr_free(proxy_name); + chand->resolving_lb_policy.reset( + grpc_core::New( + std::move(lb_args), &grpc_client_channel_trace, std::move(target_uri), + process_resolver_result_locked, chand, &error)); grpc_channel_args_destroy(new_args); + if (error != GRPC_ERROR_NONE) { + // Orphan the resolving LB policy and flush the exec_ctx to ensure + // that it finishes shutting down. This ensures that if we are + // failing, we destroy the ClientChannelControlHelper (and thus + // unref the channel stack) before we return. + // TODO(roth): This is not a complete solution, because it only + // catches the case where channel stack initialization fails in this + // particular filter. If there is a failure in a different filter, we + // will leave a dangling ref here, which can cause a crash. Fortunately, + // in practice, there are no other filters that can cause failures in + // channel stack initialization, so this works for now. + chand->resolving_lb_policy.reset(); + grpc_core::ExecCtx::Get()->Flush(); + } else { + grpc_pollset_set_add_pollset_set( + chand->resolving_lb_policy->interested_parties(), + chand->interested_parties); + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", chand, + chand->resolving_lb_policy.get()); + } + } return error; } /* Destructor for channel_data */ static void cc_destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); - chand->request_router.Destroy(); + if (chand->resolving_lb_policy != nullptr) { + grpc_pollset_set_del_pollset_set( + chand->resolving_lb_policy->interested_parties(), + chand->interested_parties); + chand->resolving_lb_policy.reset(); + } // TODO(roth): Once we convert the filter API to C++, there will no // longer be any need to explicitly reset these smart pointer data members. + chand->picker.reset(); + chand->subchannel_pool.reset(); + if (chand->client_channel_factory != nullptr) { + grpc_client_channel_factory_unref(chand->client_channel_factory); + } chand->info_lb_policy_name.reset(); chand->info_service_config_json.reset(); chand->retry_throttle_data.reset(); @@ -318,6 +520,8 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { grpc_client_channel_stop_backup_polling(chand->interested_parties); grpc_pollset_set_destroy(chand->interested_parties); GRPC_COMBINER_UNREF(chand->combiner, "client_channel"); + GRPC_ERROR_UNREF(chand->disconnect_error); + grpc_connectivity_state_destroy(&chand->state_tracker); gpr_mu_destroy(&chand->info_mu); gpr_mu_destroy(&chand->external_connectivity_watcher_list_mu); } @@ -371,6 +575,12 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { // (census filter is on top of this one) // - add census stats for retries +namespace grpc_core { +namespace { +class QueuedPickCanceller; +} // namespace +} // namespace grpc_core + namespace { struct call_data; @@ -509,8 +719,11 @@ struct call_data { for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches); ++i) { GPR_ASSERT(pending_batches[i].batch == nullptr); } - if (have_request) { - request.Destroy(); + for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) { + if (pick.pick.subchannel_call_context[i].destroy != nullptr) { + pick.pick.subchannel_call_context[i].destroy( + pick.pick.subchannel_call_context[i].value); + } } } @@ -537,8 +750,10 @@ struct call_data { // Set when we get a cancel_stream op. grpc_error* cancel_error = GRPC_ERROR_NONE; - grpc_core::ManualConstructor request; - bool have_request = false; + QueuedPick pick; + bool pick_queued = false; + bool service_config_applied = false; + grpc_core::QueuedPickCanceller* pick_canceller = nullptr; grpc_closure pick_closure; grpc_polling_entity* pollent = nullptr; @@ -600,7 +815,7 @@ static void retry_commit(grpc_call_element* elem, static void start_internal_recv_trailing_metadata(grpc_call_element* elem); static void on_complete(void* arg, grpc_error* error); static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored); -static void start_pick_locked(void* arg, grpc_error* ignored); +static void remove_call_from_queued_picks_locked(grpc_call_element* elem); // // send op data caching @@ -728,7 +943,7 @@ static void free_cached_send_op_data_for_completed_batch( // void maybe_inject_recv_trailing_metadata_ready_for_lb( - const grpc_core::LoadBalancingPolicy::PickState& pick, + const LoadBalancingPolicy::PickState& pick, grpc_transport_stream_op_batch* batch) { if (pick.recv_trailing_metadata_ready != nullptr) { *pick.original_recv_trailing_metadata_ready = @@ -846,10 +1061,25 @@ static void fail_pending_batch_in_call_combiner(void* arg, grpc_error* error) { } // This is called via the call combiner, so access to calld is synchronized. -// If yield_call_combiner is true, assumes responsibility for yielding -// the call combiner. -static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, - bool yield_call_combiner) { +// If yield_call_combiner_predicate returns true, assumes responsibility for +// yielding the call combiner. +typedef bool (*YieldCallCombinerPredicate)( + const grpc_core::CallCombinerClosureList& closures); +static bool yield_call_combiner( + const grpc_core::CallCombinerClosureList& closures) { + return true; +} +static bool no_yield_call_combiner( + const grpc_core::CallCombinerClosureList& closures) { + return false; +} +static bool yield_call_combiner_if_pending_batches_found( + const grpc_core::CallCombinerClosureList& closures) { + return closures.size() > 0; +} +static void pending_batches_fail( + grpc_call_element* elem, grpc_error* error, + YieldCallCombinerPredicate yield_call_combiner_predicate) { GPR_ASSERT(error != GRPC_ERROR_NONE); call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_trace.enabled()) { @@ -866,9 +1096,9 @@ static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { - if (batch->recv_trailing_metadata && calld->have_request) { - maybe_inject_recv_trailing_metadata_ready_for_lb( - *calld->request->pick(), batch); + if (batch->recv_trailing_metadata) { + maybe_inject_recv_trailing_metadata_ready_for_lb(calld->pick.pick, + batch); } batch->handler_private.extra_arg = calld; GRPC_CLOSURE_INIT(&batch->handler_private.closure, @@ -879,7 +1109,7 @@ static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, pending_batch_clear(calld, pending); } } - if (yield_call_combiner) { + if (yield_call_combiner_predicate(closures)) { closures.RunClosures(calld->call_combiner); } else { closures.RunClosuresWithoutYielding(calld->call_combiner); @@ -923,8 +1153,8 @@ static void pending_batches_resume(grpc_call_element* elem) { grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { if (batch->recv_trailing_metadata) { - maybe_inject_recv_trailing_metadata_ready_for_lb( - *calld->request->pick(), batch); + maybe_inject_recv_trailing_metadata_ready_for_lb(calld->pick.pick, + batch); } batch->handler_private.extra_arg = calld->subchannel_call.get(); GRPC_CLOSURE_INIT(&batch->handler_private.closure, @@ -1015,11 +1245,9 @@ static void do_retry(grpc_call_element* elem, const ClientChannelMethodParams::RetryPolicy* retry_policy = calld->method_params->retry_policy(); GPR_ASSERT(retry_policy != nullptr); + // Reset subchannel call and connected subchannel. calld->subchannel_call.reset(); - if (calld->have_request) { - calld->have_request = false; - calld->request.Destroy(); - } + calld->pick.pick.connected_subchannel.reset(); // Compute backoff delay. grpc_millis next_attempt_time; if (server_pushback_ms >= 0) { @@ -1938,7 +2166,7 @@ static void add_retriable_recv_trailing_metadata_op( batch_data->batch.payload->recv_trailing_metadata .recv_trailing_metadata_ready = &retry_state->recv_trailing_metadata_ready; - maybe_inject_recv_trailing_metadata_ready_for_lb(*calld->request->pick(), + maybe_inject_recv_trailing_metadata_ready_for_lb(calld->pick.pick, &batch_data->batch); } @@ -2207,41 +2435,38 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { // LB pick // -static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { +static void create_subchannel_call(grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); const size_t parent_data_size = calld->enable_retries ? sizeof(subchannel_call_retry_state) : 0; const grpc_core::ConnectedSubchannel::CallArgs call_args = { - calld->pollent, // pollent - calld->path, // path - calld->call_start_time, // start_time - calld->deadline, // deadline - calld->arena, // arena - calld->request->pick()->subchannel_call_context, // context - calld->call_combiner, // call_combiner - parent_data_size // parent_data_size + calld->pollent, // pollent + calld->path, // path + calld->call_start_time, // start_time + calld->deadline, // deadline + calld->arena, // arena + calld->pick.pick.subchannel_call_context, // context + calld->call_combiner, // call_combiner + parent_data_size // parent_data_size }; - grpc_error* new_error = GRPC_ERROR_NONE; + grpc_error* error = GRPC_ERROR_NONE; calld->subchannel_call = - calld->request->pick()->connected_subchannel->CreateCall(call_args, - &new_error); + calld->pick.pick.connected_subchannel->CreateCall(call_args, &error); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, calld, calld->subchannel_call.get(), - grpc_error_string(new_error)); + grpc_error_string(error)); } - if (GPR_UNLIKELY(new_error != GRPC_ERROR_NONE)) { - new_error = grpc_error_add_child(new_error, error); - pending_batches_fail(elem, new_error, true /* yield_call_combiner */); + if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { + pending_batches_fail(elem, error, yield_call_combiner); } else { if (parent_data_size > 0) { - new (calld->subchannel_call->GetParentData()) subchannel_call_retry_state( - calld->request->pick()->subchannel_call_context); + new (calld->subchannel_call->GetParentData()) + subchannel_call_retry_state(calld->pick.pick.subchannel_call_context); } pending_batches_resume(elem); } - GRPC_ERROR_UNREF(error); } // Invoked when a pick is completed, on both success or failure. @@ -2249,54 +2474,106 @@ static void pick_done(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (GPR_UNLIKELY(calld->request->pick()->connected_subchannel == nullptr)) { - // Failed to create subchannel. - // If there was no error, this is an LB policy drop, in which case - // we return an error; otherwise, we may retry. - grpc_status_code status = GRPC_STATUS_OK; - grpc_error_get_status(error, calld->deadline, &status, nullptr, nullptr, - nullptr); - if (error == GRPC_ERROR_NONE || !calld->enable_retries || - !maybe_retry(elem, nullptr /* batch_data */, status, - nullptr /* server_pushback_md */)) { - grpc_error* new_error = - error == GRPC_ERROR_NONE - ? GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Call dropped by load balancing policy") - : GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Failed to create subchannel", &error, 1); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: failed to create subchannel: error=%s", - chand, calld, grpc_error_string(new_error)); - } - pending_batches_fail(elem, new_error, true /* yield_call_combiner */); + if (error != GRPC_ERROR_NONE) { + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: failed to pick subchannel: error=%s", chand, + calld, grpc_error_string(error)); + } + pending_batches_fail(elem, GRPC_ERROR_REF(error), yield_call_combiner); + return; + } + create_subchannel_call(elem); +} + +namespace grpc_core { +namespace { + +// A class to handle the call combiner cancellation callback for a +// queued pick. +class QueuedPickCanceller { + public: + explicit QueuedPickCanceller(grpc_call_element* elem) : elem_(elem) { + auto* calld = static_cast(elem->call_data); + auto* chand = static_cast(elem->channel_data); + GRPC_CALL_STACK_REF(calld->owning_call, "QueuedPickCanceller"); + GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this, + grpc_combiner_scheduler(chand->combiner)); + grpc_call_combiner_set_notify_on_cancel(calld->call_combiner, &closure_); + } + + private: + static void CancelLocked(void* arg, grpc_error* error) { + auto* self = static_cast(arg); + auto* chand = static_cast(self->elem_->channel_data); + auto* calld = static_cast(self->elem_->call_data); + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: cancelling queued pick: " + "error=%s self=%p calld->pick_canceller=%p", + chand, calld, grpc_error_string(error), self, + calld->pick_canceller); + } + if (calld->pick_canceller == self && error != GRPC_ERROR_NONE) { + // Remove pick from list of queued picks. + remove_call_from_queued_picks_locked(self->elem_); + // Fail pending batches on the call. + pending_batches_fail(self->elem_, GRPC_ERROR_REF(error), + yield_call_combiner_if_pending_batches_found); + } + GRPC_CALL_STACK_UNREF(calld->owning_call, "QueuedPickCanceller"); + Delete(self); + } + + grpc_call_element* elem_; + grpc_closure closure_; +}; + +} // namespace +} // namespace grpc_core + +// Removes the call from the channel's list of queued picks. +static void remove_call_from_queued_picks_locked(grpc_call_element* elem) { + auto* chand = static_cast(elem->channel_data); + auto* calld = static_cast(elem->call_data); + for (QueuedPick** pick = &chand->queued_picks; *pick != nullptr; + pick = &(*pick)->next) { + if (*pick == &calld->pick) { + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, "chand=%p calld=%p: removing from queued picks list", + chand, calld); + } + calld->pick_queued = false; + *pick = calld->pick.next; + // Remove call's pollent from channel's interested_parties. + grpc_polling_entity_del_from_pollset_set(calld->pollent, + chand->interested_parties); + // Lame the call combiner canceller. + calld->pick_canceller = nullptr; + break; } - } else { - /* Create call on subchannel. */ - create_subchannel_call(elem, GRPC_ERROR_REF(error)); } } -// If the channel is in TRANSIENT_FAILURE and the call is not -// wait_for_ready=true, fails the call and returns true. -static bool fail_call_if_in_transient_failure(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - grpc_transport_stream_op_batch* batch = calld->pending_batches[0].batch; - if (chand->request_router->GetConnectivityState() == - GRPC_CHANNEL_TRANSIENT_FAILURE && - (batch->payload->send_initial_metadata.send_initial_metadata_flags & - GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) { - pending_batches_fail( - elem, - grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "channel is in state TRANSIENT_FAILURE"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), - true /* yield_call_combiner */); - return true; +// Adds the call to the channel's list of queued picks. +static void add_call_to_queued_picks_locked(grpc_call_element* elem) { + auto* chand = static_cast(elem->channel_data); + auto* calld = static_cast(elem->call_data); + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, "chand=%p calld=%p: adding to queued picks list", chand, + calld); } - return false; + calld->pick_queued = true; + // Add call to queued picks list. + calld->pick.elem = elem; + calld->pick.next = chand->queued_picks; + chand->queued_picks = &calld->pick; + // Add call's pollent to channel's interested_parties, so that I/O + // can be done under the call's CQ. + grpc_polling_entity_add_to_pollset_set(calld->pollent, + chand->interested_parties); + // Register call combiner cancellation callback. + calld->pick_canceller = grpc_core::New(elem); } // Applies service config to the call. Must be invoked once we know @@ -2356,36 +2633,37 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) { } // Invoked once resolver results are available. -static bool maybe_apply_service_config_to_call_locked(void* arg) { - grpc_call_element* elem = static_cast(arg); +static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem) { + channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - // Only get service config data on the first attempt. - if (GPR_LIKELY(calld->num_attempts_completed == 0)) { + // Apply service config data to the call only once, and only if the + // channel has the data available. + if (GPR_LIKELY(chand->have_service_config && + !calld->service_config_applied)) { + calld->service_config_applied = true; apply_service_config_to_call_locked(elem); - // Check this after applying service config, since it may have - // affected the call's wait_for_ready value. - if (fail_call_if_in_transient_failure(elem)) return false; } - return true; } -static void start_pick_locked(void* arg, grpc_error* ignored) { +static const char* pick_result_name( + LoadBalancingPolicy::SubchannelPicker::PickResult result) { + switch (result) { + case LoadBalancingPolicy::SubchannelPicker::PICK_COMPLETE: + return "COMPLETE"; + case LoadBalancingPolicy::SubchannelPicker::PICK_QUEUE: + return "QUEUE"; + case LoadBalancingPolicy::SubchannelPicker::PICK_TRANSIENT_FAILURE: + return "TRANSIENT_FAILURE"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +static void start_pick_locked(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); call_data* calld = static_cast(elem->call_data); channel_data* chand = static_cast(elem->channel_data); - GPR_ASSERT(!calld->have_request); + GPR_ASSERT(calld->pick.pick.connected_subchannel == nullptr); GPR_ASSERT(calld->subchannel_call == nullptr); - // Normally, we want to do this check until after we've processed the - // service config, so that we can honor the wait_for_ready setting in - // the service config. However, if the channel is in TRANSIENT_FAILURE - // and we don't have an LB policy at this point, that means that the - // resolver has returned a failure, so we're not going to get a service - // config right away. In that case, we fail the call now based on the - // wait_for_ready value passed in from the application. - if (chand->request_router->lb_policy() == nullptr && - fail_call_if_in_transient_failure(elem)) { - return; - } // If this is a retry, use the send_initial_metadata payload that // we've cached; otherwise, use the pending batch. The // send_initial_metadata batch will be the first pending batch in the @@ -2396,25 +2674,78 @@ static void start_pick_locked(void* arg, grpc_error* ignored) { // allocate the subchannel batch earlier so that we can give the // subchannel's copy of the metadata batch (which is copied for each // attempt) to the LB policy instead the one from the parent channel. - grpc_metadata_batch* initial_metadata = + calld->pick.pick.initial_metadata = calld->seen_send_initial_metadata ? &calld->send_initial_metadata : calld->pending_batches[0] .batch->payload->send_initial_metadata.send_initial_metadata; - uint32_t* initial_metadata_flags = + uint32_t* send_initial_metadata_flags = calld->seen_send_initial_metadata ? &calld->send_initial_metadata_flags : &calld->pending_batches[0] .batch->payload->send_initial_metadata .send_initial_metadata_flags; + // Apply service config to call if needed. + maybe_apply_service_config_to_call_locked(elem); + // When done, we schedule this closure to leave the channel combiner. GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem, grpc_schedule_on_exec_ctx); - calld->request.Init(calld->owning_call, calld->call_combiner, calld->pollent, - initial_metadata, initial_metadata_flags, - maybe_apply_service_config_to_call_locked, elem, - &calld->pick_closure); - calld->have_request = true; - chand->request_router->RouteCallLocked(calld->request.get()); + // Attempt pick. + error = GRPC_ERROR_NONE; + auto pick_result = chand->picker->Pick(&calld->pick.pick, &error); + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: LB pick returned %s (connected_subchannel=%p, " + "error=%s)", + chand, calld, pick_result_name(pick_result), + calld->pick.pick.connected_subchannel.get(), + grpc_error_string(error)); + } + switch (pick_result) { + case LoadBalancingPolicy::SubchannelPicker::PICK_TRANSIENT_FAILURE: + // If we're shutting down, fail all RPCs. + if (chand->disconnect_error != GRPC_ERROR_NONE) { + GRPC_ERROR_UNREF(error); + GRPC_CLOSURE_SCHED(&calld->pick_closure, + GRPC_ERROR_REF(chand->disconnect_error)); + break; + } + // If wait_for_ready is false, then the error indicates the RPC + // attempt's final status. + if ((*send_initial_metadata_flags & + GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) { + // Retry if appropriate; otherwise, fail. + grpc_status_code status = GRPC_STATUS_OK; + grpc_error_get_status(error, calld->deadline, &status, nullptr, nullptr, + nullptr); + if (!calld->enable_retries || + !maybe_retry(elem, nullptr /* batch_data */, status, + nullptr /* server_pushback_md */)) { + grpc_error* new_error = + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Failed to create subchannel", &error, 1); + GRPC_ERROR_UNREF(error); + GRPC_CLOSURE_SCHED(&calld->pick_closure, new_error); + } + if (calld->pick_queued) remove_call_from_queued_picks_locked(elem); + break; + } + // If wait_for_ready is true, then queue to retry when we get a new + // picker. + GRPC_ERROR_UNREF(error); + // Fallthrough + case LoadBalancingPolicy::SubchannelPicker::PICK_QUEUE: + if (!calld->pick_queued) add_call_to_queued_picks_locked(elem); + break; + default: // PICK_COMPLETE + // Handle drops. + if (GPR_UNLIKELY(calld->pick.pick.connected_subchannel == nullptr)) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Call dropped by load balancing policy"); + } + GRPC_CLOSURE_SCHED(&calld->pick_closure, error); + if (calld->pick_queued) remove_call_from_queued_picks_locked(elem); + } } // @@ -2458,8 +2789,10 @@ static void cc_start_transport_stream_op_batch( // been started), fail all pending batches. Otherwise, send the // cancellation down to the subchannel call. if (calld->subchannel_call == nullptr) { + // TODO(roth): If there is a pending retry callback, do we need to + // cancel it here? pending_batches_fail(elem, GRPC_ERROR_REF(calld->cancel_error), - false /* yield_call_combiner */); + no_yield_call_combiner); // Note: This will release the call combiner. grpc_transport_stream_op_batch_finish_with_failure( batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner); @@ -2556,7 +2889,8 @@ const grpc_channel_filter grpc_client_channel_filter = { void grpc_client_channel_set_channelz_node( grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node) { channel_data* chand = static_cast(elem->channel_data); - chand->request_router->set_channelz_node(node); + chand->channelz_node = node; + chand->resolving_lb_policy->set_channelz_node(node->Ref()); } void grpc_client_channel_populate_child_refs( @@ -2564,22 +2898,23 @@ void grpc_client_channel_populate_child_refs( grpc_core::channelz::ChildRefsList* child_subchannels, grpc_core::channelz::ChildRefsList* child_channels) { channel_data* chand = static_cast(elem->channel_data); - if (chand->request_router->lb_policy() != nullptr) { - chand->request_router->lb_policy()->FillChildRefsForChannelz( - child_subchannels, child_channels); + if (chand->resolving_lb_policy != nullptr) { + chand->resolving_lb_policy->FillChildRefsForChannelz(child_subchannels, + child_channels); } } static void try_to_connect_locked(void* arg, grpc_error* error_ignored) { channel_data* chand = static_cast(arg); - chand->request_router->ExitIdleLocked(); + chand->resolving_lb_policy->ExitIdleLocked(); GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "try_to_connect"); } grpc_connectivity_state grpc_client_channel_check_connectivity_state( grpc_channel_element* elem, int try_to_connect) { channel_data* chand = static_cast(elem->channel_data); - grpc_connectivity_state out = chand->request_router->GetConnectivityState(); + grpc_connectivity_state out = + grpc_connectivity_state_check(&chand->state_tracker); if (out == GRPC_CHANNEL_IDLE && try_to_connect) { GRPC_CHANNEL_STACK_REF(chand->owning_stack, "try_to_connect"); GRPC_CLOSURE_SCHED( @@ -2688,15 +3023,15 @@ static void watch_connectivity_state_locked(void* arg, GRPC_CLOSURE_RUN(w->watcher_timer_init, GRPC_ERROR_NONE); GRPC_CLOSURE_INIT(&w->my_closure, on_external_watch_complete_locked, w, grpc_combiner_scheduler(w->chand->combiner)); - w->chand->request_router->NotifyOnConnectivityStateChange(w->state, - &w->my_closure); + grpc_connectivity_state_notify_on_state_change(&w->chand->state_tracker, + w->state, &w->my_closure); } else { GPR_ASSERT(w->watcher_timer_init == nullptr); found = lookup_external_connectivity_watcher(w->chand, w->on_complete); if (found) { GPR_ASSERT(found->on_complete == w->on_complete); - found->chand->request_router->NotifyOnConnectivityStateChange( - nullptr, &found->my_closure); + grpc_connectivity_state_notify_on_state_change( + &found->chand->state_tracker, nullptr, &found->my_closure); } grpc_polling_entity_del_from_pollset_set(&w->pollent, w->chand->interested_parties); diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index d9b3927d1ca..9e3477b9ed5 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -54,35 +54,15 @@ grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( return nullptr; } -LoadBalancingPolicy::LoadBalancingPolicy(Args args) - : InternallyRefCounted(&grpc_trace_lb_policy_refcount), +LoadBalancingPolicy::LoadBalancingPolicy(Args args, intptr_t initial_refcount) + : InternallyRefCounted(&grpc_trace_lb_policy_refcount, initial_refcount), combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), - client_channel_factory_(args.client_channel_factory), - subchannel_pool_(std::move(args.subchannel_pool)), interested_parties_(grpc_pollset_set_create()), - request_reresolution_(nullptr) {} + channel_control_helper_(std::move(args.channel_control_helper)) {} LoadBalancingPolicy::~LoadBalancingPolicy() { grpc_pollset_set_destroy(interested_parties_); GRPC_COMBINER_UNREF(combiner_, "lb_policy"); } -void LoadBalancingPolicy::TryReresolutionLocked( - grpc_core::TraceFlag* grpc_lb_trace, grpc_error* error) { - if (request_reresolution_ != nullptr) { - GRPC_CLOSURE_SCHED(request_reresolution_, error); - request_reresolution_ = nullptr; - if (grpc_lb_trace->enabled()) { - gpr_log(GPR_INFO, - "%s %p: scheduling re-resolution closure with error=%s.", - grpc_lb_trace->name(), this, grpc_error_string(error)); - } - } else { - if (grpc_lb_trace->enabled()) { - gpr_log(GPR_INFO, "%s %p: no available re-resolution closure.", - grpc_lb_trace->name(), this); - } - } -} - } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 56bf1951cfb..aeb8138a12e 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -24,7 +24,6 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -43,8 +42,179 @@ namespace grpc_core { /// /// Any I/O done by the LB policy should be done under the pollset_set /// returned by \a interested_parties(). +// TODO(roth): Once we move to EventManager-based polling, remove the +// interested_parties() hooks from the API. class LoadBalancingPolicy : public InternallyRefCounted { public: + /// State used for an LB pick. + struct PickState { + /// Initial metadata associated with the picking call. + /// This is both an input and output parameter; the LB policy may + /// use metadata here to influence its routing decision, and it may + /// add new metadata here to be sent with the call to the chosen backend. + grpc_metadata_batch* initial_metadata = nullptr; + /// Storage for LB token in \a initial_metadata, or nullptr if not used. + // TODO(roth): Remove this from the API. Maybe have the LB policy + // allocate this on the arena instead? + grpc_linked_mdelem lb_token_mdelem_storage; + /// Callback set by lb policy to be notified of trailing metadata. + /// The callback must be scheduled on grpc_schedule_on_exec_ctx. + grpc_closure* recv_trailing_metadata_ready = nullptr; + /// The address that will be set to point to the original + /// recv_trailing_metadata_ready callback, to be invoked by the LB + /// policy's recv_trailing_metadata_ready callback when complete. + /// Must be non-null if recv_trailing_metadata_ready is non-null. + grpc_closure** original_recv_trailing_metadata_ready = nullptr; + /// If this is not nullptr, then the client channel will point it to the + /// call's trailing metadata before invoking recv_trailing_metadata_ready. + /// If this is nullptr, then the callback will still be called. + /// The lb does not have ownership of the metadata. + grpc_metadata_batch** recv_trailing_metadata = nullptr; + /// Will be set to the selected subchannel, or nullptr on failure or when + /// the LB policy decides to drop the call. + RefCountedPtr connected_subchannel; + /// Will be populated with context to pass to the subchannel call, if + /// needed. + // TODO(roth): Remove this from the API, especially since it's not + // working properly anyway (see https://github.com/grpc/grpc/issues/15927). + grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; + }; + + /// A picker is the object used to actual perform picks. + /// + /// Pickers are intended to encapsulate all of the state and logic + /// needed on the data plane (i.e., to actually process picks for + /// individual RPCs sent on the channel) while excluding all of the + /// state and logic needed on the control plane (i.e., resolver + /// updates, connectivity state notifications, etc); the latter should + /// live in the LB policy object itself. + /// + /// Currently, pickers are always accessed from within the + /// client_channel combiner, so they do not have to be thread-safe. + // TODO(roth): In a subsequent PR, split the data plane work (i.e., + // the interaction with the picker) and the control plane work (i.e., + // the interaction with the LB policy) into two different + // synchronization mechanisms, to avoid lock contention between the two. + class SubchannelPicker { + public: + enum PickResult { + // Pick complete. If connected_subchannel is non-null, client channel + // can immediately proceed with the call on connected_subchannel; + // otherwise, call should be dropped. + PICK_COMPLETE, + // Pick cannot be completed until something changes on the control + // plane. Client channel will queue the pick and try again the + // next time the picker is updated. + PICK_QUEUE, + // LB policy is in transient failure. If the pick is wait_for_ready, + // client channel will wait for the next picker and try again; + // otherwise, the call will be failed immediately (although it may + // be retried if the client channel is configured to do so). + // The Pick() method will set its error parameter if this value is + // returned. + PICK_TRANSIENT_FAILURE, + }; + + SubchannelPicker() = default; + virtual ~SubchannelPicker() = default; + + virtual PickResult Pick(PickState* pick, grpc_error** error) GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + }; + + // A picker that returns PICK_QUEUE for all picks. + // Also calls the parent LB policy's ExitIdleLocked() method when the + // first pick is seen. + class QueuePicker : public SubchannelPicker { + public: + explicit QueuePicker(RefCountedPtr parent) + : parent_(std::move(parent)) {} + + PickResult Pick(PickState* pick, grpc_error** error) override { + // We invoke the parent's ExitIdleLocked() via a closure instead + // of doing it directly here, for two reasons: + // 1. ExitIdleLocked() may cause the policy's state to change and + // a new picker to be delivered to the channel. If that new + // picker is delivered before ExitIdleLocked() returns, then by + // the time this function returns, the pick will already have + // been processed, and we'll be trying to re-process the same + // pick again, leading to a crash. + // 2. In a subsequent PR, we will split the data plane and control + // plane synchronization into separate combiners, at which + // point this will need to hop from the data plane combiner into + // the control plane combiner. + if (!exit_idle_called_) { + exit_idle_called_ = true; + parent_->Ref().release(); // ref held by closure. + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(&CallExitIdle, parent_.get(), + grpc_combiner_scheduler(parent_->combiner())), + GRPC_ERROR_NONE); + } + return PICK_QUEUE; + } + + private: + static void CallExitIdle(void* arg, grpc_error* error) { + LoadBalancingPolicy* parent = static_cast(arg); + parent->ExitIdleLocked(); + parent->Unref(); + } + + RefCountedPtr parent_; + bool exit_idle_called_ = false; + }; + + // A picker that returns PICK_TRANSIENT_FAILURE for all picks. + class TransientFailurePicker : public SubchannelPicker { + public: + explicit TransientFailurePicker(grpc_error* error) : error_(error) {} + ~TransientFailurePicker() { GRPC_ERROR_UNREF(error_); } + + PickResult Pick(PickState* pick, grpc_error** error) override { + *error = GRPC_ERROR_REF(error_); + return PICK_TRANSIENT_FAILURE; + } + + private: + grpc_error* error_; + }; + + /// A proxy object used by the LB policy to communicate with the client + /// channel. + class ChannelControlHelper { + public: + ChannelControlHelper() = default; + virtual ~ChannelControlHelper() = default; + + /// Creates a new subchannel with the specified channel args. + virtual Subchannel* CreateSubchannel(const grpc_channel_args& args) + GRPC_ABSTRACT; + + /// Creates a channel with the specified target, type, and channel args. + virtual grpc_channel* CreateChannel( + const char* target, grpc_client_channel_type type, + const grpc_channel_args& args) GRPC_ABSTRACT; + + /// Sets the connectivity state and returns a new picker to be used + /// by the client channel. + virtual void UpdateState(grpc_connectivity_state state, + grpc_error* state_error, + UniquePtr picker) { + std::move(picker); // Suppress clang-tidy complaint. + // The rest of this is copied from the GRPC_ABSTRACT macro. + gpr_log(GPR_ERROR, "Function marked GRPC_ABSTRACT was not implemented"); + GPR_ASSERT(false); + } + + /// Requests that the resolver re-resolve. + virtual void RequestReresolution() GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + }; + + /// Args used to instantiate an LB policy. struct Args { /// The combiner under which all LB policy calls will be run. /// Policy does NOT take ownership of the reference to the combiner. @@ -52,54 +222,16 @@ class LoadBalancingPolicy : public InternallyRefCounted { // API should change to take a smart pointer that does pass ownership // of a reference. grpc_combiner* combiner = nullptr; - /// Used to create channels and subchannels. - grpc_client_channel_factory* client_channel_factory = nullptr; - /// Subchannel pool. - RefCountedPtr subchannel_pool; + /// Channel control helper. + UniquePtr channel_control_helper; /// Channel args from the resolver. /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. - grpc_channel_args* args = nullptr; + const grpc_channel_args* args = nullptr; /// Load balancing config from the resolver. grpc_json* lb_config = nullptr; }; - /// State used for an LB pick. - struct PickState { - /// Initial metadata associated with the picking call. - grpc_metadata_batch* initial_metadata = nullptr; - /// Pointer to bitmask used for selective cancelling. See - /// \a CancelMatchingPicksLocked() and \a GRPC_INITIAL_METADATA_* in - /// grpc_types.h. - uint32_t* initial_metadata_flags = nullptr; - /// Storage for LB token in \a initial_metadata, or nullptr if not used. - grpc_linked_mdelem lb_token_mdelem_storage; - /// Closure to run when pick is complete, if not completed synchronously. - /// If null, pick will fail if a result is not available synchronously. - grpc_closure* on_complete = nullptr; - // Callback set by lb policy to be notified of trailing metadata. - // The callback must be scheduled on grpc_schedule_on_exec_ctx. - grpc_closure* recv_trailing_metadata_ready = nullptr; - // The address that will be set to point to the original - // recv_trailing_metadata_ready callback, to be invoked by the LB - // policy's recv_trailing_metadata_ready callback when complete. - // Must be non-null if recv_trailing_metadata_ready is non-null. - grpc_closure** original_recv_trailing_metadata_ready = nullptr; - // If this is not nullptr, then the client channel will point it to the - // call's trailing metadata before invoking recv_trailing_metadata_ready. - // If this is nullptr, then the callback will still be called. - // The lb does not have ownership of the metadata. - grpc_metadata_batch** recv_trailing_metadata = nullptr; - /// Will be set to the selected subchannel, or nullptr on failure or when - /// the LB policy decides to drop the call. - RefCountedPtr connected_subchannel; - /// Will be populated with context to pass to the subchannel call, if - /// needed. - grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; - /// Next pointer. For internal use by LB policy. - PickState* next = nullptr; - }; - // Not copyable nor movable. LoadBalancingPolicy(const LoadBalancingPolicy&) = delete; LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete; @@ -113,48 +245,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) GRPC_ABSTRACT; - /// Finds an appropriate subchannel for a call, based on data in \a pick. - /// \a pick must remain alive until the pick is complete. - /// - /// If a result is known immediately, returns true, setting \a *error - /// upon failure. Otherwise, \a pick->on_complete will be invoked once - /// the pick is complete with its error argument set to indicate success - /// or failure. - /// - /// If \a pick->on_complete is null and no result is known immediately, - /// a synchronous failure will be returned (i.e., \a *error will be - /// set and true will be returned). - virtual bool PickLocked(PickState* pick, grpc_error** error) GRPC_ABSTRACT; - - /// Cancels \a pick. - /// The \a on_complete callback of the pending pick will be invoked with - /// \a pick->connected_subchannel set to null. - virtual void CancelPickLocked(PickState* pick, - grpc_error* error) GRPC_ABSTRACT; - - /// Cancels all pending picks for which their \a initial_metadata_flags (as - /// given in the call to \a PickLocked()) matches - /// \a initial_metadata_flags_eq when ANDed with - /// \a initial_metadata_flags_mask. - virtual void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) GRPC_ABSTRACT; - - /// Requests a notification when the connectivity state of the policy - /// changes from \a *state. When that happens, sets \a *state to the - /// new state and schedules \a closure. - virtual void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) GRPC_ABSTRACT; - - /// Returns the policy's current connectivity state. Sets \a error to - /// the associated error, if any. - virtual grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) GRPC_ABSTRACT; - - /// Hands off pending picks to \a new_policy. - virtual void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) - GRPC_ABSTRACT; - /// Tries to enter a READY connectivity state. /// TODO(roth): As part of restructuring how we handle IDLE state, /// consider whether this method is still needed. @@ -183,18 +273,11 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// given the JSON node of a LoadBalancingConfig array. static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array); - /// Sets the re-resolution closure to \a request_reresolution. - void SetReresolutionClosureLocked(grpc_closure* request_reresolution) { - GPR_ASSERT(request_reresolution_ == nullptr); - request_reresolution_ = request_reresolution; - } - grpc_pollset_set* interested_parties() const { return interested_parties_; } - // Callers that need their own reference can call the returned - // object's Ref() method. - SubchannelPoolInterface* subchannel_pool() const { - return subchannel_pool_.get(); + void set_channelz_node( + RefCountedPtr channelz_node) { + channelz_node_ = std::move(channelz_node); } GRPC_ABSTRACT_BASE_CLASS @@ -202,12 +285,18 @@ class LoadBalancingPolicy : public InternallyRefCounted { protected: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - explicit LoadBalancingPolicy(Args args); + explicit LoadBalancingPolicy(Args args, intptr_t initial_refcount = 1); virtual ~LoadBalancingPolicy(); grpc_combiner* combiner() const { return combiner_; } - grpc_client_channel_factory* client_channel_factory() const { - return client_channel_factory_; + + // Note: This will return null after ShutdownLocked() has been called. + ChannelControlHelper* channel_control_helper() const { + return channel_control_helper_.get(); + } + + channelz::ClientChannelNode* channelz_node() const { + return channelz_node_.get(); } /// Shuts down the policy. Any pending picks that have not been @@ -215,27 +304,22 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// failed. virtual void ShutdownLocked() GRPC_ABSTRACT; - /// Tries to request a re-resolution. - void TryReresolutionLocked(grpc_core::TraceFlag* grpc_lb_trace, - grpc_error* error); - private: static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) { LoadBalancingPolicy* policy = static_cast(arg); policy->ShutdownLocked(); + policy->channel_control_helper_.reset(); policy->Unref(); } /// Combiner under which LB policy actions take place. grpc_combiner* combiner_; - /// Client channel factory, used to create channels and subchannels. - grpc_client_channel_factory* client_channel_factory_; - /// Subchannel pool. - RefCountedPtr subchannel_pool_; /// Owned pointer to interested parties in load balancing decisions. grpc_pollset_set* interested_parties_; - /// Callback to force a re-resolution. - grpc_closure* request_reresolution_; + /// Channel control helper. + UniquePtr channel_control_helper_; + /// Channelz node. + RefCountedPtr channelz_node_; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 63e381d64c7..fa1ca6d127a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -74,7 +74,6 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" @@ -131,16 +130,6 @@ class GrpcLb : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( @@ -148,31 +137,6 @@ class GrpcLb : public LoadBalancingPolicy { channelz::ChildRefsList* child_channels) override; private: - /// Linked list of pending pick requests. It stores all information needed to - /// eventually call (Round Robin's) pick() on them. They mainly stay pending - /// waiting for the RR policy to be created. - /// - /// Note that when a pick is sent to the RR policy, we inject our own - /// on_complete callback, so that we can intercept the result before - /// invoking the original on_complete callback. This allows us to set the - /// LB token metadata and add client_stats to the call context. - /// See \a pending_pick_complete() for details. - struct PendingPick { - // The grpclb instance that created the wrapping. This instance is not - // owned; reference counts are untouched. It's used only for logging - // purposes. - GrpcLb* grpclb_policy; - // The original pick. - PickState* pick; - // Our on_complete closure and the original one. - grpc_closure on_complete; - grpc_closure* original_on_complete; - // Stats for client-side load reporting. - RefCountedPtr client_stats; - // Next pending pick. - PendingPick* next = nullptr; - }; - /// Contains a call to the LB server and all the data related to the call. class BalancerCallState : public InternallyRefCounted { public: @@ -248,6 +212,80 @@ class GrpcLb : public LoadBalancingPolicy { grpc_closure client_load_report_closure_; }; + class Serverlist : public RefCounted { + public: + // Takes ownership of serverlist. + explicit Serverlist(grpc_grpclb_serverlist* serverlist) + : serverlist_(serverlist) {} + + ~Serverlist() { grpc_grpclb_destroy_serverlist(serverlist_); } + + bool operator==(const Serverlist& other) const; + + const grpc_grpclb_serverlist* serverlist() const { return serverlist_; } + + // Returns a text representation suitable for logging. + UniquePtr AsText() const; + + // Extracts all non-drop entries into a ServerAddressList. + ServerAddressList GetServerAddressList() const; + + // Returns true if the serverlist contains at least one drop entry and + // no backend address entries. + bool ContainsAllDropEntries() const; + + // Returns the LB token to use for a drop, or null if the call + // should not be dropped. + // Intended to be called from picker, so calls will be externally + // synchronized. + const char* ShouldDrop(); + + private: + grpc_grpclb_serverlist* serverlist_; + size_t drop_index_ = 0; + }; + + class Picker : public SubchannelPicker { + public: + Picker(GrpcLb* parent, RefCountedPtr serverlist, + UniquePtr child_picker, + RefCountedPtr client_stats) + : parent_(parent), + serverlist_(std::move(serverlist)), + child_picker_(std::move(child_picker)), + client_stats_(std::move(client_stats)) {} + + PickResult Pick(PickState* pick, grpc_error** error) override; + + private: + // Storing the address for logging, but not holding a ref. + // DO NOT DEFERENCE! + GrpcLb* parent_; + + // Serverlist to be used for determining drops. + RefCountedPtr serverlist_; + + UniquePtr child_picker_; + RefCountedPtr client_stats_; + }; + + class Helper : public ChannelControlHelper { + public: + explicit Helper(RefCountedPtr parent) + : parent_(std::move(parent)) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + grpc_channel* CreateChannel(const char* target, + grpc_client_channel_type type, + const grpc_channel_args& args) override; + void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + UniquePtr picker) override; + void RequestReresolution() override; + + private: + RefCountedPtr parent_; + }; + ~GrpcLb(); void ShutdownLocked() override; @@ -264,24 +302,10 @@ class GrpcLb : public LoadBalancingPolicy { static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); - // Pending pick methods. - static void PendingPickSetMetadataAndContext(PendingPick* pp); - PendingPick* PendingPickCreate(PickState* pick); - void AddPendingPick(PendingPick* pp); - static void OnPendingPickComplete(void* arg, grpc_error* error); - // Methods for dealing with the RR policy. void CreateOrUpdateRoundRobinPolicyLocked(); grpc_channel_args* CreateRoundRobinPolicyArgsLocked(); void CreateRoundRobinPolicyLocked(Args args); - bool PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error); - void UpdateConnectivityStateFromRoundRobinPolicyLocked( - grpc_error* rr_state_error); - static void OnRoundRobinConnectivityChangedLocked(void* arg, - grpc_error* error); - static void OnRoundRobinRequestReresolutionLocked(void* arg, - grpc_error* error); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -292,7 +316,6 @@ class GrpcLb : public LoadBalancingPolicy { // Internal state. bool started_picking_ = false; bool shutting_down_ = false; - grpc_connectivity_state_tracker state_tracker_; // The channel for communicating with the LB server. grpc_channel* lb_channel_ = nullptr; @@ -321,11 +344,7 @@ class GrpcLb : public LoadBalancingPolicy { // The deserialized response from the balancer. May be nullptr until one // such response has arrived. - grpc_grpclb_serverlist* serverlist_ = nullptr; - // Index into serverlist for next pick. - // If the server at this index is a drop, we return a drop. - // Otherwise, we delegate to the RR policy. - size_t serverlist_index_ = 0; + RefCountedPtr serverlist_; // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. @@ -337,20 +356,65 @@ class GrpcLb : public LoadBalancingPolicy { grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; - // Pending picks that are waiting on the RR policy's connectivity. - PendingPick* pending_picks_ = nullptr; - // The RR policy to use for the backends. OrphanablePtr rr_policy_; - grpc_connectivity_state rr_connectivity_state_; - grpc_closure on_rr_connectivity_changed_; - grpc_closure on_rr_request_reresolution_; }; // -// serverlist parsing code +// GrpcLb::Serverlist // +bool GrpcLb::Serverlist::operator==(const Serverlist& other) const { + return grpc_grpclb_serverlist_equals(serverlist_, other.serverlist_); +} + +void ParseServer(const grpc_grpclb_server* server, + grpc_resolved_address* addr) { + memset(addr, 0, sizeof(*addr)); + if (server->drop) return; + const uint16_t netorder_port = grpc_htons((uint16_t)server->port); + /* the addresses are given in binary format (a in(6)_addr struct) in + * server->ip_address.bytes. */ + const grpc_grpclb_ip_address* ip = &server->ip_address; + if (ip->size == 4) { + addr->len = static_cast(sizeof(grpc_sockaddr_in)); + grpc_sockaddr_in* addr4 = reinterpret_cast(&addr->addr); + addr4->sin_family = GRPC_AF_INET; + memcpy(&addr4->sin_addr, ip->bytes, ip->size); + addr4->sin_port = netorder_port; + } else if (ip->size == 16) { + addr->len = static_cast(sizeof(grpc_sockaddr_in6)); + grpc_sockaddr_in6* addr6 = (grpc_sockaddr_in6*)&addr->addr; + addr6->sin6_family = GRPC_AF_INET6; + memcpy(&addr6->sin6_addr, ip->bytes, ip->size); + addr6->sin6_port = netorder_port; + } +} + +UniquePtr GrpcLb::Serverlist::AsText() const { + gpr_strvec entries; + gpr_strvec_init(&entries); + for (size_t i = 0; i < serverlist_->num_servers; ++i) { + const auto* server = serverlist_->servers[i]; + char* ipport; + if (server->drop) { + ipport = gpr_strdup("(drop)"); + } else { + grpc_resolved_address addr; + ParseServer(server, &addr); + grpc_sockaddr_to_string(&ipport, &addr, false); + } + char* entry; + gpr_asprintf(&entry, " %" PRIuPTR ": %s token=%s\n", i, ipport, + server->load_balance_token); + gpr_free(ipport); + gpr_strvec_add(&entries, entry); + } + UniquePtr result(gpr_strvec_flatten(&entries, nullptr)); + gpr_strvec_destroy(&entries); + return result; +} + // vtable for LB token channel arg. void* lb_token_copy(void* token) { return token == nullptr @@ -393,35 +457,12 @@ bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) { return true; } -void ParseServer(const grpc_grpclb_server* server, - grpc_resolved_address* addr) { - memset(addr, 0, sizeof(*addr)); - if (server->drop) return; - const uint16_t netorder_port = grpc_htons((uint16_t)server->port); - /* the addresses are given in binary format (a in(6)_addr struct) in - * server->ip_address.bytes. */ - const grpc_grpclb_ip_address* ip = &server->ip_address; - if (ip->size == 4) { - addr->len = static_cast(sizeof(grpc_sockaddr_in)); - grpc_sockaddr_in* addr4 = reinterpret_cast(&addr->addr); - addr4->sin_family = GRPC_AF_INET; - memcpy(&addr4->sin_addr, ip->bytes, ip->size); - addr4->sin_port = netorder_port; - } else if (ip->size == 16) { - addr->len = static_cast(sizeof(grpc_sockaddr_in6)); - grpc_sockaddr_in6* addr6 = (grpc_sockaddr_in6*)&addr->addr; - addr6->sin6_family = GRPC_AF_INET6; - memcpy(&addr6->sin6_addr, ip->bytes, ip->size); - addr6->sin6_port = netorder_port; - } -} - -// Returns addresses extracted from \a serverlist. -ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { +// Returns addresses extracted from the serverlist. +ServerAddressList GrpcLb::Serverlist::GetServerAddressList() const { ServerAddressList addresses; - for (size_t i = 0; i < serverlist->num_servers; ++i) { - const grpc_grpclb_server* server = serverlist->servers[i]; - if (!IsServerValid(serverlist->servers[i], i, false)) continue; + for (size_t i = 0; i < serverlist_->num_servers; ++i) { + const grpc_grpclb_server* server = serverlist_->servers[i]; + if (!IsServerValid(serverlist_->servers[i], i, false)) continue; // Address processing. grpc_resolved_address addr; ParseServer(server, &addr); @@ -456,6 +497,176 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { return addresses; } +bool GrpcLb::Serverlist::ContainsAllDropEntries() const { + if (serverlist_->num_servers == 0) return false; + for (size_t i = 0; i < serverlist_->num_servers; ++i) { + if (!serverlist_->servers[i]->drop) return false; + } + return true; +} + +const char* GrpcLb::Serverlist::ShouldDrop() { + if (serverlist_->num_servers == 0) return nullptr; + grpc_grpclb_server* server = serverlist_->servers[drop_index_]; + drop_index_ = (drop_index_ + 1) % serverlist_->num_servers; + return server->drop ? server->load_balance_token : nullptr; +} + +// +// GrpcLb::Picker +// + +// Adds lb_token of selected subchannel (address) to the call's initial +// metadata. +grpc_error* AddLbTokenToInitialMetadata( + grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage, + grpc_metadata_batch* initial_metadata) { + GPR_ASSERT(lb_token_mdelem_storage != nullptr); + GPR_ASSERT(!GRPC_MDISNULL(lb_token)); + return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage, + lb_token); +} + +// Destroy function used when embedding client stats in call context. +void DestroyClientStats(void* arg) { + static_cast(arg)->Unref(); +} + +GrpcLb::Picker::PickResult GrpcLb::Picker::Pick(PickState* pick, + grpc_error** error) { + // Check if we should drop the call. + const char* drop_token = serverlist_->ShouldDrop(); + if (drop_token != nullptr) { + // Update client load reporting stats to indicate the number of + // dropped calls. Note that we have to do this here instead of in + // the client_load_reporting filter, because we do not create a + // subchannel call (and therefore no client_load_reporting filter) + // for dropped calls. + if (client_stats_ != nullptr) { + client_stats_->AddCallDroppedLocked(drop_token); + } + return PICK_COMPLETE; + } + // Forward pick to child policy. + PickResult result = child_picker_->Pick(pick, error); + // If pick succeeded, add LB token to initial metadata. + if (result == PickResult::PICK_COMPLETE && + pick->connected_subchannel != nullptr) { + const grpc_arg* arg = grpc_channel_args_find( + pick->connected_subchannel->args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); + if (arg == nullptr) { + gpr_log(GPR_ERROR, + "[grpclb %p picker %p] No LB token for connected subchannel " + "pick %p", + parent_, this, pick); + abort(); + } + grpc_mdelem lb_token = {reinterpret_cast(arg->value.pointer.p)}; + AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(lb_token), + &pick->lb_token_mdelem_storage, + pick->initial_metadata); + // Pass on client stats via context. Passes ownership of the reference. + if (client_stats_ != nullptr) { + pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = + client_stats_->Ref().release(); + pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = + DestroyClientStats; + } + } + return result; +} + +// +// GrpcLb::Helper +// + +Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { + if (parent_->shutting_down_) return nullptr; + return parent_->channel_control_helper()->CreateSubchannel(args); +} + +grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, + grpc_client_channel_type type, + const grpc_channel_args& args) { + if (parent_->shutting_down_) return nullptr; + return parent_->channel_control_helper()->CreateChannel(target, type, args); +} + +void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, + grpc_error* state_error, + UniquePtr picker) { + if (parent_->shutting_down_) { + GRPC_ERROR_UNREF(state_error); + return; + } + // There are three cases to consider here: + // 1. We're in fallback mode. In this case, we're always going to use + // RR's result, so we pass its picker through as-is. + // 2. The serverlist contains only drop entries. In this case, we + // want to use our own picker so that we can return the drops. + // 3. Not in fallback mode and serverlist is not all drops (i.e., it + // may be empty or contain at least one backend address). There are + // two sub-cases: + // a. RR is reporting state READY. In this case, we wrap RR's + // picker in our own, so that we can handle drops and LB token + // metadata for each pick. + // b. RR is reporting a state other than READY. In this case, we + // don't want to use our own picker, because we don't want to + // process drops for picks that yield a QUEUE result; this would + // result in dropping too many calls, since we will see the + // queued picks multiple times, and we'd consider each one a + // separate call for the drop calculation. + // + // Cases 1 and 3b: return picker from RR as-is. + if (parent_->serverlist_ == nullptr || + (!parent_->serverlist_->ContainsAllDropEntries() && + state != GRPC_CHANNEL_READY)) { + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, + "[grpclb %p helper %p] state=%s passing RR picker %p as-is", + parent_.get(), this, grpc_connectivity_state_name(state), + picker.get()); + } + parent_->channel_control_helper()->UpdateState(state, state_error, + std::move(picker)); + return; + } + // Cases 2 and 3a: wrap picker from RR in our own picker. + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping RR picker %p", + parent_.get(), this, grpc_connectivity_state_name(state), + picker.get()); + } + RefCountedPtr client_stats; + if (parent_->lb_calld_ != nullptr && + parent_->lb_calld_->client_stats() != nullptr) { + client_stats = parent_->lb_calld_->client_stats()->Ref(); + } + parent_->channel_control_helper()->UpdateState( + state, state_error, + UniquePtr( + New(parent_.get(), parent_->serverlist_, std::move(picker), + std::move(client_stats)))); +} + +void GrpcLb::Helper::RequestReresolution() { + if (parent_->shutting_down_) return; + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, + "[grpclb %p] Re-resolution requested from the internal RR policy " + "(%p).", + parent_.get(), parent_->rr_policy_.get()); + } + // If we are talking to a balancer, we expect to get updated addresses + // from the balancer, so we can ignore the re-resolution request from + // the RR policy. Otherwise, pass the re-resolution request up to the + // channel. + if (parent_->lb_calld_ == nullptr || + !parent_->lb_calld_->seen_initial_response()) { + parent_->channel_control_helper()->RequestReresolution(); + } +} + // // GrpcLb::BalancerCallState // @@ -754,27 +965,20 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( response_slice)) != nullptr) { // Have seen initial response, look for serverlist. GPR_ASSERT(lb_calld->lb_call_ != nullptr); + auto serverlist_wrapper = MakeRefCounted(serverlist); if (grpc_lb_glb_trace.enabled()) { + UniquePtr serverlist_text = serverlist_wrapper->AsText(); gpr_log(GPR_INFO, "[grpclb %p] lb_calld=%p: Serverlist with %" PRIuPTR - " servers received", - grpclb_policy, lb_calld, serverlist->num_servers); - for (size_t i = 0; i < serverlist->num_servers; ++i) { - grpc_resolved_address addr; - ParseServer(serverlist->servers[i], &addr); - char* ipport; - grpc_sockaddr_to_string(&ipport, &addr, false); - gpr_log(GPR_INFO, - "[grpclb %p] lb_calld=%p: Serverlist[%" PRIuPTR "]: %s", - grpclb_policy, lb_calld, i, ipport); - gpr_free(ipport); - } + " servers received:\n%s", + grpclb_policy, lb_calld, serverlist->num_servers, + serverlist_text.get()); } // Start sending client load report only after we start using the // serverlist returned from the current LB call. if (lb_calld->client_stats_report_interval_ > 0 && lb_calld->client_stats_ == nullptr) { - lb_calld->client_stats_.reset(New()); + lb_calld->client_stats_ = MakeRefCounted(); // TODO(roth): We currently track this ref manually. Once the // ClosureRef API is ready, we should pass the RefCountedPtr<> along // with the callback. @@ -783,19 +987,16 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( lb_calld->ScheduleNextClientLoadReportLocked(); } // Check if the serverlist differs from the previous one. - if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_, serverlist)) { + if (grpclb_policy->serverlist_ != nullptr && + *grpclb_policy->serverlist_ == *serverlist_wrapper) { if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, "[grpclb %p] lb_calld=%p: Incoming server list identical to " "current, ignoring.", grpclb_policy, lb_calld); } - grpc_grpclb_destroy_serverlist(serverlist); } else { // New serverlist. - if (grpclb_policy->serverlist_ != nullptr) { - // Dispose of the old serverlist. - grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_); - } else { + if (grpclb_policy->serverlist_ == nullptr) { // Dispose of the fallback. grpclb_policy->fallback_backend_addresses_.reset(); if (grpclb_policy->fallback_timer_callback_pending_) { @@ -805,8 +1006,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( // Update the serverlist in the GrpcLb instance. This serverlist // instance will be destroyed either upon the next update or when the // GrpcLb instance is destroyed. - grpclb_policy->serverlist_ = serverlist; - grpclb_policy->serverlist_index_ = 0; + grpclb_policy->serverlist_ = std::move(serverlist_wrapper); grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); } } else { @@ -853,13 +1053,13 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( lb_calld->lb_call_, grpc_error_string(error)); gpr_free(status_details); } - grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE); // If this lb_calld is still in use, this call ended because of a failure so // we want to retry connecting. Otherwise, we have deliberately ended this // call and no further action is required. if (lb_calld == grpclb_policy->lb_calld_.get()) { grpclb_policy->lb_calld_.reset(); GPR_ASSERT(!grpclb_policy->shutting_down_); + grpclb_policy->channel_control_helper()->RequestReresolution(); if (lb_calld->seen_initial_response_) { // If we lose connection to the LB server, reset the backoff and restart // the LB call immediately. @@ -991,13 +1191,6 @@ GrpcLb::GrpcLb(LoadBalancingPolicy::Args args) GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_rr_connectivity_changed_, - &GrpcLb::OnRoundRobinConnectivityChangedLocked, this, - grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_rr_request_reresolution_, - &GrpcLb::OnRoundRobinRequestReresolutionLocked, this, - grpc_combiner_scheduler(args.combiner)); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "grpclb"); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -1020,20 +1213,18 @@ GrpcLb::GrpcLb(LoadBalancingPolicy::Args args) arg, {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX}); // Process channel args. ProcessChannelArgsLocked(*args.args); + // Initialize channel with a picker that will start us connecting. + channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(Ref()))); } GrpcLb::~GrpcLb() { - GPR_ASSERT(pending_picks_ == nullptr); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); - grpc_connectivity_state_destroy(&state_tracker_); - if (serverlist_ != nullptr) { - grpc_grpclb_destroy_serverlist(serverlist_); - } } void GrpcLb::ShutdownLocked() { - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); shutting_down_ = true; lb_calld_.reset(); if (retry_timer_callback_pending_) { @@ -1043,7 +1234,6 @@ void GrpcLb::ShutdownLocked() { grpc_timer_cancel(&lb_fallback_timer_); } rr_policy_.reset(); - TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_CANCELLED); // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -1053,109 +1243,12 @@ void GrpcLb::ShutdownLocked() { lb_channel_ = nullptr; gpr_atm_no_barrier_store(&lb_channel_uuid_, 0); } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "grpclb_shutdown"); - // Clear pending picks. - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); } // // public methods // -void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->on_complete = pp->original_on_complete; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pp->pick, &error)) { - // Synchronous return; schedule closure. - GRPC_CLOSURE_SCHED(pp->pick->on_complete, error); - } - Delete(pp); - } -} - -// Cancel a specific pending pick. -// -// A grpclb pick progresses as follows: -// - If there's a Round Robin policy (rr_policy_) available, it'll be -// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From -// that point onwards, it'll be RR's responsibility. For cancellations, that -// implies the pick needs also be cancelled by the RR instance. -// - Otherwise, without an RR instance, picks stay pending at this policy's -// level (grpclb), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void GrpcLb::CancelPickLocked(PickState* pick, grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if (pp->pick == pick) { - pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (rr_policy_ != nullptr) { - rr_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - -// Cancel all pending picks. -// -// A grpclb pick progresses as follows: -// - If there's a Round Robin policy (rr_policy_) available, it'll be -// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From -// that point onwards, it'll be RR's responsibility. For cancellations, that -// implies the pick needs also be cancelled by the RR instance. -// - Otherwise, without an RR instance, picks stay pending at this policy's -// level (grpclb), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void GrpcLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if ((*pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (rr_policy_ != nullptr) { - rr_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, - GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - void GrpcLb::ExitIdleLocked() { if (!started_picking_) { StartPickingLocked(); @@ -1171,37 +1264,6 @@ void GrpcLb::ResetBackoffLocked() { } } -bool GrpcLb::PickLocked(PickState* pick, grpc_error** error) { - PendingPick* pp = PendingPickCreate(pick); - bool pick_done = false; - if (rr_policy_ != nullptr) { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] about to PICK from RR %p", this, - rr_policy_.get()); - } - pick_done = - PickFromRoundRobinPolicyLocked(false /* force_async */, pp, error); - } else { // rr_policy_ == NULL - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - pick_done = true; - } else { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] No RR policy. Adding to grpclb's pending picks", - this); - } - AddPendingPick(pp); - if (!started_picking_) { - StartPickingLocked(); - } - pick_done = false; - } - } - return pick_done; -} - void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { @@ -1215,17 +1277,6 @@ void GrpcLb::FillChildRefsForChannelz( } } -grpc_connectivity_state GrpcLb::CheckConnectivityLocked( - grpc_error** connectivity_error) { - return grpc_connectivity_state_get(&state_tracker_, connectivity_error); -} - -void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* notify) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - notify); -} - // Returns the backend addresses extracted from the given addresses. UniquePtr ExtractBackendAddresses( const ServerAddressList& addresses) { @@ -1271,9 +1322,8 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { if (lb_channel_ == nullptr) { char* uri_str; gpr_asprintf(&uri_str, "fake:///%s", server_name_); - lb_channel_ = grpc_client_channel_factory_create_channel( - client_channel_factory(), uri_str, - GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args); + lb_channel_ = channel_control_helper()->CreateChannel( + uri_str, GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, *lb_channel_args); GPR_ASSERT(lb_channel_ != nullptr); grpc_core::channelz::ChannelNode* channel_node = grpc_channel_get_channelz_node(lb_channel_); @@ -1454,143 +1504,10 @@ void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, } } -// -// PendingPick -// - -// Adds lb_token of selected subchannel (address) to the call's initial -// metadata. -grpc_error* AddLbTokenToInitialMetadata( - grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage, - grpc_metadata_batch* initial_metadata) { - GPR_ASSERT(lb_token_mdelem_storage != nullptr); - GPR_ASSERT(!GRPC_MDISNULL(lb_token)); - return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage, - lb_token); -} - -// Destroy function used when embedding client stats in call context. -void DestroyClientStats(void* arg) { - static_cast(arg)->Unref(); -} - -void GrpcLb::PendingPickSetMetadataAndContext(PendingPick* pp) { - // If connected_subchannel is nullptr, no pick has been made by the RR - // policy (e.g., all addresses failed to connect). There won't be any - // LB token available. - if (pp->pick->connected_subchannel != nullptr) { - const grpc_arg* arg = - grpc_channel_args_find(pp->pick->connected_subchannel->args(), - GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); - if (arg != nullptr) { - grpc_mdelem lb_token = { - reinterpret_cast(arg->value.pointer.p)}; - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(lb_token), - &pp->pick->lb_token_mdelem_storage, - pp->pick->initial_metadata); - } else { - gpr_log(GPR_ERROR, - "[grpclb %p] No LB token for connected subchannel pick %p", - pp->grpclb_policy, pp->pick); - abort(); - } - // Pass on client stats via context. Passes ownership of the reference. - if (pp->client_stats != nullptr) { - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = - pp->client_stats.release(); - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = - DestroyClientStats; - } - } else { - pp->client_stats.reset(); - } -} - -/* The \a on_complete closure passed as part of the pick requires keeping a - * reference to its associated round robin instance. We wrap this closure in - * order to unref the round robin instance upon its invocation */ -void GrpcLb::OnPendingPickComplete(void* arg, grpc_error* error) { - PendingPick* pp = static_cast(arg); - PendingPickSetMetadataAndContext(pp); - GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); - Delete(pp); -} - -GrpcLb::PendingPick* GrpcLb::PendingPickCreate(PickState* pick) { - PendingPick* pp = New(); - pp->grpclb_policy = this; - pp->pick = pick; - GRPC_CLOSURE_INIT(&pp->on_complete, &GrpcLb::OnPendingPickComplete, pp, - grpc_schedule_on_exec_ctx); - pp->original_on_complete = pick->on_complete; - pick->on_complete = &pp->on_complete; - return pp; -} - -void GrpcLb::AddPendingPick(PendingPick* pp) { - pp->next = pending_picks_; - pending_picks_ = pp; -} - // // code for interacting with the RR policy // -// Performs a pick over \a rr_policy_. Given that a pick can return -// immediately (ignoring its completion callback), we need to perform the -// cleanups this callback would otherwise be responsible for. -// If \a force_async is true, then we will manually schedule the -// completion callback even if the pick is available immediately. -bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error) { - // Check for drops if we are not using fallback backend addresses. - if (serverlist_ != nullptr && serverlist_->num_servers > 0) { - // Look at the index into the serverlist to see if we should drop this call. - grpc_grpclb_server* server = serverlist_->servers[serverlist_index_++]; - if (serverlist_index_ == serverlist_->num_servers) { - serverlist_index_ = 0; // Wrap-around. - } - if (server->drop) { - // Update client load reporting stats to indicate the number of - // dropped calls. Note that we have to do this here instead of in - // the client_load_reporting filter, because we do not create a - // subchannel call (and therefore no client_load_reporting filter) - // for dropped calls. - if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { - lb_calld_->client_stats()->AddCallDroppedLocked( - server->load_balance_token); - } - if (force_async) { - GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_NONE); - Delete(pp); - return false; - } - Delete(pp); - return true; - } - } - // Set client_stats. - if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { - pp->client_stats = lb_calld_->client_stats()->Ref(); - } - // Pick via the RR policy. - bool pick_done = rr_policy_->PickLocked(pp->pick, error); - if (pick_done) { - PendingPickSetMetadataAndContext(pp); - if (force_async) { - GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); - *error = GRPC_ERROR_NONE; - pick_done = false; - } - Delete(pp); - } - // else, the pending pick will be registered and taken care of by the - // pending pick list inside the RR policy. Eventually, - // OnPendingPickComplete() will be called, which will (among other - // things) add the LB token to the call's initial metadata. - return pick_done; -} - void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { GPR_ASSERT(rr_policy_ == nullptr); rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( @@ -1604,40 +1521,12 @@ void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, rr_policy_.get()); } - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - auto self = Ref(DEBUG_LOCATION, "on_rr_reresolution_requested"); - self.release(); - rr_policy_->SetReresolutionClosureLocked(&on_rr_request_reresolution_); - grpc_error* rr_state_error = nullptr; - rr_connectivity_state_ = rr_policy_->CheckConnectivityLocked(&rr_state_error); - // Connectivity state is a function of the RR policy updated/created. - UpdateConnectivityStateFromRoundRobinPolicyLocked(rr_state_error); // Add the gRPC LB's interested_parties pollset_set to that of the newly // created RR policy. This will make the RR policy progress upon activity on // gRPC LB, which in turn is tied to the application's call. grpc_pollset_set_add_pollset_set(rr_policy_->interested_parties(), interested_parties()); - // Subscribe to changes to the connectivity of the new RR. - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - self = Ref(DEBUG_LOCATION, "on_rr_connectivity_changed"); - self.release(); - rr_policy_->NotifyOnStateChangeLocked(&rr_connectivity_state_, - &on_rr_connectivity_changed_); rr_policy_->ExitIdleLocked(); - // Send pending picks to RR policy. - PendingPick* pp; - while ((pp = pending_picks_)) { - pending_picks_ = pp->next; - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] Pending pick about to (async) PICK from RR %p", this, - rr_policy_.get()); - } - grpc_error* error = GRPC_ERROR_NONE; - PickFromRoundRobinPolicyLocked(true /* force_async */, pp, &error); - } } grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { @@ -1645,7 +1534,7 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { ServerAddressList* addresses = &tmp_addresses; bool is_backend_from_grpclb_load_balancer = false; if (serverlist_ != nullptr) { - tmp_addresses = ProcessServerlist(serverlist_); + tmp_addresses = serverlist_->GetServerAddressList(); is_backend_from_grpclb_load_balancer = true; } else { // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't @@ -1694,110 +1583,14 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { } else { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); - lb_policy_args.client_channel_factory = client_channel_factory(); lb_policy_args.args = args; - lb_policy_args.subchannel_pool = subchannel_pool()->Ref(); + lb_policy_args.channel_control_helper = + UniquePtr(New(Ref())); CreateRoundRobinPolicyLocked(std::move(lb_policy_args)); } grpc_channel_args_destroy(args); } -void GrpcLb::OnRoundRobinRequestReresolutionLocked(void* arg, - grpc_error* error) { - GrpcLb* grpclb_policy = static_cast(arg); - if (grpclb_policy->shutting_down_ || error != GRPC_ERROR_NONE) { - grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_reresolution_requested"); - return; - } - if (grpc_lb_glb_trace.enabled()) { - gpr_log( - GPR_INFO, - "[grpclb %p] Re-resolution requested from the internal RR policy (%p).", - grpclb_policy, grpclb_policy->rr_policy_.get()); - } - // If we are talking to a balancer, we expect to get updated addresses form - // the balancer, so we can ignore the re-resolution request from the RR - // policy. Otherwise, handle the re-resolution request using the - // grpclb policy's original re-resolution closure. - if (grpclb_policy->lb_calld_ == nullptr || - !grpclb_policy->lb_calld_->seen_initial_response()) { - grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE); - } - // Give back the wrapper closure to the RR policy. - grpclb_policy->rr_policy_->SetReresolutionClosureLocked( - &grpclb_policy->on_rr_request_reresolution_); -} - -void GrpcLb::UpdateConnectivityStateFromRoundRobinPolicyLocked( - grpc_error* rr_state_error) { - const grpc_connectivity_state curr_glb_state = - grpc_connectivity_state_check(&state_tracker_); - /* The new connectivity status is a function of the previous one and the new - * input coming from the status of the RR policy. - * - * current state (grpclb's) - * | - * v || I | C | R | TF | SD | <- new state (RR's) - * ===++====+=====+=====+======+======+ - * I || I | C | R | [I] | [I] | - * ---++----+-----+-----+------+------+ - * C || I | C | R | [C] | [C] | - * ---++----+-----+-----+------+------+ - * R || I | C | R | [R] | [R] | - * ---++----+-----+-----+------+------+ - * TF || I | C | R | [TF] | [TF] | - * ---++----+-----+-----+------+------+ - * SD || NA | NA | NA | NA | NA | (*) - * ---++----+-----+-----+------+------+ - * - * A [STATE] indicates that the old RR policy is kept. In those cases, STATE - * is the current state of grpclb, which is left untouched. - * - * In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to - * the previous RR instance. - * - * Note that the status is never updated to SHUTDOWN as a result of calling - * this function. Only glb_shutdown() has the power to set that state. - * - * (*) This function mustn't be called during shutting down. */ - GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN); - switch (rr_connectivity_state_) { - case GRPC_CHANNEL_TRANSIENT_FAILURE: - case GRPC_CHANNEL_SHUTDOWN: - GPR_ASSERT(rr_state_error != GRPC_ERROR_NONE); - break; - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_READY: - GPR_ASSERT(rr_state_error == GRPC_ERROR_NONE); - } - if (grpc_lb_glb_trace.enabled()) { - gpr_log( - GPR_INFO, - "[grpclb %p] Setting grpclb's state to %s from new RR policy %p state.", - this, grpc_connectivity_state_name(rr_connectivity_state_), - rr_policy_.get()); - } - grpc_connectivity_state_set(&state_tracker_, rr_connectivity_state_, - rr_state_error, - "update_lb_connectivity_status_locked"); -} - -void GrpcLb::OnRoundRobinConnectivityChangedLocked(void* arg, - grpc_error* error) { - GrpcLb* grpclb_policy = static_cast(arg); - if (grpclb_policy->shutting_down_) { - grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_connectivity_changed"); - return; - } - grpclb_policy->UpdateConnectivityStateFromRoundRobinPolicyLocked( - GRPC_ERROR_REF(error)); - // Resubscribe. Reuse the "on_rr_connectivity_changed" ref. - grpclb_policy->rr_policy_->NotifyOnStateChangeLocked( - &grpclb_policy->rr_connectivity_state_, - &grpclb_policy->on_rr_connectivity_changed_); -} - // // factory // diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc index 087cd8f276e..1c7ed871d74 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc @@ -43,7 +43,7 @@ void GrpcLbClientStats::AddCallFinished( } } -void GrpcLbClientStats::AddCallDroppedLocked(char* token) { +void GrpcLbClientStats::AddCallDroppedLocked(const char* token) { // Increment num_calls_started and num_calls_finished. gpr_atm_full_fetch_add(&num_calls_started_, (gpr_atm)1); gpr_atm_full_fetch_add(&num_calls_finished_, (gpr_atm)1); diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h index 18ab2c94529..45ca40942ca 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h @@ -48,7 +48,7 @@ class GrpcLbClientStats : public RefCounted { bool finished_known_received); // This method is not thread-safe; caller must synchronize. - void AddCallDroppedLocked(char* token); + void AddCallDroppedLocked(const char* token); // This method is not thread-safe; caller must synchronize. void GetLocked(int64_t* num_calls_started, int64_t* num_calls_finished, diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index dc716a6adac..bf1c5bd7914 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -52,16 +52,6 @@ class PickFirst : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -99,10 +89,9 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - client_channel_factory, args) { + policy->channel_control_helper(), args) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' // pollset_sets will include the LB policy's pollset_set. @@ -115,6 +104,20 @@ class PickFirst : public LoadBalancingPolicy { } }; + class Picker : public SubchannelPicker { + public: + explicit Picker(RefCountedPtr connected_subchannel) + : connected_subchannel_(std::move(connected_subchannel)) {} + + PickResult Pick(PickState* pick, grpc_error** error) override { + pick->connected_subchannel = connected_subchannel_; + return PICK_COMPLETE; + } + + private: + RefCountedPtr connected_subchannel_; + }; + // Helper class to ensure that any function that modifies the child refs // data structures will update the channelz snapshot data structures before // returning. @@ -142,10 +145,6 @@ class PickFirst : public LoadBalancingPolicy { bool started_picking_ = false; // Are we shut down? bool shutdown_ = false; - // List of picks that are waiting on connectivity. - PickState* pending_picks_ = nullptr; - // Our connectivity state tracker. - grpc_connectivity_state_tracker state_tracker_; /// Lock and data used to capture snapshots of this channels child /// channels and subchannels. This data is consumed by channelz. @@ -155,13 +154,15 @@ class PickFirst : public LoadBalancingPolicy { }; PickFirst::PickFirst(Args args) : LoadBalancingPolicy(std::move(args)) { - GPR_ASSERT(args.client_channel_factory != nullptr); gpr_mu_init(&child_refs_mu_); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, - "pick_first"); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p created.", this); } + // Initialize channel with a picker that will start us connecting upon + // the first pick. + channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(Ref()))); UpdateLocked(*args.args, args.lb_config); } @@ -172,81 +173,16 @@ PickFirst::~PickFirst() { gpr_mu_destroy(&child_refs_mu_); GPR_ASSERT(subchannel_list_ == nullptr); GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); - GPR_ASSERT(pending_picks_ == nullptr); - grpc_connectivity_state_destroy(&state_tracker_); -} - -void PickFirst::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pick, &error)) { - // Synchronous return, schedule closure. - GRPC_CLOSURE_SCHED(pick->on_complete, error); - } - } } void PickFirst::ShutdownLocked() { AutoChildRefsUpdater guard(this); - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p Shutting down", this); } shutdown_ = true; - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error)); - } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "shutdown"); subchannel_list_.reset(); latest_pending_subchannel_list_.reset(); - TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_CANCELLED); - GRPC_ERROR_UNREF(error); -} - -void PickFirst::CancelPickLocked(PickState* pick, grpc_error* error) { - PickState* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PickState* next = pp->next; - if (pp == pick) { - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - GRPC_ERROR_UNREF(error); -} - -void PickFirst::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PickState* pick = pending_picks_; - pending_picks_ = nullptr; - while (pick != nullptr) { - PickState* next = pick->next; - if ((*pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pick->next = pending_picks_; - pending_picks_ = pick; - } - pick = next; - } - GRPC_ERROR_UNREF(error); } void PickFirst::StartPickingLocked() { @@ -270,36 +206,6 @@ void PickFirst::ResetBackoffLocked() { } } -bool PickFirst::PickLocked(PickState* pick, grpc_error** error) { - // If we have a selected subchannel already, return synchronously. - if (selected_ != nullptr) { - pick->connected_subchannel = selected_->connected_subchannel()->Ref(); - return true; - } - // No subchannel selected yet, so handle asynchronously. - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - return true; - } - pick->next = pending_picks_; - pending_picks_ = pick; - if (!started_picking_) { - StartPickingLocked(); - } - return false; -} - -grpc_connectivity_state PickFirst::CheckConnectivityLocked(grpc_error** error) { - return grpc_connectivity_state_get(&state_tracker_, error); -} - -void PickFirst::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* notify) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - notify); -} - void PickFirst::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels_to_fill, channelz::ChildRefsList* ignored) { @@ -341,10 +247,11 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, if (addresses == nullptr) { if (subchannel_list_ == nullptr) { // If we don't have a current subchannel list, go into TRANSIENT FAILURE. - grpc_connectivity_state_set( - &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"), - "pf_update_missing"); + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + UniquePtr(New(error))); } else { // otherwise, keep using the current subchannel list (ignore this update). gpr_log(GPR_ERROR, @@ -364,18 +271,17 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, grpc_channel_args* new_args = grpc_channel_args_copy_and_add(&args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, *addresses, combiner(), - client_channel_factory(), *new_args); + this, &grpc_lb_pick_first_trace, *addresses, combiner(), *new_args); grpc_channel_args_destroy(new_args); if (subchannel_list->num_subchannels() == 0) { // Empty update or no valid subchannels. Unsubscribe from all current // subchannels and put the channel in TRANSIENT_FAILURE. - grpc_connectivity_state_set( - &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), - "pf_update_empty"); subchannel_list_ = std::move(subchannel_list); // Empty list. selected_ = nullptr; + grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + UniquePtr(New(error))); return; } // If one of the subchannels in the new list is already in state @@ -453,7 +359,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( if (p->selected_ == this) { if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, - "Pick First %p connectivity changed for selected subchannel", p); + "Pick First %p selected subchannel connectivity changed to %s", p, + grpc_connectivity_state_name(connectivity_state)); } // If the new state is anything other than READY and there is a // pending update, switch to the pending update. @@ -469,14 +376,12 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->selected_ = nullptr; StopConnectivityWatchLocked(); p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); - grpc_connectivity_state_set( - &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - error != GRPC_ERROR_NONE - ? GRPC_ERROR_REF(error) - : GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "selected subchannel not ready; switching to pending " - "update"), - "selected_not_ready+switch_to_update"); + grpc_error* new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "selected subchannel not ready; switching to pending update", &error, + 1); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), + UniquePtr(New(new_error))); } else { if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { // If the selected subchannel goes bad, request a re-resolution. We also @@ -484,17 +389,28 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // is that if the new state is TRANSIENT_FAILURE due to a GOAWAY // reception we don't want to connect to the re-resolved backends until // we leave the IDLE state. - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_IDLE, - GRPC_ERROR_NONE, - "selected_changed+reresolve"); p->started_picking_ = false; - p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE); + p->channel_control_helper()->RequestReresolution(); // In transient failure. Rely on re-resolution to recover. p->selected_ = nullptr; StopConnectivityWatchLocked(); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(p->Ref()))); } else { - grpc_connectivity_state_set(&p->state_tracker_, connectivity_state, - GRPC_ERROR_REF(error), "selected_changed"); + // This is unlikely but can happen when a subchannel has been asked + // to reconnect by a different channel and this channel has dropped + // some connectivity state notifications. + if (connectivity_state == GRPC_CHANNEL_READY) { + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, GRPC_ERROR_NONE, + UniquePtr( + New(connected_subchannel()->Ref()))); + } else { // CONNECTING + p->channel_control_helper()->UpdateState( + connectivity_state, GRPC_ERROR_REF(error), + UniquePtr(New(p->Ref()))); + } // Renew notification. RenewConnectivityWatchLocked(); } @@ -527,10 +443,14 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // Case 1: Only set state to TRANSIENT_FAILURE if we've tried // all subchannels. if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) { - p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE); - grpc_connectivity_state_set( - &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(error), "exhausted_subchannels"); + p->channel_control_helper()->RequestReresolution(); + grpc_error* new_error = + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "failed to connect to all addresses", &error, 1); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), + UniquePtr( + New(new_error))); } sd->CheckConnectivityStateAndStartWatchingLocked(); break; @@ -539,9 +459,9 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( case GRPC_CHANNEL_IDLE: { // Only update connectivity state in case 1. if (subchannel_list() == p->subchannel_list_.get()) { - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_REF(error), - "connecting_changed"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + UniquePtr(New(p->Ref()))); } // Renew notification. RenewConnectivityWatchLocked(); @@ -578,23 +498,13 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); } // Cases 1 and 2. - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY, - GRPC_ERROR_NONE, "subchannel_ready"); p->selected_ = this; + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, GRPC_ERROR_NONE, + UniquePtr(New(connected_subchannel()->Ref()))); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); } - // Update any calls that were waiting for a pick. - PickState* pick; - while ((pick = p->pending_picks_)) { - p->pending_picks_ = pick->next; - pick->connected_subchannel = p->selected_->connected_subchannel()->Ref(); - if (grpc_lb_pick_first_trace.enabled()) { - gpr_log(GPR_INFO, "Servicing pending pick with selected subchannel %p", - p->selected_->subchannel()); - } - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); - } } void PickFirst::PickFirstSubchannelData:: diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index aab6dd68216..0406efb71d3 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -26,6 +26,7 @@ #include +#include #include #include @@ -62,16 +63,6 @@ class RoundRobin : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -117,14 +108,12 @@ class RoundRobin : public LoadBalancingPolicy { : public SubchannelList { public: - RoundRobinSubchannelList( - RoundRobin* policy, TraceFlag* tracer, - const ServerAddressList& addresses, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, - const grpc_channel_args& args) + RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer, + const ServerAddressList& addresses, + grpc_combiner* combiner, + const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - client_channel_factory, args), - last_ready_index_(num_subchannels() - 1) { + policy->channel_control_helper(), args) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' // pollset_sets will include the LB policy's pollset_set. @@ -157,15 +146,25 @@ class RoundRobin : public LoadBalancingPolicy { // subchannels in each state. void UpdateRoundRobinStateFromSubchannelStateCountsLocked(); - size_t GetNextReadySubchannelIndexLocked(); - void UpdateLastReadySubchannelIndexLocked(size_t last_ready_index); - private: size_t num_ready_ = 0; size_t num_connecting_ = 0; size_t num_transient_failure_ = 0; grpc_error* last_transient_failure_error_ = GRPC_ERROR_NONE; - size_t last_ready_index_; // Index into list of last pick. + }; + + class Picker : public SubchannelPicker { + public: + Picker(RoundRobin* parent, RoundRobinSubchannelList* subchannel_list); + + PickResult Pick(PickState* pick, grpc_error** error) override; + + private: + // Using pointer value only, no ref held -- do not dereference! + RoundRobin* parent_; + + size_t last_picked_index_; + InlinedVector, 10> subchannels_; }; // Helper class to ensure that any function that modifies the child refs @@ -183,8 +182,6 @@ class RoundRobin : public LoadBalancingPolicy { void ShutdownLocked() override; void StartPickingLocked(); - bool DoPickLocked(PickState* pick); - void DrainPendingPicksLocked(); void UpdateChildRefsLocked(); /** list of subchannels */ @@ -199,10 +196,6 @@ class RoundRobin : public LoadBalancingPolicy { bool started_picking_ = false; /** are we shutting down? */ bool shutdown_ = false; - /** List of picks that are waiting on connectivity */ - PickState* pending_picks_ = nullptr; - /** our connectivity state tracker */ - grpc_connectivity_state_tracker state_tracker_; /// Lock and data used to capture snapshots of this channel's child /// channels and subchannels. This data is consumed by channelz. gpr_mu child_refs_mu_; @@ -210,16 +203,62 @@ class RoundRobin : public LoadBalancingPolicy { channelz::ChildRefsList child_channels_; }; -RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) { - GPR_ASSERT(args.client_channel_factory != nullptr); - gpr_mu_init(&child_refs_mu_); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, - "round_robin"); - UpdateLocked(*args.args, args.lb_config); - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, "[RR %p] Created with %" PRIuPTR " subchannels", this, - subchannel_list_->num_subchannels()); +// +// RoundRobin::Picker +// + +RoundRobin::Picker::Picker(RoundRobin* parent, + RoundRobinSubchannelList* subchannel_list) + : parent_(parent) { + for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { + auto* connected_subchannel = + subchannel_list->subchannel(i)->connected_subchannel(); + if (connected_subchannel != nullptr) { + subchannels_.push_back(connected_subchannel->Ref()); + } } + // For discussion on why we generate a random starting index for + // the picker, see https://github.com/grpc/grpc-go/issues/2580. + // TODO(roth): rand(3) is not thread-safe. This should be replaced with + // something better as part of https://github.com/grpc/grpc/issues/17891. + last_picked_index_ = rand() % subchannels_.size(); + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, + "[RR %p picker %p] created picker from subchannel_list=%p " + "with %" PRIuPTR " READY subchannels; last_picked_index_=%" PRIuPTR, + parent_, this, subchannel_list, subchannels_.size(), + last_picked_index_); + } +} + +RoundRobin::Picker::PickResult RoundRobin::Picker::Pick(PickState* pick, + grpc_error** error) { + last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size(); + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, + "[RR %p picker %p] returning index %" PRIuPTR + ", connected_subchannel=%p", + parent_, this, last_picked_index_, + subchannels_[last_picked_index_].get()); + } + pick->connected_subchannel = subchannels_[last_picked_index_]; + return PICK_COMPLETE; +} + +// +// RoundRobin +// + +RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) { + gpr_mu_init(&child_refs_mu_); + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, "[RR %p] Created", this); + } + // Initialize channel with a picker that will start us connecting. + channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(Ref()))); + UpdateLocked(*args.args, args.lb_config); } RoundRobin::~RoundRobin() { @@ -229,82 +268,16 @@ RoundRobin::~RoundRobin() { gpr_mu_destroy(&child_refs_mu_); GPR_ASSERT(subchannel_list_ == nullptr); GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); - GPR_ASSERT(pending_picks_ == nullptr); - grpc_connectivity_state_destroy(&state_tracker_); -} - -void RoundRobin::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pick, &error)) { - // Synchronous return, schedule closure. - GRPC_CLOSURE_SCHED(pick->on_complete, error); - } - } } void RoundRobin::ShutdownLocked() { AutoChildRefsUpdater guard(this); - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] Shutting down", this); } shutdown_ = true; - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error)); - } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "rr_shutdown"); subchannel_list_.reset(); latest_pending_subchannel_list_.reset(); - TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_CANCELLED); - GRPC_ERROR_UNREF(error); -} - -void RoundRobin::CancelPickLocked(PickState* pick, grpc_error* error) { - PickState* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PickState* next = pp->next; - if (pp == pick) { - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - GRPC_ERROR_UNREF(error); -} - -void RoundRobin::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PickState* pick = pending_picks_; - pending_picks_ = nullptr; - while (pick != nullptr) { - PickState* next = pick->next; - if ((*pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pick->next = pending_picks_; - pending_picks_ = pick; - } - pick = next; - } - GRPC_ERROR_UNREF(error); } void RoundRobin::StartPickingLocked() { @@ -325,60 +298,6 @@ void RoundRobin::ResetBackoffLocked() { } } -bool RoundRobin::DoPickLocked(PickState* pick) { - const size_t next_ready_index = - subchannel_list_->GetNextReadySubchannelIndexLocked(); - if (next_ready_index < subchannel_list_->num_subchannels()) { - /* readily available, report right away */ - RoundRobinSubchannelData* sd = - subchannel_list_->subchannel(next_ready_index); - GPR_ASSERT(sd->connected_subchannel() != nullptr); - pick->connected_subchannel = sd->connected_subchannel()->Ref(); - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, - "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, " - "index %" PRIuPTR ")", - this, sd->subchannel(), pick->connected_subchannel.get(), - sd->subchannel_list(), next_ready_index); - } - /* only advance the last picked pointer if the selection was used */ - subchannel_list_->UpdateLastReadySubchannelIndexLocked(next_ready_index); - return true; - } - return false; -} - -void RoundRobin::DrainPendingPicksLocked() { - PickState* pick; - while ((pick = pending_picks_)) { - pending_picks_ = pick->next; - GPR_ASSERT(DoPickLocked(pick)); - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); - } -} - -bool RoundRobin::PickLocked(PickState* pick, grpc_error** error) { - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, "[RR %p] Trying to pick (shutdown: %d)", this, shutdown_); - } - GPR_ASSERT(!shutdown_); - if (subchannel_list_ != nullptr) { - if (DoPickLocked(pick)) return true; - } - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - return true; - } - /* no pick currently available. Save for later in list of pending picks */ - pick->next = pending_picks_; - pending_picks_ = pick; - if (!started_picking_) { - StartPickingLocked(); - } - return false; -} - void RoundRobin::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels_to_fill, channelz::ChildRefsList* ignored) { @@ -462,8 +381,8 @@ void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked( last_transient_failure_error_ = transient_failure_error; } -// Sets the RR policy's connectivity state based on the current -// subchannel list. +// Sets the RR policy's connectivity state and generates a new picker based +// on the current subchannel list. void RoundRobin::RoundRobinSubchannelList:: MaybeUpdateRoundRobinConnectivityStateLocked() { RoundRobin* p = static_cast(policy()); @@ -485,18 +404,21 @@ void RoundRobin::RoundRobinSubchannelList:: */ if (num_ready_ > 0) { /* 1) READY */ - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY, - GRPC_ERROR_NONE, "rr_ready"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, GRPC_ERROR_NONE, + UniquePtr(New(p, this))); } else if (num_connecting_ > 0) { /* 2) CONNECTING */ - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_NONE, "rr_connecting"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + UniquePtr(New(p->Ref()))); } else if (num_transient_failure_ == num_subchannels()) { /* 3) TRANSIENT_FAILURE */ - grpc_connectivity_state_set(&p->state_tracker_, - GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(last_transient_failure_error_), - "rr_exhausted_subchannels"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_REF(last_transient_failure_error_), + UniquePtr(New( + GRPC_ERROR_REF(last_transient_failure_error_)))); } } @@ -525,8 +447,6 @@ void RoundRobin::RoundRobinSubchannelList:: } p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); } - // Drain pending picks. - p->DrainPendingPicksLocked(); } // Update the RR policy's connectivity state if needed. MaybeUpdateRoundRobinConnectivityStateLocked(); @@ -566,7 +486,7 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( "Requesting re-resolution", p, subchannel()); } - p->TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_NONE); + p->channel_control_helper()->RequestReresolution(); } // Update state counters. UpdateConnectivityStateLocked(connectivity_state, error); @@ -575,73 +495,6 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( RenewConnectivityWatchLocked(); } -/** Returns the index into p->subchannel_list->subchannels of the next - * subchannel in READY state, or p->subchannel_list->num_subchannels if no - * subchannel is READY. - * - * Note that this function does *not* update p->last_ready_subchannel_index. - * The caller must do that if it returns a pick. */ -size_t -RoundRobin::RoundRobinSubchannelList::GetNextReadySubchannelIndexLocked() { - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, - "[RR %p] getting next ready subchannel (out of %" PRIuPTR - "), last_ready_index=%" PRIuPTR, - policy(), num_subchannels(), last_ready_index_); - } - for (size_t i = 0; i < num_subchannels(); ++i) { - const size_t index = (i + last_ready_index_ + 1) % num_subchannels(); - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log( - GPR_INFO, - "[RR %p] checking subchannel %p, subchannel_list %p, index %" PRIuPTR - ": state=%s", - policy(), subchannel(index)->subchannel(), this, index, - grpc_connectivity_state_name( - subchannel(index)->connectivity_state())); - } - if (subchannel(index)->connectivity_state() == GRPC_CHANNEL_READY) { - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, - "[RR %p] found next ready subchannel (%p) at index %" PRIuPTR - " of subchannel_list %p", - policy(), subchannel(index)->subchannel(), index, this); - } - return index; - } - } - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, "[RR %p] no subchannels in ready state", this); - } - return num_subchannels(); -} - -// Sets last_ready_index_ to last_ready_index. -void RoundRobin::RoundRobinSubchannelList::UpdateLastReadySubchannelIndexLocked( - size_t last_ready_index) { - GPR_ASSERT(last_ready_index < num_subchannels()); - last_ready_index_ = last_ready_index; - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, - "[RR %p] setting last_ready_subchannel_index=%" PRIuPTR - " (SC %p, CSC %p)", - policy(), last_ready_index, - subchannel(last_ready_index)->subchannel(), - subchannel(last_ready_index)->connected_subchannel()); - } -} - -grpc_connectivity_state RoundRobin::CheckConnectivityLocked( - grpc_error** error) { - return grpc_connectivity_state_get(&state_tracker_, error); -} - -void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* notify) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - notify); -} - void RoundRobin::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { AutoChildRefsUpdater guard(this); @@ -651,10 +504,11 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, // If we don't have a current subchannel list, go into TRANSIENT_FAILURE. // Otherwise, keep using the current subchannel list (ignore this update). if (subchannel_list_ == nullptr) { - grpc_connectivity_state_set( - &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"), - "rr_update_missing"); + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + UniquePtr(New(error))); } return; } @@ -671,17 +525,16 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, *addresses, combiner(), - client_channel_factory(), args); + this, &grpc_lb_round_robin_trace, *addresses, combiner(), args); // If we haven't started picking yet or the new list is empty, // immediately promote the new list to the current list. if (!started_picking_ || latest_pending_subchannel_list_->num_subchannels() == 0) { if (latest_pending_subchannel_list_->num_subchannels() == 0) { - grpc_connectivity_state_set( - &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), - "rr_update_empty"); + grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + UniquePtr(New(error))); } subchannel_list_ = std::move(latest_pending_subchannel_list_); } else { diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 0174a98a73d..c262dfe60f5 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -232,7 +232,7 @@ class SubchannelList : public InternallyRefCounted { protected: SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, + LoadBalancingPolicy::ChannelControlHelper* helper, const grpc_channel_args& args); virtual ~SubchannelList(); @@ -486,7 +486,7 @@ template SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, + LoadBalancingPolicy::ChannelControlHelper* helper, const grpc_channel_args& args) : InternallyRefCounted(tracer), policy_(policy), @@ -509,12 +509,8 @@ SubchannelList::SubchannelList( GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. for (size_t i = 0; i < addresses.size(); i++) { - // If there were any balancer addresses, we would have chosen grpclb - // policy, which does not use a SubchannelList. GPR_ASSERT(!addresses[i].IsBalancer()); - InlinedVector args_to_add; - args_to_add.emplace_back( - SubchannelPoolInterface::CreateChannelArg(policy_->subchannel_pool())); + InlinedVector args_to_add; const size_t subchannel_address_arg_index = args_to_add.size(); args_to_add.emplace_back( Subchannel::CreateSubchannelAddressArg(&addresses[i].address())); @@ -527,8 +523,7 @@ SubchannelList::SubchannelList( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); gpr_free(args_to_add[subchannel_address_arg_index].value.string); - Subchannel* subchannel = grpc_client_channel_factory_create_subchannel( - client_channel_factory, new_args); + Subchannel* subchannel = helper->CreateSubchannel(*new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) { // Subchannel could not be created. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 678b4d75eb9..4b3f2882424 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -70,7 +70,6 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" @@ -125,16 +124,6 @@ class XdsLb : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( @@ -142,31 +131,6 @@ class XdsLb : public LoadBalancingPolicy { channelz::ChildRefsList* child_channels) override; private: - /// Linked list of pending pick requests. It stores all information needed to - /// eventually call pick() on them. They mainly stay pending waiting for the - /// child policy to be created. - /// - /// Note that when a pick is sent to the child policy, we inject our own - /// on_complete callback, so that we can intercept the result before - /// invoking the original on_complete callback. This allows us to set the - /// LB token metadata and add client_stats to the call context. - /// See \a pending_pick_complete() for details. - struct PendingPick { - // The xds lb instance that created the wrapping. This instance is not - // owned; reference counts are untouched. It's used only for logging - // purposes. - XdsLb* xdslb_policy; - // The original pick. - PickState* pick; - // Our on_complete closure and the original one. - grpc_closure on_complete; - grpc_closure* original_on_complete; - // Stats for client-side load reporting. - RefCountedPtr client_stats; - // Next pending pick. - PendingPick* next = nullptr; - }; - /// Contains a call to the LB server and all the data related to the call. class BalancerCallState : public InternallyRefCounted { public: @@ -241,6 +205,36 @@ class XdsLb : public LoadBalancingPolicy { grpc_closure client_load_report_closure_; }; + class Picker : public SubchannelPicker { + public: + Picker(UniquePtr child_picker, + RefCountedPtr client_stats) + : child_picker_(std::move(child_picker)), + client_stats_(std::move(client_stats)) {} + + PickResult Pick(PickState* pick, grpc_error** error) override; + + private: + UniquePtr child_picker_; + RefCountedPtr client_stats_; + }; + + class Helper : public ChannelControlHelper { + public: + explicit Helper(RefCountedPtr parent) : parent_(std::move(parent)) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + grpc_channel* CreateChannel(const char* target, + grpc_client_channel_type type, + const grpc_channel_args& args) override; + void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + UniquePtr picker) override; + void RequestReresolution() override; + + private: + RefCountedPtr parent_; + }; + ~XdsLb(); void ShutdownLocked() override; @@ -263,24 +257,10 @@ class XdsLb : public LoadBalancingPolicy { static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); - // Pending pick methods. - static void PendingPickCleanup(PendingPick* pp); - PendingPick* PendingPickCreate(PickState* pick); - void AddPendingPick(PendingPick* pp); - static void OnPendingPickComplete(void* arg, grpc_error* error); - // Methods for dealing with the child policy. void CreateOrUpdateChildPolicyLocked(); grpc_channel_args* CreateChildPolicyArgsLocked(); void CreateChildPolicyLocked(const char* name, Args args); - bool PickFromChildPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error); - void UpdateConnectivityStateFromChildPolicyLocked( - grpc_error* child_state_error); - static void OnChildPolicyConnectivityChangedLocked(void* arg, - grpc_error* error); - static void OnChildPolicyRequestReresolutionLocked(void* arg, - grpc_error* error); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -294,7 +274,6 @@ class XdsLb : public LoadBalancingPolicy { // Internal state. bool started_picking_ = false; bool shutting_down_ = false; - grpc_connectivity_state_tracker state_tracker_; // The channel for communicating with the LB server. grpc_channel* lb_channel_ = nullptr; @@ -337,17 +316,91 @@ class XdsLb : public LoadBalancingPolicy { grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; - // Pending picks that are waiting on the xDS policy's connectivity. - PendingPick* pending_picks_ = nullptr; - // The policy to use for the backends. OrphanablePtr child_policy_; UniquePtr child_policy_json_string_; - grpc_connectivity_state child_connectivity_state_; - grpc_closure on_child_connectivity_changed_; - grpc_closure on_child_request_reresolution_; }; +// +// XdsLb::Picker +// + +// Destroy function used when embedding client stats in call context. +void DestroyClientStats(void* arg) { + static_cast(arg)->Unref(); +} + +XdsLb::Picker::PickResult XdsLb::Picker::Pick(PickState* pick, + grpc_error** error) { + // TODO(roth): Add support for drop handling. + // Forward pick to child policy. + PickResult result = child_picker_->Pick(pick, error); + // If pick succeeded, add client stats. + if (result == PickResult::PICK_COMPLETE && + pick->connected_subchannel != nullptr && client_stats_ != nullptr) { + pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = + client_stats_->Ref().release(); + pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = + DestroyClientStats; + } + return result; +} + +// +// XdsLb::Helper +// + +Subchannel* XdsLb::Helper::CreateSubchannel(const grpc_channel_args& args) { + if (parent_->shutting_down_) return nullptr; + return parent_->channel_control_helper()->CreateSubchannel(args); +} + +grpc_channel* XdsLb::Helper::CreateChannel(const char* target, + grpc_client_channel_type type, + const grpc_channel_args& args) { + if (parent_->shutting_down_) return nullptr; + return parent_->channel_control_helper()->CreateChannel(target, type, args); +} + +void XdsLb::Helper::UpdateState(grpc_connectivity_state state, + grpc_error* state_error, + UniquePtr picker) { + if (parent_->shutting_down_) { + GRPC_ERROR_UNREF(state_error); + return; + } + // TODO(juanlishen): When in fallback mode, pass the child picker + // through without wrapping it. (Or maybe use a different helper for + // the fallback policy?) + RefCountedPtr client_stats; + if (parent_->lb_calld_ != nullptr && + parent_->lb_calld_->client_stats() != nullptr) { + client_stats = parent_->lb_calld_->client_stats()->Ref(); + } + parent_->channel_control_helper()->UpdateState( + state, state_error, + UniquePtr( + New(std::move(picker), std::move(client_stats)))); +} + +void XdsLb::Helper::RequestReresolution() { + if (parent_->shutting_down_) return; + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] Re-resolution requested from the internal RR policy " + "(%p).", + parent_.get(), parent_->child_policy_.get()); + } + // If we are talking to a balancer, we expect to get updated addresses + // from the balancer, so we can ignore the re-resolution request from + // the RR policy. Otherwise, pass the re-resolution request up to the + // channel. + if (parent_->lb_calld_ == nullptr || + !parent_->lb_calld_->seen_initial_response()) { + parent_->channel_control_helper()->RequestReresolution(); + } +} + // // serverlist parsing code // @@ -709,7 +762,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( // serverlist returned from the current LB call. if (lb_calld->client_stats_report_interval_ > 0 && lb_calld->client_stats_ == nullptr) { - lb_calld->client_stats_.reset(New()); + lb_calld->client_stats_ = MakeRefCounted(); // TODO(roth): We currently track this ref manually. Once the // ClosureRef API is ready, we should pass the RefCountedPtr<> along // with the callback. @@ -792,13 +845,13 @@ void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked( lb_calld->lb_call_, grpc_error_string(error)); gpr_free(status_details); } - xdslb_policy->TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_NONE); // If this lb_calld is still in use, this call ended because of a failure so // we want to retry connecting. Otherwise, we have deliberately ended this // call and no further action is required. if (lb_calld == xdslb_policy->lb_calld_.get()) { xdslb_policy->lb_calld_.reset(); GPR_ASSERT(!xdslb_policy->shutting_down_); + xdslb_policy->channel_control_helper()->RequestReresolution(); if (lb_calld->seen_initial_response_) { // If we lose connection to the LB server, reset the backoff and restart // the LB call immediately. @@ -919,13 +972,6 @@ XdsLb::XdsLb(LoadBalancingPolicy::Args args) GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &XdsLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_child_connectivity_changed_, - &XdsLb::OnChildPolicyConnectivityChangedLocked, this, - grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_child_request_reresolution_, - &XdsLb::OnChildPolicyRequestReresolutionLocked, this, - grpc_combiner_scheduler(args.combiner)); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "xds"); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -950,21 +996,22 @@ XdsLb::XdsLb(LoadBalancingPolicy::Args args) ParseLbConfig(args.lb_config); // Process channel args. ProcessChannelArgsLocked(*args.args); + // Initialize channel with a picker that will start us connecting. + channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(Ref()))); } XdsLb::~XdsLb() { - GPR_ASSERT(pending_picks_ == nullptr); gpr_mu_destroy(&lb_channel_mu_); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); - grpc_connectivity_state_destroy(&state_tracker_); if (serverlist_ != nullptr) { xds_grpclb_destroy_serverlist(serverlist_); } } void XdsLb::ShutdownLocked() { - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); shutting_down_ = true; lb_calld_.reset(); if (retry_timer_callback_pending_) { @@ -974,7 +1021,6 @@ void XdsLb::ShutdownLocked() { grpc_timer_cancel(&lb_fallback_timer_); } child_policy_.reset(); - TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_CANCELLED); // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -985,109 +1031,12 @@ void XdsLb::ShutdownLocked() { lb_channel_ = nullptr; gpr_mu_unlock(&lb_channel_mu_); } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "xds_shutdown"); - // Clear pending picks. - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); } // // public methods // -void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->on_complete = pp->original_on_complete; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pp->pick, &error)) { - // Synchronous return; schedule closure. - GRPC_CLOSURE_SCHED(pp->pick->on_complete, error); - } - Delete(pp); - } -} - -// Cancel a specific pending pick. -// -// A pick progresses as follows: -// - If there's a child policy available, it'll be handed over to child policy -// (in CreateChildPolicyLocked()). From that point onwards, it'll be the -// child policy's responsibility. For cancellations, that implies the pick -// needs to be also cancelled by the child policy instance. -// - Otherwise, without a child policy instance, picks stay pending at this -// policy's level (xds), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void XdsLb::CancelPickLocked(PickState* pick, grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if (pp->pick == pick) { - pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (child_policy_ != nullptr) { - child_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - -// Cancel all pending picks. -// -// A pick progresses as follows: -// - If there's a child policy available, it'll be handed over to child policy -// (in CreateChildPolicyLocked()). From that point onwards, it'll be the -// child policy's responsibility. For cancellations, that implies the pick -// needs to be also cancelled by the child policy instance. -// - Otherwise, without a child policy instance, picks stay pending at this -// policy's level (xds), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void XdsLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if ((*pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (child_policy_ != nullptr) { - child_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, - GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - void XdsLb::ExitIdleLocked() { if (!started_picking_) { StartPickingLocked(); @@ -1103,36 +1052,6 @@ void XdsLb::ResetBackoffLocked() { } } -bool XdsLb::PickLocked(PickState* pick, grpc_error** error) { - PendingPick* pp = PendingPickCreate(pick); - bool pick_done = false; - if (child_policy_ != nullptr) { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] about to PICK from policy %p", this, - child_policy_.get()); - } - pick_done = PickFromChildPolicyLocked(false /* force_async */, pp, error); - } else { // child_policy_ == NULL - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - pick_done = true; - } else { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] No child policy. Adding to xds's pending picks", - this); - } - AddPendingPick(pp); - if (!started_picking_) { - StartPickingLocked(); - } - pick_done = false; - } - } - return pick_done; -} - void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { // delegate to the child_policy_ to fill the children subchannels. @@ -1147,17 +1066,6 @@ void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, } } -grpc_connectivity_state XdsLb::CheckConnectivityLocked( - grpc_error** connectivity_error) { - return grpc_connectivity_state_get(&state_tracker_, connectivity_error); -} - -void XdsLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* closure) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - closure); -} - void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); if (addresses == nullptr) { @@ -1185,9 +1093,8 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { char* uri_str; gpr_asprintf(&uri_str, "fake:///%s", server_name_); gpr_mu_lock(&lb_channel_mu_); - lb_channel_ = grpc_client_channel_factory_create_channel( - client_channel_factory(), uri_str, - GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args); + lb_channel_ = channel_control_helper()->CreateChannel( + uri_str, GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, *lb_channel_args); gpr_mu_unlock(&lb_channel_mu_); GPR_ASSERT(lb_channel_ != nullptr); gpr_free(uri_str); @@ -1402,90 +1309,10 @@ void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg, } } -// -// PendingPick -// - -// Destroy function used when embedding client stats in call context. -void DestroyClientStats(void* arg) { - static_cast(arg)->Unref(); -} - -void XdsLb::PendingPickCleanup(PendingPick* pp) { - // If connected_subchannel is nullptr, no pick has been made by the - // child policy (e.g., all addresses failed to connect). - if (pp->pick->connected_subchannel != nullptr) { - // Pass on client stats via context. Passes ownership of the reference. - if (pp->client_stats != nullptr) { - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = - pp->client_stats.release(); - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = - DestroyClientStats; - } - } else { - pp->client_stats.reset(); - } -} - -/* The \a on_complete closure passed as part of the pick requires keeping a - * reference to its associated child policy instance. We wrap this closure in - * order to unref the child policy instance upon its invocation */ -void XdsLb::OnPendingPickComplete(void* arg, grpc_error* error) { - PendingPick* pp = static_cast(arg); - PendingPickCleanup(pp); - GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); - Delete(pp); -} - -XdsLb::PendingPick* XdsLb::PendingPickCreate(PickState* pick) { - PendingPick* pp = New(); - pp->xdslb_policy = this; - pp->pick = pick; - GRPC_CLOSURE_INIT(&pp->on_complete, &XdsLb::OnPendingPickComplete, pp, - grpc_schedule_on_exec_ctx); - pp->original_on_complete = pick->on_complete; - pick->on_complete = &pp->on_complete; - return pp; -} - -void XdsLb::AddPendingPick(PendingPick* pp) { - pp->next = pending_picks_; - pending_picks_ = pp; -} - // // code for interacting with the child policy // -// Performs a pick over \a child_policy_. Given that a pick can return -// immediately (ignoring its completion callback), we need to perform the -// cleanups this callback would otherwise be responsible for. -// If \a force_async is true, then we will manually schedule the -// completion callback even if the pick is available immediately. -bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error) { - // Set client_stats. - if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { - pp->client_stats = lb_calld_->client_stats()->Ref(); - } - // Pick via the child policy. - bool pick_done = child_policy_->PickLocked(pp->pick, error); - if (pick_done) { - PendingPickCleanup(pp); - if (force_async) { - GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); - *error = GRPC_ERROR_NONE; - pick_done = false; - } - Delete(pp); - } - // else, the pending pick will be registered and taken care of by the - // pending pick list inside the child policy. Eventually, - // OnPendingPickComplete() will be called, which will (among other - // things) add the LB token to the call's initial metadata. - return pick_done; -} - void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { GPR_ASSERT(child_policy_ == nullptr); child_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( @@ -1494,42 +1321,12 @@ void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { gpr_log(GPR_ERROR, "[xdslb %p] Failure creating a child policy", this); return; } - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - auto self = Ref(DEBUG_LOCATION, "on_child_reresolution_requested"); - self.release(); - child_policy_->SetReresolutionClosureLocked(&on_child_request_reresolution_); - grpc_error* child_state_error = nullptr; - child_connectivity_state_ = - child_policy_->CheckConnectivityLocked(&child_state_error); - // Connectivity state is a function of the child policy updated/created. - UpdateConnectivityStateFromChildPolicyLocked(child_state_error); // Add the xDS's interested_parties pollset_set to that of the newly created // child policy. This will make the child policy progress upon activity on // xDS LB, which in turn is tied to the application's call. grpc_pollset_set_add_pollset_set(child_policy_->interested_parties(), interested_parties()); - // Subscribe to changes to the connectivity of the new child policy. - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - self = Ref(DEBUG_LOCATION, "on_child_connectivity_changed"); - self.release(); - child_policy_->NotifyOnStateChangeLocked(&child_connectivity_state_, - &on_child_connectivity_changed_); child_policy_->ExitIdleLocked(); - // Send pending picks to child policy. - PendingPick* pp; - while ((pp = pending_picks_)) { - pending_picks_ = pp->next; - if (grpc_lb_xds_trace.enabled()) { - gpr_log( - GPR_INFO, - "[xdslb %p] Pending pick about to (async) PICK from child policy %p", - this, child_policy_.get()); - } - grpc_error* error = GRPC_ERROR_NONE; - PickFromChildPolicyLocked(true /* force_async */, pp, &error); - } } grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { @@ -1587,9 +1384,9 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { } else { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); - lb_policy_args.client_channel_factory = client_channel_factory(); - lb_policy_args.subchannel_pool = subchannel_pool()->Ref(); lb_policy_args.args = args; + lb_policy_args.channel_control_helper = + UniquePtr(New(Ref())); lb_policy_args.lb_config = child_policy_config; CreateChildPolicyLocked(child_policy_name, std::move(lb_policy_args)); if (grpc_lb_xds_trace.enabled()) { @@ -1601,102 +1398,6 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { grpc_json_destroy(child_policy_json); } -void XdsLb::OnChildPolicyRequestReresolutionLocked(void* arg, - grpc_error* error) { - XdsLb* xdslb_policy = static_cast(arg); - if (xdslb_policy->shutting_down_ || error != GRPC_ERROR_NONE) { - xdslb_policy->Unref(DEBUG_LOCATION, "on_child_reresolution_requested"); - return; - } - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Re-resolution requested from child policy " - "(%p).", - xdslb_policy, xdslb_policy->child_policy_.get()); - } - // If we are talking to a balancer, we expect to get updated addresses form - // the balancer, so we can ignore the re-resolution request from the child - // policy. - // Otherwise, handle the re-resolution request using the xds policy's - // original re-resolution closure. - if (xdslb_policy->lb_calld_ == nullptr || - !xdslb_policy->lb_calld_->seen_initial_response()) { - xdslb_policy->TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_NONE); - } - // Give back the wrapper closure to the child policy. - xdslb_policy->child_policy_->SetReresolutionClosureLocked( - &xdslb_policy->on_child_request_reresolution_); -} - -void XdsLb::UpdateConnectivityStateFromChildPolicyLocked( - grpc_error* child_state_error) { - const grpc_connectivity_state curr_glb_state = - grpc_connectivity_state_check(&state_tracker_); - /* The new connectivity status is a function of the previous one and the new - * input coming from the status of the child policy. - * - * current state (xds's) - * | - * v || I | C | R | TF | SD | <- new state (child policy's) - * ===++====+=====+=====+======+======+ - * I || I | C | R | [I] | [I] | - * ---++----+-----+-----+------+------+ - * C || I | C | R | [C] | [C] | - * ---++----+-----+-----+------+------+ - * R || I | C | R | [R] | [R] | - * ---++----+-----+-----+------+------+ - * TF || I | C | R | [TF] | [TF] | - * ---++----+-----+-----+------+------+ - * SD || NA | NA | NA | NA | NA | (*) - * ---++----+-----+-----+------+------+ - * - * A [STATE] indicates that the old child policy is kept. In those cases, - * STATE is the current state of xds, which is left untouched. - * - * In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to - * the previous child policy instance. - * - * Note that the status is never updated to SHUTDOWN as a result of calling - * this function. Only glb_shutdown() has the power to set that state. - * - * (*) This function mustn't be called during shutting down. */ - GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN); - switch (child_connectivity_state_) { - case GRPC_CHANNEL_TRANSIENT_FAILURE: - case GRPC_CHANNEL_SHUTDOWN: - GPR_ASSERT(child_state_error != GRPC_ERROR_NONE); - break; - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_READY: - GPR_ASSERT(child_state_error == GRPC_ERROR_NONE); - } - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Setting xds's state to %s from child policy %p state.", - this, grpc_connectivity_state_name(child_connectivity_state_), - child_policy_.get()); - } - grpc_connectivity_state_set(&state_tracker_, child_connectivity_state_, - child_state_error, - "update_lb_connectivity_status_locked"); -} - -void XdsLb::OnChildPolicyConnectivityChangedLocked(void* arg, - grpc_error* error) { - XdsLb* xdslb_policy = static_cast(arg); - if (xdslb_policy->shutting_down_) { - xdslb_policy->Unref(DEBUG_LOCATION, "on_child_connectivity_changed"); - return; - } - xdslb_policy->UpdateConnectivityStateFromChildPolicyLocked( - GRPC_ERROR_REF(error)); - // Resubscribe. Reuse the "on_child_connectivity_changed" ref. - xdslb_policy->child_policy_->NotifyOnStateChangeLocked( - &xdslb_policy->child_connectivity_state_, - &xdslb_policy->on_child_connectivity_changed_); -} - // // factory // diff --git a/src/core/ext/filters/client_channel/request_routing.cc b/src/core/ext/filters/client_channel/request_routing.cc deleted file mode 100644 index d6ff34c99b5..00000000000 --- a/src/core/ext/filters/client_channel/request_routing.cc +++ /dev/null @@ -1,946 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/ext/filters/client_channel/request_routing.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" -#include "src/core/ext/filters/client_channel/http_connect_handshaker.h" -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" -#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" -#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" -#include "src/core/ext/filters/client_channel/resolver_registry.h" -#include "src/core/ext/filters/client_channel/retry_throttle.h" -#include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/ext/filters/deadline/deadline_filter.h" -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/channel/status_util.h" -#include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/inlined_vector.h" -#include "src/core/lib/gprpp/manual_constructor.h" -#include "src/core/lib/iomgr/combiner.h" -#include "src/core/lib/iomgr/iomgr.h" -#include "src/core/lib/iomgr/polling_entity.h" -#include "src/core/lib/profiling/timers.h" -#include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/surface/channel.h" -#include "src/core/lib/transport/connectivity_state.h" -#include "src/core/lib/transport/error_utils.h" -#include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/metadata_batch.h" -#include "src/core/lib/transport/service_config.h" -#include "src/core/lib/transport/static_metadata.h" -#include "src/core/lib/transport/status_metadata.h" - -namespace grpc_core { - -// -// RequestRouter::Request::ResolverResultWaiter -// - -// Handles waiting for a resolver result. -// Used only for the first call on an idle channel. -class RequestRouter::Request::ResolverResultWaiter { - public: - explicit ResolverResultWaiter(Request* request) - : request_router_(request->request_router_), - request_(request), - tracer_enabled_(request_router_->tracer_->enabled()) { - if (tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: deferring pick pending resolver " - "result", - request_router_, request); - } - // Add closure to be run when a resolver result is available. - GRPC_CLOSURE_INIT(&done_closure_, &DoneLocked, this, - grpc_combiner_scheduler(request_router_->combiner_)); - AddToWaitingList(); - // Set cancellation closure, so that we abort if the call is cancelled. - GRPC_CLOSURE_INIT(&cancel_closure_, &CancelLocked, this, - grpc_combiner_scheduler(request_router_->combiner_)); - grpc_call_combiner_set_notify_on_cancel(request->call_combiner_, - &cancel_closure_); - } - - private: - // Adds done_closure_ to - // request_router_->waiting_for_resolver_result_closures_. - void AddToWaitingList() { - grpc_closure_list_append( - &request_router_->waiting_for_resolver_result_closures_, &done_closure_, - GRPC_ERROR_NONE); - } - - // Invoked when a resolver result is available. - static void DoneLocked(void* arg, grpc_error* error) { - ResolverResultWaiter* self = static_cast(arg); - RequestRouter* request_router = self->request_router_; - // If CancelLocked() has already run, delete ourselves without doing - // anything. Note that the call stack may have already been destroyed, - // so it's not safe to access anything in state_. - if (GPR_UNLIKELY(self->finished_)) { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p: call cancelled before resolver result", - request_router); - } - Delete(self); - return; - } - // Otherwise, process the resolver result. - Request* request = self->request_; - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: resolver failed to return data", - request_router, request); - } - GRPC_CLOSURE_RUN(request->on_route_done_, GRPC_ERROR_REF(error)); - } else if (GPR_UNLIKELY(request_router->resolver_ == nullptr)) { - // Shutting down. - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, "request_router=%p request=%p: resolver disconnected", - request_router, request); - } - GRPC_CLOSURE_RUN(request->on_route_done_, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); - } else if (GPR_UNLIKELY(request_router->lb_policy_ == nullptr)) { - // Transient resolver failure. - // If call has wait_for_ready=true, try again; otherwise, fail. - if (*request->pick_.initial_metadata_flags & - GRPC_INITIAL_METADATA_WAIT_FOR_READY) { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: resolver returned but no LB " - "policy; wait_for_ready=true; trying again", - request_router, request); - } - // Re-add ourselves to the waiting list. - self->AddToWaitingList(); - // Return early so that we don't set finished_ to true below. - return; - } else { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: resolver returned but no LB " - "policy; wait_for_ready=false; failing", - request_router, request); - } - GRPC_CLOSURE_RUN( - request->on_route_done_, - grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Name resolution failure"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); - } - } else { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: resolver returned, doing LB " - "pick", - request_router, request); - } - request->ProcessServiceConfigAndStartLbPickLocked(); - } - self->finished_ = true; - } - - // Invoked when the call is cancelled. - // Note: This runs under the client_channel combiner, but will NOT be - // holding the call combiner. - static void CancelLocked(void* arg, grpc_error* error) { - ResolverResultWaiter* self = static_cast(arg); - RequestRouter* request_router = self->request_router_; - // If DoneLocked() has already run, delete ourselves without doing anything. - if (self->finished_) { - Delete(self); - return; - } - Request* request = self->request_; - // If we are being cancelled, immediately invoke on_route_done_ - // to propagate the error back to the caller. - if (error != GRPC_ERROR_NONE) { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: cancelling call waiting for " - "name resolution", - request_router, request); - } - // Note: Although we are not in the call combiner here, we are - // basically stealing the call combiner from the pending pick, so - // it's safe to run on_route_done_ here -- we are essentially - // calling it here instead of calling it in DoneLocked(). - GRPC_CLOSURE_RUN(request->on_route_done_, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick cancelled", &error, 1)); - } - self->finished_ = true; - } - - RequestRouter* request_router_; - Request* request_; - const bool tracer_enabled_; - grpc_closure done_closure_; - grpc_closure cancel_closure_; - bool finished_ = false; -}; - -// -// RequestRouter::Request::AsyncPickCanceller -// - -// Handles the call combiner cancellation callback for an async LB pick. -class RequestRouter::Request::AsyncPickCanceller { - public: - explicit AsyncPickCanceller(Request* request) - : request_router_(request->request_router_), - request_(request), - tracer_enabled_(request_router_->tracer_->enabled()) { - GRPC_CALL_STACK_REF(request->owning_call_, "pick_callback_cancel"); - // Set cancellation closure, so that we abort if the call is cancelled. - GRPC_CLOSURE_INIT(&cancel_closure_, &CancelLocked, this, - grpc_combiner_scheduler(request_router_->combiner_)); - grpc_call_combiner_set_notify_on_cancel(request->call_combiner_, - &cancel_closure_); - } - - void MarkFinishedLocked() { - finished_ = true; - GRPC_CALL_STACK_UNREF(request_->owning_call_, "pick_callback_cancel"); - } - - private: - // Invoked when the call is cancelled. - // Note: This runs under the client_channel combiner, but will NOT be - // holding the call combiner. - static void CancelLocked(void* arg, grpc_error* error) { - AsyncPickCanceller* self = static_cast(arg); - Request* request = self->request_; - RequestRouter* request_router = self->request_router_; - if (!self->finished_) { - // Note: request_router->lb_policy_ may have changed since we started our - // pick, in which case we will be cancelling the pick on a policy other - // than the one we started it on. However, this will just be a no-op. - if (error != GRPC_ERROR_NONE && request_router->lb_policy_ != nullptr) { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: cancelling pick from LB " - "policy %p", - request_router, request, request_router->lb_policy_.get()); - } - request_router->lb_policy_->CancelPickLocked(&request->pick_, - GRPC_ERROR_REF(error)); - } - request->pick_canceller_ = nullptr; - GRPC_CALL_STACK_UNREF(request->owning_call_, "pick_callback_cancel"); - } - Delete(self); - } - - RequestRouter* request_router_; - Request* request_; - const bool tracer_enabled_; - grpc_closure cancel_closure_; - bool finished_ = false; -}; - -// -// RequestRouter::Request -// - -RequestRouter::Request::Request(grpc_call_stack* owning_call, - grpc_call_combiner* call_combiner, - grpc_polling_entity* pollent, - grpc_metadata_batch* send_initial_metadata, - uint32_t* send_initial_metadata_flags, - ApplyServiceConfigCallback apply_service_config, - void* apply_service_config_user_data, - grpc_closure* on_route_done) - : owning_call_(owning_call), - call_combiner_(call_combiner), - pollent_(pollent), - apply_service_config_(apply_service_config), - apply_service_config_user_data_(apply_service_config_user_data), - on_route_done_(on_route_done) { - pick_.initial_metadata = send_initial_metadata; - pick_.initial_metadata_flags = send_initial_metadata_flags; -} - -RequestRouter::Request::~Request() { - if (pick_.connected_subchannel != nullptr) { - pick_.connected_subchannel.reset(); - } - for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) { - if (pick_.subchannel_call_context[i].destroy != nullptr) { - pick_.subchannel_call_context[i].destroy( - pick_.subchannel_call_context[i].value); - } - } -} - -// Invoked once resolver results are available. -void RequestRouter::Request::ProcessServiceConfigAndStartLbPickLocked() { - // Get service config data if needed. - if (!apply_service_config_(apply_service_config_user_data_)) return; - // Start LB pick. - StartLbPickLocked(); -} - -void RequestRouter::Request::MaybeAddCallToInterestedPartiesLocked() { - if (!pollent_added_to_interested_parties_) { - pollent_added_to_interested_parties_ = true; - grpc_polling_entity_add_to_pollset_set( - pollent_, request_router_->interested_parties_); - } -} - -void RequestRouter::Request::MaybeRemoveCallFromInterestedPartiesLocked() { - if (pollent_added_to_interested_parties_) { - pollent_added_to_interested_parties_ = false; - grpc_polling_entity_del_from_pollset_set( - pollent_, request_router_->interested_parties_); - } -} - -// Starts a pick on the LB policy. -void RequestRouter::Request::StartLbPickLocked() { - if (request_router_->tracer_->enabled()) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: starting pick on lb_policy=%p", - request_router_, this, request_router_->lb_policy_.get()); - } - GRPC_CLOSURE_INIT(&on_pick_done_, &LbPickDoneLocked, this, - grpc_combiner_scheduler(request_router_->combiner_)); - pick_.on_complete = &on_pick_done_; - GRPC_CALL_STACK_REF(owning_call_, "pick_callback"); - grpc_error* error = GRPC_ERROR_NONE; - const bool pick_done = - request_router_->lb_policy_->PickLocked(&pick_, &error); - if (pick_done) { - // Pick completed synchronously. - if (request_router_->tracer_->enabled()) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: pick completed synchronously", - request_router_, this); - } - GRPC_CLOSURE_RUN(on_route_done_, error); - GRPC_CALL_STACK_UNREF(owning_call_, "pick_callback"); - } else { - // Pick will be returned asynchronously. - // Add the request's polling entity to the request_router's - // interested_parties, so that the I/O of the LB policy can be done - // under it. It will be removed in LbPickDoneLocked(). - MaybeAddCallToInterestedPartiesLocked(); - // Request notification on call cancellation. - // We allocate a separate object to track cancellation, since the - // cancellation closure might still be pending when we need to reuse - // the memory in which this Request object is stored for a subsequent - // retry attempt. - pick_canceller_ = New(this); - } -} - -// Callback invoked by LoadBalancingPolicy::PickLocked() for async picks. -// Unrefs the LB policy and invokes on_route_done_. -void RequestRouter::Request::LbPickDoneLocked(void* arg, grpc_error* error) { - Request* self = static_cast(arg); - RequestRouter* request_router = self->request_router_; - if (request_router->tracer_->enabled()) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: pick completed asynchronously", - request_router, self); - } - self->MaybeRemoveCallFromInterestedPartiesLocked(); - if (self->pick_canceller_ != nullptr) { - self->pick_canceller_->MarkFinishedLocked(); - } - GRPC_CLOSURE_RUN(self->on_route_done_, GRPC_ERROR_REF(error)); - GRPC_CALL_STACK_UNREF(self->owning_call_, "pick_callback"); -} - -// -// RequestRouter::LbConnectivityWatcher -// - -class RequestRouter::LbConnectivityWatcher { - public: - LbConnectivityWatcher(RequestRouter* request_router, - grpc_connectivity_state state, - LoadBalancingPolicy* lb_policy, - grpc_channel_stack* owning_stack, - grpc_combiner* combiner) - : request_router_(request_router), - state_(state), - lb_policy_(lb_policy), - owning_stack_(owning_stack) { - GRPC_CHANNEL_STACK_REF(owning_stack_, "LbConnectivityWatcher"); - GRPC_CLOSURE_INIT(&on_changed_, &OnLbPolicyStateChangedLocked, this, - grpc_combiner_scheduler(combiner)); - lb_policy_->NotifyOnStateChangeLocked(&state_, &on_changed_); - } - - ~LbConnectivityWatcher() { - GRPC_CHANNEL_STACK_UNREF(owning_stack_, "LbConnectivityWatcher"); - } - - private: - static void OnLbPolicyStateChangedLocked(void* arg, grpc_error* error) { - LbConnectivityWatcher* self = static_cast(arg); - // If the notification is not for the current policy, we're stale, - // so delete ourselves. - if (self->lb_policy_ != self->request_router_->lb_policy_.get()) { - Delete(self); - return; - } - // Otherwise, process notification. - if (self->request_router_->tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: lb_policy=%p state changed to %s", - self->request_router_, self->lb_policy_, - grpc_connectivity_state_name(self->state_)); - } - self->request_router_->SetConnectivityStateLocked( - self->state_, GRPC_ERROR_REF(error), "lb_changed"); - // If shutting down, terminate watch. - if (self->state_ == GRPC_CHANNEL_SHUTDOWN) { - Delete(self); - return; - } - // Renew watch. - self->lb_policy_->NotifyOnStateChangeLocked(&self->state_, - &self->on_changed_); - } - - RequestRouter* request_router_; - grpc_connectivity_state state_; - // LB policy address. No ref held, so not safe to dereference unless - // it happens to match request_router->lb_policy_. - LoadBalancingPolicy* lb_policy_; - grpc_channel_stack* owning_stack_; - grpc_closure on_changed_; -}; - -// -// RequestRounter::ReresolutionRequestHandler -// - -class RequestRouter::ReresolutionRequestHandler { - public: - ReresolutionRequestHandler(RequestRouter* request_router, - LoadBalancingPolicy* lb_policy, - grpc_channel_stack* owning_stack, - grpc_combiner* combiner) - : request_router_(request_router), - lb_policy_(lb_policy), - owning_stack_(owning_stack) { - GRPC_CHANNEL_STACK_REF(owning_stack_, "ReresolutionRequestHandler"); - GRPC_CLOSURE_INIT(&closure_, &OnRequestReresolutionLocked, this, - grpc_combiner_scheduler(combiner)); - lb_policy_->SetReresolutionClosureLocked(&closure_); - } - - private: - static void OnRequestReresolutionLocked(void* arg, grpc_error* error) { - ReresolutionRequestHandler* self = - static_cast(arg); - RequestRouter* request_router = self->request_router_; - // If this invocation is for a stale LB policy, treat it as an LB shutdown - // signal. - if (self->lb_policy_ != request_router->lb_policy_.get() || - error != GRPC_ERROR_NONE || request_router->resolver_ == nullptr) { - GRPC_CHANNEL_STACK_UNREF(request_router->owning_stack_, - "ReresolutionRequestHandler"); - Delete(self); - return; - } - if (request_router->tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: started name re-resolving", - request_router); - } - request_router->resolver_->RequestReresolutionLocked(); - // Give back the closure to the LB policy. - self->lb_policy_->SetReresolutionClosureLocked(&self->closure_); - } - - RequestRouter* request_router_; - // LB policy address. No ref held, so not safe to dereference unless - // it happens to match request_router->lb_policy_. - LoadBalancingPolicy* lb_policy_; - grpc_channel_stack* owning_stack_; - grpc_closure closure_; -}; - -// -// RequestRouter -// - -RequestRouter::RequestRouter( - grpc_channel_stack* owning_stack, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, - grpc_pollset_set* interested_parties, TraceFlag* tracer, - ProcessResolverResultCallback process_resolver_result, - void* process_resolver_result_user_data, const char* target_uri, - const grpc_channel_args* args, grpc_error** error) - : owning_stack_(owning_stack), - combiner_(combiner), - client_channel_factory_(client_channel_factory), - interested_parties_(interested_parties), - tracer_(tracer), - process_resolver_result_(process_resolver_result), - process_resolver_result_user_data_(process_resolver_result_user_data) { - // Get subchannel pool. - const grpc_arg* arg = - grpc_channel_args_find(args, GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL); - if (grpc_channel_arg_get_bool(arg, false)) { - subchannel_pool_ = MakeRefCounted(); - } else { - subchannel_pool_ = GlobalSubchannelPool::instance(); - } - GRPC_CLOSURE_INIT(&on_resolver_result_changed_, - &RequestRouter::OnResolverResultChangedLocked, this, - grpc_combiner_scheduler(combiner)); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, - "request_router"); - grpc_channel_args* new_args = nullptr; - if (process_resolver_result == nullptr) { - grpc_arg arg = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), 0); - new_args = grpc_channel_args_copy_and_add(args, &arg, 1); - } - resolver_ = ResolverRegistry::CreateResolver( - target_uri, (new_args == nullptr ? args : new_args), interested_parties_, - combiner_); - grpc_channel_args_destroy(new_args); - if (resolver_ == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); - } -} - -RequestRouter::~RequestRouter() { - if (resolver_ != nullptr) { - // The only way we can get here is if we never started resolving, - // because we take a ref to the channel stack when we start - // resolving and do not release it until the resolver callback is - // invoked after the resolver shuts down. - resolver_.reset(); - } - if (lb_policy_ != nullptr) { - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties_); - lb_policy_.reset(); - } - if (client_channel_factory_ != nullptr) { - grpc_client_channel_factory_unref(client_channel_factory_); - } - grpc_connectivity_state_destroy(&state_tracker_); -} - -namespace { - -const char* GetChannelConnectivityStateChangeString( - grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "Channel state change to IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "Channel state change to CONNECTING"; - case GRPC_CHANNEL_READY: - return "Channel state change to READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "Channel state change to TRANSIENT_FAILURE"; - case GRPC_CHANNEL_SHUTDOWN: - return "Channel state change to SHUTDOWN"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -} // namespace - -void RequestRouter::SetConnectivityStateLocked(grpc_connectivity_state state, - grpc_error* error, - const char* reason) { - if (lb_policy_ != nullptr) { - if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - // Cancel picks with wait_for_ready=false. - lb_policy_->CancelMatchingPicksLocked( - /* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY, - /* check= */ 0, GRPC_ERROR_REF(error)); - } else if (state == GRPC_CHANNEL_SHUTDOWN) { - // Cancel all picks. - lb_policy_->CancelMatchingPicksLocked(/* mask= */ 0, /* check= */ 0, - GRPC_ERROR_REF(error)); - } - } - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: setting connectivity state to %s", - this, grpc_connectivity_state_name(state)); - } - if (channelz_node_ != nullptr) { - channelz_node_->AddTraceEvent( - channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - GetChannelConnectivityStateChangeString(state))); - } - grpc_connectivity_state_set(&state_tracker_, state, error, reason); -} - -void RequestRouter::StartResolvingLocked() { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: starting name resolution", this); - } - GPR_ASSERT(!started_resolving_); - started_resolving_ = true; - GRPC_CHANNEL_STACK_REF(owning_stack_, "resolver"); - resolver_->NextLocked(&resolver_result_, &on_resolver_result_changed_); -} - -// Invoked from the resolver NextLocked() callback when the resolver -// is shutting down. -void RequestRouter::OnResolverShutdownLocked(grpc_error* error) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: shutting down", this); - } - if (lb_policy_ != nullptr) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: shutting down lb_policy=%p", this, - lb_policy_.get()); - } - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties_); - lb_policy_.reset(); - } - if (resolver_ != nullptr) { - // This should never happen; it can only be triggered by a resolver - // implementation spotaneously deciding to report shutdown without - // being orphaned. This code is included just to be defensive. - if (tracer_->enabled()) { - gpr_log(GPR_INFO, - "request_router=%p: spontaneous shutdown from resolver %p", this, - resolver_.get()); - } - resolver_.reset(); - SetConnectivityStateLocked(GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Resolver spontaneous shutdown", &error, 1), - "resolver_spontaneous_shutdown"); - } - grpc_closure_list_fail_all(&waiting_for_resolver_result_closures_, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Channel disconnected", &error, 1)); - GRPC_CLOSURE_LIST_SCHED(&waiting_for_resolver_result_closures_); - GRPC_CHANNEL_STACK_UNREF(owning_stack_, "resolver"); - grpc_channel_args_destroy(resolver_result_); - resolver_result_ = nullptr; - GRPC_ERROR_UNREF(error); -} - -// Creates a new LB policy, replacing any previous one. -// If the new policy is created successfully, sets *connectivity_state and -// *connectivity_error to its initial connectivity state; otherwise, -// leaves them unchanged. -void RequestRouter::CreateNewLbPolicyLocked( - const char* lb_policy_name, grpc_json* lb_config, - grpc_connectivity_state* connectivity_state, - grpc_error** connectivity_error, TraceStringVector* trace_strings) { - LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = combiner_; - lb_policy_args.client_channel_factory = client_channel_factory_; - lb_policy_args.subchannel_pool = subchannel_pool_; - lb_policy_args.args = resolver_result_; - lb_policy_args.lb_config = lb_config; - OrphanablePtr new_lb_policy = - LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(lb_policy_name, - lb_policy_args); - if (GPR_UNLIKELY(new_lb_policy == nullptr)) { - gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); - if (channelz_node_ != nullptr) { - char* str; - gpr_asprintf(&str, "Could not create LB policy \'%s\'", lb_policy_name); - trace_strings->push_back(str); - } - } else { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: created new LB policy \"%s\" (%p)", - this, lb_policy_name, new_lb_policy.get()); - } - if (channelz_node_ != nullptr) { - char* str; - gpr_asprintf(&str, "Created new LB policy \'%s\'", lb_policy_name); - trace_strings->push_back(str); - } - // Swap out the LB policy and update the fds in interested_parties_. - if (lb_policy_ != nullptr) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: shutting down lb_policy=%p", this, - lb_policy_.get()); - } - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties_); - lb_policy_->HandOffPendingPicksLocked(new_lb_policy.get()); - } - lb_policy_ = std::move(new_lb_policy); - grpc_pollset_set_add_pollset_set(lb_policy_->interested_parties(), - interested_parties_); - // Create re-resolution request handler for the new LB policy. It - // will delete itself when no longer needed. - New(this, lb_policy_.get(), owning_stack_, - combiner_); - // Get the new LB policy's initial connectivity state and start a - // connectivity watch. - GRPC_ERROR_UNREF(*connectivity_error); - *connectivity_state = - lb_policy_->CheckConnectivityLocked(connectivity_error); - if (exit_idle_when_lb_policy_arrives_) { - lb_policy_->ExitIdleLocked(); - exit_idle_when_lb_policy_arrives_ = false; - } - // Create new watcher. It will delete itself when done. - New(this, *connectivity_state, lb_policy_.get(), - owning_stack_, combiner_); - } -} - -void RequestRouter::MaybeAddTraceMessagesForAddressChangesLocked( - TraceStringVector* trace_strings) { - const ServerAddressList* addresses = - FindServerAddressListChannelArg(resolver_result_); - const bool resolution_contains_addresses = - addresses != nullptr && addresses->size() > 0; - if (!resolution_contains_addresses && - previous_resolution_contained_addresses_) { - trace_strings->push_back(gpr_strdup("Address list became empty")); - } else if (resolution_contains_addresses && - !previous_resolution_contained_addresses_) { - trace_strings->push_back(gpr_strdup("Address list became non-empty")); - } - previous_resolution_contained_addresses_ = resolution_contains_addresses; -} - -void RequestRouter::ConcatenateAndAddChannelTraceLocked( - TraceStringVector* trace_strings) const { - if (!trace_strings->empty()) { - gpr_strvec v; - gpr_strvec_init(&v); - gpr_strvec_add(&v, gpr_strdup("Resolution event: ")); - bool is_first = 1; - for (size_t i = 0; i < trace_strings->size(); ++i) { - if (!is_first) gpr_strvec_add(&v, gpr_strdup(", ")); - is_first = false; - gpr_strvec_add(&v, (*trace_strings)[i]); - } - char* flat; - size_t flat_len = 0; - flat = gpr_strvec_flatten(&v, &flat_len); - channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info, - grpc_slice_new(flat, flat_len, gpr_free)); - gpr_strvec_destroy(&v); - } -} - -// Callback invoked when a resolver result is available. -void RequestRouter::OnResolverResultChangedLocked(void* arg, - grpc_error* error) { - RequestRouter* self = static_cast(arg); - if (self->tracer_->enabled()) { - const char* disposition = - self->resolver_result_ != nullptr - ? "" - : (error == GRPC_ERROR_NONE ? " (transient error)" - : " (resolver shutdown)"); - gpr_log(GPR_INFO, - "request_router=%p: got resolver result: resolver_result=%p " - "error=%s%s", - self, self->resolver_result_, grpc_error_string(error), - disposition); - } - // Handle shutdown. - if (error != GRPC_ERROR_NONE || self->resolver_ == nullptr) { - self->OnResolverShutdownLocked(GRPC_ERROR_REF(error)); - return; - } - // Data used to set the channel's connectivity state. - bool set_connectivity_state = true; - // We only want to trace the address resolution in the follow cases: - // (a) Address resolution resulted in service config change. - // (b) Address resolution that causes number of backends to go from - // zero to non-zero. - // (c) Address resolution that causes number of backends to go from - // non-zero to zero. - // (d) Address resolution that causes a new LB policy to be created. - // - // we track a list of strings to eventually be concatenated and traced. - TraceStringVector trace_strings; - grpc_connectivity_state connectivity_state = GRPC_CHANNEL_TRANSIENT_FAILURE; - grpc_error* connectivity_error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy"); - // resolver_result_ will be null in the case of a transient - // resolution error. In that case, we don't have any new result to - // process, which means that we keep using the previous result (if any). - if (self->resolver_result_ == nullptr) { - if (self->tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: resolver transient failure", self); - } - // Don't override connectivity state if we already have an LB policy. - if (self->lb_policy_ != nullptr) set_connectivity_state = false; - } else { - // Parse the resolver result. - const char* lb_policy_name = nullptr; - grpc_json* lb_policy_config = nullptr; - const bool service_config_changed = self->process_resolver_result_( - self->process_resolver_result_user_data_, *self->resolver_result_, - &lb_policy_name, &lb_policy_config); - GPR_ASSERT(lb_policy_name != nullptr); - // Check to see if we're already using the right LB policy. - const bool lb_policy_name_changed = - self->lb_policy_ == nullptr || - strcmp(self->lb_policy_->name(), lb_policy_name) != 0; - if (self->lb_policy_ != nullptr && !lb_policy_name_changed) { - // Continue using the same LB policy. Update with new addresses. - if (self->tracer_->enabled()) { - gpr_log(GPR_INFO, - "request_router=%p: updating existing LB policy \"%s\" (%p)", - self, lb_policy_name, self->lb_policy_.get()); - } - self->lb_policy_->UpdateLocked(*self->resolver_result_, lb_policy_config); - // No need to set the channel's connectivity state; the existing - // watch on the LB policy will take care of that. - set_connectivity_state = false; - } else { - // Instantiate new LB policy. - self->CreateNewLbPolicyLocked(lb_policy_name, lb_policy_config, - &connectivity_state, &connectivity_error, - &trace_strings); - } - // Add channel trace event. - if (self->channelz_node_ != nullptr) { - if (service_config_changed) { - // TODO(ncteisen): might be worth somehow including a snippet of the - // config in the trace, at the risk of bloating the trace logs. - trace_strings.push_back(gpr_strdup("Service config changed")); - } - self->MaybeAddTraceMessagesForAddressChangesLocked(&trace_strings); - self->ConcatenateAndAddChannelTraceLocked(&trace_strings); - } - // Clean up. - grpc_channel_args_destroy(self->resolver_result_); - self->resolver_result_ = nullptr; - } - // Set the channel's connectivity state if needed. - if (set_connectivity_state) { - self->SetConnectivityStateLocked(connectivity_state, connectivity_error, - "resolver_result"); - } else { - GRPC_ERROR_UNREF(connectivity_error); - } - // Invoke closures that were waiting for results and renew the watch. - GRPC_CLOSURE_LIST_SCHED(&self->waiting_for_resolver_result_closures_); - self->resolver_->NextLocked(&self->resolver_result_, - &self->on_resolver_result_changed_); -} - -void RequestRouter::RouteCallLocked(Request* request) { - GPR_ASSERT(request->pick_.connected_subchannel == nullptr); - request->request_router_ = this; - if (lb_policy_ != nullptr) { - // We already have resolver results, so process the service config - // and start an LB pick. - request->ProcessServiceConfigAndStartLbPickLocked(); - } else if (resolver_ == nullptr) { - GRPC_CLOSURE_RUN(request->on_route_done_, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); - } else { - // We do not yet have an LB policy, so wait for a resolver result. - if (!started_resolving_) { - StartResolvingLocked(); - } - // Create a new waiter, which will delete itself when done. - New(request); - // Add the request's polling entity to the request_router's - // interested_parties, so that the I/O of the resolver can be done - // under it. It will be removed in LbPickDoneLocked(). - request->MaybeAddCallToInterestedPartiesLocked(); - } -} - -void RequestRouter::ShutdownLocked(grpc_error* error) { - if (resolver_ != nullptr) { - SetConnectivityStateLocked(GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), - "disconnect"); - resolver_.reset(); - if (!started_resolving_) { - grpc_closure_list_fail_all(&waiting_for_resolver_result_closures_, - GRPC_ERROR_REF(error)); - GRPC_CLOSURE_LIST_SCHED(&waiting_for_resolver_result_closures_); - } - if (lb_policy_ != nullptr) { - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties_); - lb_policy_.reset(); - } - } - GRPC_ERROR_UNREF(error); -} - -grpc_connectivity_state RequestRouter::GetConnectivityState() { - return grpc_connectivity_state_check(&state_tracker_); -} - -void RequestRouter::NotifyOnConnectivityStateChange( - grpc_connectivity_state* state, grpc_closure* closure) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, state, - closure); -} - -void RequestRouter::ExitIdleLocked() { - if (lb_policy_ != nullptr) { - lb_policy_->ExitIdleLocked(); - } else { - exit_idle_when_lb_policy_arrives_ = true; - if (!started_resolving_ && resolver_ != nullptr) { - StartResolvingLocked(); - } - } -} - -void RequestRouter::ResetConnectionBackoffLocked() { - if (resolver_ != nullptr) { - resolver_->ResetBackoffLocked(); - resolver_->RequestReresolutionLocked(); - } - if (lb_policy_ != nullptr) { - lb_policy_->ResetBackoffLocked(); - } -} - -} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/request_routing.h b/src/core/ext/filters/client_channel/request_routing.h deleted file mode 100644 index 0027163869e..00000000000 --- a/src/core/ext/filters/client_channel/request_routing.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H - -#include - -#include "src/core/ext/filters/client_channel/client_channel_channelz.h" -#include "src/core/ext/filters/client_channel/client_channel_factory.h" -#include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/ext/filters/client_channel/resolver.h" -#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/channel_stack.h" -#include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/inlined_vector.h" -#include "src/core/lib/gprpp/orphanable.h" -#include "src/core/lib/iomgr/call_combiner.h" -#include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/polling_entity.h" -#include "src/core/lib/iomgr/pollset_set.h" -#include "src/core/lib/transport/connectivity_state.h" -#include "src/core/lib/transport/metadata_batch.h" - -namespace grpc_core { - -class RequestRouter { - public: - class Request { - public: - // Synchronous callback that applies the service config to a call. - // Returns false if the call should be failed. - typedef bool (*ApplyServiceConfigCallback)(void* user_data); - - Request(grpc_call_stack* owning_call, grpc_call_combiner* call_combiner, - grpc_polling_entity* pollent, - grpc_metadata_batch* send_initial_metadata, - uint32_t* send_initial_metadata_flags, - ApplyServiceConfigCallback apply_service_config, - void* apply_service_config_user_data, grpc_closure* on_route_done); - - ~Request(); - - // TODO(roth): It seems a bit ugly to expose this member in a - // non-const way. Find a better API to avoid this. - LoadBalancingPolicy::PickState* pick() { return &pick_; } - - private: - friend class RequestRouter; - - class ResolverResultWaiter; - class AsyncPickCanceller; - - void ProcessServiceConfigAndStartLbPickLocked(); - void StartLbPickLocked(); - static void LbPickDoneLocked(void* arg, grpc_error* error); - - void MaybeAddCallToInterestedPartiesLocked(); - void MaybeRemoveCallFromInterestedPartiesLocked(); - - // Populated by caller. - grpc_call_stack* owning_call_; - grpc_call_combiner* call_combiner_; - grpc_polling_entity* pollent_; - ApplyServiceConfigCallback apply_service_config_; - void* apply_service_config_user_data_; - grpc_closure* on_route_done_; - LoadBalancingPolicy::PickState pick_; - - // Internal state. - RequestRouter* request_router_ = nullptr; - bool pollent_added_to_interested_parties_ = false; - grpc_closure on_pick_done_; - AsyncPickCanceller* pick_canceller_ = nullptr; - }; - - // Synchronous callback that takes the service config JSON string and - // LB policy name. - // Returns true if the service config has changed since the last result. - typedef bool (*ProcessResolverResultCallback)(void* user_data, - const grpc_channel_args& args, - const char** lb_policy_name, - grpc_json** lb_policy_config); - - RequestRouter(grpc_channel_stack* owning_stack, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, - grpc_pollset_set* interested_parties, TraceFlag* tracer, - ProcessResolverResultCallback process_resolver_result, - void* process_resolver_result_user_data, const char* target_uri, - const grpc_channel_args* args, grpc_error** error); - - ~RequestRouter(); - - void set_channelz_node(channelz::ClientChannelNode* channelz_node) { - channelz_node_ = channelz_node; - } - - void RouteCallLocked(Request* request); - - // TODO(roth): Add methods to cancel picks. - - void ShutdownLocked(grpc_error* error); - - void ExitIdleLocked(); - void ResetConnectionBackoffLocked(); - - grpc_connectivity_state GetConnectivityState(); - void NotifyOnConnectivityStateChange(grpc_connectivity_state* state, - grpc_closure* closure); - - LoadBalancingPolicy* lb_policy() const { return lb_policy_.get(); } - - private: - using TraceStringVector = InlinedVector; - - class ReresolutionRequestHandler; - class LbConnectivityWatcher; - - void StartResolvingLocked(); - void OnResolverShutdownLocked(grpc_error* error); - void CreateNewLbPolicyLocked(const char* lb_policy_name, grpc_json* lb_config, - grpc_connectivity_state* connectivity_state, - grpc_error** connectivity_error, - TraceStringVector* trace_strings); - void MaybeAddTraceMessagesForAddressChangesLocked( - TraceStringVector* trace_strings); - void ConcatenateAndAddChannelTraceLocked( - TraceStringVector* trace_strings) const; - static void OnResolverResultChangedLocked(void* arg, grpc_error* error); - - void SetConnectivityStateLocked(grpc_connectivity_state state, - grpc_error* error, const char* reason); - - // Passed in from caller at construction time. - grpc_channel_stack* owning_stack_; - grpc_combiner* combiner_; - grpc_client_channel_factory* client_channel_factory_; - grpc_pollset_set* interested_parties_; - TraceFlag* tracer_; - - channelz::ClientChannelNode* channelz_node_ = nullptr; - - // Resolver and associated state. - OrphanablePtr resolver_; - ProcessResolverResultCallback process_resolver_result_; - void* process_resolver_result_user_data_; - bool started_resolving_ = false; - grpc_channel_args* resolver_result_ = nullptr; - bool previous_resolution_contained_addresses_ = false; - grpc_closure_list waiting_for_resolver_result_closures_; - grpc_closure on_resolver_result_changed_; - - // LB policy and associated state. - OrphanablePtr lb_policy_; - bool exit_idle_when_lb_policy_arrives_ = false; - - // Subchannel pool to pass to LB policy. - RefCountedPtr subchannel_pool_; - - grpc_connectivity_state_tracker state_tracker_; -}; - -} // namespace grpc_core - -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H */ diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc new file mode 100644 index 00000000000..ad9720fdda9 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -0,0 +1,460 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/ext/filters/client_channel/resolving_lb_policy.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/http_connect_handshaker.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" +#include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/retry_throttle.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/ext/filters/deadline/deadline_filter.h" +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/status_util.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/error_utils.h" +#include "src/core/lib/transport/metadata.h" +#include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/transport/service_config.h" +#include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/status_metadata.h" + +namespace grpc_core { + +// +// ResolvingLoadBalancingPolicy::ResolvingControlHelper +// + +class ResolvingLoadBalancingPolicy::ResolvingControlHelper + : public LoadBalancingPolicy::ChannelControlHelper { + public: + explicit ResolvingControlHelper( + RefCountedPtr parent) + : parent_(std::move(parent)) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. + return parent_->channel_control_helper()->CreateSubchannel(args); + } + + grpc_channel* CreateChannel(const char* target, grpc_client_channel_type type, + const grpc_channel_args& args) override { + if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. + return parent_->channel_control_helper()->CreateChannel(target, type, args); + } + + void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + UniquePtr picker) override { + if (parent_->resolver_ == nullptr) { + // shutting down. + GRPC_ERROR_UNREF(state_error); + return; + } + parent_->channel_control_helper()->UpdateState(state, state_error, + std::move(picker)); + } + + void RequestReresolution() override { + if (parent_->tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: started name re-resolving", + parent_.get()); + } + if (parent_->resolver_ != nullptr) { + parent_->resolver_->RequestReresolutionLocked(); + } + } + + private: + RefCountedPtr parent_; +}; + +// +// ResolvingLoadBalancingPolicy +// + +ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( + Args args, TraceFlag* tracer, UniquePtr target_uri, + UniquePtr child_policy_name, grpc_json* child_lb_config, + grpc_error** error) + : LoadBalancingPolicy(std::move(args)), + tracer_(tracer), + target_uri_(std::move(target_uri)), + child_policy_name_(std::move(child_policy_name)), + child_lb_config_str_(grpc_json_dump_to_string(child_lb_config, 0)), + child_lb_config_(grpc_json_parse_string(child_lb_config_str_.get())) { + GPR_ASSERT(child_policy_name_ != nullptr); + // Don't fetch service config, since this ctor is for use in nested LB + // policies, not at the top level, and we only fetch the service + // config at the top level. + grpc_arg arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), 0); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(args.args, &arg, 1); + *error = Init(*new_args); + grpc_channel_args_destroy(new_args); +} + +ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( + Args args, TraceFlag* tracer, UniquePtr target_uri, + ProcessResolverResultCallback process_resolver_result, + void* process_resolver_result_user_data, grpc_error** error) + : LoadBalancingPolicy(std::move(args)), + tracer_(tracer), + target_uri_(std::move(target_uri)), + process_resolver_result_(process_resolver_result), + process_resolver_result_user_data_(process_resolver_result_user_data) { + GPR_ASSERT(process_resolver_result != nullptr); + *error = Init(*args.args); +} + +grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) { + GRPC_CLOSURE_INIT( + &on_resolver_result_changed_, + &ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked, this, + grpc_combiner_scheduler(combiner())); + resolver_ = ResolverRegistry::CreateResolver( + target_uri_.get(), &args, interested_parties(), combiner()); + if (resolver_ == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); + } + // Return our picker to the channel. + channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(Ref()))); + return GRPC_ERROR_NONE; +} + +ResolvingLoadBalancingPolicy::~ResolvingLoadBalancingPolicy() { + GPR_ASSERT(resolver_ == nullptr); + GPR_ASSERT(lb_policy_ == nullptr); + grpc_json_destroy(child_lb_config_); +} + +void ResolvingLoadBalancingPolicy::ShutdownLocked() { + if (resolver_ != nullptr) { + resolver_.reset(); + if (lb_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties()); + lb_policy_.reset(); + } + } +} + +void ResolvingLoadBalancingPolicy::ExitIdleLocked() { + if (lb_policy_ != nullptr) { + lb_policy_->ExitIdleLocked(); + } else { + if (!started_resolving_ && resolver_ != nullptr) { + StartResolvingLocked(); + } + } +} + +void ResolvingLoadBalancingPolicy::ResetBackoffLocked() { + if (resolver_ != nullptr) { + resolver_->ResetBackoffLocked(); + resolver_->RequestReresolutionLocked(); + } + if (lb_policy_ != nullptr) { + lb_policy_->ResetBackoffLocked(); + } +} + +void ResolvingLoadBalancingPolicy::FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) { + if (lb_policy_ != nullptr) { + lb_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + } +} + +void ResolvingLoadBalancingPolicy::StartResolvingLocked() { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: starting name resolution", this); + } + GPR_ASSERT(!started_resolving_); + started_resolving_ = true; + Ref().release(); + resolver_->NextLocked(&resolver_result_, &on_resolver_result_changed_); +} + +// Invoked from the resolver NextLocked() callback when the resolver +// is shutting down. +void ResolvingLoadBalancingPolicy::OnResolverShutdownLocked(grpc_error* error) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down", this); + } + if (lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, + lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties()); + lb_policy_.reset(); + } + if (resolver_ != nullptr) { + // This should never happen; it can only be triggered by a resolver + // implementation spotaneously deciding to report shutdown without + // being orphaned. This code is included just to be defensive. + if (tracer_->enabled()) { + gpr_log(GPR_INFO, + "resolving_lb=%p: spontaneous shutdown from resolver %p", this, + resolver_.get()); + } + resolver_.reset(); + grpc_error* error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Resolver spontaneous shutdown", &error, 1); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), + UniquePtr(New(error))); + } + grpc_channel_args_destroy(resolver_result_); + resolver_result_ = nullptr; + GRPC_ERROR_UNREF(error); + Unref(); +} + +// Creates a new LB policy, replacing any previous one. +// Updates trace_strings to indicate what was done. +void ResolvingLoadBalancingPolicy::CreateNewLbPolicyLocked( + const char* lb_policy_name, grpc_json* lb_config, + TraceStringVector* trace_strings) { + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = combiner(); + lb_policy_args.channel_control_helper = + UniquePtr(New(Ref())); + lb_policy_args.args = resolver_result_; + lb_policy_args.lb_config = lb_config; + OrphanablePtr new_lb_policy = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + lb_policy_name, std::move(lb_policy_args)); + if (GPR_UNLIKELY(new_lb_policy == nullptr)) { + gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); + if (channelz_node() != nullptr) { + char* str; + gpr_asprintf(&str, "Could not create LB policy \"%s\"", lb_policy_name); + trace_strings->push_back(str); + } + } else { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: created new LB policy \"%s\" (%p)", + this, lb_policy_name, new_lb_policy.get()); + } + if (channelz_node() != nullptr) { + char* str; + gpr_asprintf(&str, "Created new LB policy \"%s\"", lb_policy_name); + trace_strings->push_back(str); + } + // Propagate channelz node. + auto* channelz = channelz_node(); + if (channelz != nullptr) { + new_lb_policy->set_channelz_node(channelz->Ref()); + } + // Swap out the LB policy and update the fds in interested_parties_. + if (lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, + lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties()); + } + lb_policy_ = std::move(new_lb_policy); + grpc_pollset_set_add_pollset_set(lb_policy_->interested_parties(), + interested_parties()); + lb_policy_->ExitIdleLocked(); + } +} + +void ResolvingLoadBalancingPolicy::MaybeAddTraceMessagesForAddressChangesLocked( + TraceStringVector* trace_strings) { + const ServerAddressList* addresses = + FindServerAddressListChannelArg(resolver_result_); + const bool resolution_contains_addresses = + addresses != nullptr && addresses->size() > 0; + if (!resolution_contains_addresses && + previous_resolution_contained_addresses_) { + trace_strings->push_back(gpr_strdup("Address list became empty")); + } else if (resolution_contains_addresses && + !previous_resolution_contained_addresses_) { + trace_strings->push_back(gpr_strdup("Address list became non-empty")); + } + previous_resolution_contained_addresses_ = resolution_contains_addresses; +} + +void ResolvingLoadBalancingPolicy::ConcatenateAndAddChannelTraceLocked( + TraceStringVector* trace_strings) const { + if (!trace_strings->empty()) { + gpr_strvec v; + gpr_strvec_init(&v); + gpr_strvec_add(&v, gpr_strdup("Resolution event: ")); + bool is_first = 1; + for (size_t i = 0; i < trace_strings->size(); ++i) { + if (!is_first) gpr_strvec_add(&v, gpr_strdup(", ")); + is_first = false; + gpr_strvec_add(&v, (*trace_strings)[i]); + } + char* flat; + size_t flat_len = 0; + flat = gpr_strvec_flatten(&v, &flat_len); + channelz_node()->AddTraceEvent(channelz::ChannelTrace::Severity::Info, + grpc_slice_new(flat, flat_len, gpr_free)); + gpr_strvec_destroy(&v); + } +} + +// Callback invoked when a resolver result is available. +void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( + void* arg, grpc_error* error) { + auto* self = static_cast(arg); + if (self->tracer_->enabled()) { + const char* disposition = + self->resolver_result_ != nullptr + ? "" + : (error == GRPC_ERROR_NONE ? " (transient error)" + : " (resolver shutdown)"); + gpr_log(GPR_INFO, + "resolving_lb=%p: got resolver result: resolver_result=%p " + "error=%s%s", + self, self->resolver_result_, grpc_error_string(error), + disposition); + } + // Handle shutdown. + if (error != GRPC_ERROR_NONE || self->resolver_ == nullptr) { + self->OnResolverShutdownLocked(GRPC_ERROR_REF(error)); + return; + } + // We only want to trace the address resolution in the follow cases: + // (a) Address resolution resulted in service config change. + // (b) Address resolution that causes number of backends to go from + // zero to non-zero. + // (c) Address resolution that causes number of backends to go from + // non-zero to zero. + // (d) Address resolution that causes a new LB policy to be created. + // + // we track a list of strings to eventually be concatenated and traced. + TraceStringVector trace_strings; + // resolver_result_ will be null in the case of a transient + // resolution error. In that case, we don't have any new result to + // process, which means that we keep using the previous result (if any). + if (self->resolver_result_ == nullptr) { + if (self->tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: resolver transient failure", self); + } + // If we already have an LB policy from a previous resolution + // result, then we continue to let it set the connectivity state. + // Otherwise, we go into TRANSIENT_FAILURE. + if (self->lb_policy_ == nullptr) { + // TODO(roth): When we change the resolver API to be able to + // return transient errors in a cleaner way, we should make it the + // resolver's responsibility to attach a status to the error, + // rather than doing it centrally here. + grpc_error* state_error = grpc_error_set_int( + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Resolver transient failure", &error, 1), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + self->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(state_error), + UniquePtr( + New(state_error))); + } + } else { + // Parse the resolver result. + const char* lb_policy_name = nullptr; + grpc_json* lb_policy_config = nullptr; + bool service_config_changed = false; + if (self->process_resolver_result_ != nullptr) { + service_config_changed = self->process_resolver_result_( + self->process_resolver_result_user_data_, *self->resolver_result_, + &lb_policy_name, &lb_policy_config); + } else { + lb_policy_name = self->child_policy_name_.get(); + lb_policy_config = self->child_lb_config_; + } + GPR_ASSERT(lb_policy_name != nullptr); + // Check to see if we're already using the right LB policy. + const bool lb_policy_name_changed = + self->lb_policy_ == nullptr || + strcmp(self->lb_policy_->name(), lb_policy_name) != 0; + if (self->lb_policy_ != nullptr && !lb_policy_name_changed) { + // Continue using the same LB policy. Update with new addresses. + if (self->tracer_->enabled()) { + gpr_log(GPR_INFO, + "resolving_lb=%p: updating existing LB policy \"%s\" (%p)", + self, lb_policy_name, self->lb_policy_.get()); + } + self->lb_policy_->UpdateLocked(*self->resolver_result_, lb_policy_config); + } else { + // Instantiate new LB policy. + if (self->tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: creating new LB policy \"%s\"", + self, lb_policy_name); + } + self->CreateNewLbPolicyLocked(lb_policy_name, lb_policy_config, + &trace_strings); + } + // Add channel trace event. + if (self->channelz_node() != nullptr) { + if (service_config_changed) { + // TODO(ncteisen): might be worth somehow including a snippet of the + // config in the trace, at the risk of bloating the trace logs. + trace_strings.push_back(gpr_strdup("Service config changed")); + } + self->MaybeAddTraceMessagesForAddressChangesLocked(&trace_strings); + self->ConcatenateAndAddChannelTraceLocked(&trace_strings); + } + // Clean up. + grpc_channel_args_destroy(self->resolver_result_); + self->resolver_result_ = nullptr; + } + // Renew resolver callback. + self->resolver_->NextLocked(&self->resolver_result_, + &self->on_resolver_result_changed_); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h new file mode 100644 index 00000000000..c302ae5d975 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -0,0 +1,137 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H + +#include + +#include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/iomgr/call_combiner.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/metadata_batch.h" + +namespace grpc_core { + +// An LB policy that wraps a resolver and a child LB policy to make use +// of the addresses returned by the resolver. +// +// When used in the client_channel code, the resolver will attempt to +// fetch the service config, and the child LB policy name and config +// will be determined based on the service config. +// +// When used in an LB policy implementation that needs to do another +// round of resolution before creating a child policy, the resolver does +// not fetch the service config, and the caller must pre-determine the +// child LB policy and config to use. +class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { + public: + // If error is set when this returns, then construction failed, and + // the caller may not use the new object. + ResolvingLoadBalancingPolicy(Args args, TraceFlag* tracer, + UniquePtr target_uri, + UniquePtr child_policy_name, + grpc_json* child_lb_config, grpc_error** error); + + // Private ctor, to be used by client_channel only! + // + // Synchronous callback that takes the resolver result and sets + // lb_policy_name and lb_policy_config to point to the right data. + // Returns true if the service config has changed since the last result. + typedef bool (*ProcessResolverResultCallback)(void* user_data, + const grpc_channel_args& args, + const char** lb_policy_name, + grpc_json** lb_policy_config); + // If error is set when this returns, then construction failed, and + // the caller may not use the new object. + ResolvingLoadBalancingPolicy( + Args args, TraceFlag* tracer, UniquePtr target_uri, + ProcessResolverResultCallback process_resolver_result, + void* process_resolver_result_user_data, grpc_error** error); + + virtual const char* name() const override { return "resolving_lb"; } + + // No-op -- should never get updates from the channel. + // TODO(roth): Need to support updating child LB policy's config. + // For xds policy, will also need to support updating config + // independently of args from resolver, since they will be coming from + // different places. Maybe change LB policy API to support that? + void UpdateLocked(const grpc_channel_args& args, + grpc_json* lb_config) override {} + + void ExitIdleLocked() override; + + void ResetBackoffLocked() override; + + void FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) override; + + private: + using TraceStringVector = InlinedVector; + + class ResolvingControlHelper; + + ~ResolvingLoadBalancingPolicy(); + + grpc_error* Init(const grpc_channel_args& args); + void ShutdownLocked() override; + + void StartResolvingLocked(); + void OnResolverShutdownLocked(grpc_error* error); + void CreateNewLbPolicyLocked(const char* lb_policy_name, grpc_json* lb_config, + TraceStringVector* trace_strings); + void MaybeAddTraceMessagesForAddressChangesLocked( + TraceStringVector* trace_strings); + void ConcatenateAndAddChannelTraceLocked( + TraceStringVector* trace_strings) const; + static void OnResolverResultChangedLocked(void* arg, grpc_error* error); + + // Passed in from caller at construction time. + TraceFlag* tracer_; + UniquePtr target_uri_; + ProcessResolverResultCallback process_resolver_result_ = nullptr; + void* process_resolver_result_user_data_ = nullptr; + UniquePtr child_policy_name_; + UniquePtr child_lb_config_str_; + grpc_json* child_lb_config_ = nullptr; + + // Resolver and associated state. + OrphanablePtr resolver_; + bool started_resolving_ = false; + grpc_channel_args* resolver_result_ = nullptr; + bool previous_resolution_contained_addresses_ = false; + grpc_closure on_resolver_result_changed_; + + // Child LB policy and associated state. + OrphanablePtr lb_policy_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H */ diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 1a07edad09c..e2e19a32fd6 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -956,22 +956,17 @@ void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) { } else if (c->disconnected_) { GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } else { - c->SetConnectivityStateLocked( - GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Connect Failed", &error, 1), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), - "connect_failed"); - grpc_connectivity_state_set( - &c->state_and_health_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Connect Failed", &error, 1), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), - "connect_failed"); - const char* errmsg = grpc_error_string(error); gpr_log(GPR_INFO, "Connect failed: %s", errmsg); - + error = + grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Connect Failed", &error, 1), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_REF(error), "connect_failed"); + grpc_connectivity_state_set(&c->state_and_health_tracker_, + GRPC_CHANNEL_TRANSIENT_FAILURE, error, + "connect_failed"); c->MaybeStartConnectingLocked(); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h index 9053c60111f..dda5026cbca 100644 --- a/src/core/lib/gprpp/orphanable.h +++ b/src/core/lib/gprpp/orphanable.h @@ -94,8 +94,9 @@ class InternallyRefCounted : public Orphanable { // Note: RefCount tracing is only enabled on debug builds, even when a // TraceFlag is used. template - explicit InternallyRefCounted(TraceFlagT* trace_flag = nullptr) - : refs_(1, trace_flag) {} + explicit InternallyRefCounted(TraceFlagT* trace_flag = nullptr, + intptr_t initial_refcount = 1) + : refs_(initial_refcount, trace_flag) {} virtual ~InternallyRefCounted() = default; RefCountedPtr Ref() GRPC_MUST_USE_RESULT { diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index fa97ffcfed2..761b77baf58 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -221,8 +221,9 @@ class RefCounted : public Impl { // Note: RefCount tracing is only enabled on debug builds, even when a // TraceFlag is used. template - explicit RefCounted(TraceFlagT* trace_flag = nullptr) - : refs_(1, trace_flag) {} + explicit RefCounted(TraceFlagT* trace_flag = nullptr, + intptr_t initial_refcount = 1) + : refs_(initial_refcount, trace_flag) {} // Note: Depending on the Impl used, this dtor can be implicitly virtual. ~RefCounted() = default; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 71de0c4abe0..a9d045281ec 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -329,10 +329,10 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', diff --git a/test/core/channel/channel_stack_builder_test.cc b/test/core/channel/channel_stack_builder_test.cc index b5598e63f9f..efe616ab7fd 100644 --- a/test/core/channel/channel_stack_builder_test.cc +++ b/test/core/channel/channel_stack_builder_test.cc @@ -45,16 +45,6 @@ static void call_destroy_func(grpc_call_element* elem, const grpc_call_final_info* final_info, grpc_closure* ignored) {} -static void call_func(grpc_call_element* elem, - grpc_transport_stream_op_batch* op) {} - -static void channel_func(grpc_channel_element* elem, grpc_transport_op* op) { - if (op->disconnect_with_error != GRPC_ERROR_NONE) { - GRPC_ERROR_UNREF(op->disconnect_with_error); - } - GRPC_CLOSURE_SCHED(op->on_consumed, GRPC_ERROR_NONE); -} - bool g_replacement_fn_called = false; bool g_original_fn_called = false; void set_arg_once_fn(grpc_channel_stack* channel_stack, @@ -77,8 +67,8 @@ static void test_channel_stack_builder_filter_replace(void) { } const grpc_channel_filter replacement_filter = { - call_func, - channel_func, + grpc_call_next_op, + grpc_channel_next_op, 0, call_init_func, grpc_call_stack_ignore_set_pollset_or_pollset_set, @@ -90,8 +80,8 @@ const grpc_channel_filter replacement_filter = { "filter_name"}; const grpc_channel_filter original_filter = { - call_func, - channel_func, + grpc_call_next_op, + grpc_channel_next_op, 0, call_init_func, grpc_call_stack_ignore_set_pollset_or_pollset_set, diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index d6d072101ac..77b354740e5 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -48,25 +48,19 @@ namespace { // A minimal forwarding class to avoid implementing a standalone test LB. class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { public: - ForwardingLoadBalancingPolicy(Args args, - const std::string& delegate_policy_name) - : LoadBalancingPolicy(std::move(args)) { + ForwardingLoadBalancingPolicy( + UniquePtr delegating_helper, Args args, + const std::string& delegate_policy_name, intptr_t initial_refcount = 1) + : LoadBalancingPolicy(std::move(args), initial_refcount) { Args delegate_args; delegate_args.combiner = combiner(); - delegate_args.client_channel_factory = client_channel_factory(); - delegate_args.subchannel_pool = subchannel_pool()->Ref(); + delegate_args.channel_control_helper = std::move(delegating_helper); delegate_args.args = args.args; delegate_args.lb_config = args.lb_config; delegate_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( delegate_policy_name.c_str(), std::move(delegate_args)); grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), interested_parties()); - // Give re-resolution closure to delegate. - GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, - OnDelegateRequestReresolutionLocked, this, - grpc_combiner_scheduler(combiner())); - Ref().release(); // held by callback. - delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); } ~ForwardingLoadBalancingPolicy() override = default; @@ -76,35 +70,6 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { delegate_->UpdateLocked(args, lb_config); } - bool PickLocked(PickState* pick, grpc_error** error) override { - return delegate_->PickLocked(pick, error); - } - - void CancelPickLocked(PickState* pick, grpc_error* error) override { - delegate_->CancelPickLocked(pick, error); - } - - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override { - delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, error); - } - - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override { - delegate_->NotifyOnStateChangeLocked(state, closure); - } - - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override { - return delegate_->CheckConnectivityLocked(connectivity_error); - } - - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { - delegate_->HandOffPendingPicksLocked(new_policy); - } - void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } @@ -116,26 +81,9 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { } private: - void ShutdownLocked() override { - delegate_.reset(); - TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_CANCELLED); - } - - static void OnDelegateRequestReresolutionLocked(void* arg, - grpc_error* error) { - ForwardingLoadBalancingPolicy* self = - static_cast(arg); - if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { - self->Unref(); - return; - } - self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); - self->delegate_->SetReresolutionClosureLocked( - &self->on_delegate_request_reresolution_); - } + void ShutdownLocked() override { delegate_.reset(); } OrphanablePtr delegate_; - grpc_closure on_delegate_request_reresolution_; }; // @@ -150,10 +98,13 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy public: InterceptRecvTrailingMetadataLoadBalancingPolicy( Args args, InterceptRecvTrailingMetadataCallback cb, void* user_data) - : ForwardingLoadBalancingPolicy(std::move(args), - /*delegate_lb_policy_name=*/"pick_first"), - cb_(cb), - user_data_(user_data) {} + : ForwardingLoadBalancingPolicy( + UniquePtr(New( + RefCountedPtr( + this), + cb, user_data)), + std::move(args), /*delegate_lb_policy_name=*/"pick_first", + /*initial_refcount=*/2) {} ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; @@ -161,17 +112,65 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy return kInterceptRecvTrailingMetadataLbPolicyName; } - bool PickLocked(PickState* pick, grpc_error** error) override { - bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); - // Note: This assumes that the delegate policy does not - // intercepting recv_trailing_metadata. If we ever need to use - // this with a delegate policy that does, then we'll need to - // handle async pick returns separately. - New(pick, cb_, user_data_); // deletes itself - return ret; - } - private: + class Picker : public SubchannelPicker { + public: + explicit Picker(UniquePtr delegate_picker, + InterceptRecvTrailingMetadataCallback cb, void* user_data) + : delegate_picker_(std::move(delegate_picker)), + cb_(cb), + user_data_(user_data) {} + + PickResult Pick(PickState* pick, grpc_error** error) override { + PickResult result = delegate_picker_->Pick(pick, error); + if (result == PICK_COMPLETE && pick->connected_subchannel != nullptr) { + New(pick, cb_, user_data_); // deletes itself + } + return result; + } + + private: + UniquePtr delegate_picker_; + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; + }; + + class Helper : public ChannelControlHelper { + public: + Helper( + RefCountedPtr parent, + InterceptRecvTrailingMetadataCallback cb, void* user_data) + : parent_(std::move(parent)), cb_(cb), user_data_(user_data) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + return parent_->channel_control_helper()->CreateSubchannel(args); + } + + grpc_channel* CreateChannel(const char* target, + grpc_client_channel_type type, + const grpc_channel_args& args) override { + return parent_->channel_control_helper()->CreateChannel(target, type, + args); + } + + void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + UniquePtr picker) override { + parent_->channel_control_helper()->UpdateState( + state, state_error, + UniquePtr( + New(std::move(picker), cb_, user_data_))); + } + + void RequestReresolution() override { + parent_->channel_control_helper()->RequestReresolution(); + } + + private: + RefCountedPtr parent_; + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; + }; + class TrailingMetadataHandler { public: TrailingMetadataHandler(PickState* pick, @@ -204,9 +203,6 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; grpc_metadata_batch* recv_trailing_metadata_ = nullptr; }; - - InterceptRecvTrailingMetadataCallback cb_; - void* user_data_; }; class InterceptTrailingFactory : public LoadBalancingPolicyFactory { diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 973f47beaf7..e57650fe5b7 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -570,6 +570,7 @@ static void BM_IsolatedFilter(benchmark::State& state) { } gpr_arena_destroy(call_args.arena); grpc_channel_stack_destroy(channel_stack); + grpc_core::ExecCtx::Get()->Flush(); gpr_free(channel_stack); gpr_free(call_stack); diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 86b57b23d9a..e90acca9c50 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -936,8 +936,6 @@ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper.h \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.h \ -src/core/ext/filters/client_channel/request_routing.cc \ -src/core/ext/filters/client_channel/request_routing.h \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver.h \ src/core/ext/filters/client_channel/resolver/README.md \ @@ -962,6 +960,8 @@ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_registry.h \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.h \ +src/core/ext/filters/client_channel/resolving_lb_policy.cc \ +src/core/ext/filters/client_channel/resolving_lb_policy.h \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/retry_throttle.h \ src/core/ext/filters/client_channel/server_address.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 84d5c45095f..823e17dd45a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9968,11 +9968,11 @@ "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", - "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", @@ -10015,8 +10015,6 @@ "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", - "src/core/ext/filters/client_channel/request_routing.cc", - "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.cc", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", @@ -10024,6 +10022,8 @@ "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.cc", "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/resolving_lb_policy.cc", + "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.cc", From 28145c30b7873e589d06b7fe4105bacdb812ea86 Mon Sep 17 00:00:00 2001 From: Jerry Date: Wed, 13 Feb 2019 10:07:01 -0800 Subject: [PATCH 361/814] removed tailing whitespace and clean MemoryLeakTest --- src/php/bin/run_tests.sh | 12 +- .../tests/MemoryLeakTest/MemoryLeakTest.php | 2210 ----------------- 2 files changed, 6 insertions(+), 2216 deletions(-) diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh index 39ef669190e..49fd84514c1 100755 --- a/src/php/bin/run_tests.sh +++ b/src/php/bin/run_tests.sh @@ -28,10 +28,10 @@ php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ php $extension_dir -d max_execution_time=300 $(which phpunit) -v --debug \ ../tests/unit_tests/PersistentChannelTests -export ZEND_DONT_UNLOAD_MODULES=1 -export USE_ZEND_ALLOC=0 -# Detect whether valgrind is executable -if [ -x "$(command -v valgrind)" ]; then - valgrind --error-exitcode=10 --leak-check=yes php $extension_dir -d max_execution_time=300 \ - ../tests/MemoryLeakTest/MemoryLeakTest.php +export ZEND_DONT_UNLOAD_MODULES=1 +export USE_ZEND_ALLOC=0 +# Detect whether valgrind is executable +if [ -x "$(command -v valgrind)" ]; then + valgrind --error-exitcode=10 --leak-check=yes php $extension_dir -d max_execution_time=300 \ + ../tests/MemoryLeakTest/MemoryLeakTest.php fi diff --git a/src/php/tests/MemoryLeakTest/MemoryLeakTest.php b/src/php/tests/MemoryLeakTest/MemoryLeakTest.php index 62ba3295504..29eca656f42 100644 --- a/src/php/tests/MemoryLeakTest/MemoryLeakTest.php +++ b/src/php/tests/MemoryLeakTest/MemoryLeakTest.php @@ -88,2213 +88,3 @@ unset($now); unset($deadline); $channel->close(); - -// Test InvalidConstructorWithNull -try { - $channel = new Grpc\Channel(); - assert($channel == NULL); -} -catch (\Exception $e) { -} - -// Test InvalidConstructorWith -try { - $channel = new Grpc\Channel('localhost:0', 'invalid'); - assert($channel == NULL); -} -catch (\Exception $e) { -} - -// Test InvalideCredentials -try { - $channel = new Grpc\Channel('localhost:0', ['credentials' => new Grpc\Timeval(100)]); -} -catch (\Exception $e) { -} - -// Test InvalidOptionsArrray -try { - $channel = new Grpc\Channel('localhost:0', ['abc' => []]); -} -catch (\Exception $e) { -} - -// Test InvalidGetConnectivityStateWithArray -$channel = new Grpc\Channel('localhost:0', ['credentials' => Grpc\ChannelCredentials::createInsecure()]); -try { - $channel->getConnectivityState([]); -} -catch (\Exception $e) { -} - -// Test InvalidWatchConnectivityState -try { - $channel->watchConnectivityState([]); -} -catch (\Exception $e) { -} - -// Test InvalidWatchConnectivityState2 -try { - $channel->watchConnectivityState(1, 'hi'); -} -catch (\Exception $e) { -} - -$channel->close(); - -// Test PersistentChannelSameHost -$channel1 = new Grpc\Channel('localhost:1', []); -$channel2 = new Grpc\Channel('localhost:1', []); -$state = $channel1->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelDifferentHost -$channel1 = new Grpc\Channel('localhost:1', ["grpc_target_persist_bound" => 3,]); -$channel2 = new Grpc\Channel('localhost:2', []); -$state = $channel1->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelSameArgs -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 3, - "abc" => "def", - ]); -$channel2 = new Grpc\Channel('localhost:1', ["abc" => "def"]); -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelDifferentArgs -$channel1 = new Grpc\Channel('localhost:1', []); -$channel2 = new Grpc\Channel('localhost:1', ["abc" => "def"]); -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelSameChannelCredentials -$creds1 = Grpc\ChannelCredentials::createSsl(); -$creds2 = Grpc\ChannelCredentials::createSsl(); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => $creds1, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => $creds2]); - -$state = $channel1->getConnectivityState(true); -print "state: ".$state."......................"; -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelDifferentChannelCredentials -$creds1 = Grpc\ChannelCredentials::createSsl(); -$creds2 = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => $creds1, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => $creds2]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - - -// Test PersistentChannelSameChannelCredentialsRootCerts -$creds1 = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); -$creds2 = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => $creds1, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => $creds2]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelDifferentSecureChannelCredentials -$creds1 = Grpc\ChannelCredentials::createSsl(); -$creds2 = Grpc\ChannelCredentials::createInsecure(); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => $creds1, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => $creds2]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelSharedChannelClose1 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 3, -]); -$channel2 = new Grpc\Channel('localhost:1', []); - -$channel1->close(); - -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$channel2->close(); - -// Test PersistentChannelSharedChannelClose2 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 3, -]); -$channel2 = new Grpc\Channel('localhost:1', []); - -$channel1->close(); - -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -try{ - $state = $channel1->getConnectivityState(); -} -catch(\Exception $e){ -} - -$channel2->close(); - -//Test PersistentChannelCreateAfterClose -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 3, -]); - -$channel1->close(); - -$channel2 = new Grpc\Channel('localhost:1', []); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel2->close(); - -//Test PersistentChannelSharedMoreThanTwo -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 3, -]); -$channel2 = new Grpc\Channel('localhost:1', []); -$channel3 = new Grpc\Channel('localhost:1', []); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); -$state = $channel3->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); - -//Test PersistentChannelWithCallCredentials -$creds = Grpc\ChannelCredentials::createSsl(); -$callCreds = Grpc\CallCredentials::createFromPlugin( - 'callbackFunc'); -$credsWithCallCreds = Grpc\ChannelCredentials::createComposite( - $creds, $callCreds); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => - $credsWithCallCreds, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => - $credsWithCallCreds]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelWithDifferentCallCredentials -$callCreds1 = Grpc\CallCredentials::createFromPlugin('callbackFunc'); -$callCreds2 = Grpc\CallCredentials::createFromPlugin('callbackFunc2'); - -$creds1 = Grpc\ChannelCredentials::createSsl(); -$creds2 = Grpc\ChannelCredentials::createComposite( - $creds1, $callCreds1); -$creds3 = Grpc\ChannelCredentials::createComposite( - $creds1, $callCreds2); - -$channel1 = new Grpc\Channel('localhost:1', - ["credentials" => $creds1, - "grpc_target_persist_bound" => 3, - ]); -$channel2 = new Grpc\Channel('localhost:1', - ["credentials" => $creds2]); -$channel3 = new Grpc\Channel('localhost:1', - ["credentials" => $creds3]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$state = $channel3->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); -$channel3->close(); - -// Test PersistentChannelForceNew -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', - ["force_new" => true]); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelForceNewOldChannelIdle1 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', - ["force_new" => true]); -$channel3 = new Grpc\Channel('localhost:1', []); - -$state = $channel2->getConnectivityState(true); -waitUntilNotIdle($channel2); -$state = $channel1->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); -$state = $channel3->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelForceNewOldChannelIdle2 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', []); - -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel2); -$state = $channel1->getConnectivityState(); -assertConnecting($state); -$state = $channel2->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); -$channel2->close(); - -// Test PersistentChannelForceNewOldChannelClose1 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', - ["force_new" => true]); -$channel3 = new Grpc\Channel('localhost:1', []); - -$channel1->close(); - -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); -$state = $channel3->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -$channel2->close(); -$channel3->close(); - -// Test PersistentChannelForceNewOldChannelClose2 -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', - ["force_new" => true]); -// channel3 shares with channel1 -$channel3 = new Grpc\Channel('localhost:1', []); - -$channel1->close(); - -$state = $channel2->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -// channel3 is still usable -$state = $channel3->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -// channel 1 is closed -try{ - $channel1->getConnectivityState(); -} -catch(\Exception $e){ -} - -$channel2->close(); -$channel3->close(); - -// Test PersistentChannelForceNewNewChannelClose -$channel1 = new Grpc\Channel('localhost:1', [ - "grpc_target_persist_bound" => 2, -]); -$channel2 = new Grpc\Channel('localhost:1', - ["force_new" => true]); -$channel3 = new Grpc\Channel('localhost:1', []); - -$channel2->close(); - -$state = $channel1->getConnectivityState(); -assert(GRPC\CHANNEL_IDLE == $state); - -// can still connect on channel1 -$state = $channel1->getConnectivityState(true); -waitUntilNotIdle($channel1); - -$state = $channel1->getConnectivityState(); -assertConnecting($state); - -$channel1->close(); - -//============== Call Test ==================== -$server = new Grpc\Server([]); -$port = $server->addHttp2Port('0.0.0.0:53000'); -$channel = new Grpc\Channel('localhost:'.$port, []); -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); - -// Test AddEmptyMetadata -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => [], -]; -$result = $call->startBatch($batch); -assert($result->send_metadata == true); - -// Test testAddSingleMetadata -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value']], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -$result = $call->startBatch($batch); -assert($result->send_metadata == true); - -// Test AddMultiValue -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value1', 'value2']], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -$result = $call->startBatch($batch); -assert($result->send_metadata == true); - -// Test AddSingleAndMultiValueMetadata -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], - 'key2' => ['value2', - 'value3', ], ], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -$result = $call->startBatch($batch); -assert($result->send_metadata == true); - -// Test AddMultiAndMultiValueMetadata -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], - 'key2' => ['value2', - 'value3', ], ], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -$result = $call->startBatch($batch); -assert($result->send_metadata == true); - -// Test GetPeer -assert(is_string($call->getPeer()) == true); - -// Test Cancel -assert($call->cancel == NULL); - -// Test InvalidStartBatchKey -$batch = [ - 'invalid' => ['key1' => 'value1'], -]; -try{ - $result = $call->startBatch($batch); -} -catch(\Exception $e){ -} - -// Test InvalideMetadataStrKey -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['Key' => ['value1', 'value2']], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -try{ - $result = $call->startBatch($batch); -} -catch(\Exception $e){ -} - -// Test InvalidMetadataIntKey -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => [1 => ['value1', 'value2']], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -try{ - $result = $call->startBatch($batch); -} -catch(\Exception $e){ -} - -// Test InvalidMetadataInnerValue -$batch = [ - Grpc\OP_SEND_INITIAL_METADATA => ['key1' => 'value1'], -]; -$call = new Grpc\Call($channel, - '/foo', - Grpc\Timeval::infFuture()); -try{ - $result = $call->startBatch($batch); -} -catch(\Exception $e){ -} - -// Test InvalidConstuctor -try { - $call = new Grpc\Call(); -} catch (\Exception $e) {} - -// Test InvalidConstuctor2 -try { - $call = new Grpc\Call('hi', 'hi', 'hi'); -} catch (\Exception $e) {} - -// Test InvalidSetCredentials -try{ - $call->setCredentials('hi'); -} -catch(\Exception $e){ -} - -// Test InvalidSetCredentials2 -try { - $call->setCredentials([]); -} catch (\Exception $e) {} - - -//============== CallCredentials Test 2 ==================== -// Set Up -$credentials = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); -$server_credentials = Grpc\ServerCredentials::createSsl( - null, - file_get_contents(dirname(__FILE__).'/../data/server1.key'), - file_get_contents(dirname(__FILE__).'/../data/server1.pem')); -$server = new Grpc\Server(); -$port = $server->addSecureHttp2Port('0.0.0.0:0', - $server_credentials); -$server->start(); -$host_override = 'foo.test.google.fr'; -$channel = new Grpc\Channel( - 'localhost:'.$port, - [ - 'grpc.ssl_target_name_override' => $host_override, - 'grpc.default_authority' => $host_override, - 'credentials' => $credentials, - ] -); -function callCredscallbackFunc($context) -{ - is_string($context->service_url); - is_string($context->method_name); - return ['k1' => ['v1'], 'k2' => ['v2']]; -} - -// Test CreateFromPlugin -$deadline = Grpc\Timeval::infFuture(); -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - '/abc/dummy_method', - $deadline, - $host_override); - $call_credentials = Grpc\CallCredentials::createFromPlugin( - 'callCredscallbackFunc'); -$call->setCredentials($call_credentials); - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); - -$event = $server->requestCall(); -assert(is_array($event->metadata) == true); - -$metadata = $event->metadata; -assert(array_key_exists('k1', $metadata) == true); -assert(array_key_exists('k2', $metadata) == true); -assert($metadata['k1'] == ['v1']); -assert($metadata['k2'] == ['v2']); -assert('/abc/dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert($event->send_metadata == true); -assert($event->send_status == true); -assert($event->cancelled == false); - -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert([] == $event->metadata); - -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -function invalidKeyCallbackFunc($context) -{ - is_string($context->service_url); - is_string($context->method_name); - return ['K1' => ['v1']]; -} - -// Test CallbackWithInvalidKey -$deadline = Grpc\Timeval::infFuture(); -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - '/abc/dummy_method', - $deadline, - $host_override); - $call_credentials = Grpc\CallCredentials::createFromPlugin( - 'invalidKeyCallbackFunc'); -$call->setCredentials($call_credentials); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); -assert(($event->status->code == Grpc\STATUS_UNAVAILABLE) == true); - -function invalidReturnCallbackFunc($context) -{ - is_string($context->service_url); - is_string($context->method_name); - return 'a string'; -} - -// Test CallbackWithInvalidReturnValue -$deadline = Grpc\Timeval::infFuture(); -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - '/abc/dummy_method', - $deadline, - $host_override); - $call_credentials = Grpc\CallCredentials::createFromPlugin( - 'invalidReturnCallbackFunc'); -$call->setCredentials($call_credentials); - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); - -assert($event->send_metadata == true); -assert($event->send_close == true); -assert(($event->status->code == Grpc\STATUS_UNAVAILABLE) == true); - -unset($channel); -unset($server); - -//============== CallCredentials Test ==================== -//Set Up -$credentials = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); -$call_credentials = Grpc\CallCredentials::createFromPlugin('callbackFunc'); -$credentials = Grpc\ChannelCredentials::createComposite( - $credentials, - $call_credentials -); -$server_credentials = Grpc\ServerCredentials::createSsl( - null, - file_get_contents(dirname(__FILE__).'/../data/server1.key'), - file_get_contents(dirname(__FILE__).'/../data/server1.pem')); -$server = new Grpc\Server(); -$port = $server->addSecureHttp2Port('0.0.0.0:0', - $server_credentials); -$server->start(); -$host_override = 'foo.test.google.fr'; -$channel = new Grpc\Channel( - 'localhost:'.$port, - [ - 'grpc.ssl_target_name_override' => $host_override, - 'grpc.default_authority' => $host_override, - 'credentials' => $credentials, - ] -); - -// Test CreateComposite -$call_credentials2 = Grpc\CallCredentials::createFromPlugin('callbackFunc'); -$call_credentials3 = Grpc\CallCredentials::createComposite( - $call_credentials, - $call_credentials2 -); -assert('Grpc\CallCredentials' == get_class($call_credentials3)); - -// Test CreateFromPluginInvalidParam -try{ - $call_credentials = Grpc\CallCredentials::createFromPlugin( - 'callbackFunc' - ); -} -catch(\Exception $e){} - -// Test CreateCompositeInvalidParam -try{ - $call_credentials3 = Grpc\CallCredentials::createComposite( - $call_credentials, - $credentials - ); -} -catch(\Exception $e){} - -unset($channel); -unset($server); - - -//============== EndToEnd Test ==================== -// Set Up -$server = new Grpc\Server([]); -$port = $server->addHttp2Port('0.0.0.0:0'); -$channel = new Grpc\Channel('localhost:'.$port, []); -$server->start(); - -// Test SimpleRequestBody -$deadline = Grpc\Timeval::infFuture(); -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert($event->send_metadata == true); -assert($event->send_status == true); -assert($event->cancelled == false) -; - $event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -// Test MessageWriteFlags -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'message_write_flags_test'; -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $req_text, - 'flags' => Grpc\WRITE_NO_COMPRESS, ], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], -]); -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -$status = $event->status; - -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -// Test ClientServerFullRequestResponse -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -assert($event->send_metadata == true); -assert($event->send_close == true); -assert($event->send_message == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); -$server_call = $event->call; - -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert($event->send_metadata == true); -assert($event->send_status == true); -assert($event->send_message == true); -assert($event->cancelled == false); -assert($req_text == $event->message); - -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert([] == $event->metadata); -assert($reply_text == $event->message); -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -// Test InvalidClientMessageArray -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -try { - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => 'invalid', - ]); -} catch (\Exception $e) {} - -// Test InvalidClientMessageString -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -try{ - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => 0], - ]); -} catch (\Exception $e) {} - -// Test InvalidClientMessageFlags -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -try{ - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => 'abc', - 'flags' => 'invalid', - ], - ]); -} catch (\Exception $e) {} - -// Test InvalidServerStatusMetadata -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -assert($event->send_metadata == true); -assert($event->send_close == true); -assert($event->send_message == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); -$server_call = $event->call; -try { - $event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => 'invalid', - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, - ]); -} catch (\Exception $e) {} - -// Test InvalidServerStatusCode -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -assert($event->send_metadata == true); -assert($event->send_close == true); -assert($event->send_message == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); -$server_call = $event->call; -try { - $event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => 'invalid', - 'details' => $status_text, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, - ]); -} catch (\Exception $e) {} - -// Test MissingServerStatusCode -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -$event = $server->requestCall(); -$server_call = $event->call; -try { - $event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'details' => $status_text, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, - ]); -} catch (\Exception $e) {} - -// Test InvalidServerStatusDetails -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -$event = $server->requestCall(); -$server_call = $event->call; -try { - $event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => 0, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, - ]); -} catch (\Exception $e) {} - -// Test MissingServerStatusDetails -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -$event = $server->requestCall(); -$server_call = $event->call; -try { - $event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, - ]); -} catch (\Exception $e) {} - -// Test InvalidStartBatchKey -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -try { - $event = $call->startBatch([ - 9999999 => [], - ]); -} catch (\Exception $e) {} - -// Test InvalidStartBatch -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline); -try { - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => 'abc', - ], - ]); -} catch (\Exception $e) {} - -// Test GetTarget -assert(is_string($channel->getTarget()) == true); - -// Test GetConnectivityState -assert(($channel->getConnectivityState() == - Grpc\CHANNEL_IDLE) == true); - -// Test WatchConnectivityStateFailed -$idle_state = $channel->getConnectivityState(); -assert(($idle_state == Grpc\CHANNEL_IDLE) == true); - -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(50000); // should timeout -$deadline = $now->add($delta); -assert($channel->watchConnectivityState( - $idle_state, $deadline) == false); - -// Test WatchConnectivityStateSuccess() -$idle_state = $channel->getConnectivityState(true); -assert(($idle_state == Grpc\CHANNEL_IDLE) == true); - -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(3000000); // should finish well before -$deadline = $now->add($delta); -$new_state = $channel->getConnectivityState(); -assert($new_state != $idle_state); - -// Test WatchConnectivityStateDoNothing -$idle_state = $channel->getConnectivityState(); -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(50000); -$deadline = $now->add($delta); -assert(!$channel->watchConnectivityState( - $idle_state, $deadline)); - -$new_state = $channel->getConnectivityState(); -assert($new_state == Grpc\CHANNEL_IDLE); - -// Test GetConnectivityStateInvalidParam -try { - $channel->getConnectivityState(new Grpc\Timeval()); -} catch (\Exception $e) {} -// Test WatchConnectivityStateInvalidParam -try { - $channel->watchConnectivityState(0, 1000); -} catch (\Exception $e) {} -// Test ChannelConstructorInvalidParam -try { - $channel = new Grpc\Channel('localhost:'.$port, null); -} catch (\Exception $e) {} -// testClose() -$channel->close(); - - -//============== SecureEndToEnd Test ==================== -// Set Up - -$credentials = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); -$server_credentials = Grpc\ServerCredentials::createSsl( - null, - file_get_contents(dirname(__FILE__).'/../data/server1.key'), - file_get_contents(dirname(__FILE__).'/../data/server1.pem')); -$server = new Grpc\Server(); -$port = $server->addSecureHttp2Port('0.0.0.0:0', - $server_credentials); -$server->start(); -$host_override = 'foo.test.google.fr'; -$channel = new Grpc\Channel( - 'localhost:'.$port, - [ - 'grpc.ssl_target_name_override' => $host_override, - 'grpc.default_authority' => $host_override, - 'credentials' => $credentials, - ] -); - -// Test SimpleRequestBody -$deadline = Grpc\Timeval::infFuture(); -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline, - $host_override); - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert($event->send_metadata == true); -assert($event->send_status == true); -assert($event->cancelled == false); - -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert([] == $event->metadata); -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -// Test MessageWriteFlags -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'message_write_flags_test'; -$status_text = 'xyz'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline, - $host_override); - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $req_text, - 'flags' => Grpc\WRITE_NO_COMPRESS, ], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, -]); -assert($event->send_metadata == true); -assert($event->send_close == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], -]); -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert([] == $event->metadata); -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details);unset($call); - -unset($call); -unset($server_call); - -// Test ClientServerFullRequestResponse -$deadline = Grpc\Timeval::infFuture(); -$req_text = 'client_server_full_request_response'; -$reply_text = 'reply:client_server_full_request_response'; -$status_text = 'status:client_server_full_response_text'; -$call = new Grpc\Call($channel, - 'dummy_method', - $deadline, - $host_override); -$event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - Grpc\OP_SEND_MESSAGE => ['message' => $req_text], -]); -assert($event->send_metadata == true); -assert($event->send_close == true); -assert($event->send_message == true); - -$event = $server->requestCall(); -assert('dummy_method' == $event->method); - -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_MESSAGE => ['message' => $reply_text], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert($event->send_metadata); -assert($event->send_status); -assert($event->send_message); -assert(!$event->cancelled); -assert($req_text == $event->message); - -$event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, -]); -assert([] == $event->metadata); -assert($reply_text == $event->message); -$status = $event->status; -assert([] == $status->metadata); -assert(Grpc\STATUS_OK == $status->code); -assert($status_text == $status->details); - -unset($call); -unset($server_call); - -$channel->close(); - - -//============== Timeval Test ==================== -// Test ConstructorWithInt -$time = new Grpc\Timeval(1234); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test ConstructorWithNegative -$time = new Grpc\Timeval(-123); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test ConstructorWithZero -$time = new Grpc\Timeval(0); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test ConstructorWithOct -$time = new Grpc\Timeval(0123); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test ConstructorWithHex -$time = new Grpc\Timeval(0x1A); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test ConstructorWithFloat -$time = new Grpc\Timeval(123.456); -assert($time != NULL); -assert('Grpc\Timeval' == get_class($time)); - -// Test CompareSame -$zero = Grpc\Timeval::zero(); -assert(0 == Grpc\Timeval::compare($zero, $zero)); - -// Test PastIsLessThanZero -$zero = Grpc\Timeval::zero(); -$past = Grpc\Timeval::infPast(); -assert(0 > Grpc\Timeval::compare($past, $zero)); -assert(0 < Grpc\Timeval::compare($zero, $past)); - -// Test FutureIsGreaterThanZero -$zero = Grpc\Timeval::zero(); -$future = Grpc\Timeval::infFuture(); -assert(0 > Grpc\Timeval::compare($zero, $future)); -assert(0 < Grpc\Timeval::compare($future, $zero)); - -// Test NowIsBetweenZeroAndFuture -$zero = Grpc\Timeval::zero(); -$future = Grpc\Timeval::infFuture(); -$now = Grpc\Timeval::now(); -assert(0 > Grpc\Timeval::compare($zero, $now)); -assert(0 > Grpc\Timeval::compare($now, $future)); - -// Test NowAndAdd -$now = Grpc\Timeval::now(); -assert($now != NULL); -$delta = new Grpc\Timeval(1000); -$deadline = $now->add($delta); -assert(0 < Grpc\Timeval::compare($deadline, $now)); - -// Test NowAndSubtract -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(1000); -$deadline = $now->subtract($delta); -assert(0 > Grpc\Timeval::compare($deadline, $now)); - -// Test AddAndSubtract -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(1000); -$deadline = $now->add($delta); -$back_to_now = $deadline->subtract($delta); -assert(0 == Grpc\Timeval::compare($back_to_now, $now)); - -// Test Similar -$a = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(1000); -$b = $a->add($delta); -$thresh = new Grpc\Timeval(1100); -assert(Grpc\Timeval::similar($a, $b, $thresh)); -$thresh = new Grpc\Timeval(900); -assert(!Grpc\Timeval::similar($a, $b, $thresh)); - -// Test SleepUntil -$curr_microtime = microtime(true); -$now = Grpc\Timeval::now(); -$delta = new Grpc\Timeval(1000); -$deadline = $now->add($delta); -$deadline->sleepUntil(); -$done_microtime = microtime(true); -assert(($done_microtime - $curr_microtime) > 0.0009); - -// Test ConstructorInvalidParam -try { - $delta = new Grpc\Timeval('abc'); -} catch (\Exception $e) {} -// Test AddInvalidParam -$a = Grpc\Timeval::now(); -try { - $a->add(1000); -} catch (\Exception $e) {} -// Test SubtractInvalidParam -$a = Grpc\Timeval::now(); -try { - $a->subtract(1000); -} catch (\Exception $e) {} -// Test CompareInvalidParam -try { - $a = Grpc\Timeval::compare(1000, 1100); -} catch (\Exception $e) {} -// Test SimilarInvalidParam -try { - $a = Grpc\Timeval::similar(1000, 1100, 1200); -} catch (\Exception $e) {} - unset($time); - - //============== Server Test ==================== - //Set Up - $server = NULL; - - // Test ConstructorWithNull -$server = new Grpc\Server(); -assert($server != NULL); - -// Test ConstructorWithNullArray -$server = new Grpc\Server([]); -assert($server != NULL); - -// Test ConstructorWithArray -$server = new Grpc\Server(['ip' => '127.0.0.1', - 'port' => '8080', ]); -assert($server != NULL); - -// Test RequestCall -$server = new Grpc\Server(); -$port = $server->addHttp2Port('0.0.0.0:0'); -$server->start(); -$channel = new Grpc\Channel('localhost:'.$port, - [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure() - ]); - -$deadline = Grpc\Timeval::infFuture(); -$call = new Grpc\Call($channel, 'dummy_method', $deadline); - -$event = $call->startBatch([Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - ]); - -$c = $server->requestCall(); -assert('dummy_method' == $c->method); -assert(is_string($c->host)); - -unset($call); -unset($channel); - -// Test InvalidConstructorWithNumKeyOfArray -try{ - $server = new Grpc\Server([10 => '127.0.0.1', - 20 => '8080', ]); -} -catch(\Exception $e){} - -// Test Invalid ArgumentException -try{ - $server = new Grpc\Server(['127.0.0.1', '8080']); -} -catch(\Exception $e){} - -// Test InvalidAddHttp2Port -$server = new Grpc\Server([]); -try{ - $port = $server->addHttp2Port(['0.0.0.0:0']); -} -catch(\Exception $e){} - -// Test InvalidAddSecureHttp2Port -$server = new Grpc\Server([]); -try{ - $port = $server->addSecureHttp2Port(['0.0.0.0:0']); -} -catch(\Exception $e){} - -// Test InvalidAddSecureHttp2Port2 -$server = new Grpc\Server(); -try{ - $port = $server->addSecureHttp2Port('0.0.0.0:0'); -} -catch(\Exception $e){} - -// Test InvalidAddSecureHttp2Port3 -$server = new Grpc\Server(); -try{ - $port = $server->addSecureHttp2Port('0.0.0.0:0', 'invalid'); -} -catch(\Exception $e){} -unset($server); - - -//============== ChannelCredential Test ==================== -// Test CreateSslWith3Null -$channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, - null); -assert($channel_credentials != NULL); - -// Test CreateSslWith3NullString -$channel_credentials = Grpc\ChannelCredentials::createSsl('', '', ''); -assert($channel_credentials != NULL); - -// Test CreateInsecure -$channel_credentials = Grpc\ChannelCredentials::createInsecure(); -assert($channel_credentials == NULL); - -// Test InvalidCreateSsl() -try { - $channel_credentials = Grpc\ChannelCredentials::createSsl([]); -} -catch (\Exception $e) { -} -try { - $channel_credentials = Grpc\ChannelCredentials::createComposite( - 'something', 'something'); -} -catch (\Exception $e) { -} - -//============== Interceptor Test ==================== -require_once(dirname(__FILE__).'/../../lib/Grpc/BaseStub.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/AbstractCall.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/UnaryCall.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/ClientStreamingCall.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/Interceptor.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/CallInvoker.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/DefaultCallInvoker.php'); -require_once(dirname(__FILE__).'/../../lib/Grpc/Internal/InterceptorChannel.php'); - -class SimpleRequest -{ - private $data; - public function __construct($data) - { - $this->data = $data; - } - public function setData($data) - { - $this->data = $data; - } - public function serializeToString() - { - return $this->data; - } -} - -class InterceptorClient extends Grpc\BaseStub -{ - - /** - * @param string $hostname hostname - * @param array $opts channel options - * @param Channel|InterceptorChannel $channel (optional) re-use channel object - */ - public function __construct($hostname, $opts, $channel = null) - { - parent::__construct($hostname, $opts, $channel); - } - - /** - * A simple RPC. - * @param SimpleRequest $argument input argument - * @param array $metadata metadata - * @param array $options call options - */ - public function UnaryCall( - SimpleRequest $argument, - $metadata = [], - $options = [] - ) { - return $this->_simpleRequest( - '/dummy_method', - $argument, - [], - $metadata, - $options - ); - } - - /** - * A client-to-server streaming RPC. - * @param array $metadata metadata - * @param array $options call options - */ - public function StreamCall( - $metadata = [], - $options = [] - ) { - return $this->_clientStreamRequest('/dummy_method', [], $metadata, $options); - } -} - -class ChangeMetadataInterceptor extends Grpc\Interceptor -{ - public function interceptUnaryUnary($method, - $argument, - $deserialize, - array $metadata = [], - array $options = [], - $continuation) - { - $metadata["foo"] = array('interceptor_from_unary_request'); - return $continuation($method, $argument, $deserialize, $metadata, $options); - } - public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) - { - $metadata["foo"] = array('interceptor_from_stream_request'); - return $continuation($method, $deserialize, $metadata, $options); - } -} - -class ChangeMetadataInterceptor2 extends Grpc\Interceptor -{ - public function interceptUnaryUnary($method, - $argument, - $deserialize, - array $metadata = [], - array $options = [], - $continuation) - { - if (array_key_exists('foo', $metadata)) { - $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first'); - } else { - $metadata["bar"] = array('interceptor_from_unary_request'); - } - return $continuation($method, $argument, $deserialize, $metadata, $options); - } - public function interceptStreamUnary($method, - $deserialize, - array $metadata = [], - array $options = [], - $continuation) - { - if (array_key_exists('foo', $metadata)) { - $metadata['bar'] = array('ChangeMetadataInterceptor should be executed first'); - } else { - $metadata["bar"] = array('interceptor_from_stream_request'); - } - return $continuation($method, $deserialize, $metadata, $options); - } -} - -class ChangeRequestCall -{ - private $call; - - public function __construct($call) - { - $this->call = $call; - } - public function getCall() - { - return $this->call; - } - - public function write($request) - { - $request->setData('intercepted_stream_request'); - $this->getCall()->write($request); - } - - public function wait() - { - return $this->getCall()->wait(); - } -} - -class ChangeRequestInterceptor extends Grpc\Interceptor -{ - public function interceptUnaryUnary($method, - $argument, - $deserialize, - array $metadata = [], - array $options = [], - $continuation) - { - $argument->setData('intercepted_unary_request'); - return $continuation($method, $argument, $deserialize, $metadata, $options); - } - public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) - { - return new ChangeRequestCall( - $continuation($method, $deserialize, $metadata, $options) - ); - } -} - -class StopCallInterceptor extends Grpc\Interceptor -{ - public function interceptUnaryUnary($method, - $argument, - array $metadata = [], - array $options = [], - $continuation) - { - $metadata["foo"] = array('interceptor_from_request_response'); - } - public function interceptStreamUnary($method, - array $metadata = [], - array $options = [], - $continuation) - { - $metadata["foo"] = array('interceptor_from_request_response'); - } -} - -// Set Up -$server = new Grpc\Server([]); -$port = $server->addHttp2Port('0.0.0.0:0'); -$channel = new Grpc\Channel('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure()]); -$server->start(); - -// Test ClientChangeMetadataOneInterceptor -$req_text = 'client_request'; -$channel_matadata_interceptor = new ChangeMetadataInterceptor(); -$intercept_channel = Grpc\Interceptor::intercept($channel, $channel_matadata_interceptor); -$client = new InterceptorClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), -], $intercept_channel); -$req = new SimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_unary_request'] == $event->metadata['foo']); - -$stream_call = $client->StreamCall(); -$stream_call->write($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_stream_request'] == $event->metadata['foo']); - -unset($unary_call); -unset($stream_call); -unset($server_call); - -// Test ClientChangeMetadataTwoInterceptor -$req_text = 'client_request'; -$channel_matadata_interceptor = new ChangeMetadataInterceptor(); -$channel_matadata_intercepto2 = new ChangeMetadataInterceptor2(); -// test intercept separately. -$intercept_channel1 = Grpc\Interceptor::intercept($channel, $channel_matadata_interceptor); -$intercept_channel2 = Grpc\Interceptor::intercept($intercept_channel1, $channel_matadata_intercepto2); -$client = new InterceptorClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), -], $intercept_channel2); - -$req = new SimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_unary_request'] == $event->metadata['foo']); -assert(['interceptor_from_unary_request'] == $event->metadata['bar']); - -$stream_call = $client->StreamCall(); -$stream_call->write($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_stream_request'] == $event->metadata['foo']); -assert(['interceptor_from_stream_request'] == $event->metadata['bar']); - -unset($unary_call); -unset($stream_call); -unset($server_call); - -// test intercept by array. -$intercept_channel3 = Grpc\Interceptor::intercept($channel, - [$channel_matadata_intercepto2, $channel_matadata_interceptor]); -$client = new InterceptorClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), -], $intercept_channel3); - -$req = new SimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_unary_request'] == $event->metadata['foo']); -assert(['interceptor_from_unary_request'] == $event->metadata['bar']); - -$stream_call = $client->StreamCall(); -$stream_call->write($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -assert(['interceptor_from_stream_request'] == $event->metadata['foo']); -assert(['interceptor_from_stream_request'] == $event->metadata['bar']); - -unset($unary_call); -unset($stream_call); -unset($server_call); - - -// Test ClientChangeRequestInterceptor -$req_text = 'client_request'; -$change_request_interceptor = new ChangeRequestInterceptor(); -$intercept_channel = Grpc\Interceptor::intercept($channel, - $change_request_interceptor); -$client = new InterceptorClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), -], $intercept_channel); - -$req = new SimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); - -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => '', - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert('intercepted_unary_request' == $event->message); - -$stream_call = $client->StreamCall(); -$stream_call->write($req); -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => '', - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert('intercepted_stream_request' == $event->message); - -unset($unary_call); -unset($stream_call); -unset($server_call); - -// Test ClientChangeStopCallInterceptor -$req_text = 'client_request'; -$channel_request_interceptor = new StopCallInterceptor(); -$intercept_channel = Grpc\Interceptor::intercept($channel, - $channel_request_interceptor); -$client = new InterceptorClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), -], $intercept_channel); - -$req = new SimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); -assert($unary_call == NULL); - - -$stream_call = $client->StreamCall(); -assert($stream_call == NULL); - -unset($unary_call); -unset($stream_call); -unset($server_call); - -// Test GetInterceptorChannelConnectivityState -$channel = new Grpc\Channel( - 'localhost:0', - [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure() - ] -); -$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); -$state = $interceptor_channel->getConnectivityState(); -assert(0 == $state); -$channel->close(); - -// Test InterceptorChannelWatchConnectivityState -$channel = new Grpc\Channel( - 'localhost:0', - [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure() - ] -); -$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); -$now = Grpc\Timeval::now(); -$deadline = $now->add(new Grpc\Timeval(100*1000)); -$state = $interceptor_channel->watchConnectivityState(1, $deadline); -assert($state); -unset($time); -unset($deadline); -$channel->close(); - -// Test InterceptorChannelClose -$channel = new Grpc\Channel( - 'localhost:0', - [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure() - ] -); -$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); -assert($interceptor_channel != NULL); -$channel->close(); - -// Test InterceptorChannelGetTarget -$channel = new Grpc\Channel( - 'localhost:8888', - [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure() - ] -); -$interceptor_channel = Grpc\Interceptor::intercept($channel, new Grpc\Interceptor()); -$target = $interceptor_channel->getTarget(); -assert(is_string($target)); - -$channel->close(); -unset($server); - - -//============== CallInvoker Test ==================== -class CallInvokerSimpleRequest -{ - private $data; - public function __construct($data) - { - $this->data = $data; - } - public function setData($data) - { - $this->data = $data; - } - public function serializeToString() - { - return $this->data; - } -} - -class CallInvokerClient extends Grpc\BaseStub -{ - - /** - * @param string $hostname hostname - * @param array $opts channel options - * @param Channel|InterceptorChannel $channel (optional) re-use channel object - */ - public function __construct($hostname, $opts, $channel = null) - { - parent::__construct($hostname, $opts, $channel); - } - - /** - * A simple RPC. - * @param SimpleRequest $argument input argument - * @param array $metadata metadata - * @param array $options call options - */ - public function UnaryCall( - CallInvokerSimpleRequest $argument, - $metadata = [], - $options = [] - ) { - return $this->_simpleRequest( - '/dummy_method', - $argument, - [], - $metadata, - $options - ); - } -} - -class CallInvokerUpdateChannel implements \Grpc\CallInvoker -{ - private $channel; - - public function getChannel() { - return $this->channel; - } - - public function createChannelFactory($hostname, $opts) { - $this->channel = new \Grpc\Channel('localhost:50050', $opts); - return $this->channel; - } - - public function UnaryCall($channel, $method, $deserialize, $options) { - return new UnaryCall($channel, $method, $deserialize, $options); - } - - public function ClientStreamingCall($channel, $method, $deserialize, $options) { - return new ClientStreamingCall($channel, $method, $deserialize, $options); - } - - public function ServerStreamingCall($channel, $method, $deserialize, $options) { - return new ServerStreamingCall($channel, $method, $deserialize, $options); - } - - public function BidiStreamingCall($channel, $method, $deserialize, $options) { - return new BidiStreamingCall($channel, $method, $deserialize, $options); - } -} - -class CallInvokerChangeRequest implements \Grpc\CallInvoker -{ - private $channel; - - public function getChannel() { - return $this->channel; - } - public function createChannelFactory($hostname, $opts) { - $this->channel = new \Grpc\Channel($hostname, $opts); - return $this->channel; - } - - public function UnaryCall($channel, $method, $deserialize, $options) { - return new CallInvokerChangeRequestCall($channel, $method, $deserialize, $options); - } - - public function ClientStreamingCall($channel, $method, $deserialize, $options) { - return new ClientStreamingCall($channel, $method, $deserialize, $options); - } - - public function ServerStreamingCall($channel, $method, $deserialize, $options) { - return new ServerStreamingCall($channel, $method, $deserialize, $options); - } - - public function BidiStreamingCall($channel, $method, $deserialize, $options) { - return new BidiStreamingCall($channel, $method, $deserialize, $options); - } -} - -class CallInvokerChangeRequestCall -{ - private $call; - - public function __construct($channel, $method, $deserialize, $options) - { - $this->call = new \Grpc\UnaryCall($channel, $method, $deserialize, $options); - } - - public function start($argument, $metadata, $options) { - $argument->setData('intercepted_unary_request'); - $this->call->start($argument, $metadata, $options); - } - - public function wait() - { - return $this->call->wait(); - } -} - -// Set Up -$server = new Grpc\Server([]); -$port = $server->addHttp2Port('0.0.0.0:0'); -$server->start(); - -// Test CreateDefaultCallInvoker -$call_invoker = new \Grpc\DefaultCallInvoker(); - -// Test CreateCallInvoker -$call_invoker = new CallInvokerUpdateChannel(); - -// Test CallInvokerAccessChannel -$call_invoker = new CallInvokerUpdateChannel(); -$stub = new \Grpc\BaseStub('localhost:50051', - ['credentials' => \Grpc\ChannelCredentials::createInsecure(), - 'grpc_call_invoker' => $call_invoker]); -assert($call_invoker->getChannel()->getTarget() == 'localhost:50050'); -$call_invoker->getChannel()->close(); - -// Test ClientChangeRequestCallInvoker -$req_text = 'client_request'; -$call_invoker = new CallInvokerChangeRequest(); -$client = new CallInvokerClient('localhost:'.$port, [ - 'force_new' => true, - 'credentials' => Grpc\ChannelCredentials::createInsecure(), - 'grpc_call_invoker' => $call_invoker, -]); - -$req = new CallInvokerSimpleRequest($req_text); -$unary_call = $client->UnaryCall($req); - -$event = $server->requestCall(); -assert('/dummy_method' == $event->method); -$server_call = $event->call; -$event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => '', - ], - Grpc\OP_RECV_MESSAGE => true, - Grpc\OP_RECV_CLOSE_ON_SERVER => true, -]); -assert('intercepted_unary_request' == $event->message); -$call_invoker->getChannel()->close(); -unset($unary_call); -unset($server_call); - -unset($server); - - From 39d3b7335c0dc31ca6fbff136a946a14f4286016 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 13 Feb 2019 19:17:18 +0100 Subject: [PATCH 362/814] Missed a spot. --- src/cpp/client/channel_cc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 182eb2115bc..b4bb1b41a21 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -51,7 +51,7 @@ void grpc::experimental::ChannelResetConnectionBackoff( ::grpc::Channel* channel) { - ChannelResetConnectionBackoff(channel); + grpc_impl::experimental::ChannelResetConnectionBackoff(channel); } namespace grpc_impl { From 684643ff0ab0760bb45195fb4396e4bef5dedcfc Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 13 Feb 2019 11:02:48 -0800 Subject: [PATCH 363/814] Test fixing php --- include/grpc/grpc.h | 3 +++ src/core/lib/surface/init.h | 1 - src/php/ext/grpc/php_grpc.c | 1 + test/core/util/test_config.cc | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 3cb9cf85318..e6988f489f2 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -86,6 +86,9 @@ GRPCAPI void grpc_shutdown(void); part of stabilizing the fork support API, as tracked in https://github.com/grpc/grpc/issues/15334 */ GRPCAPI int grpc_is_initialized(void); +/** EXPERIMENTAL. Wait for grpc_shutdown to finish if it is in process. + This is only for wrapped language to use now. */ +GRPCAPI void grpc_maybe_wait_for_async_shutdown(void); /** Return a string representing the current version of grpc */ GRPCAPI const char* grpc_version_string(void); diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 6eaa488d054..193f51447d9 100644 --- a/src/core/lib/surface/init.h +++ b/src/core/lib/surface/init.h @@ -22,6 +22,5 @@ void grpc_register_security_filters(void); void grpc_security_pre_init(void); void grpc_security_init(void); -void grpc_maybe_wait_for_async_shutdown(void); #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 111c6f4867d..256efad37a8 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -362,6 +362,7 @@ PHP_MSHUTDOWN_FUNCTION(grpc) { grpc_shutdown_timeval(TSRMLS_C); grpc_php_shutdown_completion_queue(TSRMLS_C); grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); GRPC_G(initialized) = 0; } return SUCCESS; diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 0c0492fdbbd..0caca1b164c 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include From 0c19be2fc8f38fb735bcf9f73905aa25043d1a78 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 13 Feb 2019 20:12:13 +0100 Subject: [PATCH 364/814] Fixing cronet --- src/cpp/client/cronet_credentials.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc index b2801764f20..0f8b988674b 100644 --- a/src/cpp/client/cronet_credentials.cc +++ b/src/cpp/client/cronet_credentials.cc @@ -47,7 +47,7 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return ::grpc_impl::CreateChannelInternal( "", grpc_cronet_secure_channel_create(engine_, target.c_str(), &channel_args, nullptr), From 233406d45053bbe1f6372368420a1b616fd16672 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 13 Feb 2019 11:29:40 -0800 Subject: [PATCH 365/814] generate projects --- grpc.def | 1 + src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 ++ src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 +++ test/core/surface/public_headers_must_be_c89.c | 1 + 4 files changed, 7 insertions(+) diff --git a/grpc.def b/grpc.def index 59e29e0d168..a9fba8dff2b 100644 --- a/grpc.def +++ b/grpc.def @@ -16,6 +16,7 @@ EXPORTS grpc_init grpc_shutdown grpc_is_initialized + grpc_maybe_wait_for_async_shutdown grpc_version_string grpc_g_stands_for grpc_completion_queue_factory_lookup diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 47250ec7141..0ff5bcbf44e 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -39,6 +39,7 @@ grpc_register_plugin_type grpc_register_plugin_import; grpc_init_type grpc_init_import; grpc_shutdown_type grpc_shutdown_import; grpc_is_initialized_type grpc_is_initialized_import; +grpc_maybe_wait_for_async_shutdown_type grpc_maybe_wait_for_async_shutdown_import; grpc_version_string_type grpc_version_string_import; grpc_g_stands_for_type grpc_g_stands_for_import; grpc_completion_queue_factory_lookup_type grpc_completion_queue_factory_lookup_import; @@ -306,6 +307,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_init_import = (grpc_init_type) GetProcAddress(library, "grpc_init"); grpc_shutdown_import = (grpc_shutdown_type) GetProcAddress(library, "grpc_shutdown"); grpc_is_initialized_import = (grpc_is_initialized_type) GetProcAddress(library, "grpc_is_initialized"); + grpc_maybe_wait_for_async_shutdown_import = (grpc_maybe_wait_for_async_shutdown_type) GetProcAddress(library, "grpc_maybe_wait_for_async_shutdown"); grpc_version_string_import = (grpc_version_string_type) GetProcAddress(library, "grpc_version_string"); grpc_g_stands_for_import = (grpc_g_stands_for_type) GetProcAddress(library, "grpc_g_stands_for"); grpc_completion_queue_factory_lookup_import = (grpc_completion_queue_factory_lookup_type) GetProcAddress(library, "grpc_completion_queue_factory_lookup"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 9437f6d3918..3008e631115 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -92,6 +92,9 @@ extern grpc_shutdown_type grpc_shutdown_import; typedef int(*grpc_is_initialized_type)(void); extern grpc_is_initialized_type grpc_is_initialized_import; #define grpc_is_initialized grpc_is_initialized_import +typedef void(*grpc_maybe_wait_for_async_shutdown_type)(void); +extern grpc_maybe_wait_for_async_shutdown_type grpc_maybe_wait_for_async_shutdown_import; +#define grpc_maybe_wait_for_async_shutdown grpc_maybe_wait_for_async_shutdown_import typedef const char*(*grpc_version_string_type)(void); extern grpc_version_string_type grpc_version_string_import; #define grpc_version_string grpc_version_string_import diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 1c9b67027c5..200dba1a1d9 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -78,6 +78,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_init); printf("%lx", (unsigned long) grpc_shutdown); printf("%lx", (unsigned long) grpc_is_initialized); + printf("%lx", (unsigned long) grpc_maybe_wait_for_async_shutdown); printf("%lx", (unsigned long) grpc_version_string); printf("%lx", (unsigned long) grpc_g_stands_for); printf("%lx", (unsigned long) grpc_completion_queue_factory_lookup); From 170931302336e7ed46081bb37853b07c24480536 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 13 Feb 2019 12:02:43 -0800 Subject: [PATCH 366/814] changed fields --- tools/run_tests/python_utils/upload_rbe_results.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index fa8a2612bda..d93ac8c1c18 100755 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -125,7 +125,7 @@ def _get_resultstore_data(api_key, invocation_id): print(page_token) req = urllib2.Request( url= - 'https://resultstore.googleapis.com/v2/invocations/%s/targets/-/configuredTargets/-/actions?key=%s&pageToken=%s&fields=id,status_attributes,timing,test_action' + 'https://resultstore.googleapis.com/v2/invocations/%s/targets/-/configuredTargets/-/actions?key=%s&pageToken=%s&fields=next_page_token,actions.id,actions.status_attributes' % (invocation_id, api_key, page_token), headers={ 'Content-Type': 'application/json' From 50497c23172a228a28adf45c26a951a46c396c93 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 13 Feb 2019 12:46:07 -0800 Subject: [PATCH 367/814] Reviewer comments --- include/grpcpp/impl/codegen/client_interceptor.h | 3 +++ test/cpp/end2end/client_interceptors_end2end_test.cc | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index defbeabfb63..43472803a08 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -179,6 +179,9 @@ class ClientRpcInfo { void RegisterGlobalClientInterceptorFactory( ClientInterceptorFactoryInterface* factory); +// For testing purposes only +void TestOnlyResetGlobalClientInterceptorFactory(); + } // namespace experimental } // namespace grpc diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc index cdeadb5364c..421b31ad08a 100644 --- a/test/cpp/end2end/client_interceptors_end2end_test.cc +++ b/test/cpp/end2end/client_interceptors_end2end_test.cc @@ -40,10 +40,6 @@ #include namespace grpc { - -namespace experimental { -void TestOnlyResetGlobalClientInterceptorFactory(); -} namespace testing { namespace { From 48c44ef9e407fb1e129a87ca123bd71232eca5b0 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Wed, 13 Feb 2019 13:00:06 -0800 Subject: [PATCH 368/814] grpc: aligned creation of handshaker factory lists --- src/core/lib/channel/handshaker_registry.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/lib/channel/handshaker_registry.cc b/src/core/lib/channel/handshaker_registry.cc index b65129a6ed6..199cb877497 100644 --- a/src/core/lib/channel/handshaker_registry.cc +++ b/src/core/lib/channel/handshaker_registry.cc @@ -19,6 +19,7 @@ #include #include "src/core/lib/channel/handshaker_registry.h" +#include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/memory.h" @@ -74,8 +75,11 @@ void HandshakerFactoryList::AddHandshakers(const grpc_channel_args* args, void HandshakerRegistry::Init() { GPR_ASSERT(g_handshaker_factory_lists == nullptr); - g_handshaker_factory_lists = static_cast( - gpr_malloc(sizeof(*g_handshaker_factory_lists) * NUM_HANDSHAKER_TYPES)); + g_handshaker_factory_lists = + static_cast(gpr_malloc_aligned( + sizeof(*g_handshaker_factory_lists) * NUM_HANDSHAKER_TYPES, + GPR_MAX_ALIGNMENT)); + GPR_ASSERT(g_handshaker_factory_lists != nullptr); for (auto idx = 0; idx < NUM_HANDSHAKER_TYPES; ++idx) { auto factory_list = g_handshaker_factory_lists + idx; @@ -89,7 +93,7 @@ void HandshakerRegistry::Shutdown() { auto factory_list = g_handshaker_factory_lists + idx; factory_list->~HandshakerFactoryList(); } - gpr_free(g_handshaker_factory_lists); + gpr_free_aligned(g_handshaker_factory_lists); g_handshaker_factory_lists = nullptr; } From 70f2ccd1a671ce610be3f99167f8e22398f675db Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 13 Feb 2019 13:05:53 -0800 Subject: [PATCH 369/814] Run android interop test on a physical device --- src/android/test/interop/app/build.gradle | 1 - tools/internal_ci/linux/grpc_android.sh | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/android/test/interop/app/build.gradle b/src/android/test/interop/app/build.gradle index 2f58b99c8e2..fb500a71c71 100644 --- a/src/android/test/interop/app/build.gradle +++ b/src/android/test/interop/app/build.gradle @@ -29,7 +29,6 @@ android { arguments '-DgRPC_CPP_PLUGIN_EXECUTABLE=' + grpc_cpp_plugin } } - ndk.abiFilters 'x86' } buildTypes { debug { diff --git a/tools/internal_ci/linux/grpc_android.sh b/tools/internal_ci/linux/grpc_android.sh index 42c7f5fb042..209b30d1ad7 100755 --- a/tools/internal_ci/linux/grpc_android.sh +++ b/tools/internal_ci/linux/grpc_android.sh @@ -44,7 +44,8 @@ gcloud firebase test android run \ --device model=Nexus6P,version=24,locale=en,orientation=portrait \ --device model=Nexus6P,version=23,locale=en,orientation=portrait \ --device model=Nexus6,version=22,locale=en,orientation=portrait \ - --device model=Nexus6,version=21,locale=en,orientation=portrait + --device model=Nexus6,version=21,locale=en,orientation=portrait \ + --device model=walleye,version=28,locale=en,orientation=portrait # Build hello world example From 18c75f13a12fceb825350341e03b67bd962f20b0 Mon Sep 17 00:00:00 2001 From: Jerry Date: Wed, 13 Feb 2019 13:17:28 -0800 Subject: [PATCH 370/814] removed php docker file --- .../test/php_jessie_x64/Dockerfile.template | 26 ------ .../dockerfile/test/php_jessie_x64/Dockerfile | 90 ------------------- 2 files changed, 116 deletions(-) delete mode 100644 templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template delete mode 100644 tools/dockerfile/test/php_jessie_x64/Dockerfile diff --git a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template deleted file mode 100644 index 329205363e3..00000000000 --- a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template +++ /dev/null @@ -1,26 +0,0 @@ -%YAML 1.2 ---- | - # Copyright 2015 gRPC authors. - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - - FROM debian:jessie - - <%include file="../../apt_get_basic.include"/> - <%include file="../../gcp_api_libraries.include"/> - <%include file="../../python_deps.include"/> - <%include file="../../php_deps.include"/> - <%include file="../../php_valgrind.include"/> - <%include file="../../run_tests_addons.include"/> - # Define the default command. - CMD ["bash"] diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile deleted file mode 100644 index c2c37d3b438..00000000000 --- a/tools/dockerfile/test/php_jessie_x64/Dockerfile +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright 2015 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM debian:jessie - -# Install Git and basic packages. -RUN apt-get update && apt-get install -y \ - autoconf \ - autotools-dev \ - build-essential \ - bzip2 \ - ccache \ - curl \ - dnsutils \ - gcc \ - gcc-multilib \ - git \ - golang \ - gyp \ - lcov \ - libc6 \ - libc6-dbg \ - libc6-dev \ - libgtest-dev \ - libtool \ - make \ - perl \ - strace \ - python-dev \ - python-setuptools \ - python-yaml \ - telnet \ - unzip \ - wget \ - zip && apt-get clean - -#================ -# Build profiling -RUN apt-get update && apt-get install -y time && apt-get clean - -# Google Cloud platform API libraries -RUN apt-get update && apt-get install -y python-pip && apt-get clean -RUN pip install --upgrade google-api-python-client oauth2client - -#==================== -# Python dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - python-all-dev \ - python3-all-dev \ - python-pip - -# Install Python packages from PyPI -RUN pip install --upgrade pip==10.0.1 -RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 - -#================= -# PHP dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - git php5 php5-dev phpunit unzip - -#================= -# PHP Test dependencies - - # Install dependencies - - RUN apt-get update && apt-get install -y \ - valgrind - -RUN mkdir /var/local/jenkins - -# Define the default command. -CMD ["bash"] From 5d5e2a4b8fe1c6b8849d12d1f1d56e92c08fe70a Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 13 Feb 2019 22:27:45 +0100 Subject: [PATCH 371/814] Regenerating goldef test files. --- test/cpp/codegen/compiler_test_golden | 5 ++++- test/cpp/codegen/golden_file_test.cc | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 1871e1375ed..de71dcd5cb1 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -40,9 +40,12 @@ #include #include +namespace grpc_impl { +class Channel; +} // namespace grpc_impl + namespace grpc { class CompletionQueue; -class Channel; class ServerCompletionQueue; class ServerContext; } // namespace grpc diff --git a/test/cpp/codegen/golden_file_test.cc b/test/cpp/codegen/golden_file_test.cc index bfd36494941..19f267dd4b5 100644 --- a/test/cpp/codegen/golden_file_test.cc +++ b/test/cpp/codegen/golden_file_test.cc @@ -31,7 +31,7 @@ using namespace gflags; DEFINE_string( generated_file_path, "", - "path to the directory containing generated files compiler_test.grpc.pb.h" + "path to the directory containing generated files compiler_test.grpc.pb.h " "and compiler_test_mock.grpc.pb.h"); const char kGoldenFilePath[] = "test/cpp/codegen/compiler_test_golden"; From 3ebbce2f59ed5138277b89db2dcf0a5cef7ae397 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 13 Feb 2019 13:30:03 -0800 Subject: [PATCH 372/814] Disable c-ares on Android --- include/grpc/impl/codegen/port_platform.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index cf760eaad05..0da45acab57 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -125,6 +125,10 @@ #elif defined(ANDROID) || defined(__ANDROID__) #define GPR_PLATFORM_STRING "android" #define GPR_ANDROID 1 +// TODO(apolcyn): re-evaluate support for c-ares +// on android after upgrading our c-ares dependency. +// See https://github.com/grpc/grpc/issues/18038. +#define GRPC_ARES 0 #ifdef _LP64 #define GPR_ARCH_64 1 #else /* _LP64 */ From 62c8b447a8e457361920c855ed4adbcf8c04347d Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 13 Feb 2019 11:42:35 -0800 Subject: [PATCH 373/814] Fix subchannel ref_from_weak_ref --- .../filters/client_channel/global_subchannel_pool.cc | 11 +++++++---- src/core/ext/filters/client_channel/subchannel.h | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/ext/filters/client_channel/global_subchannel_pool.cc b/src/core/ext/filters/client_channel/global_subchannel_pool.cc index ee6e58159a0..96a0244eb24 100644 --- a/src/core/ext/filters/client_channel/global_subchannel_pool.cc +++ b/src/core/ext/filters/client_channel/global_subchannel_pool.cc @@ -66,10 +66,13 @@ Subchannel* GlobalSubchannelPool::RegisterSubchannel(SubchannelKey* key, // Check to see if a subchannel already exists. c = static_cast(grpc_avl_get(old_map, key, nullptr)); if (c != nullptr) { - // The subchannel already exists. Reuse it. + // The subchannel already exists. Try to reuse it. c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "subchannel_register+reuse"); - GRPC_SUBCHANNEL_UNREF(constructed, "subchannel_register+found_existing"); - // Exit the CAS loop without modifying the shared map. + if (c != nullptr) { + GRPC_SUBCHANNEL_UNREF(constructed, + "subchannel_register+found_existing"); + // Exit the CAS loop without modifying the shared map. + } // Else, reuse failed, so retry CAS loop. } else { // There hasn't been such subchannel. Add one. // Note that we should ref the old map first because grpc_avl_add() will @@ -128,7 +131,7 @@ Subchannel* GlobalSubchannelPool::FindSubchannel(SubchannelKey* key) { grpc_avl index = grpc_avl_ref(subchannel_map_, nullptr); gpr_mu_unlock(&mu_); Subchannel* c = static_cast(grpc_avl_get(index, key, nullptr)); - if (c != nullptr) GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "found_from_pool"); + if (c != nullptr) c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "found_from_pool"); grpc_avl_unref(index, nullptr); return c; } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index bb8e45bf965..968fc74e22a 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -189,6 +189,9 @@ class Subchannel { void Unref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); Subchannel* WeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); void WeakUnref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); + // Attempts to return a strong ref when only the weak refcount is guaranteed + // non-zero. If the strong refcount is zero, does not alter the refcount and + // returns null. Subchannel* RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); intptr_t GetChildSocketUuid(); From 8f151edcd0c17c877541b892fdbfbda463f39601 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 13 Feb 2019 15:00:25 -0800 Subject: [PATCH 374/814] Remove subchannel_index.{h,cc} --- .../client_channel/subchannel_index.cc | 222 ------------------ .../filters/client_channel/subchannel_index.h | 66 ------ 2 files changed, 288 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/subchannel_index.cc delete mode 100644 src/core/ext/filters/client_channel/subchannel_index.h diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc deleted file mode 100644 index 1c839ddd6a3..00000000000 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ /dev/null @@ -1,222 +0,0 @@ -// -// -// Copyright 2016 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// - -#include - -#include "src/core/ext/filters/client_channel/subchannel_index.h" - -#include -#include - -#include -#include - -#include "src/core/lib/avl/avl.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/tls.h" - -// a map of subchannel_key --> subchannel, used for detecting connections -// to the same destination in order to share them -static grpc_avl g_subchannel_index; - -static gpr_mu g_mu; - -static gpr_refcount g_refcount; - -struct grpc_subchannel_key { - grpc_channel_args* args; -}; - -static grpc_subchannel_key* create_key( - const grpc_channel_args* args, - grpc_channel_args* (*copy_channel_args)(const grpc_channel_args* args)) { - grpc_subchannel_key* k = - static_cast(gpr_malloc(sizeof(*k))); - k->args = copy_channel_args(args); - return k; -} - -grpc_subchannel_key* grpc_subchannel_key_create(const grpc_channel_args* args) { - return create_key(args, grpc_channel_args_normalize); -} - -static grpc_subchannel_key* subchannel_key_copy(grpc_subchannel_key* k) { - return create_key(k->args, grpc_channel_args_copy); -} - -int grpc_subchannel_key_compare(const grpc_subchannel_key* a, - const grpc_subchannel_key* b) { - return grpc_channel_args_compare(a->args, b->args); -} - -void grpc_subchannel_key_destroy(grpc_subchannel_key* k) { - grpc_channel_args_destroy(k->args); - gpr_free(k); -} - -static void sck_avl_destroy(void* p, void* unused) { - grpc_subchannel_key_destroy(static_cast(p)); -} - -static void* sck_avl_copy(void* p, void* unused) { - return subchannel_key_copy(static_cast(p)); -} - -static long sck_avl_compare(void* a, void* b, void* unused) { - return grpc_subchannel_key_compare(static_cast(a), - static_cast(b)); -} - -static void scv_avl_destroy(void* p, void* unused) { - GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "subchannel_index"); -} - -static void* scv_avl_copy(void* p, void* unused) { - GRPC_SUBCHANNEL_WEAK_REF((grpc_subchannel*)p, "subchannel_index"); - return p; -} - -static const grpc_avl_vtable subchannel_avl_vtable = { - sck_avl_destroy, // destroy_key - sck_avl_copy, // copy_key - sck_avl_compare, // compare_keys - scv_avl_destroy, // destroy_value - scv_avl_copy // copy_value -}; - -void grpc_subchannel_index_init(void) { - g_subchannel_index = grpc_avl_create(&subchannel_avl_vtable); - gpr_mu_init(&g_mu); - gpr_ref_init(&g_refcount, 1); -} - -void grpc_subchannel_index_shutdown(void) { - // TODO(juanlishen): This refcounting mechanism may lead to memory leackage. - // To solve that, we should force polling to flush any pending callbacks, then - // shutdown safely. - grpc_subchannel_index_unref(); -} - -void grpc_subchannel_index_unref(void) { - if (gpr_unref(&g_refcount)) { - gpr_mu_destroy(&g_mu); - grpc_avl_unref(g_subchannel_index, nullptr); - } -} - -void grpc_subchannel_index_ref(void) { gpr_ref_non_zero(&g_refcount); } - -grpc_subchannel* grpc_subchannel_index_find(grpc_subchannel_key* key) { - // Lock, and take a reference to the subchannel index. - // We don't need to do the search under a lock as avl's are immutable. - gpr_mu_lock(&g_mu); - grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr); - gpr_mu_unlock(&g_mu); - - grpc_subchannel* c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF( - (grpc_subchannel*)grpc_avl_get(index, key, nullptr), "index_find"); - grpc_avl_unref(index, nullptr); - - return c; -} - -grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key, - grpc_subchannel* constructed) { - grpc_subchannel* c = nullptr; - bool need_to_unref_constructed = false; - - while (c == nullptr) { - need_to_unref_constructed = false; - - // Compare and swap loop: - // - take a reference to the current index - gpr_mu_lock(&g_mu); - grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr); - gpr_mu_unlock(&g_mu); - - // - Check to see if a subchannel already exists - c = static_cast(grpc_avl_get(index, key, nullptr)); - if (c != nullptr) { - c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "index_register"); - } - if (c != nullptr) { - // yes -> we're done - need_to_unref_constructed = true; - } else { - // no -> update the avl and compare/swap - grpc_avl updated = grpc_avl_add( - grpc_avl_ref(index, nullptr), subchannel_key_copy(key), - GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"), nullptr); - - // it may happen (but it's expected to be unlikely) - // that some other thread has changed the index: - // compare/swap here to check that, and retry as necessary - gpr_mu_lock(&g_mu); - if (index.root == g_subchannel_index.root) { - GPR_SWAP(grpc_avl, updated, g_subchannel_index); - c = constructed; - } - gpr_mu_unlock(&g_mu); - - grpc_avl_unref(updated, nullptr); - } - grpc_avl_unref(index, nullptr); - } - - if (need_to_unref_constructed) { - GRPC_SUBCHANNEL_UNREF(constructed, "index_register"); - } - - return c; -} - -void grpc_subchannel_index_unregister(grpc_subchannel_key* key, - grpc_subchannel* constructed) { - bool done = false; - while (!done) { - // Compare and swap loop: - // - take a reference to the current index - gpr_mu_lock(&g_mu); - grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr); - gpr_mu_unlock(&g_mu); - - // Check to see if this key still refers to the previously - // registered subchannel - grpc_subchannel* c = - static_cast(grpc_avl_get(index, key, nullptr)); - if (c != constructed) { - grpc_avl_unref(index, nullptr); - break; - } - - // compare and swap the update (some other thread may have - // mutated the index behind us) - grpc_avl updated = - grpc_avl_remove(grpc_avl_ref(index, nullptr), key, nullptr); - - gpr_mu_lock(&g_mu); - if (index.root == g_subchannel_index.root) { - GPR_SWAP(grpc_avl, updated, g_subchannel_index); - done = true; - } - gpr_mu_unlock(&g_mu); - - grpc_avl_unref(updated, nullptr); - grpc_avl_unref(index, nullptr); - } -} diff --git a/src/core/ext/filters/client_channel/subchannel_index.h b/src/core/ext/filters/client_channel/subchannel_index.h deleted file mode 100644 index 1aeb51e6535..00000000000 --- a/src/core/ext/filters/client_channel/subchannel_index.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H - -#include - -#include "src/core/ext/filters/client_channel/subchannel.h" - -/** \file Provides an index of active subchannels so that they can be - shared amongst channels */ - -/** Create a key that can be used to uniquely identify a subchannel */ -grpc_subchannel_key* grpc_subchannel_key_create(const grpc_channel_args* args); - -/** Destroy a subchannel key */ -void grpc_subchannel_key_destroy(grpc_subchannel_key* key); - -/** Given a subchannel key, find the subchannel registered for it. - Returns NULL if no such channel exists. - Thread-safe. */ -grpc_subchannel* grpc_subchannel_index_find(grpc_subchannel_key* key); - -/** Register a subchannel against a key. - Takes ownership of \a constructed. - Returns the registered subchannel. This may be different from - \a constructed in the case of a registration race. */ -grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key, - grpc_subchannel* constructed); - -/** Remove \a constructed as the registered subchannel for \a key. */ -void grpc_subchannel_index_unregister(grpc_subchannel_key* key, - grpc_subchannel* constructed); - -int grpc_subchannel_key_compare(const grpc_subchannel_key* a, - const grpc_subchannel_key* b); - -/** Initialize the subchannel index (global) */ -void grpc_subchannel_index_init(void); -/** Shutdown the subchannel index (global) */ -void grpc_subchannel_index_shutdown(void); - -/** Increment the refcount (non-zero) of subchannel index (global). */ -void grpc_subchannel_index_ref(void); - -/** Decrement the refcount of subchannel index (global). If the refcount drops - to zero, unref the subchannel index and destroy its mutex. */ -void grpc_subchannel_index_unref(void); - -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H */ From ab4fbc88b6cc2732435d46f4907d63f48ed515e9 Mon Sep 17 00:00:00 2001 From: Jerry Date: Wed, 13 Feb 2019 15:01:25 -0800 Subject: [PATCH 375/814] removed changes in php docker file --- .../test/php_jessie_x64/Dockerfile.template | 25 ++++++ .../dockerfile/test/php_jessie_x64/Dockerfile | 83 +++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template create mode 100644 tools/dockerfile/test/php_jessie_x64/Dockerfile diff --git a/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template new file mode 100644 index 00000000000..fdbad53c391 --- /dev/null +++ b/templates/tools/dockerfile/test/php_jessie_x64/Dockerfile.template @@ -0,0 +1,25 @@ +%YAML 1.2 +--- | + # Copyright 2015 gRPC authors. + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + FROM debian:jessie + + <%include file="../../apt_get_basic.include"/> + <%include file="../../gcp_api_libraries.include"/> + <%include file="../../python_deps.include"/> + <%include file="../../php_deps.include"/> + <%include file="../../run_tests_addons.include"/> + # Define the default command. + CMD ["bash"] diff --git a/tools/dockerfile/test/php_jessie_x64/Dockerfile b/tools/dockerfile/test/php_jessie_x64/Dockerfile new file mode 100644 index 00000000000..ed59e569956 --- /dev/null +++ b/tools/dockerfile/test/php_jessie_x64/Dockerfile @@ -0,0 +1,83 @@ +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM debian:jessie + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + dnsutils \ + gcc \ + gcc-multilib \ + git \ + golang \ + gyp \ + lcov \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +#================ +# Build profiling +RUN apt-get update && apt-get install -y time && apt-get clean + +# Google Cloud platform API libraries +RUN apt-get update && apt-get install -y python-pip && apt-get clean +RUN pip install --upgrade google-api-python-client oauth2client + +#==================== +# Python dependencies + +# Install dependencies + +RUN apt-get update && apt-get install -y \ + python-all-dev \ + python3-all-dev \ + python-pip + +# Install Python packages from PyPI +RUN pip install --upgrade pip==10.0.1 +RUN pip install virtualenv +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 + +#================= +# PHP dependencies + +# Install dependencies + +RUN apt-get update && apt-get install -y \ + git php5 php5-dev phpunit unzip + + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] From 152626b13cf7d6cace9c9bb7fb43361d93017449 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 13 Feb 2019 15:22:23 -0800 Subject: [PATCH 376/814] removed debug printouts --- tools/run_tests/python_utils/upload_rbe_results.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index d93ac8c1c18..11cc1aa5dd4 100755 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -120,9 +120,6 @@ def _get_resultstore_data(api_key, invocation_id): # that limit, the 'nextPageToken' field is included in the request to get # subsequent data, so keep requesting until 'nextPageToken' field is omitted. while True: - print(invocation_id) - print(api_key) - print(page_token) req = urllib2.Request( url= 'https://resultstore.googleapis.com/v2/invocations/%s/targets/-/configuredTargets/-/actions?key=%s&pageToken=%s&fields=next_page_token,actions.id,actions.status_attributes' From 69fab8eacb83eef5307cf89519db7b640f04d3a8 Mon Sep 17 00:00:00 2001 From: Vu Cong Tuan Date: Thu, 14 Feb 2019 11:12:59 +0700 Subject: [PATCH 377/814] Fix many typos in doc Signed-off-by: Vu Cong Tuan --- doc/PROTOCOL-WEB.md | 2 +- doc/connection-backoff-interop-test-description.md | 2 +- doc/connectivity-semantics-and-api.md | 2 +- doc/core/grpc-client-server-polling-engine-usage.md | 2 +- doc/core/transport_explainer.md | 2 +- doc/environment_variables.md | 4 ++-- doc/naming.md | 2 +- doc/wait-for-ready.md | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/PROTOCOL-WEB.md b/doc/PROTOCOL-WEB.md index a06dfb1b54d..66544543804 100644 --- a/doc/PROTOCOL-WEB.md +++ b/doc/PROTOCOL-WEB.md @@ -132,7 +132,7 @@ finalized and implemented in modern browsers Versioning -* Special headers may be introduced to support features that may break compatiblity. +* Special headers may be introduced to support features that may break compatibility. --- diff --git a/doc/connection-backoff-interop-test-description.md b/doc/connection-backoff-interop-test-description.md index 4778efe4530..7675059d9a3 100644 --- a/doc/connection-backoff-interop-test-description.md +++ b/doc/connection-backoff-interop-test-description.md @@ -40,7 +40,7 @@ Procedure of client: 1. Calls Start on server control port with a large deadline or no deadline, waits for its finish and checks it succeeded. 2. Initiates a channel connection to server retry port, which should perform -reconnections with proper backoffs. A convienent way to achieve this is to +reconnections with proper backoffs. A convenient way to achieve this is to call Start with a deadline of 540s. The rpc should fail with deadline exceeded. 3. Calls Stop on server control port and checks it succeeded. 4. Checks the response to see whether the server thinks the backoffs passed the diff --git a/doc/connectivity-semantics-and-api.md b/doc/connectivity-semantics-and-api.md index 44fdf050c65..48a847670ce 100644 --- a/doc/connectivity-semantics-and-api.md +++ b/doc/connectivity-semantics-and-api.md @@ -43,7 +43,7 @@ connection because of a lack of new or pending RPCs. New RPCs MAY be created in this state. Any attempt to start an RPC on the channel will push the channel out of this state to connecting. When there has been no RPC activity on a channel for a specified IDLE_TIMEOUT, i.e., no new or pending (active) RPCs for this -period, channels that are READY or CONNECTING switch to IDLE. Additionaly, +period, channels that are READY or CONNECTING switch to IDLE. Additionally, channels that receive a GOAWAY when there are no active or pending RPCs should also switch to IDLE to avoid connection overload at servers that are attempting to shed connections. We will use a default IDLE_TIMEOUT of 300 seconds (5 minutes). diff --git a/doc/core/grpc-client-server-polling-engine-usage.md b/doc/core/grpc-client-server-polling-engine-usage.md index 3a560e71a81..f66dcf09caa 100644 --- a/doc/core/grpc-client-server-polling-engine-usage.md +++ b/doc/core/grpc-client-server-polling-engine-usage.md @@ -17,7 +17,7 @@ This document talks about how polling engine is used in gRPC core (both on clien ### Making progress on Async `connect()` on sub-channels (`grpc_pollset_set` usecase) - A gRPC channel is created between a client and a 'target'. The 'target' may resolve in to one or more backend servers. - A sub-channel is the 'connection' from a client to the backend server -- While establishing sub-cannels (i.e connections) to the backends, gRPC issues async [`connect()`](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/tcp_client_posix.cc#L296) calls which may not complete right away. When the `connect()` eventually succeeds, the socket fd is make 'writable' +- While establishing sub-channels (i.e connections) to the backends, gRPC issues async [`connect()`](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/tcp_client_posix.cc#L296) calls which may not complete right away. When the `connect()` eventually succeeds, the socket fd is make 'writable' - This means that the polling engine must be monitoring all these sub-channel `fd`s for writable events and we need to make sure there is a polling thread that monitors all these fds - To accomplish this, the `grpc_pollset_set` is used the following way (see picture below) diff --git a/doc/core/transport_explainer.md b/doc/core/transport_explainer.md index f48fa0f3b1f..a100128e538 100644 --- a/doc/core/transport_explainer.md +++ b/doc/core/transport_explainer.md @@ -110,7 +110,7 @@ There are other possible sample timelines. For example, for client-side streamin - These correspond to a client issuing `WritesDone` which causes the server's `Read` to fail 1. Server: send\_message, send\_trailing\_metadata - - These correpond to the server doing `Finish` + - These correspond to the server doing `Finish` The sends on one side will call their own callbacks when complete, and they will in turn trigger actions that cause the other side's recv operations to diff --git a/doc/environment_variables.md b/doc/environment_variables.md index d1172e62f45..132de81a7bd 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -114,7 +114,7 @@ some configuration as environment variables that can be set. - ERROR - log only errors * GRPC_TRACE_FUZZER - if set, the fuzzers will output trace (it is usually supressed). + if set, the fuzzers will output trace (it is usually suppressed). * GRPC_DNS_RESOLVER Declares which DNS resolver to use. The default is ares if gRPC is built with @@ -144,7 +144,7 @@ some configuration as environment variables that can be set. * GRPC_ARENA_INIT_STRATEGY Selects the initialization strategy for blocks allocated in the arena. Valid values are: - - no_init (default): Do not inialize the arena block. + - no_init (default): Do not initialize the arena block. - zero_init: Initialize the arena blocks with 0. - non_zero_init: Initialize the arena blocks with a non-zero value. diff --git a/doc/naming.md b/doc/naming.md index 5e54ca67b31..f7cda581f25 100644 --- a/doc/naming.md +++ b/doc/naming.md @@ -52,7 +52,7 @@ but may not be supported in other languages: - `ipv6:address[:port][,address[:port],...]` -- IPv6 addresses - Can specify multiple comma-delimited addresses of the form `address[:port]`: - `address` is the IPv6 address to use. To use with a `port` the `address` - must enclosed in literal square brakets (`[` and `]`). Example: + must enclosed in literal square brackets (`[` and `]`). Example: `ipv6:[2607:f8b0:400e:c00::ef]:443` or `ipv6:[::]:1234` - `port` is the port to use. If not specified, 443 is used. diff --git a/doc/wait-for-ready.md b/doc/wait-for-ready.md index fd426042693..c08f20c14ae 100644 --- a/doc/wait-for-ready.md +++ b/doc/wait-for-ready.md @@ -2,7 +2,7 @@ gRPC Wait for Ready Semantics ============================= If an RPC is issued but the channel is in `TRANSIENT_FAILURE` or `SHUTDOWN` -states, the RPC is unable to be transmited promptly. By default, gRPC +states, the RPC is unable to be transmitted promptly. By default, gRPC implementations SHOULD fail such RPCs immediately. This is known as "fail fast," but usage of the term is historical. RPCs SHOULD NOT fail as a result of the channel being in other states (`CONNECTING`, `READY`, or `IDLE`). From cfc2156665a262252eb01aa4e9508b6f9e54594e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 14 Feb 2019 18:25:28 +0100 Subject: [PATCH 378/814] add AspNetCore interop server --- .../Dockerfile.template | 20 ++++++++++++ .../build_interop.sh.template | 31 +++++++++++++++++++ .../grpc_interop_aspnetcore/Dockerfile | 18 +++++++++++ .../grpc_interop_aspnetcore/build_interop.sh | 29 +++++++++++++++++ .../dockerize/build_interop_image.sh | 8 +++++ 5 files changed, 106 insertions(+) create mode 100644 templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template create mode 100644 templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template create mode 100644 tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile create mode 100644 tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template new file mode 100644 index 00000000000..e1b6da89a74 --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template @@ -0,0 +1,20 @@ +%YAML 1.2 +--- | + # Copyright 2017 gRPC authors. + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + FROM microsoft/dotnet:3.0.100-preview2-sdk-stretch + + # Define the default command. + CMD ["bash"] diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template new file mode 100644 index 00000000000..69e2ed387b2 --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template @@ -0,0 +1,31 @@ +%YAML 1.2 +--- | + #!/bin/bash + # Copyright 2017 gRPC authors. + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + # + # Builds Grpc.AspNetCore.Server interop server in a base image. + set -e + + mkdir -p /var/local/git + git clone /var/local/jenkins/grpc-dotnet /var/local/git/grpc-dotnet + + # copy service account keys if available + cp -r /var/local/jenkins/service_account $HOME || true + + cd /var/local/git/grpc-dotnet + ./build/get-grpc.sh + + cd testassets/InteropTestsWebsite + dotnet build --configuration Debug diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile new file mode 100644 index 00000000000..2caa093ccc1 --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile @@ -0,0 +1,18 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM microsoft/dotnet:3.0.100-preview2-sdk-stretch + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh new file mode 100644 index 00000000000..38feae39623 --- /dev/null +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Builds Grpc.AspNetCore.Server interop server in a base image. +set -e + +mkdir -p /var/local/git +git clone /var/local/jenkins/grpc-dotnet /var/local/git/grpc-dotnet + +# copy service account keys if available +cp -r /var/local/jenkins/service_account $HOME || true + +cd /var/local/git/grpc-dotnet +./build/get-grpc.sh + +cd testassets/InteropTestsWebsite +dotnet build --configuration Debug diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh index 025c532d976..fe37defd146 100755 --- a/tools/run_tests/dockerize/build_interop_image.sh +++ b/tools/run_tests/dockerize/build_interop_image.sh @@ -64,6 +64,14 @@ else echo "WARNING: grpc-node not found, it won't be mounted to the docker container." fi +echo "GRPC_DOTNET_ROOT: ${GRPC_DOTNET_ROOT:=$(cd ../grpc-dotnet && pwd)}" +if [ -n "$GRPC_DOTNET_ROOT" ] +then + MOUNT_ARGS+=" -v $GRPC_DOTNET_ROOT:/var/local/jenkins/grpc-dotnet:ro" +else + echo "WARNING: grpc-dotnet not found, it won't be mounted to the docker container." +fi + # Mount service account dir if available. # If service_directory does not contain the service account JSON file, # some of the tests will fail. From 1898e1be256fe4796f2ba6f0b9e2bf7b774f460a Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 14 Feb 2019 10:39:47 -0800 Subject: [PATCH 379/814] debug printouts --- tools/run_tests/python_utils/upload_rbe_results.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index 11cc1aa5dd4..ba2c012e20f 100755 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -145,6 +145,7 @@ if __name__ == "__main__": api_key = args.api_key or _get_api_key() invocation_id = args.invocation_id or _get_invocation_id() resultstore_actions = _get_resultstore_data(api_key, invocation_id) + print(resultstore_actions) bq_rows = [] for index, action in enumerate(resultstore_actions): From 5428bdeb8388abc5a9601a298c20924730cd245f Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 14 Feb 2019 11:09:55 -0800 Subject: [PATCH 380/814] more debug printouts --- tools/run_tests/python_utils/upload_rbe_results.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index ba2c012e20f..0dfa487033a 100755 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -96,8 +96,10 @@ def _upload_results_to_bq(rows): max_retries = 3 for attempt in range(max_retries): - if big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET_ID, _TABLE_ID, - rows): + k = big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET_ID, _TABLE_ID, + rows) + print(k) + if k: break else: if attempt < max_retries - 1: @@ -145,7 +147,6 @@ if __name__ == "__main__": api_key = args.api_key or _get_api_key() invocation_id = args.invocation_id or _get_invocation_id() resultstore_actions = _get_resultstore_data(api_key, invocation_id) - print(resultstore_actions) bq_rows = [] for index, action in enumerate(resultstore_actions): From 4d0b1236092eb1e2484b771420eae79ef380904e Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 14 Feb 2019 13:52:43 -0800 Subject: [PATCH 381/814] more debug printouts --- tools/gcp/utils/big_query_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/gcp/utils/big_query_utils.py b/tools/gcp/utils/big_query_utils.py index 6e9cda376ba..339ad0f9f98 100755 --- a/tools/gcp/utils/big_query_utils.py +++ b/tools/gcp/utils/big_query_utils.py @@ -178,6 +178,7 @@ def insert_rows(big_query, project_id, dataset_id, table_id, rows_list): is_success = False except HttpError as http_error: print('Error inserting rows to the table %s' % table_id) + print(HttpError) is_success = False return is_success From 545c555d31c44ba1d05dee32d34b3256decbbb2e Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 14 Feb 2019 14:03:02 -0800 Subject: [PATCH 382/814] Rename new public API --- grpc.def | 2 +- include/grpc/grpc.h | 5 +-- src/core/lib/surface/init.cc | 32 +++++++++++++------ src/core/lib/surface/init.h | 1 + src/php/ext/grpc/php_grpc.c | 3 +- src/ruby/ext/grpc/rb_grpc_imports.generated.c | 4 +-- src/ruby/ext/grpc/rb_grpc_imports.generated.h | 6 ++-- test/core/memory_usage/client.cc | 4 +-- test/core/memory_usage/server.cc | 4 +-- test/core/surface/init_test.cc | 16 ++++++++-- .../core/surface/public_headers_must_be_c89.c | 2 +- test/core/util/port.cc | 4 +-- test/core/util/test_config.cc | 1 - test/cpp/naming/address_sorting_test.cc | 6 +--- 14 files changed, 53 insertions(+), 37 deletions(-) diff --git a/grpc.def b/grpc.def index a9fba8dff2b..e0a08d22c19 100644 --- a/grpc.def +++ b/grpc.def @@ -16,7 +16,7 @@ EXPORTS grpc_init grpc_shutdown grpc_is_initialized - grpc_maybe_wait_for_async_shutdown + grpc_shutdown_blocking grpc_version_string grpc_g_stands_for grpc_completion_queue_factory_lookup diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index e6988f489f2..eb4248f8eb1 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -86,9 +86,10 @@ GRPCAPI void grpc_shutdown(void); part of stabilizing the fork support API, as tracked in https://github.com/grpc/grpc/issues/15334 */ GRPCAPI int grpc_is_initialized(void); -/** EXPERIMENTAL. Wait for grpc_shutdown to finish if it is in process. + +/** EXPERIMENTAL. Blocking shut down grpc library. This is only for wrapped language to use now. */ -GRPCAPI void grpc_maybe_wait_for_async_shutdown(void); +GRPCAPI void grpc_shutdown_blocking(void); /** Return a string representing the current version of grpc */ GRPCAPI const char* grpc_version_string(void); diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index fca85ac876a..d8eeaf1c424 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -164,16 +164,8 @@ void grpc_init(void) { GRPC_API_TRACE("grpc_init(void)", 0, ()); } -void grpc_shutdown_internal(void* ignored) { +void grpc_shutdown_internal_locked(void) { int i; - GRPC_API_TRACE("grpc_shutdown_internal", 0, ()); - gpr_mu_lock(&g_init_mu); - // We have released lock from the shutdown thread and it is possible that - // another grpc_init has been called, and do nothing if that is the case. - if (--g_initializations != 0) { - gpr_mu_unlock(&g_init_mu); - return; - } { grpc_core::ExecCtx exec_ctx(0); grpc_iomgr_shutdown_background_closure(); @@ -200,6 +192,18 @@ void grpc_shutdown_internal(void* ignored) { grpc_core::ApplicationCallbackExecCtx::GlobalShutdown(); g_shutting_down = false; gpr_cv_broadcast(g_shutting_down_cv); +} + +void grpc_shutdown_internal(void* ignored) { + GRPC_API_TRACE("grpc_shutdown_internal", 0, ()); + gpr_mu_lock(&g_init_mu); + // We have released lock from the shutdown thread and it is possible that + // another grpc_init has been called, and do nothing if that is the case. + if (--g_initializations != 0) { + gpr_mu_unlock(&g_init_mu); + return; + } + grpc_shutdown_internal_locked(); gpr_mu_unlock(&g_init_mu); } @@ -219,6 +223,16 @@ void grpc_shutdown(void) { gpr_mu_unlock(&g_init_mu); } +void grpc_shutdown_blocking(void) { + GRPC_API_TRACE("grpc_shutdown_blocking(void)", 0, ()); + gpr_mu_lock(&g_init_mu); + if (--g_initializations == 0) { + g_shutting_down = true; + grpc_shutdown_internal_locked(); + } + gpr_mu_unlock(&g_init_mu); +} + int grpc_is_initialized(void) { int r; gpr_once_init(&g_basic_init, do_basic_init); diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 193f51447d9..6eaa488d054 100644 --- a/src/core/lib/surface/init.h +++ b/src/core/lib/surface/init.h @@ -22,5 +22,6 @@ void grpc_register_security_filters(void); void grpc_security_pre_init(void); void grpc_security_init(void); +void grpc_maybe_wait_for_async_shutdown(void); #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 256efad37a8..fa6f0be837b 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -361,8 +361,7 @@ PHP_MSHUTDOWN_FUNCTION(grpc) { zend_hash_destroy(&grpc_target_upper_bound_map); grpc_shutdown_timeval(TSRMLS_C); grpc_php_shutdown_completion_queue(TSRMLS_C); - grpc_shutdown(); - grpc_maybe_wait_for_async_shutdown(); + grpc_shutdown_blocking(); GRPC_G(initialized) = 0; } return SUCCESS; diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 0ff5bcbf44e..fdbe0df4e52 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -39,7 +39,7 @@ grpc_register_plugin_type grpc_register_plugin_import; grpc_init_type grpc_init_import; grpc_shutdown_type grpc_shutdown_import; grpc_is_initialized_type grpc_is_initialized_import; -grpc_maybe_wait_for_async_shutdown_type grpc_maybe_wait_for_async_shutdown_import; +grpc_shutdown_blocking_type grpc_shutdown_blocking_import; grpc_version_string_type grpc_version_string_import; grpc_g_stands_for_type grpc_g_stands_for_import; grpc_completion_queue_factory_lookup_type grpc_completion_queue_factory_lookup_import; @@ -307,7 +307,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_init_import = (grpc_init_type) GetProcAddress(library, "grpc_init"); grpc_shutdown_import = (grpc_shutdown_type) GetProcAddress(library, "grpc_shutdown"); grpc_is_initialized_import = (grpc_is_initialized_type) GetProcAddress(library, "grpc_is_initialized"); - grpc_maybe_wait_for_async_shutdown_import = (grpc_maybe_wait_for_async_shutdown_type) GetProcAddress(library, "grpc_maybe_wait_for_async_shutdown"); + grpc_shutdown_blocking_import = (grpc_shutdown_blocking_type) GetProcAddress(library, "grpc_shutdown_blocking"); grpc_version_string_import = (grpc_version_string_type) GetProcAddress(library, "grpc_version_string"); grpc_g_stands_for_import = (grpc_g_stands_for_type) GetProcAddress(library, "grpc_g_stands_for"); grpc_completion_queue_factory_lookup_import = (grpc_completion_queue_factory_lookup_type) GetProcAddress(library, "grpc_completion_queue_factory_lookup"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 3008e631115..cf16f0ca33b 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -92,9 +92,9 @@ extern grpc_shutdown_type grpc_shutdown_import; typedef int(*grpc_is_initialized_type)(void); extern grpc_is_initialized_type grpc_is_initialized_import; #define grpc_is_initialized grpc_is_initialized_import -typedef void(*grpc_maybe_wait_for_async_shutdown_type)(void); -extern grpc_maybe_wait_for_async_shutdown_type grpc_maybe_wait_for_async_shutdown_import; -#define grpc_maybe_wait_for_async_shutdown grpc_maybe_wait_for_async_shutdown_import +typedef void(*grpc_shutdown_blocking_type)(void); +extern grpc_shutdown_blocking_type grpc_shutdown_blocking_import; +#define grpc_shutdown_blocking grpc_shutdown_blocking_import typedef const char*(*grpc_version_string_type)(void); extern grpc_version_string_type grpc_version_string_import; #define grpc_version_string grpc_version_string_import diff --git a/test/core/memory_usage/client.cc b/test/core/memory_usage/client.cc index 9552e1b88ed..097288c5efa 100644 --- a/test/core/memory_usage/client.cc +++ b/test/core/memory_usage/client.cc @@ -29,7 +29,6 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/surface/init.h" #include "test/core/util/cmdline.h" #include "test/core/util/memory_counters.h" @@ -286,8 +285,7 @@ int main(int argc, char** argv) { grpc_slice_unref(slice); grpc_completion_queue_destroy(cq); - grpc_shutdown(); - grpc_maybe_wait_for_async_shutdown(); + grpc_shutdown_blocking(); gpr_log(GPR_INFO, "---------client stats--------"); gpr_log( diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 0c67ee4fcdf..6fb14fa31a0 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -34,7 +34,6 @@ #include #include "src/core/lib/gpr/host_port.h" -#include "src/core/lib/surface/init.h" #include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/cmdline.h" #include "test/core/util/memory_counters.h" @@ -319,8 +318,7 @@ int main(int argc, char** argv) { grpc_server_destroy(server); grpc_completion_queue_destroy(cq); - grpc_shutdown(); - grpc_maybe_wait_for_async_shutdown(); + grpc_shutdown_blocking(); grpc_memory_counters_destroy(); return 0; } diff --git a/test/core/surface/init_test.cc b/test/core/surface/init_test.cc index 0ca83b4359c..583dd1b6de9 100644 --- a/test/core/surface/init_test.cc +++ b/test/core/surface/init_test.cc @@ -36,6 +36,16 @@ static void test(int rounds) { grpc_maybe_wait_for_async_shutdown(); } +static void test_blocking(int rounds) { + int i; + for (i = 0; i < rounds; i++) { + grpc_init(); + } + for (i = 0; i < rounds; i++) { + grpc_shutdown_blocking(); + } +} + static void test_mixed(void) { grpc_init(); grpc_init(); @@ -53,8 +63,7 @@ static void test_plugin() { grpc_register_plugin(plugin_init, plugin_destroy); grpc_init(); GPR_ASSERT(g_flag == 1); - grpc_shutdown(); - grpc_maybe_wait_for_async_shutdown(); + grpc_shutdown_blocking(); GPR_ASSERT(g_flag == 2); } @@ -71,6 +80,9 @@ int main(int argc, char** argv) { test(1); test(2); test(3); + test_blocking(1); + test_blocking(2); + test_blocking(3); test_mixed(); test_plugin(); test_repeatedly(); diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 200dba1a1d9..04d0506b3c2 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -78,7 +78,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_init); printf("%lx", (unsigned long) grpc_shutdown); printf("%lx", (unsigned long) grpc_is_initialized); - printf("%lx", (unsigned long) grpc_maybe_wait_for_async_shutdown); + printf("%lx", (unsigned long) grpc_shutdown_blocking); printf("%lx", (unsigned long) grpc_version_string); printf("%lx", (unsigned long) grpc_g_stands_for); printf("%lx", (unsigned long) grpc_completion_queue_factory_lookup); diff --git a/test/core/util/port.cc b/test/core/util/port.cc index 14d648b7eaf..fe4caa6faf6 100644 --- a/test/core/util/port.cc +++ b/test/core/util/port.cc @@ -34,7 +34,6 @@ #include "src/core/lib/http/httpcli.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" -#include "src/core/lib/surface/init.h" #include "test/core/util/port_server_client.h" static int* chosen_ports = nullptr; @@ -67,8 +66,7 @@ static void free_chosen_ports(void) { for (i = 0; i < num_chosen_ports; i++) { grpc_free_port_using_server(chosen_ports[i]); } - grpc_shutdown(); - grpc_maybe_wait_for_async_shutdown(); + grpc_shutdown_blocking(); gpr_free(chosen_ports); } diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 0caca1b164c..0c0492fdbbd 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -25,7 +25,6 @@ #include #include -#include #include #include diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index 33c35c46409..e6b14888ffb 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -47,7 +47,6 @@ #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" -#include "src/core/lib/surface/init.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -198,10 +197,7 @@ void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses, class AddressSortingTest : public ::testing::Test { protected: void SetUp() override { grpc_init(); } - void TearDown() override { - grpc_shutdown(); - grpc_maybe_wait_for_async_shutdown(); - } + void TearDown() override { grpc_shutdown_blocking(); } }; /* Tests for rule 1 */ From cd83999dd916dbaf845022ea9138b149cb154df7 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 14 Feb 2019 14:22:52 -0800 Subject: [PATCH 383/814] debug outputs --- tools/gcp/utils/big_query_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gcp/utils/big_query_utils.py b/tools/gcp/utils/big_query_utils.py index 339ad0f9f98..1f675a79e9c 100755 --- a/tools/gcp/utils/big_query_utils.py +++ b/tools/gcp/utils/big_query_utils.py @@ -178,7 +178,7 @@ def insert_rows(big_query, project_id, dataset_id, table_id, rows_list): is_success = False except HttpError as http_error: print('Error inserting rows to the table %s' % table_id) - print(HttpError) + print(http_error) is_success = False return is_success From be55d61b6485770ea73a6947af43523e9b2b0b56 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 14 Feb 2019 15:07:04 -0800 Subject: [PATCH 384/814] more fields for filter --- tools/gcp/utils/big_query_utils.py | 2 +- tools/run_tests/python_utils/upload_rbe_results.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/gcp/utils/big_query_utils.py b/tools/gcp/utils/big_query_utils.py index 1f675a79e9c..168b48d1e65 100755 --- a/tools/gcp/utils/big_query_utils.py +++ b/tools/gcp/utils/big_query_utils.py @@ -178,7 +178,7 @@ def insert_rows(big_query, project_id, dataset_id, table_id, rows_list): is_success = False except HttpError as http_error: print('Error inserting rows to the table %s' % table_id) - print(http_error) + print('Error message: %s' % http_error) is_success = False return is_success diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index 0dfa487033a..3dd384efd91 100755 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -124,7 +124,7 @@ def _get_resultstore_data(api_key, invocation_id): while True: req = urllib2.Request( url= - 'https://resultstore.googleapis.com/v2/invocations/%s/targets/-/configuredTargets/-/actions?key=%s&pageToken=%s&fields=next_page_token,actions.id,actions.status_attributes' + 'https://resultstore.googleapis.com/v2/invocations/%s/targets/-/configuredTargets/-/actions?key=%s&pageToken=%s&fields=next_page_token,actions.id,actions.status_attributes,actions.timing,actions.test_action' % (invocation_id, api_key, page_token), headers={ 'Content-Type': 'application/json' From ecee06640e39b4c249a45da88a55da31a28cbe2d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 15 Feb 2019 00:17:05 +0100 Subject: [PATCH 385/814] update prepare scripts --- tools/internal_ci/helper_scripts/prepare_build_interop_rc | 1 + tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/internal_ci/helper_scripts/prepare_build_interop_rc b/tools/internal_ci/helper_scripts/prepare_build_interop_rc index fb0f4b8054e..e462a83e522 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_interop_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_interop_rc @@ -28,6 +28,7 @@ git clone --recursive https://github.com/grpc/grpc-go ./../grpc-go git clone --recursive https://github.com/grpc/grpc-java ./../grpc-java git clone --recursive https://github.com/grpc/grpc-node ./../grpc-node git clone --recursive https://github.com/grpc/grpc-dart ./../grpc-dart +git clone --recursive https://github.com/grpc/grpc-dotnet ./../grpc-dotnet # Download json file. mkdir ~/service_account diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc index 43bc9609c7e..cbc3ef2d9a9 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc +++ b/tools/internal_ci/helper_scripts/prepare_build_macos_interop_rc @@ -22,3 +22,4 @@ git clone --recursive https://github.com/grpc/grpc-go ./../grpc-go git clone --recursive https://github.com/grpc/grpc-java ./../grpc-java git clone --recursive https://github.com/grpc/grpc-node ./../grpc-node git clone --recursive https://github.com/grpc/grpc-dart ./../grpc-dart +git clone --recursive https://github.com/grpc/grpc-dotnet ./../grpc-dotnet From 4564b78b2724404252166d2921d726e6b409e06d Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 14 Feb 2019 15:29:19 -0800 Subject: [PATCH 386/814] more fields for filter --- tools/run_tests/python_utils/upload_rbe_results.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index 3dd384efd91..6eb47356bc9 100755 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -150,6 +150,7 @@ if __name__ == "__main__": bq_rows = [] for index, action in enumerate(resultstore_actions): + print(action); # Filter out non-test related data, such as build results. if 'testAction' not in action: continue From 03de98d5ef3da5697cc19e922110a497adcd48d2 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 14 Feb 2019 15:35:44 -0800 Subject: [PATCH 387/814] Revert "Add test for network transitions when CFStream is enabled" --- BUILD | 18 -- bazel/grpc_build_system.bzl | 16 +- src/core/lib/iomgr/endpoint_cfstream.cc | 4 +- test/cpp/end2end/BUILD | 32 -- test/cpp/end2end/cfstream_test.cc | 275 ------------------ tools/internal_ci/macos/grpc_cfstream.cfg | 18 -- .../internal_ci/macos/grpc_run_bazel_tests.sh | 28 -- 7 files changed, 10 insertions(+), 381 deletions(-) delete mode 100644 test/cpp/end2end/cfstream_test.cc delete mode 100644 tools/internal_ci/macos/grpc_cfstream.cfg delete mode 100644 tools/internal_ci/macos/grpc_run_bazel_tests.sh diff --git a/BUILD b/BUILD index 7986c156ed2..6c184f19941 100644 --- a/BUILD +++ b/BUILD @@ -63,21 +63,6 @@ config_setting( values = {"cpu": "x64_windows_msvc"}, ) -config_setting( - name = "mac_x86_64", - values = {"cpu": "darwin"}, -) - -COPTS = select({ - ":mac_x86_64": ["-DGRPC_CFSTREAM"], - "//conditions:default": [], -}) - -LINK_OPTS = select({ - ":mac_x86_64": ["-framework CoreFoundation"], - "//conditions:default": [], -}) - # This should be updated along with build.yaml g_stands_for = "godric" @@ -996,7 +981,6 @@ grpc_cc_library( "zlib", ], language = "c++", - copts = COPTS, public_hdrs = GRPC_PUBLIC_HDRS, deps = [ "gpr_base", @@ -1056,8 +1040,6 @@ grpc_cc_library( "src/core/lib/iomgr/iomgr_posix_cfstream.cc", "src/core/lib/iomgr/tcp_client_cfstream.cc", ], - copts = COPTS, - linkopts = LINK_OPTS, hdrs = [ "src/core/lib/iomgr/cfstream_handle.h", "src/core/lib/iomgr/endpoint_cfstream.h", diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 5d5f75073af..be85bc87324 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -73,11 +73,10 @@ def grpc_cc_library( testonly = False, visibility = None, alwayslink = 0, - data = [], - copts = [], - linkopts = []): + data = []): + copts = [] if language.upper() == "C": - copts = copts + if_not_windows(["-std=c99"]) + copts = if_not_windows(["-std=c99"]) native.cc_library( name = name, srcs = srcs, @@ -99,7 +98,7 @@ def grpc_cc_library( copts = copts, visibility = visibility, testonly = testonly, - linkopts = linkopts + if_not_windows(["-pthread"]), + linkopts = if_not_windows(["-pthread"]), includes = [ "include", ], @@ -133,9 +132,10 @@ def grpc_proto_library( generate_mocks = generate_mocks, ) -def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = None, tags = [], exec_compatible_with = [], copts = [], linkopts = []): +def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = None, tags = [], exec_compatible_with = []): + copts = [] if language.upper() == "C": - copts = copts + if_not_windows(["-std=c99"]) + copts = if_not_windows(["-std=c99"]) args = { "name": name, "srcs": srcs, @@ -143,7 +143,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data "data": data, "deps": deps + _get_external_deps(external_deps), "copts": copts, - "linkopts": linkopts + if_not_windows(["-pthread"]), + "linkopts": if_not_windows(["-pthread"]), "size": size, "timeout": timeout, "exec_compatible_with": exec_compatible_with, diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index 25146e7861c..7c4bc1ace2a 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -182,7 +182,7 @@ static void ReadAction(void* arg, grpc_error* error) { GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), ep)); EP_UNREF(ep, "read"); } else { - if (read_size < static_cast(len)) { + if (read_size < len) { grpc_slice_buffer_trim_end(ep->read_slices, len - read_size, nullptr); } CallReadCb(ep, GRPC_ERROR_NONE); @@ -217,7 +217,7 @@ static void WriteAction(void* arg, grpc_error* error) { CallWriteCb(ep, error); EP_UNREF(ep, "write"); } else { - if (write_size < static_cast(GRPC_SLICE_LENGTH(slice))) { + if (write_size < GRPC_SLICE_LENGTH(slice)) { grpc_slice_buffer_undo_take_first( ep->write_slices, grpc_slice_sub(slice, write_size, slice_len)); } diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 173142ce409..64b3eae60da 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -16,16 +16,6 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library", "grpc_cc_test", "grpc_package") -config_setting( - name = "mac_x86_64", - values = {"cpu": "darwin"}, -) - -COPTS = select({ - ":mac_x86_64": ["-DGRPC_CFSTREAM"], - "//conditions:default": [], -}) - grpc_package( name = "test/cpp/end2end", visibility = "public", @@ -635,25 +625,3 @@ grpc_cc_test( "//test/cpp/util:test_util", ], ) - -grpc_cc_test( - name = "cfstream_test", - srcs = ["cfstream_test.cc"], - external_deps = [ - "gtest", - ], - tags = ["manual"], # test requires root, won't work with bazel RBE - copts = COPTS, - deps = [ - ":test_service_impl", - "//:gpr", - "//:grpc", - "//:grpc++", - "//:grpc_cfstream", - "//src/proto/grpc/testing:echo_messages_proto", - "//src/proto/grpc/testing:echo_proto", - "//src/proto/grpc/testing:simple_messages_proto", - "//test/core/util:grpc_test_util", - "//test/cpp/util:test_util", - ], -) diff --git a/test/cpp/end2end/cfstream_test.cc b/test/cpp/end2end/cfstream_test.cc deleted file mode 100644 index 8d4cec55515..00000000000 --- a/test/cpp/end2end/cfstream_test.cc +++ /dev/null @@ -1,275 +0,0 @@ -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "src/core/lib/iomgr/port.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/gpr/env.h" - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" - -#ifdef GRPC_CFSTREAM -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; -using std::chrono::system_clock; - -namespace grpc { -namespace testing { -namespace { - -class CFStreamTest : public ::testing::Test { - protected: - CFStreamTest() - : server_host_("grpctest"), - interface_("lo0"), - ipv4_address_("10.0.0.1"), - netmask_("/32"), - kRequestMessage_("🖖") {} - - void DNSUp() { - std::ostringstream cmd; - // Add DNS entry for server_host_ in /etc/hosts - cmd << "echo '" << ipv4_address_ << " " << server_host_ - << " ' | sudo tee -a /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void DNSDown() { - std::ostringstream cmd; - // Remove DNS entry for server_host_ in /etc/hosts - cmd << "sudo sed -i '.bak' '/" << server_host_ << "/d' /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void InterfaceUp() { - std::ostringstream cmd; - cmd << "sudo /sbin/ifconfig " << interface_ << " alias " << ipv4_address_; - std::system(cmd.str().c_str()); - } - - void InterfaceDown() { - std::ostringstream cmd; - cmd << "sudo /sbin/ifconfig " << interface_ << " -alias " << ipv4_address_; - std::system(cmd.str().c_str()); - } - - void NetworkUp() { - InterfaceUp(); - DNSUp(); - } - - void NetworkDown() { - InterfaceDown(); - DNSDown(); - } - - void SetUp() override { - NetworkUp(); - grpc_init(); - StartServer(); - } - - void TearDown() override { - NetworkDown(); - StopServer(); - grpc_shutdown(); - } - - void StartServer() { - port_ = grpc_pick_unused_port_or_die(); - server_.reset(new ServerData(port_)); - server_->Start(server_host_); - } - void StopServer() { server_->Shutdown(); } - - std::unique_ptr BuildStub( - const std::shared_ptr& channel) { - return grpc::testing::EchoTestService::NewStub(channel); - } - - std::shared_ptr BuildChannel() { - std::ostringstream server_address; - server_address << server_host_ << ":" << port_; - return CreateCustomChannel( - server_address.str(), InsecureChannelCredentials(), ChannelArguments()); - } - - void SendRpc( - const std::unique_ptr& stub, - bool expect_success = false) { - auto response = std::unique_ptr(new EchoResponse()); - EchoRequest request; - request.set_message(kRequestMessage_); - ClientContext context; - Status status = stub->Echo(&context, request, response.get()); - if (status.ok()) { - gpr_log(GPR_DEBUG, "RPC returned %s\n", response->message().c_str()); - } else { - gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); - } - if (expect_success) { - EXPECT_TRUE(status.ok()); - } - } - - bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(false /* try_to_connect */)) == - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - bool WaitForChannelReady(Channel* channel, int timeout_seconds = 10) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(true /* try_to_connect */)) != - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - private: - struct ServerData { - int port_; - std::unique_ptr server_; - TestServiceImpl service_; - std::unique_ptr thread_; - bool server_ready_ = false; - - explicit ServerData(int port) { port_ = port; } - - void Start(const grpc::string& server_host) { - gpr_log(GPR_INFO, "starting server on port %d", port_); - std::mutex mu; - std::unique_lock lock(mu); - std::condition_variable cond; - thread_.reset(new std::thread( - std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); - cond.wait(lock, [this] { return server_ready_; }); - server_ready_ = false; - gpr_log(GPR_INFO, "server startup complete"); - } - - void Serve(const grpc::string& server_host, std::mutex* mu, - std::condition_variable* cond) { - std::ostringstream server_address; - server_address << server_host << ":" << port_; - ServerBuilder builder; - builder.AddListeningPort(server_address.str(), - InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - std::lock_guard lock(*mu); - server_ready_ = true; - cond->notify_one(); - } - - void Shutdown(bool join = true) { - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - if (join) thread_->join(); - } - }; - - const grpc::string server_host_; - const grpc::string interface_; - const grpc::string ipv4_address_; - const grpc::string netmask_; - std::unique_ptr stub_; - std::unique_ptr server_; - int port_; - const grpc::string kRequestMessage_; -}; - -// gRPC should automatically detech network flaps (without enabling keepalives) -// when CFStream is enabled -TEST_F(CFStreamTest, NetworkTransition) { - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - SendRpc(stub, /*expect_success=*/true); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - std::atomic_bool shutdown{false}; - std::thread sender = std::thread([this, &stub, &shutdown]() { - while (true) { - if (shutdown.load()) { - return; - } - SendRpc(stub); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - }); - - // bring down network - NetworkDown(); - - // network going down should be detected by cfstream - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - - // bring network interface back up - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - NetworkUp(); - - // channel should reconnect - EXPECT_TRUE(WaitForChannelReady(channel.get())); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - shutdown.store(true); - sender.join(); -} - -} // namespace -} // namespace testing -} // namespace grpc -#endif // GRPC_CFSTREAM - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); - gpr_setenv("grpc_cfstream", "1"); - const auto result = RUN_ALL_TESTS(); - return result; -} diff --git a/tools/internal_ci/macos/grpc_cfstream.cfg b/tools/internal_ci/macos/grpc_cfstream.cfg deleted file mode 100644 index b911bbe6c69..00000000000 --- a/tools/internal_ci/macos/grpc_cfstream.cfg +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2019 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Config file for the internal CI (in protobuf text format) - -# Location of the continuous shell script in repository. -build_file: "grpc/tools/internal_ci/macos/grpc_run_bazel_tests.sh" diff --git a/tools/internal_ci/macos/grpc_run_bazel_tests.sh b/tools/internal_ci/macos/grpc_run_bazel_tests.sh deleted file mode 100644 index 3dfa182d7c6..00000000000 --- a/tools/internal_ci/macos/grpc_run_bazel_tests.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2019 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -ex - -# change to grpc repo root -cd $(dirname $0)/../../.. - - -./tools/run_tests/start_port_server.py - -# run cfstream_test separately because it messes with the network -bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all //test/cpp/end2end:cfstream_test - -# kill port_server.py to prevent the build from hanging -ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9 From 43277f83c8f061d01fcb68b040391a653308c670 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 14 Feb 2019 16:29:08 -0800 Subject: [PATCH 388/814] filted out malformed resultstore data --- tools/run_tests/python_utils/upload_rbe_results.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index 6eb47356bc9..615313f7ea4 100755 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -188,6 +188,8 @@ if __name__ == "__main__": 'startTime': resultstore_actions[index - 1]['timing']['startTime'] } + elif 'testSuite' not in action['testAction']: + continue else: test_cases = action['testAction']['testSuite']['tests'][0][ 'testSuite']['tests'] From f5a71f73139cb74bc8703bfb89a5203a12b182ca Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Thu, 14 Feb 2019 10:18:51 -0800 Subject: [PATCH 389/814] Clean up deprecated tsi_create_ssl_server_handshaker_factory callers --- .../ssl/ssl_security_connector.cc | 45 ++++++++++++------- src/core/tsi/ssl_transport_security.h | 28 ++++++++++-- test/core/tsi/ssl_transport_security_test.cc | 13 +++--- 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index 37cb41b9637..8a00bbb82ed 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -104,7 +104,6 @@ class grpc_ssl_channel_security_connector final config->pem_key_cert_pair->private_key != nullptr && config->pem_key_cert_pair->cert_chain != nullptr; tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); GPR_DEBUG_ASSERT(pem_root_certs != nullptr); options.pem_root_certs = pem_root_certs; options.root_store = root_store; @@ -262,15 +261,22 @@ class grpc_ssl_server_security_connector size_t num_alpn_protocols = 0; const char** alpn_protocol_strings = grpc_fill_alpn_protocol_strings(&num_alpn_protocols); - const tsi_result result = tsi_create_ssl_server_handshaker_factory_ex( - server_credentials->config().pem_key_cert_pairs, - server_credentials->config().num_key_cert_pairs, - server_credentials->config().pem_root_certs, + tsi_ssl_server_handshaker_options options; + options.pem_key_cert_pairs = + server_credentials->config().pem_key_cert_pairs; + options.num_key_cert_pairs = + server_credentials->config().num_key_cert_pairs; + options.pem_client_root_certs = + server_credentials->config().pem_root_certs; + options.client_certificate_request = grpc_get_tsi_client_certificate_request_type( - server_credentials->config().client_certificate_request), - grpc_get_ssl_cipher_suites(), alpn_protocol_strings, - static_cast(num_alpn_protocols), - &server_handshaker_factory_); + server_credentials->config().client_certificate_request); + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.alpn_protocols = alpn_protocol_strings; + options.num_alpn_protocols = static_cast(num_alpn_protocols); + const tsi_result result = + tsi_create_ssl_server_handshaker_factory_with_options( + &options, &server_handshaker_factory_); gpr_free((void*)alpn_protocol_strings); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", @@ -360,19 +366,24 @@ class grpc_ssl_server_security_connector size_t num_alpn_protocols = 0; const char** alpn_protocol_strings = grpc_fill_alpn_protocol_strings(&num_alpn_protocols); - tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( - config->pem_key_cert_pairs, config->num_key_cert_pairs); tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; const grpc_ssl_server_credentials* server_creds = static_cast(this->server_creds()); GPR_DEBUG_ASSERT(config->pem_root_certs != nullptr); - tsi_result result = tsi_create_ssl_server_handshaker_factory_ex( - cert_pairs, config->num_key_cert_pairs, config->pem_root_certs, + tsi_ssl_server_handshaker_options options; + options.pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( + config->pem_key_cert_pairs, config->num_key_cert_pairs); + options.num_key_cert_pairs = config->num_key_cert_pairs; + options.pem_client_root_certs = config->pem_root_certs; + options.client_certificate_request = grpc_get_tsi_client_certificate_request_type( - server_creds->config().client_certificate_request), - grpc_get_ssl_cipher_suites(), alpn_protocol_strings, - static_cast(num_alpn_protocols), &new_handshaker_factory); - gpr_free(cert_pairs); + server_creds->config().client_certificate_request); + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.alpn_protocols = alpn_protocol_strings; + options.num_alpn_protocols = static_cast(num_alpn_protocols); + tsi_result result = tsi_create_ssl_server_handshaker_factory_with_options( + &options, &new_handshaker_factory); + gpr_free((void*)options.pem_key_cert_pairs); gpr_free((void*)alpn_protocol_strings); if (result != TSI_OK) { diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index cabf5830980..769949e4aad 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -111,7 +111,7 @@ tsi_result tsi_create_ssl_client_handshaker_factory( const char** alpn_protocols, uint16_t num_alpn_protocols, tsi_ssl_client_handshaker_factory** factory); -typedef struct { +struct tsi_ssl_client_handshaker_options { /* pem_key_cert_pair is a pointer to the object containing client's private key and certificate chain. This parameter can be NULL if the client does not have such a key/cert pair. */ @@ -140,7 +140,16 @@ typedef struct { size_t num_alpn_protocols; /* ssl_session_cache is a cache for reusable client-side sessions. */ tsi_ssl_session_cache* session_cache; -} tsi_ssl_client_handshaker_options; + + tsi_ssl_client_handshaker_options() + : pem_key_cert_pair(nullptr), + pem_root_certs(nullptr), + root_store(nullptr), + cipher_suites(nullptr), + alpn_protocols(nullptr), + num_alpn_protocols(0), + session_cache(nullptr) {} +}; /* Creates a client handshaker factory. - options is the options used to create a factory. @@ -221,7 +230,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex( const char* cipher_suites, const char** alpn_protocols, uint16_t num_alpn_protocols, tsi_ssl_server_handshaker_factory** factory); -typedef struct { +struct tsi_ssl_server_handshaker_options { /* pem_key_cert_pairs is an array private key / certificate chains of the server. */ const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs; @@ -255,7 +264,18 @@ typedef struct { const char* session_ticket_key; /* session_ticket_key_size is a size of session ticket encryption key. */ size_t session_ticket_key_size; -} tsi_ssl_server_handshaker_options; + + tsi_ssl_server_handshaker_options() + : pem_key_cert_pairs(nullptr), + num_key_cert_pairs(0), + pem_client_root_certs(nullptr), + client_certificate_request(TSI_DONT_REQUEST_CLIENT_CERTIFICATE), + cipher_suites(nullptr), + alpn_protocols(nullptr), + num_alpn_protocols(0), + session_ticket_key(nullptr), + session_ticket_key_size(0) {} +}; /* Creates a server handshaker factory. - options is the options used to create a factory. diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index 033618a2d42..5985b0ecaa5 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -107,7 +107,6 @@ static void ssl_test_setup_handshakers(tsi_test_fixture* fixture) { ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; /* Create client handshaker factory. */ tsi_ssl_client_handshaker_options client_options; - memset(&client_options, 0, sizeof(client_options)); client_options.pem_root_certs = key_cert_lib->root_cert; if (ssl_fixture->force_client_auth) { client_options.pem_key_cert_pair = @@ -131,7 +130,6 @@ static void ssl_test_setup_handshakers(tsi_test_fixture* fixture) { TSI_OK); /* Create server handshaker factory. */ tsi_ssl_server_handshaker_options server_options; - memset(&server_options, 0, sizeof(server_options)); if (alpn_lib->alpn_mode == ALPN_SERVER_NO_CLIENT || alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { @@ -681,7 +679,6 @@ void test_tsi_ssl_client_handshaker_factory_refcounting() { char* cert_chain = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "client.pem"); tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); options.pem_root_certs = cert_chain; tsi_ssl_client_handshaker_factory* client_handshaker_factory; GPR_ASSERT(tsi_create_ssl_client_handshaker_factory_with_options( @@ -726,10 +723,13 @@ void test_tsi_ssl_server_handshaker_factory_refcounting() { cert_pair.cert_chain = cert_chain; cert_pair.private_key = load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "server0.key"); + tsi_ssl_server_handshaker_options options; + options.pem_key_cert_pairs = &cert_pair; + options.num_key_cert_pairs = 1; + options.pem_client_root_certs = cert_chain; - GPR_ASSERT(tsi_create_ssl_server_handshaker_factory( - &cert_pair, 1, cert_chain, 0, nullptr, nullptr, 0, - &server_handshaker_factory) == TSI_OK); + GPR_ASSERT(tsi_create_ssl_server_handshaker_factory_with_options( + &options, &server_handshaker_factory) == TSI_OK); handshaker_factory_destructor_called = false; original_vtable = tsi_ssl_handshaker_factory_swap_vtable( @@ -763,7 +763,6 @@ void test_tsi_ssl_client_handshaker_factory_bad_params() { tsi_ssl_client_handshaker_factory* client_handshaker_factory; tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); options.pem_root_certs = cert_chain; GPR_ASSERT(tsi_create_ssl_client_handshaker_factory_with_options( &options, &client_handshaker_factory) == TSI_INVALID_ARGUMENT); From 987ac52ee2b6e17de79306defa2a05ae7ba04868 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 14 Feb 2019 17:46:41 -0800 Subject: [PATCH 390/814] formatting --- tools/run_tests/python_utils/upload_rbe_results.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index 615313f7ea4..bda567e977e 100755 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -96,10 +96,8 @@ def _upload_results_to_bq(rows): max_retries = 3 for attempt in range(max_retries): - k = big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET_ID, _TABLE_ID, - rows) - print(k) - if k: + if big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET_ID, _TABLE_ID, + rows): break else: if attempt < max_retries - 1: @@ -150,7 +148,6 @@ if __name__ == "__main__": bq_rows = [] for index, action in enumerate(resultstore_actions): - print(action); # Filter out non-test related data, such as build results. if 'testAction' not in action: continue From 508c8d805a1fe3dda77ebda27386597a7af1073c Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 14 Feb 2019 12:18:09 -0500 Subject: [PATCH 391/814] Introduce more helper methods in gprpp/atomic.h Retire the old atomic_with_atm.h and atomic_with_std.h as they are not needed anymore. Introduce helper methods which call GPR_ATM_INC_ADD_THEN and GPR_ATM_INC_CAS_THEN, and use them everywhere. Also introduce AtomicIncrementIfNonzero, originally authored by vjpai@. This is going to be used for completion queues. --- BUILD | 5 +- build.yaml | 2 - gRPC-C++.podspec | 4 -- gRPC-Core.podspec | 4 -- grpc.gemspec | 2 - package.xml | 2 - .../server_load_reporting_filter.cc | 2 +- src/core/lib/gprpp/atomic.h | 63 +++++++++++++++++-- src/core/lib/gprpp/atomic_with_atm.h | 57 ----------------- src/core/lib/gprpp/atomic_with_std.h | 35 ----------- src/core/lib/gprpp/ref_counted.h | 9 ++- src/core/lib/surface/lame_client.cc | 11 ++-- tools/doxygen/Doxyfile.c++.internal | 2 - tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 4 -- 15 files changed, 69 insertions(+), 135 deletions(-) delete mode 100644 src/core/lib/gprpp/atomic_with_atm.h delete mode 100644 src/core/lib/gprpp/atomic_with_std.h diff --git a/BUILD b/BUILD index 3f1e735466d..0618f0e6b67 100644 --- a/BUILD +++ b/BUILD @@ -613,10 +613,6 @@ grpc_cc_library( grpc_cc_library( name = "atomic", - hdrs = [ - "src/core/lib/gprpp/atomic_with_atm.h", - "src/core/lib/gprpp/atomic_with_std.h", - ], language = "c++", public_hdrs = [ "src/core/lib/gprpp/atomic.h", @@ -672,6 +668,7 @@ grpc_cc_library( language = "c++", public_hdrs = ["src/core/lib/gprpp/ref_counted.h"], deps = [ + "atomic", "debug_location", "gpr_base", "grpc_trace", diff --git a/build.yaml b/build.yaml index f9085f3ee5b..2f095a5539c 100644 --- a/build.yaml +++ b/build.yaml @@ -192,8 +192,6 @@ filegroups: - src/core/lib/gpr/useful.h - src/core/lib/gprpp/abstract.h - src/core/lib/gprpp/atomic.h - - src/core/lib/gprpp/atomic_with_atm.h - - src/core/lib/gprpp/atomic_with_std.h - src/core/lib/gprpp/fork.h - src/core/lib/gprpp/manual_constructor.h - src/core/lib/gprpp/memory.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index e1b1cf1564e..b465e28d136 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -251,8 +251,6 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/useful.h', 'src/core/lib/gprpp/abstract.h', 'src/core/lib/gprpp/atomic.h', - 'src/core/lib/gprpp/atomic_with_atm.h', - 'src/core/lib/gprpp/atomic_with_std.h', 'src/core/lib/gprpp/fork.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/memory.h', @@ -567,8 +565,6 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/useful.h', 'src/core/lib/gprpp/abstract.h', 'src/core/lib/gprpp/atomic.h', - 'src/core/lib/gprpp/atomic_with_atm.h', - 'src/core/lib/gprpp/atomic_with_std.h', 'src/core/lib/gprpp/fork.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/memory.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index da48fe7e953..719a35fd552 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -206,8 +206,6 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/useful.h', 'src/core/lib/gprpp/abstract.h', 'src/core/lib/gprpp/atomic.h', - 'src/core/lib/gprpp/atomic_with_atm.h', - 'src/core/lib/gprpp/atomic_with_std.h', 'src/core/lib/gprpp/fork.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/memory.h', @@ -876,8 +874,6 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/useful.h', 'src/core/lib/gprpp/abstract.h', 'src/core/lib/gprpp/atomic.h', - 'src/core/lib/gprpp/atomic_with_atm.h', - 'src/core/lib/gprpp/atomic_with_std.h', 'src/core/lib/gprpp/fork.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/memory.h', diff --git a/grpc.gemspec b/grpc.gemspec index 9a3c657cc85..9786a155b96 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -100,8 +100,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gpr/useful.h ) s.files += %w( src/core/lib/gprpp/abstract.h ) s.files += %w( src/core/lib/gprpp/atomic.h ) - s.files += %w( src/core/lib/gprpp/atomic_with_atm.h ) - s.files += %w( src/core/lib/gprpp/atomic_with_std.h ) s.files += %w( src/core/lib/gprpp/fork.h ) s.files += %w( src/core/lib/gprpp/manual_constructor.h ) s.files += %w( src/core/lib/gprpp/memory.h ) diff --git a/package.xml b/package.xml index 69b6fdfa671..72708e1a47b 100644 --- a/package.xml +++ b/package.xml @@ -105,8 +105,6 @@ - - diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc index 6a7231ff7db..b0420a28b5f 100644 --- a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc +++ b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc @@ -342,7 +342,7 @@ bool MaybeAddServerLoadReportingFilter(const grpc_channel_args& args) { // time if we build with the filter target. struct ServerLoadReportingFilterStaticRegistrar { ServerLoadReportingFilterStaticRegistrar() { - static std::atomic_bool registered{false}; + static grpc_core::Atomic registered{false}; if (registered) return; RegisterChannelFilter( diff --git a/src/core/lib/gprpp/atomic.h b/src/core/lib/gprpp/atomic.h index 8b08fc4e9c4..9ba4f85db89 100644 --- a/src/core/lib/gprpp/atomic.h +++ b/src/core/lib/gprpp/atomic.h @@ -21,10 +21,63 @@ #include -#ifdef GPR_HAS_CXX11_ATOMIC -#include "src/core/lib/gprpp/atomic_with_std.h" -#else -#include "src/core/lib/gprpp/atomic_with_atm.h" -#endif +#include + +namespace grpc_core { + +template +using Atomic = std::atomic; + +// Prefer the helper methods below over the same functions provided by +// std::atomic, because they maintain stats over atomic opertions which are +// useful for comparing benchmarks. + +template +bool AtomicCompareExchangeWeak(std::atomic* storage, T* expected, T desired, + std::memory_order success, + std::memory_order failure) { + return GPR_ATM_INC_CAS_THEN( + storage->compare_exchange_weak(*expected, desired, success, failure)); +} + +template +bool AtomicCompareExchangeStrong(std::atomic* storage, T* expected, + T desired, std::memory_order success, + std::memory_order failure) { + return GPR_ATM_INC_CAS_THEN( + storage->compare_exchange_weak(*expected, desired, success, failure)); +} + +template +T AtomicFetchAdd(std::atomic* storage, Arg arg, + std::memory_order order = std::memory_order_seq_cst) { + return GPR_ATM_INC_ADD_THEN(storage->fetch_add(static_cast(arg), order)); +} + +template +T AtomicFetchSub(std::atomic* storage, Arg arg, + std::memory_order order = std::memory_order_seq_cst) { + return GPR_ATM_INC_ADD_THEN(storage->fetch_sub(static_cast(arg), order)); +} + +// Atomically increment a counter only if the counter value is not zero. +// Returns true if increment took place; false if counter is zero. +template +bool AtomicIncrementIfNonzero( + std::atomic* counter, + std::memory_order load_order = std::memory_order_acquire) { + T count = counter->load(load_order); + do { + // If zero, we are done (without an increment). If not, we must do a CAS to + // maintain the contract: do not increment the counter if it is already zero + if (count == 0) { + return false; + } + } while (!AtomicCompareExchangeWeak(counter, &count, count + 1, + std::memory_order_acq_rel, load_order)); + return true; +} + +} // namespace grpc_core #endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_H */ diff --git a/src/core/lib/gprpp/atomic_with_atm.h b/src/core/lib/gprpp/atomic_with_atm.h deleted file mode 100644 index 3d0021bb1ce..00000000000 --- a/src/core/lib/gprpp/atomic_with_atm.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright 2017 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H -#define GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H - -#include - -#include - -namespace grpc_core { - -enum MemoryOrderRelaxed { memory_order_relaxed }; - -template -class atomic; - -template <> -class atomic { - public: - atomic() { gpr_atm_no_barrier_store(&x_, static_cast(false)); } - explicit atomic(bool x) { - gpr_atm_no_barrier_store(&x_, static_cast(x)); - } - - bool compare_exchange_strong(bool& expected, bool update, MemoryOrderRelaxed, - MemoryOrderRelaxed) { - if (!gpr_atm_no_barrier_cas(&x_, static_cast(expected), - static_cast(update))) { - expected = gpr_atm_no_barrier_load(&x_) != 0; - return false; - } - return true; - } - - private: - gpr_atm x_; -}; - -} // namespace grpc_core - -#endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H */ diff --git a/src/core/lib/gprpp/atomic_with_std.h b/src/core/lib/gprpp/atomic_with_std.h deleted file mode 100644 index a4ad16e5cf7..00000000000 --- a/src/core/lib/gprpp/atomic_with_std.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * - * Copyright 2017 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H -#define GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H - -#include - -#include - -namespace grpc_core { - -template -using atomic = std::atomic; - -typedef std::memory_order memory_order; - -} // namespace grpc_core - -#endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H */ diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index fa97ffcfed2..b0430b6b809 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -31,6 +31,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/abstract.h" +#include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -89,7 +90,7 @@ class RefCount { // Increases the ref-count by `n`. void Ref(Value n = 1) { - GPR_ATM_INC_ADD_THEN(value_.fetch_add(n, std::memory_order_relaxed)); + AtomicFetchAdd(&value_, n, std::memory_order_relaxed); } void Ref(const DebugLocation& location, const char* reason, Value n = 1) { #ifndef NDEBUG @@ -106,8 +107,7 @@ class RefCount { // Similar to Ref() with an assert on the ref-count being non-zero. void RefNonZero() { #ifndef NDEBUG - const Value prior = - GPR_ATM_INC_ADD_THEN(value_.fetch_add(1, std::memory_order_relaxed)); + const Value prior = AtomicFetchAdd(&value_, 1, std::memory_order_relaxed); assert(prior > 0); #else Ref(); @@ -127,8 +127,7 @@ class RefCount { // Decrements the ref-count and returns true if the ref-count reaches 0. bool Unref() { - const Value prior = - GPR_ATM_INC_ADD_THEN(value_.fetch_sub(1, std::memory_order_acq_rel)); + const Value prior = AtomicFetchSub(&value_, 1, std::memory_order_acq_rel); GPR_DEBUG_ASSERT(prior > 0); return prior == 1; } diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc index 5a84428b0ee..0ff512f07e2 100644 --- a/src/core/lib/surface/lame_client.cc +++ b/src/core/lib/surface/lame_client.cc @@ -25,10 +25,9 @@ #include #include -#include "src/core/lib/gprpp/atomic.h" - #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel.h" @@ -43,7 +42,7 @@ struct CallData { grpc_call_combiner* call_combiner; grpc_linked_mdelem status; grpc_linked_mdelem details; - grpc_core::atomic filled_metadata; + grpc_core::Atomic filled_metadata; }; struct ChannelData { @@ -54,9 +53,9 @@ struct ChannelData { static void fill_metadata(grpc_call_element* elem, grpc_metadata_batch* mdb) { CallData* calld = static_cast(elem->call_data); bool expected = false; - if (!calld->filled_metadata.compare_exchange_strong( - expected, true, grpc_core::memory_order_relaxed, - grpc_core::memory_order_relaxed)) { + if (!AtomicCompareExchangeStrong(&calld->filled_metadata, &expected, true, + std::memory_order_relaxed, + std::memory_order_relaxed)) { return; } ChannelData* chand = static_cast(elem->channel_data); diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 8aec165a339..970e5620496 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1068,8 +1068,6 @@ src/core/lib/gpr/tmpfile.h \ src/core/lib/gpr/useful.h \ src/core/lib/gprpp/abstract.h \ src/core/lib/gprpp/atomic.h \ -src/core/lib/gprpp/atomic_with_atm.h \ -src/core/lib/gprpp/atomic_with_std.h \ src/core/lib/gprpp/debug_location.h \ src/core/lib/gprpp/fork.h \ src/core/lib/gprpp/inlined_vector.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 2aced414218..1dcd21fb055 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1158,8 +1158,6 @@ src/core/lib/gpr/wrap_memcpy.cc \ src/core/lib/gprpp/README.md \ src/core/lib/gprpp/abstract.h \ src/core/lib/gprpp/atomic.h \ -src/core/lib/gprpp/atomic_with_atm.h \ -src/core/lib/gprpp/atomic_with_std.h \ src/core/lib/gprpp/debug_location.h \ src/core/lib/gprpp/fork.cc \ src/core/lib/gprpp/fork.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 506b64c19fc..57ed70458cb 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9249,8 +9249,6 @@ "src/core/lib/gpr/useful.h", "src/core/lib/gprpp/abstract.h", "src/core/lib/gprpp/atomic.h", - "src/core/lib/gprpp/atomic_with_atm.h", - "src/core/lib/gprpp/atomic_with_std.h", "src/core/lib/gprpp/fork.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/memory.h", @@ -9297,8 +9295,6 @@ "src/core/lib/gpr/useful.h", "src/core/lib/gprpp/abstract.h", "src/core/lib/gprpp/atomic.h", - "src/core/lib/gprpp/atomic_with_atm.h", - "src/core/lib/gprpp/atomic_with_std.h", "src/core/lib/gprpp/fork.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/memory.h", From fb3b85a81a022f6fb8220e2766b9dd56b8e76cbb Mon Sep 17 00:00:00 2001 From: xtao Date: Tue, 5 Feb 2019 13:33:06 +0800 Subject: [PATCH 392/814] 1) Add MACRO GPR_HAS_FEATURE; 2) Add test code within GRPC_ASAN_ENABLED for gpr_mu/cv mem-leak detection. --- include/grpc/impl/codegen/port_platform.h | 17 ++++- include/grpc/impl/codegen/sync_posix.h | 18 ++++++ src/core/lib/gpr/sync_posix.cc | 79 +++++++++++++++++++++-- 3 files changed, 108 insertions(+), 6 deletions(-) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 0da45acab57..af114de4153 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -534,6 +534,14 @@ typedef unsigned __int64 uint64_t; #endif #endif /* GPR_HAS_ATTRIBUTE */ +#ifndef GPR_HAS_FEATURE +#ifdef __has_feature +#define GPR_HAS_FEATURE(a) __has_feature(a) +#else +#define GPR_HAS_FEATURE(a) 0 +#endif +#endif /* GPR_HAS_FEATURE */ + #ifndef GPR_ATTRIBUTE_NOINLINE #if GPR_HAS_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)) #define GPR_ATTRIBUTE_NOINLINE __attribute__((noinline)) @@ -569,10 +577,15 @@ typedef unsigned __int64 uint64_t; /* GRPC_TSAN_ENABLED will be defined, when compiled with thread sanitizer. */ #if defined(__SANITIZE_THREAD__) #define GRPC_TSAN_ENABLED -#elif defined(__has_feature) -#if __has_feature(thread_sanitizer) +#elif GPR_HAS_FEATURE(thread_sanitizer) #define GRPC_TSAN_ENABLED #endif + +/* GRPC_ASAN_ENABLED will be defined, when compiled with address sanitizer. */ +#if defined(__SANITIZE_ADDRESS__) +#define GRPC_ASAN_ENABLED +#elif GPR_HAS_FEATURE(address_sanitizer) +#define GRPC_ASAN_ENABLED #endif /* GRPC_ALLOW_EXCEPTIONS should be 0 or 1 if exceptions are allowed or not */ diff --git a/include/grpc/impl/codegen/sync_posix.h b/include/grpc/impl/codegen/sync_posix.h index d927046c53e..cf95e4c6345 100644 --- a/include/grpc/impl/codegen/sync_posix.h +++ b/include/grpc/impl/codegen/sync_posix.h @@ -25,8 +25,26 @@ #include +#ifdef GRPC_ASAN_ENABLED +/* The member |leak_checker| is used to check whether there is memory leak + * that may be caused by upper layer logic which missing the |gpr_xx_destroy| + * call to this object before freeing. + * This issue was reported at https://github.com/grpc/grpc/issues/17563 + * and discussed at https://github.com/grpc/grpc/pull/17586 + */ +typedef struct { + pthread_mutex_t mutex; + int *leak_checker; +} gpr_mu; + +typedef struct { + pthread_cond_t cond_var; + int *leak_checker; +} gpr_cv; +#else typedef pthread_mutex_t gpr_mu; typedef pthread_cond_t gpr_cv; +#endif typedef pthread_once_t gpr_once; #define GPR_ONCE_INIT PTHREAD_ONCE_INIT diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index c09a7598acb..a915bbfad95 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -17,6 +17,7 @@ */ #include +#include #ifdef GPR_POSIX_SYNC @@ -72,27 +73,58 @@ gpr_atm gpr_counter_atm_add = 0; #endif void gpr_mu_init(gpr_mu* mu) { +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_mutex_init(&mu->mutex, nullptr) == 0); + mu->leak_checker = (int*)gpr_malloc(sizeof(*mu->leak_checker)); + GPR_ASSERT(mu->leak_checker != nullptr); + /* Initial it with a magic number, make no sense, just use the memory. + * This only take effect when ASAN enabled, so, + * if memory allocation failed, let it crash. + */ + *mu->leak_checker = 0x12F34D0; +#else GPR_ASSERT(pthread_mutex_init(mu, nullptr) == 0); +#endif } -void gpr_mu_destroy(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_destroy(mu) == 0); } +void gpr_mu_destroy(gpr_mu* mu) { +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_mutex_destroy(&mu->mutex) == 0); + gpr_free(mu->leak_checker); +#else + GPR_ASSERT(pthread_mutex_destroy(mu) == 0); +#endif +} void gpr_mu_lock(gpr_mu* mu) { #ifdef GPR_LOW_LEVEL_COUNTERS GPR_ATM_INC_COUNTER(gpr_mu_locks); #endif GPR_TIMER_SCOPE("gpr_mu_lock", 0); +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_mutex_lock(&mu->mutex) == 0); +#else GPR_ASSERT(pthread_mutex_lock(mu) == 0); +#endif } void gpr_mu_unlock(gpr_mu* mu) { GPR_TIMER_SCOPE("gpr_mu_unlock", 0); +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_mutex_unlock(&mu->mutex) == 0); +#else GPR_ASSERT(pthread_mutex_unlock(mu) == 0); +#endif } int gpr_mu_trylock(gpr_mu* mu) { GPR_TIMER_SCOPE("gpr_mu_trylock", 0); - int err = pthread_mutex_trylock(mu); + int err = 0; +#ifdef GRPC_ASAN_ENABLED + err = pthread_mutex_trylock(&mu->mutex); +#else + err = pthread_mutex_trylock(mu); +#endif GPR_ASSERT(err == 0 || err == EBUSY); return err == 0; } @@ -105,10 +137,29 @@ void gpr_cv_init(gpr_cv* cv) { #if GPR_LINUX GPR_ASSERT(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0); #endif // GPR_LINUX + +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_cond_init(&cv->cond_var, &attr) == 0); + cv->leak_checker = (int*)gpr_malloc(sizeof(*cv->leak_checker)); + GPR_ASSERT(cv->leak_checker != nullptr); + /* Initial it with a magic number, make no sense, just use the memory. + * This only take effect when ASAN enabled, so, + * if memory allocation failed, let it crash. + */ + *cv->leak_checker = 0x12F34D0; +#else GPR_ASSERT(pthread_cond_init(cv, &attr) == 0); +#endif } -void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); } +void gpr_cv_destroy(gpr_cv* cv) { +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_cond_destroy(&cv->cond_var) == 0); + gpr_free(cv->leak_checker); +#else + GPR_ASSERT(pthread_cond_destroy(cv) == 0); +#endif +} // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. @@ -169,7 +220,11 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { #endif if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == 0) { +#ifdef GRPC_ASAN_ENABLED + err = pthread_cond_wait(&cv->cond_var, &mu->mutex); +#else err = pthread_cond_wait(cv, mu); +#endif } else { struct timespec abs_deadline_ts; #if GPR_LINUX @@ -181,7 +236,13 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { #endif // GPR_LINUX abs_deadline_ts.tv_sec = static_cast(abs_deadline.tv_sec); abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; + +#ifdef GRPC_ASAN_ENABLED + err = pthread_cond_timedwait(&cv->cond_var, &mu->mutex, &abs_deadline_ts); +#else err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts); +#endif + #ifdef GRPC_DEBUG_TIMER_MANAGER // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. @@ -226,10 +287,20 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { return err == ETIMEDOUT; } -void gpr_cv_signal(gpr_cv* cv) { GPR_ASSERT(pthread_cond_signal(cv) == 0); } +void gpr_cv_signal(gpr_cv* cv) { +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_cond_signal(&cv->cond_var) == 0); +#else + GPR_ASSERT(pthread_cond_signal(cv) == 0); +#endif +} void gpr_cv_broadcast(gpr_cv* cv) { +#ifdef GRPC_ASAN_ENABLED + GPR_ASSERT(pthread_cond_broadcast(&cv->cond_var) == 0); +#else GPR_ASSERT(pthread_cond_broadcast(cv) == 0); +#endif } /*----------------------------------------*/ From c03496fdacda031c0c4f67e40f38dbbad632f385 Mon Sep 17 00:00:00 2001 From: xtao Date: Fri, 8 Feb 2019 22:36:19 +0800 Subject: [PATCH 393/814] 1) remove unnecessary initialization; 2) correct comment grammar issue; 3) fix the newly caught leaks; --- include/grpc/impl/codegen/sync_posix.h | 10 +++++----- src/core/ext/filters/max_age/max_age_filter.cc | 5 ++++- src/core/lib/gpr/sync_posix.cc | 12 +----------- src/core/lib/iomgr/ev_epollex_linux.cc | 1 + src/core/lib/iomgr/ev_poll_posix.cc | 4 ++++ 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/include/grpc/impl/codegen/sync_posix.h b/include/grpc/impl/codegen/sync_posix.h index cf95e4c6345..2aec3a3f8d6 100644 --- a/include/grpc/impl/codegen/sync_posix.h +++ b/include/grpc/impl/codegen/sync_posix.h @@ -26,20 +26,20 @@ #include #ifdef GRPC_ASAN_ENABLED -/* The member |leak_checker| is used to check whether there is memory leak - * that may be caused by upper layer logic which missing the |gpr_xx_destroy| - * call to this object before freeing. +/* The member |leak_checker| is used to check whether there is a memory leak + * caused by upper layer logic that's missing the |gpr_xx_destroy| call + * to the object before freeing it. * This issue was reported at https://github.com/grpc/grpc/issues/17563 * and discussed at https://github.com/grpc/grpc/pull/17586 */ typedef struct { pthread_mutex_t mutex; - int *leak_checker; + int* leak_checker; } gpr_mu; typedef struct { pthread_cond_t cond_var; - int *leak_checker; + int* leak_checker; } gpr_cv; #else typedef pthread_mutex_t gpr_mu; diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc index ec7f4e254aa..f2308581c13 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -499,7 +499,10 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, } /* Destructor for channel_data. */ -static void destroy_channel_elem(grpc_channel_element* elem) {} +static void destroy_channel_elem(grpc_channel_element* elem) { + channel_data* chand = static_cast(elem->channel_data); + gpr_mu_destroy(&chand->max_age_timer_mu); +} const grpc_channel_filter grpc_max_age_filter = { grpc_call_next_op, diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index a915bbfad95..52745dbff0a 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -16,8 +16,8 @@ * */ -#include #include +#include #ifdef GPR_POSIX_SYNC @@ -77,11 +77,6 @@ void gpr_mu_init(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_init(&mu->mutex, nullptr) == 0); mu->leak_checker = (int*)gpr_malloc(sizeof(*mu->leak_checker)); GPR_ASSERT(mu->leak_checker != nullptr); - /* Initial it with a magic number, make no sense, just use the memory. - * This only take effect when ASAN enabled, so, - * if memory allocation failed, let it crash. - */ - *mu->leak_checker = 0x12F34D0; #else GPR_ASSERT(pthread_mutex_init(mu, nullptr) == 0); #endif @@ -142,11 +137,6 @@ void gpr_cv_init(gpr_cv* cv) { GPR_ASSERT(pthread_cond_init(&cv->cond_var, &attr) == 0); cv->leak_checker = (int*)gpr_malloc(sizeof(*cv->leak_checker)); GPR_ASSERT(cv->leak_checker != nullptr); - /* Initial it with a magic number, make no sense, just use the memory. - * This only take effect when ASAN enabled, so, - * if memory allocation failed, let it crash. - */ - *cv->leak_checker = 0x12F34D0; #else GPR_ASSERT(pthread_cond_init(cv, &attr) == 0); #endif diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 0e66bc56440..27656063ba5 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -612,6 +612,7 @@ static void pollable_unref(pollable* p, int line, const char* reason) { close(p->epfd); grpc_wakeup_fd_destroy(&p->wakeup); gpr_mu_destroy(&p->owner_orphan_mu); + gpr_mu_destroy(&p->mu); gpr_free(p); } } diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index c479206410b..9350ef5a2af 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -1535,6 +1535,9 @@ static void cache_harvest_locked() { gpr_inf_future(GPR_CLOCK_MONOTONIC)); } args->poller_thd.Join(); + gpr_cv_destroy(&args->trigger); + gpr_cv_destroy(&args->harvest); + gpr_cv_destroy(&args->join); gpr_free(args); } } @@ -1713,6 +1716,7 @@ static int cvfd_poll(struct pollfd* fds, nfds_t nfds, int timeout) { } gpr_free(fd_cvs); + gpr_cv_destroy(pollcv->cv); gpr_free(pollcv); if (result) { decref_poll_result(result); From 902820a5de91f65cae85d6a559c8f98e0c36002a Mon Sep 17 00:00:00 2001 From: xtao Date: Sat, 9 Feb 2019 14:19:22 +0800 Subject: [PATCH 394/814] 1) fix the asan tests caught leaks; 2) fix the tsan tests caught data races; --- src/core/ext/transport/inproc/inproc_transport.cc | 4 ++++ src/core/lib/gpr/sync_posix.cc | 3 ++- test/core/util/mock_endpoint.cc | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 0b9bf5dd11b..ac5441fd39d 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -64,6 +64,10 @@ struct shared_mu { gpr_ref_init(&refs, 2); } + ~shared_mu() { + gpr_mu_destroy(&mu); + } + gpr_mu mu; gpr_refcount refs; }; diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 52745dbff0a..d4a295fe778 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -16,9 +16,10 @@ * */ -#include #include +#include + #ifdef GPR_POSIX_SYNC #include diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc index e5867cd526b..df2ee7aedfd 100644 --- a/test/core/util/mock_endpoint.cc +++ b/test/core/util/mock_endpoint.cc @@ -89,6 +89,7 @@ static void me_destroy(grpc_endpoint* ep) { mock_endpoint* m = reinterpret_cast(ep); grpc_slice_buffer_destroy(&m->read_buffer); grpc_resource_user_unref(m->resource_user); + gpr_mu_destroy(&m->mu); gpr_free(m); } From 7766912dda5b2ce1d6a13f2acc7762fd21104b10 Mon Sep 17 00:00:00 2001 From: xtao Date: Tue, 12 Feb 2019 16:52:02 +0800 Subject: [PATCH 395/814] fix more detected mu/cv leaks --- src/core/ext/transport/inproc/inproc_transport.cc | 5 ++--- test/core/end2end/inproc_callback_test.cc | 5 ++++- test/core/gpr/cpu_test.cc | 2 ++ test/core/gpr/mpscq_test.cc | 1 + test/core/gprpp/thd_test.cc | 2 ++ test/cpp/microbenchmarks/bm_closure.cc | 2 ++ test/cpp/util/grpc_tool.cc | 1 + 7 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index ac5441fd39d..b0f93eb63f4 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -64,9 +64,7 @@ struct shared_mu { gpr_ref_init(&refs, 2); } - ~shared_mu() { - gpr_mu_destroy(&mu); - } + ~shared_mu() { gpr_mu_destroy(&mu); } gpr_mu mu; gpr_refcount refs; @@ -87,6 +85,7 @@ struct inproc_transport { ~inproc_transport() { grpc_connectivity_state_destroy(&connectivity); if (gpr_unref(&mu->refs)) { + mu->~shared_mu(); gpr_free(mu); } } diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc index 72ad992d54c..550c2c2d69a 100644 --- a/test/core/end2end/inproc_callback_test.cc +++ b/test/core/end2end/inproc_callback_test.cc @@ -65,7 +65,10 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { gpr_mu_init(&mu_); gpr_cv_init(&cv_); } - ~ShutdownCallback() {} + ~ShutdownCallback() { + gpr_mu_destroy(&mu_); + gpr_cv_destroy(&cv_); + } static void StaticRun(grpc_experimental_completion_queue_functor* cb, int ok) { auto* callback = static_cast(cb); diff --git a/test/core/gpr/cpu_test.cc b/test/core/gpr/cpu_test.cc index dbaeb08c183..316a4c61bef 100644 --- a/test/core/gpr/cpu_test.cc +++ b/test/core/gpr/cpu_test.cc @@ -140,6 +140,8 @@ static void cpu_test(void) { } fprintf(stderr, "] (%d/%d)\n", cores_seen, ct.ncores); fflush(stderr); + gpr_mu_destroy(&ct.mu); + gpr_cv_destroy(&ct.done_cv); gpr_free(ct.used); } diff --git a/test/core/gpr/mpscq_test.cc b/test/core/gpr/mpscq_test.cc index c826ccb498b..744cea934c5 100644 --- a/test/core/gpr/mpscq_test.cc +++ b/test/core/gpr/mpscq_test.cc @@ -178,6 +178,7 @@ static void test_mt_multipop(void) { for (auto& th : thds) { th.Join(); } + gpr_mu_destroy(&pa.mu); gpr_mpscq_destroy(&q); } diff --git a/test/core/gprpp/thd_test.cc b/test/core/gprpp/thd_test.cc index 06aa58984b0..eda78d95323 100644 --- a/test/core/gprpp/thd_test.cc +++ b/test/core/gprpp/thd_test.cc @@ -71,6 +71,8 @@ static void test1(void) { th.Join(); } GPR_ASSERT(t.n == 0); + gpr_mu_destroy(&t.mu); + gpr_cv_destroy(&t.done_cv); } static void thd_body2(void* v) {} diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc index 74ca1ce3a49..e1f1e92d4d8 100644 --- a/test/cpp/microbenchmarks/bm_closure.cc +++ b/test/cpp/microbenchmarks/bm_closure.cc @@ -183,6 +183,7 @@ static void BM_AcquireMutex(benchmark::State& state) { DoNothing(nullptr, GRPC_ERROR_NONE); gpr_mu_unlock(&mu); } + gpr_mu_destroy(&mu); track_counters.Finish(state); } @@ -202,6 +203,7 @@ static void BM_TryAcquireMutex(benchmark::State& state) { abort(); } } + gpr_mu_destroy(&mu); track_counters.Finish(state); } diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index 80eaf4f7279..44b14bf617f 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -590,6 +590,7 @@ bool GrpcTool::CallMethod(int argc, const char** argv, call.WritesDoneAndWait(); read_thread.join(); + gpr_mu_destroy(&parser_mu); std::multimap server_trailing_metadata; Status status = call.Finish(&server_trailing_metadata); From 7cbb42bb9ec05a0122dcae70b03aac381293f9e6 Mon Sep 17 00:00:00 2001 From: xtao Date: Thu, 14 Feb 2019 10:20:11 +0800 Subject: [PATCH 396/814] define GPR_ATTRIBUTE_NO_TSAN by using GPR_HAS_FEATURE. --- include/grpc/impl/codegen/port_platform.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index af114de4153..a6bbe66e248 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -564,11 +564,9 @@ typedef unsigned __int64 uint64_t; #endif /* GPR_ATTRIBUTE_WEAK */ #ifndef GPR_ATTRIBUTE_NO_TSAN /* (1) */ -#if defined(__has_feature) -#if __has_feature(thread_sanitizer) +#if GPR_HAS_FEATURE(thread_sanitizer) #define GPR_ATTRIBUTE_NO_TSAN __attribute__((no_sanitize("thread"))) -#endif /* __has_feature(thread_sanitizer) */ -#endif /* defined(__has_feature) */ +#endif /* GPR_HAS_FEATURE */ #ifndef GPR_ATTRIBUTE_NO_TSAN /* (2) */ #define GPR_ATTRIBUTE_NO_TSAN #endif /* GPR_ATTRIBUTE_NO_TSAN (2) */ From 7260eb62ffd2e315f5364767511b14024863d24f Mon Sep 17 00:00:00 2001 From: xtao Date: Fri, 15 Feb 2019 23:41:02 +0800 Subject: [PATCH 397/814] use static_cast to convert type instead of explicit type casting. --- src/core/lib/gpr/sync_posix.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index d4a295fe778..3c49d78f9c1 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -76,7 +76,7 @@ gpr_atm gpr_counter_atm_add = 0; void gpr_mu_init(gpr_mu* mu) { #ifdef GRPC_ASAN_ENABLED GPR_ASSERT(pthread_mutex_init(&mu->mutex, nullptr) == 0); - mu->leak_checker = (int*)gpr_malloc(sizeof(*mu->leak_checker)); + mu->leak_checker = static_cast(gpr_malloc(sizeof(*mu->leak_checker))); GPR_ASSERT(mu->leak_checker != nullptr); #else GPR_ASSERT(pthread_mutex_init(mu, nullptr) == 0); @@ -136,7 +136,7 @@ void gpr_cv_init(gpr_cv* cv) { #ifdef GRPC_ASAN_ENABLED GPR_ASSERT(pthread_cond_init(&cv->cond_var, &attr) == 0); - cv->leak_checker = (int*)gpr_malloc(sizeof(*cv->leak_checker)); + cv->leak_checker = static_cast(gpr_malloc(sizeof(*cv->leak_checker))); GPR_ASSERT(cv->leak_checker != nullptr); #else GPR_ASSERT(pthread_cond_init(cv, &attr) == 0); @@ -227,7 +227,6 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { #endif // GPR_LINUX abs_deadline_ts.tv_sec = static_cast(abs_deadline.tv_sec); abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; - #ifdef GRPC_ASAN_ENABLED err = pthread_cond_timedwait(&cv->cond_var, &mu->mutex, &abs_deadline_ts); #else From 8ba48b42cec19ab450db8ae95e0fd34fd29c6dfd Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 15 Feb 2019 16:10:43 +0100 Subject: [PATCH 398/814] dummy grpc_csharp_ext stubs should never be reached --- .../runtimes/grpc_csharp_ext_dummy_stubs.c | 478 ++++++++++++++---- .../grpc_csharp_ext_dummy_stubs.c.template | 8 +- 2 files changed, 390 insertions(+), 96 deletions(-) diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c index f7e622ab5f1..200dd022bf8 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c @@ -19,98 +19,386 @@ // make il2cpp happy. // See https://github.com/grpc/grpc/issues/16012 -void grpcsharp_init() {} -void grpcsharp_shutdown() {} -void grpcsharp_version_string() {} -void grpcsharp_batch_context_create() {} -void grpcsharp_batch_context_recv_initial_metadata() {} -void grpcsharp_batch_context_recv_message_length() {} -void grpcsharp_batch_context_recv_message_to_buffer() {} -void grpcsharp_batch_context_recv_status_on_client_status() {} -void grpcsharp_batch_context_recv_status_on_client_details() {} -void grpcsharp_batch_context_recv_status_on_client_trailing_metadata() {} -void grpcsharp_batch_context_recv_close_on_server_cancelled() {} -void grpcsharp_batch_context_reset() {} -void grpcsharp_batch_context_destroy() {} -void grpcsharp_request_call_context_create() {} -void grpcsharp_request_call_context_call() {} -void grpcsharp_request_call_context_method() {} -void grpcsharp_request_call_context_host() {} -void grpcsharp_request_call_context_deadline() {} -void grpcsharp_request_call_context_request_metadata() {} -void grpcsharp_request_call_context_reset() {} -void grpcsharp_request_call_context_destroy() {} -void grpcsharp_composite_call_credentials_create() {} -void grpcsharp_call_credentials_release() {} -void grpcsharp_call_cancel() {} -void grpcsharp_call_cancel_with_status() {} -void grpcsharp_call_start_unary() {} -void grpcsharp_call_start_client_streaming() {} -void grpcsharp_call_start_server_streaming() {} -void grpcsharp_call_start_duplex_streaming() {} -void grpcsharp_call_send_message() {} -void grpcsharp_call_send_close_from_client() {} -void grpcsharp_call_send_status_from_server() {} -void grpcsharp_call_recv_message() {} -void grpcsharp_call_recv_initial_metadata() {} -void grpcsharp_call_start_serverside() {} -void grpcsharp_call_send_initial_metadata() {} -void grpcsharp_call_set_credentials() {} -void grpcsharp_call_get_peer() {} -void grpcsharp_call_destroy() {} -void grpcsharp_channel_args_create() {} -void grpcsharp_channel_args_set_string() {} -void grpcsharp_channel_args_set_integer() {} -void grpcsharp_channel_args_destroy() {} -void grpcsharp_override_default_ssl_roots() {} -void grpcsharp_ssl_credentials_create() {} -void grpcsharp_composite_channel_credentials_create() {} -void grpcsharp_channel_credentials_release() {} -void grpcsharp_insecure_channel_create() {} -void grpcsharp_secure_channel_create() {} -void grpcsharp_channel_create_call() {} -void grpcsharp_channel_check_connectivity_state() {} -void grpcsharp_channel_watch_connectivity_state() {} -void grpcsharp_channel_get_target() {} -void grpcsharp_channel_destroy() {} -void grpcsharp_sizeof_grpc_event() {} -void grpcsharp_completion_queue_create_async() {} -void grpcsharp_completion_queue_create_sync() {} -void grpcsharp_completion_queue_shutdown() {} -void grpcsharp_completion_queue_next() {} -void grpcsharp_completion_queue_pluck() {} -void grpcsharp_completion_queue_destroy() {} -void gprsharp_free() {} -void grpcsharp_metadata_array_create() {} -void grpcsharp_metadata_array_add() {} -void grpcsharp_metadata_array_count() {} -void grpcsharp_metadata_array_get_key() {} -void grpcsharp_metadata_array_get_value() {} -void grpcsharp_metadata_array_destroy_full() {} -void grpcsharp_redirect_log() {} -void grpcsharp_metadata_credentials_create_from_plugin() {} -void grpcsharp_metadata_credentials_notify_from_plugin() {} -void grpcsharp_ssl_server_credentials_create() {} -void grpcsharp_server_credentials_release() {} -void grpcsharp_server_create() {} -void grpcsharp_server_register_completion_queue() {} -void grpcsharp_server_add_insecure_http2_port() {} -void grpcsharp_server_add_secure_http2_port() {} -void grpcsharp_server_start() {} -void grpcsharp_server_request_call() {} -void grpcsharp_server_cancel_all_calls() {} -void grpcsharp_server_shutdown_and_notify_callback() {} -void grpcsharp_server_destroy() {} -void grpcsharp_call_auth_context() {} -void grpcsharp_auth_context_peer_identity_property_name() {} -void grpcsharp_auth_context_property_iterator() {} -void grpcsharp_auth_property_iterator_next() {} -void grpcsharp_auth_context_release() {} -void gprsharp_now() {} -void gprsharp_inf_future() {} -void gprsharp_inf_past() {} -void gprsharp_convert_clock_type() {} -void gprsharp_sizeof_timespec() {} -void grpcsharp_test_callback() {} -void grpcsharp_test_nop() {} -void grpcsharp_test_override_method() {} +#include +#include + +void grpcsharp_init() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_shutdown() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_version_string() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_initial_metadata() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_message_length() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_message_to_buffer() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_status_on_client_status() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_status_on_client_details() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_status_on_client_trailing_metadata() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_recv_close_on_server_cancelled() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_reset() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_batch_context_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_call() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_method() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_host() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_deadline() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_request_metadata() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_reset() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_request_call_context_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_composite_call_credentials_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_credentials_release() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_cancel() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_cancel_with_status() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_start_unary() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_start_client_streaming() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_start_server_streaming() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_start_duplex_streaming() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_send_message() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_send_close_from_client() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_send_status_from_server() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_recv_message() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_recv_initial_metadata() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_start_serverside() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_send_initial_metadata() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_set_credentials() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_get_peer() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_args_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_args_set_string() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_args_set_integer() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_args_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_override_default_ssl_roots() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_ssl_credentials_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_composite_channel_credentials_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_credentials_release() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_insecure_channel_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_secure_channel_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_create_call() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_check_connectivity_state() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_watch_connectivity_state() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_get_target() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_channel_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_sizeof_grpc_event() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_create_async() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_create_sync() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_shutdown() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_next() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_pluck() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_completion_queue_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_free() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_add() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_count() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_get_key() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_get_value() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_array_destroy_full() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_redirect_log() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_credentials_create_from_plugin() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_metadata_credentials_notify_from_plugin() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_ssl_server_credentials_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_credentials_release() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_create() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_register_completion_queue() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_add_insecure_http2_port() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_add_secure_http2_port() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_start() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_request_call() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_cancel_all_calls() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_shutdown_and_notify_callback() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_server_destroy() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_call_auth_context() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_auth_context_peer_identity_property_name() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_auth_context_property_iterator() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_auth_property_iterator_next() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_auth_context_release() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_now() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_inf_future() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_inf_past() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_convert_clock_type() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void gprsharp_sizeof_timespec() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_test_callback() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_test_nop() { + fprintf(stderr, "Should never reach here"); + abort(); +} +void grpcsharp_test_override_method() { + fprintf(stderr, "Should never reach here"); + abort(); +} diff --git a/templates/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.template b/templates/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.template index 318113d18a7..a38ae2bf4ed 100644 --- a/templates/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.template +++ b/templates/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c.template @@ -21,6 +21,12 @@ // make il2cpp happy. // See https://github.com/grpc/grpc/issues/16012 + #include + #include + % for method in get_native_methods(): - void ${method['name']}() {} + void ${method['name']}() { + fprintf(stderr, "Should never reach here"); + abort(); + } % endfor From 0d7a0ded1cc93bb7f4d69a156b0a69829557cbf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20He=C3=9F?= Date: Thu, 13 Jul 2017 13:43:03 +0200 Subject: [PATCH 399/814] when cross-compiling, the host grpc_cpp_plugin should be used --- CMakeLists.txt | 9 ++++++++- templates/CMakeLists.txt.template | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41f6ad0ee6d..6f9d9607b16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,6 +190,13 @@ function(protobuf_generate_grpc_cpp) get_filename_component(REL_DIR ${REL_FIL} DIRECTORY) set(RELFIL_WE "${REL_DIR}/${FIL_WE}") + #if cross-compiling, find host plugin + if(CMAKE_CROSSCOMPILING) + find_program(gRPC_CPP_PLUGIN grpc_cpp_plugin) + else() + set(gRPC_CPP_PLUGIN $) + endif() + add_custom_command( OUTPUT "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" "${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" @@ -199,7 +206,7 @@ function(protobuf_generate_grpc_cpp) COMMAND ${_gRPC_PROTOBUF_PROTOC_EXECUTABLE} ARGS --grpc_out=generate_mock_code=true:${_gRPC_PROTO_GENS_DIR} --cpp_out=${_gRPC_PROTO_GENS_DIR} - --plugin=protoc-gen-grpc=$ + --plugin=protoc-gen-grpc=${gRPC_CPP_PLUGIN} ${_protobuf_include_path} ${REL_FIL} DEPENDS ${ABS_FIL} ${_gRPC_PROTOBUF_PROTOC} grpc_cpp_plugin diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index f33d980cd00..98600285ee9 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -239,6 +239,13 @@ get_filename_component(REL_DIR <%text>${REL_FIL} DIRECTORY) set(RELFIL_WE "<%text>${REL_DIR}/${FIL_WE}") + #if cross-compiling, find host plugin + if(CMAKE_CROSSCOMPILING) + find_program(gRPC_CPP_PLUGIN grpc_cpp_plugin) + else() + set(gRPC_CPP_PLUGIN $) + endif() + add_custom_command( OUTPUT <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc" <%text>"${_gRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h" @@ -248,7 +255,7 @@ COMMAND <%text>${_gRPC_PROTOBUF_PROTOC_EXECUTABLE} ARGS --grpc_out=<%text>generate_mock_code=true:${_gRPC_PROTO_GENS_DIR} --cpp_out=<%text>${_gRPC_PROTO_GENS_DIR} - --plugin=protoc-gen-grpc=$ + --plugin=protoc-gen-grpc=<%text>${gRPC_CPP_PLUGIN} <%text>${_protobuf_include_path} <%text>${REL_FIL} DEPENDS <%text>${ABS_FIL} <%text>${_gRPC_PROTOBUF_PROTOC} grpc_cpp_plugin From 0e4c18484562e043f81fb94b1b5a5fb296260977 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 15 Feb 2019 17:51:52 +0100 Subject: [PATCH 400/814] use internal variable --- CMakeLists.txt | 6 +++--- templates/CMakeLists.txt.template | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f9d9607b16..8d76be8e65c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -192,9 +192,9 @@ function(protobuf_generate_grpc_cpp) #if cross-compiling, find host plugin if(CMAKE_CROSSCOMPILING) - find_program(gRPC_CPP_PLUGIN grpc_cpp_plugin) + find_program(_gRPC_CPP_PLUGIN grpc_cpp_plugin) else() - set(gRPC_CPP_PLUGIN $) + set(_gRPC_CPP_PLUGIN $) endif() add_custom_command( @@ -206,7 +206,7 @@ function(protobuf_generate_grpc_cpp) COMMAND ${_gRPC_PROTOBUF_PROTOC_EXECUTABLE} ARGS --grpc_out=generate_mock_code=true:${_gRPC_PROTO_GENS_DIR} --cpp_out=${_gRPC_PROTO_GENS_DIR} - --plugin=protoc-gen-grpc=${gRPC_CPP_PLUGIN} + --plugin=protoc-gen-grpc=${_gRPC_CPP_PLUGIN} ${_protobuf_include_path} ${REL_FIL} DEPENDS ${ABS_FIL} ${_gRPC_PROTOBUF_PROTOC} grpc_cpp_plugin diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 98600285ee9..e7fdfe5de55 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -241,9 +241,9 @@ #if cross-compiling, find host plugin if(CMAKE_CROSSCOMPILING) - find_program(gRPC_CPP_PLUGIN grpc_cpp_plugin) + find_program(_gRPC_CPP_PLUGIN grpc_cpp_plugin) else() - set(gRPC_CPP_PLUGIN $) + set(_gRPC_CPP_PLUGIN $) endif() add_custom_command( @@ -255,7 +255,7 @@ COMMAND <%text>${_gRPC_PROTOBUF_PROTOC_EXECUTABLE} ARGS --grpc_out=<%text>generate_mock_code=true:${_gRPC_PROTO_GENS_DIR} --cpp_out=<%text>${_gRPC_PROTO_GENS_DIR} - --plugin=protoc-gen-grpc=<%text>${gRPC_CPP_PLUGIN} + --plugin=protoc-gen-grpc=<%text>${_gRPC_CPP_PLUGIN} <%text>${_protobuf_include_path} <%text>${REL_FIL} DEPENDS <%text>${ABS_FIL} <%text>${_gRPC_PROTOBUF_PROTOC} grpc_cpp_plugin From 2ea6d3ef0b1b8fe6085c34de68ec10eb5bbf1d32 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 29 Aug 2018 22:20:21 -0700 Subject: [PATCH 401/814] Add fork tests as Python unit tests --- src/python/grpcio/grpc/_channel.py | 3 +- .../grpc/_cython/_cygrpc/fork_posix.pyx.pxi | 44 +++-- src/python/grpcio_tests/commands.py | 2 + .../tests/fork/_fork_interop_test.py | 152 ++++++++++++++++++ src/python/grpcio_tests/tests/fork/client.py | 6 +- src/python/grpcio_tests/tests/fork/methods.py | 98 ++++++----- src/python/grpcio_tests/tests/tests.json | 1 + 7 files changed, 241 insertions(+), 65 deletions(-) create mode 100644 src/python/grpcio_tests/tests/fork/_fork_interop_test.py diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index df06ffaeb3b..1d2495cdd21 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -1033,6 +1033,7 @@ class Channel(grpc.Channel): def _close(self): self._channel.close(cygrpc.StatusCode.cancelled, 'Channel closed!') + cygrpc.fork_unregister_channel(self) _moot(self._connectivity_state) def _close_on_fork(self): @@ -1060,8 +1061,6 @@ class Channel(grpc.Channel): # for as long as they are in use and to close them after using them, # then deletion of this grpc._channel.Channel instance can be made to # effect closure of the underlying cygrpc.Channel instance. - if cygrpc is not None: # Globals may have already been collected. - cygrpc.fork_unregister_channel(self) # This prevent the failed-at-initializing object removal from failing. # Though the __init__ failed, the removal will still trigger __del__. if _moot is not None and hasattr(self, '_connectivity_state'): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi index 433ae1f374f..6dbd6a985e3 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. - import logging import os import threading @@ -37,8 +36,12 @@ _GRPC_ENABLE_FORK_SUPPORT = ( os.environ.get('GRPC_ENABLE_FORK_SUPPORT', '0') .lower() in _TRUE_VALUES) +_fork_handler_failed = False + cdef void __prefork() nogil: with gil: + global _fork_handler_failed + _fork_handler_failed = False with _fork_state.fork_in_progress_condition: _fork_state.fork_in_progress = True if not _fork_state.active_thread_count.await_zero_threads( @@ -46,6 +49,7 @@ cdef void __prefork() nogil: _LOGGER.error( 'Failed to shutdown gRPC Python threads prior to fork. ' 'Behavior after fork will be undefined.') + _fork_handler_failed = True cdef void __postfork_parent() nogil: @@ -57,20 +61,28 @@ cdef void __postfork_parent() nogil: cdef void __postfork_child() nogil: with gil: - # Thread could be holding the fork_in_progress_condition inside of - # block_if_fork_in_progress() when fork occurs. Reset the lock here. - _fork_state.fork_in_progress_condition = threading.Condition() - # A thread in return_from_user_request_generator() may hold this lock - # when fork occurs. - _fork_state.active_thread_count = _ActiveThreadCount() - for state_to_reset in _fork_state.postfork_states_to_reset: - state_to_reset.reset_postfork_child() - _fork_state.fork_epoch += 1 - for channel in _fork_state.channels: - channel._close_on_fork() - # TODO(ericgribkoff) Check and abort if core is not shutdown - with _fork_state.fork_in_progress_condition: - _fork_state.fork_in_progress = False + try: + if _fork_handler_failed: + return + # Thread could be holding the fork_in_progress_condition inside of + # block_if_fork_in_progress() when fork occurs. Reset the lock here. + _fork_state.fork_in_progress_condition = threading.Condition() + # A thread in return_from_user_request_generator() may hold this lock + # when fork occurs. + _fork_state.active_thread_count = _ActiveThreadCount() + for state_to_reset in _fork_state.postfork_states_to_reset: + state_to_reset.reset_postfork_child() + _fork_state.postfork_states_to_reset = [] + _fork_state.fork_epoch += 1 + for channel in _fork_state.channels: + channel._close_on_fork() + with _fork_state.fork_in_progress_condition: + _fork_state.fork_in_progress = False + except: + _LOGGER.error('Exiting child due to raised exception') + _LOGGER.error(sys.exc_info()[0]) + os._exit(os.EX_USAGE) + if grpc_is_initialized() > 0: with gil: _LOGGER.error('Failed to shutdown gRPC Core after fork()') @@ -148,7 +160,7 @@ def fork_register_channel(channel): def fork_unregister_channel(channel): if _GRPC_ENABLE_FORK_SUPPORT: - _fork_state.channels.remove(channel) + _fork_state.channels.discard(channel) class _ActiveThreadCount(object): diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 582ce898dee..866fb6de1f7 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -111,6 +111,8 @@ class TestGevent(setuptools.Command): """Command to run tests w/gevent.""" BANNED_TESTS = ( + # Fork support is not compatible with gevent + 'fork._fork_interop_test.ForkInteropTest', # These tests send a lot of RPCs and are really slow on gevent. They will # eventually succeed, but need to dig into performance issues. 'unit._cython._no_messages_server_completion_queue_per_call_test.Test.test_rpcs', diff --git a/src/python/grpcio_tests/tests/fork/_fork_interop_test.py b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py new file mode 100644 index 00000000000..bbcfb7446a9 --- /dev/null +++ b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py @@ -0,0 +1,152 @@ +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Client-side fork interop tests as a unit test.""" + +import six +import subprocess +import sys +import threading +import unittest +from grpc._cython import cygrpc +from tests.fork import methods + +# New instance of multiprocessing.Process using fork without exec can and will +# hang if the Python process has any other threads running. This includes the +# additional thread spawned by our _runner.py class. So in order to test our +# compatibility with multiprocessing, we first fork+exec a new process to ensure +# we don't have any conflicting background threads. +_CLIENT_FORK_SCRIPT_TEMPLATE = """if True: + import os + import sys + from grpc._cython import cygrpc + from tests.fork import methods + + cygrpc._GRPC_ENABLE_FORK_SUPPORT = True + os.environ['GRPC_POLL_STRATEGY'] = 'epoll1' + methods.TestCase.%s.run_test({ + 'server_host': 'localhost', + 'server_port': %d, + 'use_tls': False + }) +""" +_SUBPROCESS_TIMEOUT_S = 30 + + +@unittest.skipUnless( + sys.platform.startswith("linux"), + "not supported on windows, and fork+exec networking blocked on mac") +@unittest.skipUnless(six.PY2, "https://github.com/grpc/grpc/issues/18075") +class ForkInteropTest(unittest.TestCase): + + def setUp(self): + start_server_script = """if True: + import sys + import time + + import grpc + from src.proto.grpc.testing import test_pb2_grpc + from tests.interop import methods as interop_methods + from tests.unit import test_common + + server = test_common.test_server() + test_pb2_grpc.add_TestServiceServicer_to_server( + interop_methods.TestService(), server) + port = server.add_insecure_port('[::]:0') + server.start() + print(port) + sys.stdout.flush() + while True: + time.sleep(1) + """ + self._server_process = subprocess.Popen( + [sys.executable, '-c', start_server_script], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + timer = threading.Timer(_SUBPROCESS_TIMEOUT_S, + self._server_process.kill) + try: + timer.start() + self._port = int(self._server_process.stdout.readline()) + except ValueError: + raise Exception('Failed to get port from server') + finally: + timer.cancel() + + def testConnectivityWatch(self): + self._verifyTestCase(methods.TestCase.CONNECTIVITY_WATCH) + + def testCloseChannelBeforeFork(self): + self._verifyTestCase(methods.TestCase.CLOSE_CHANNEL_BEFORE_FORK) + + def testAsyncUnarySameChannel(self): + self._verifyTestCase(methods.TestCase.ASYNC_UNARY_SAME_CHANNEL) + + def testAsyncUnaryNewChannel(self): + self._verifyTestCase(methods.TestCase.ASYNC_UNARY_NEW_CHANNEL) + + def testBlockingUnarySameChannel(self): + self._verifyTestCase(methods.TestCase.BLOCKING_UNARY_SAME_CHANNEL) + + def testBlockingUnaryNewChannel(self): + self._verifyTestCase(methods.TestCase.BLOCKING_UNARY_NEW_CHANNEL) + + def testInProgressBidiContinueCall(self): + self._verifyTestCase(methods.TestCase.IN_PROGRESS_BIDI_CONTINUE_CALL) + + def testInProgressBidiSameChannelAsyncCall(self): + self._verifyTestCase( + methods.TestCase.IN_PROGRESS_BIDI_SAME_CHANNEL_ASYNC_CALL) + + def testInProgressBidiSameChannelBlockingCall(self): + self._verifyTestCase( + methods.TestCase.IN_PROGRESS_BIDI_SAME_CHANNEL_BLOCKING_CALL) + + def testInProgressBidiNewChannelAsyncCall(self): + self._verifyTestCase( + methods.TestCase.IN_PROGRESS_BIDI_NEW_CHANNEL_ASYNC_CALL) + + def testInProgressBidiNewChannelBlockingCall(self): + self._verifyTestCase( + methods.TestCase.IN_PROGRESS_BIDI_NEW_CHANNEL_BLOCKING_CALL) + + def tearDown(self): + self._server_process.kill() + + def _verifyTestCase(self, test_case): + script = _CLIENT_FORK_SCRIPT_TEMPLATE % (test_case.name, self._port) + process = subprocess.Popen( + [sys.executable, '-c', script], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + timer = threading.Timer(_SUBPROCESS_TIMEOUT_S, process.kill) + try: + timer.start() + try: + out, err = process.communicate(timeout=_SUBPROCESS_TIMEOUT_S) + except TypeError: + # The timeout parameter was added in Python 3.3. + out, err = process.communicate() + except subprocess.TimeoutExpired: + process.kill() + raise ValueError('Process failed to terminate') + finally: + timer.cancel() + self.assertEqual( + 0, process.returncode, + 'process failed with exit code %d (stdout: %s, stderr: %s)' % + (process.returncode, out, err)) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/fork/client.py b/src/python/grpcio_tests/tests/fork/client.py index 9a32629ed5a..94a20b33714 100644 --- a/src/python/grpcio_tests/tests/fork/client.py +++ b/src/python/grpcio_tests/tests/fork/client.py @@ -63,12 +63,12 @@ def _test_case_from_arg(test_case_arg): def test_fork(): logging.basicConfig(level=logging.INFO) - args = _args() - if args.test_case == "all": + args = vars(_args()) + if args['test_case'] == "all": for test_case in methods.TestCase: test_case.run_test(args) else: - test_case = _test_case_from_arg(args.test_case) + test_case = _test_case_from_arg(args['test_case']) test_case.run_test(args) diff --git a/src/python/grpcio_tests/tests/fork/methods.py b/src/python/grpcio_tests/tests/fork/methods.py index 889ef13cb28..9481d004cd9 100644 --- a/src/python/grpcio_tests/tests/fork/methods.py +++ b/src/python/grpcio_tests/tests/fork/methods.py @@ -30,11 +30,13 @@ from src.proto.grpc.testing import messages_pb2 from src.proto.grpc.testing import test_pb2_grpc _LOGGER = logging.getLogger(__name__) +_RPC_TIMEOUT_S = 10 +_CHILD_FINISH_TIMEOUT_S = 60 def _channel(args): - target = '{}:{}'.format(args.server_host, args.server_port) - if args.use_tls: + target = '{}:{}'.format(args['server_host'], args['server_port']) + if args['use_tls']: channel_credentials = grpc.ssl_channel_credentials() channel = grpc.secure_channel(target, channel_credentials) else: @@ -57,7 +59,7 @@ def _async_unary(stub): response_type=messages_pb2.COMPRESSABLE, response_size=size, payload=messages_pb2.Payload(body=b'\x00' * 271828)) - response_future = stub.UnaryCall.future(request) + response_future = stub.UnaryCall.future(request, timeout=_RPC_TIMEOUT_S) response = response_future.result() _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE, size) @@ -68,7 +70,7 @@ def _blocking_unary(stub): response_type=messages_pb2.COMPRESSABLE, response_size=size, payload=messages_pb2.Payload(body=b'\x00' * 271828)) - response = stub.UnaryCall(request) + response = stub.UnaryCall(request, timeout=_RPC_TIMEOUT_S) _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE, size) @@ -121,6 +123,8 @@ class _ChildProcess(object): def record_exceptions(): try: task(*args) + except grpc.RpcError as rpc_error: + self._exceptions.put('RpcError: %s' % rpc_error) except Exception as e: # pylint: disable=broad-except self._exceptions.put(e) @@ -130,7 +134,9 @@ class _ChildProcess(object): self._process.start() def finish(self): - self._process.join() + self._process.join(timeout=_CHILD_FINISH_TIMEOUT_S) + if self._process.is_alive(): + raise ValueError('Child process did not terminate') if self._process.exitcode != 0: raise ValueError('Child process failed with exitcode %d' % self._process.exitcode) @@ -162,10 +168,10 @@ def _async_unary_same_channel(channel): def _async_unary_new_channel(channel, args): def child_target(): - child_channel = _channel(args) - child_stub = test_pb2_grpc.TestServiceStub(child_channel) - _async_unary(child_stub) - child_channel.close() + with _channel(args) as child_channel: + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + _async_unary(child_stub) + child_channel.close() stub = test_pb2_grpc.TestServiceStub(channel) _async_unary(stub) @@ -195,10 +201,9 @@ def _blocking_unary_same_channel(channel): def _blocking_unary_new_channel(channel, args): def child_target(): - child_channel = _channel(args) - child_stub = test_pb2_grpc.TestServiceStub(child_channel) - _blocking_unary(child_stub) - child_channel.close() + with _channel(args) as child_channel: + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + _blocking_unary(child_stub) stub = test_pb2_grpc.TestServiceStub(channel) _blocking_unary(stub) @@ -213,54 +218,59 @@ def _close_channel_before_fork(channel, args): def child_target(): new_channel.close() - child_channel = _channel(args) - child_stub = test_pb2_grpc.TestServiceStub(child_channel) - _blocking_unary(child_stub) - child_channel.close() + with _channel(args) as child_channel: + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + _blocking_unary(child_stub) stub = test_pb2_grpc.TestServiceStub(channel) _blocking_unary(stub) channel.close() - new_channel = _channel(args) - new_stub = test_pb2_grpc.TestServiceStub(new_channel) - child_process = _ChildProcess(child_target) - child_process.start() - _blocking_unary(new_stub) - child_process.finish() + with _channel(args) as new_channel: + new_stub = test_pb2_grpc.TestServiceStub(new_channel) + child_process = _ChildProcess(child_target) + child_process.start() + _blocking_unary(new_stub) + child_process.finish() def _connectivity_watch(channel, args): def child_target(): + child_channel_ready_event = threading.Event() + def child_connectivity_callback(state): - child_states.append(state) + if state is grpc.ChannelConnectivity.READY: + child_channel_ready_event.set() child_states = [] - child_channel = _channel(args) - child_stub = test_pb2_grpc.TestServiceStub(child_channel) - child_channel.subscribe(child_connectivity_callback) - _async_unary(child_stub) - if len(child_states - ) < 2 or child_states[-1] != grpc.ChannelConnectivity.READY: - raise ValueError('Channel did not move to READY') - if len(parent_states) > 1: - raise ValueError('Received connectivity updates on parent callback') - child_channel.unsubscribe(child_connectivity_callback) - child_channel.close() + with _channel(args) as child_channel: + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + child_channel.subscribe(child_connectivity_callback) + _async_unary(child_stub) + if not child_channel_ready_event.wait(timeout=_RPC_TIMEOUT_S): + raise ValueError('Channel did not move to READY') + if len(parent_states) > 1: + raise ValueError( + 'Received connectivity updates on parent callback', + parent_states) + child_channel.unsubscribe(child_connectivity_callback) + + parent_states = [] + parent_channel_ready_event = threading.Event() def parent_connectivity_callback(state): parent_states.append(state) + if state is grpc.ChannelConnectivity.READY: + parent_channel_ready_event.set() - parent_states = [] channel.subscribe(parent_connectivity_callback) stub = test_pb2_grpc.TestServiceStub(channel) child_process = _ChildProcess(child_target) child_process.start() _async_unary(stub) - if len(parent_states - ) < 2 or parent_states[-1] != grpc.ChannelConnectivity.READY: + if not parent_channel_ready_event.wait(timeout=_RPC_TIMEOUT_S): raise ValueError('Channel did not move to READY') channel.unsubscribe(parent_connectivity_callback) child_process.finish() @@ -380,9 +390,9 @@ def _in_progress_bidi_same_channel_blocking_call(channel): def _in_progress_bidi_new_channel_async_call(channel, args): def child_target(parent_bidi_call, parent_channel, args): - channel = _channel(args) - stub = test_pb2_grpc.TestServiceStub(channel) - _async_unary(stub) + with _channel(args) as channel: + stub = test_pb2_grpc.TestServiceStub(channel) + _async_unary(stub) _ping_pong_with_child_processes_after_first_response( channel, args, child_target) @@ -391,9 +401,9 @@ def _in_progress_bidi_new_channel_async_call(channel, args): def _in_progress_bidi_new_channel_blocking_call(channel, args): def child_target(parent_bidi_call, parent_channel, args): - channel = _channel(args) - stub = test_pb2_grpc.TestServiceStub(channel) - _blocking_unary(stub) + with _channel(args) as channel: + stub = test_pb2_grpc.TestServiceStub(channel) + _blocking_unary(stub) _ping_pong_with_child_processes_after_first_response( channel, args, child_target) diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index de4c2c1fdde..00b55b02e89 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -1,6 +1,7 @@ [ "_sanity._sanity_test.SanityTest", "channelz._channelz_servicer_test.ChannelzServicerTest", + "fork._fork_interop_test.ForkInteropTest", "health_check._health_servicer_test.HealthServicerTest", "interop._insecure_intraop_test.InsecureIntraopTest", "interop._secure_intraop_test.SecureIntraopTest", From 2ad245cb0ce72cecf3ac6b1c4a3b2c1696a9bab9 Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Fri, 15 Feb 2019 09:52:15 -0800 Subject: [PATCH 402/814] Revert "Folding the Channel class into the grpc_impl namespace." --- BUILD | 1 - CMakeLists.txt | 3 - Makefile | 3 - build.yaml | 1 - gRPC-C++.podspec | 1 - include/grpcpp/channel.h | 86 ++++++++++++- include/grpcpp/channel_impl.h | 115 ------------------ include/grpcpp/impl/codegen/client_callback.h | 5 +- include/grpcpp/impl/codegen/client_context.h | 13 +- .../grpcpp/impl/codegen/client_interceptor.h | 6 +- .../grpcpp/impl/codegen/completion_queue.h | 8 +- .../grpcpp/impl/codegen/server_interface.h | 5 +- include/grpcpp/security/credentials.h | 16 +-- include/grpcpp/server.h | 1 - src/compiler/cpp_generator.cc | 4 +- src/cpp/client/channel_cc.cc | 60 +++++---- src/cpp/client/client_context.cc | 9 +- src/cpp/client/create_channel.cc | 4 +- src/cpp/client/create_channel_internal.cc | 9 +- src/cpp/client/create_channel_internal.h | 9 +- src/cpp/client/create_channel_posix.cc | 6 +- src/cpp/client/cronet_credentials.cc | 2 +- src/cpp/client/insecure_credentials.cc | 2 +- src/cpp/client/secure_credentials.cc | 2 +- src/cpp/client/secure_credentials.h | 9 +- src/cpp/server/server_cc.cc | 4 +- test/cpp/codegen/compiler_test_golden | 5 +- test/cpp/codegen/golden_file_test.cc | 2 +- test/cpp/microbenchmarks/bm_call_create.cc | 2 +- test/cpp/microbenchmarks/fullstack_fixtures.h | 2 +- test/cpp/performance/writes_per_rpc_test.cc | 2 +- test/cpp/util/create_test_channel.h | 18 ++- tools/doxygen/Doxyfile.c++ | 1 - tools/doxygen/Doxyfile.c++.internal | 1 - .../generated/sources_and_headers.json | 2 - 35 files changed, 161 insertions(+), 258 deletions(-) delete mode 100644 include/grpcpp/channel_impl.h diff --git a/BUILD b/BUILD index 6c184f19941..f0de4399beb 100644 --- a/BUILD +++ b/BUILD @@ -206,7 +206,6 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/alarm.h", "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", - "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 41f6ad0ee6d..458e9b88b74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2991,7 +2991,6 @@ foreach(_hdr include/grpcpp/alarm.h include/grpcpp/alarm_impl.h include/grpcpp/channel.h - include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h @@ -3583,7 +3582,6 @@ foreach(_hdr include/grpcpp/alarm.h include/grpcpp/alarm_impl.h include/grpcpp/channel.h - include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h @@ -4539,7 +4537,6 @@ foreach(_hdr include/grpcpp/alarm.h include/grpcpp/alarm_impl.h include/grpcpp/channel.h - include/grpcpp/channel_impl.h include/grpcpp/client_context.h include/grpcpp/completion_queue.h include/grpcpp/create_channel.h diff --git a/Makefile b/Makefile index 721ef768003..9d0b37b687a 100644 --- a/Makefile +++ b/Makefile @@ -5397,7 +5397,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ - include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ @@ -5998,7 +5997,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ - include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ @@ -6911,7 +6909,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ - include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ diff --git a/build.yaml b/build.yaml index 3b0f3e11b2a..d347bcd8189 100644 --- a/build.yaml +++ b/build.yaml @@ -1341,7 +1341,6 @@ filegroups: - include/grpcpp/alarm.h - include/grpcpp/alarm_impl.h - include/grpcpp/channel.h - - include/grpcpp/channel_impl.h - include/grpcpp/client_context.h - include/grpcpp/completion_queue.h - include/grpcpp/create_channel.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index fd5edbe744e..272e41f8223 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -82,7 +82,6 @@ Pod::Spec.new do |s| ss.source_files = 'include/grpcpp/alarm.h', 'include/grpcpp/alarm_impl.h', 'include/grpcpp/channel.h', - 'include/grpcpp/channel_impl.h', 'include/grpcpp/client_context.h', 'include/grpcpp/completion_queue.h', 'include/grpcpp/create_channel.h', diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h index 05a45680916..ee833960698 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -19,16 +19,96 @@ #ifndef GRPCPP_CHANNEL_H #define GRPCPP_CHANNEL_H -#include +#include +#include + +#include +#include +#include +#include +#include +#include + +struct grpc_channel; namespace grpc { -typedef ::grpc_impl::Channel Channel; - namespace experimental { +/// Resets the channel's connection backoff. +/// TODO(roth): Once we see whether this proves useful, either create a gRFC +/// and change this to be a method of the Channel class, or remove it. void ChannelResetConnectionBackoff(Channel* channel); } // namespace experimental +/// Channels represent a connection to an endpoint. Created by \a CreateChannel. +class Channel final : public ChannelInterface, + public internal::CallHook, + public std::enable_shared_from_this, + private GrpcLibraryCodegen { + public: + ~Channel(); + + /// Get the current channel state. If the channel is in IDLE and + /// \a try_to_connect is set to true, try to connect. + grpc_connectivity_state GetState(bool try_to_connect) override; + + /// Returns the LB policy name, or the empty string if not yet available. + grpc::string GetLoadBalancingPolicyName() const; + + /// Returns the service config in JSON form, or the empty string if + /// not available. + grpc::string GetServiceConfigJSON() const; + + private: + template + friend class internal::BlockingUnaryCallImpl; + friend void experimental::ChannelResetConnectionBackoff(Channel* channel); + friend std::shared_ptr CreateChannelInternal( + const grpc::string& host, grpc_channel* c_channel, + std::vector< + std::unique_ptr> + interceptor_creators); + friend class internal::InterceptedChannel; + Channel(const grpc::string& host, grpc_channel* c_channel, + std::vector< + std::unique_ptr> + interceptor_creators); + + internal::Call CreateCall(const internal::RpcMethod& method, + ClientContext* context, + CompletionQueue* cq) override; + void PerformOpsOnCall(internal::CallOpSetInterface* ops, + internal::Call* call) override; + void* RegisterMethod(const char* method) override; + + void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, + gpr_timespec deadline, CompletionQueue* cq, + void* tag) override; + bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, + gpr_timespec deadline) override; + + CompletionQueue* CallbackCQ() override; + + internal::Call CreateCallInternal(const internal::RpcMethod& method, + ClientContext* context, CompletionQueue* cq, + size_t interceptor_pos) override; + + const grpc::string host_; + grpc_channel* const c_channel_; // owned + + // mu_ protects callback_cq_ (the per-channel callbackable completion queue) + std::mutex mu_; + + // callback_cq_ references the callbackable completion queue associated + // with this channel (if any). It is set on the first call to CallbackCQ(). + // It is _not owned_ by the channel; ownership belongs with its internal + // shutdown callback tag (invoked when the CQ is fully shutdown). + CompletionQueue* callback_cq_ = nullptr; + + std::vector> + interceptor_creators_; +}; + } // namespace grpc #endif // GRPCPP_CHANNEL_H diff --git a/include/grpcpp/channel_impl.h b/include/grpcpp/channel_impl.h deleted file mode 100644 index ea90e5b8f7b..00000000000 --- a/include/grpcpp/channel_impl.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPCPP_CHANNEL_IMPL_H -#define GRPCPP_CHANNEL_IMPL_H - -#include -#include - -#include -#include -#include -#include -#include -#include - -struct grpc_channel; - -namespace grpc_impl { - -namespace experimental { -/// Resets the channel's connection backoff. -/// TODO(roth): Once we see whether this proves useful, either create a gRFC -/// and change this to be a method of the Channel class, or remove it. -void ChannelResetConnectionBackoff(Channel* channel); -} // namespace experimental - -/// Channels represent a connection to an endpoint. Created by \a CreateChannel. -class Channel final : public ::grpc::ChannelInterface, - public ::grpc::internal::CallHook, - public std::enable_shared_from_this, - private ::grpc::GrpcLibraryCodegen { - public: - ~Channel(); - - /// Get the current channel state. If the channel is in IDLE and - /// \a try_to_connect is set to true, try to connect. - grpc_connectivity_state GetState(bool try_to_connect) override; - - /// Returns the LB policy name, or the empty string if not yet available. - grpc::string GetLoadBalancingPolicyName() const; - - /// Returns the service config in JSON form, or the empty string if - /// not available. - grpc::string GetServiceConfigJSON() const; - - private: - template - friend class ::grpc::internal::BlockingUnaryCallImpl; - friend void experimental::ChannelResetConnectionBackoff(Channel* channel); - friend std::shared_ptr CreateChannelInternal( - const grpc::string& host, grpc_channel* c_channel, - std::vector> - interceptor_creators); - friend class ::grpc::internal::InterceptedChannel; - Channel(const grpc::string& host, grpc_channel* c_channel, - std::vector> - interceptor_creators); - - ::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method, - ::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq) override; - void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, - ::grpc::internal::Call* call) override; - void* RegisterMethod(const char* method) override; - - void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline, - ::grpc::CompletionQueue* cq, void* tag) override; - bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, - gpr_timespec deadline) override; - - ::grpc::CompletionQueue* CallbackCQ() override; - - ::grpc::internal::Call CreateCallInternal( - const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq, size_t interceptor_pos) override; - - const grpc::string host_; - grpc_channel* const c_channel_; // owned - - // mu_ protects callback_cq_ (the per-channel callbackable completion queue) - std::mutex mu_; - - // callback_cq_ references the callbackable completion queue associated - // with this channel (if any). It is set on the first call to CallbackCQ(). - // It is _not owned_ by the channel; ownership belongs with its internal - // shutdown callback tag (invoked when the CQ is fully shutdown). - ::grpc::CompletionQueue* callback_cq_ = nullptr; - - std::vector< - std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>> - interceptor_creators_; -}; - -} // namespace grpc_impl - -#endif // GRPCPP_CHANNEL_IMPL_H diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 6a0d0948cc6..52bcea99706 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -29,12 +29,9 @@ #include #include -namespace grpc_impl { -class Channel; -} - namespace grpc { +class Channel; class ClientContext; class CompletionQueue; diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index e6579b5b7a7..5946488566e 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -56,13 +56,9 @@ struct census_context; struct grpc_call; -namespace grpc_impl { - -class Channel; -} - namespace grpc { +class Channel; class ChannelInterface; class CompletionQueue; class CallCredentials; @@ -395,7 +391,7 @@ class ClientContext { friend class ::grpc::testing::InteropClientContextInspector; friend class ::grpc::internal::CallOpClientRecvStatus; friend class ::grpc::internal::CallOpRecvInitialMetadata; - friend class ::grpc_impl::Channel; + friend class Channel; template friend class ::grpc::ClientReader; template @@ -427,8 +423,7 @@ class ClientContext { } grpc_call* call() const { return call_; } - void set_call(grpc_call* call, - const std::shared_ptr<::grpc_impl::Channel>& channel); + void set_call(grpc_call* call, const std::shared_ptr& channel); experimental::ClientRpcInfo* set_client_rpc_info( const char* method, internal::RpcMethod::RpcType type, @@ -461,7 +456,7 @@ class ClientContext { bool wait_for_ready_explicitly_set_; bool idempotent_; bool cacheable_; - std::shared_ptr<::grpc_impl::Channel> channel_; + std::shared_ptr channel_; std::mutex mu_; grpc_call* call_; bool call_canceled_; diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index c3bdf2364f0..7dfe2290a3f 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -26,14 +26,10 @@ #include #include -namespace grpc_impl { - -class Channel; -} - namespace grpc { class ClientContext; +class Channel; namespace internal { class InterceptorBatchMethodsImpl; diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 79a2805cb5f..4812f0253d4 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -41,11 +41,6 @@ struct grpc_completion_queue; -namespace grpc_impl { - -class Channel; -} - namespace grpc { template @@ -63,6 +58,7 @@ template class ServerReaderWriterBody; } // namespace internal +class Channel; class ChannelInterface; class ClientContext; class CompletionQueue; @@ -282,7 +278,7 @@ class CompletionQueue : private GrpcLibraryCodegen { friend class ::grpc::internal::BlockingUnaryCallImpl; // Friends that need access to constructor for callback CQ - friend class ::grpc_impl::Channel; + friend class ::grpc::Channel; // For access to Register/CompleteAvalanching template diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index b056643269a..890a5650d02 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -28,13 +28,10 @@ #include #include -namespace grpc_impl { -class Channel; -} - namespace grpc { class AsyncGenericService; +class Channel; class GenericServerContext; class ServerCompletionQueue; class ServerContext; diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 8f090da070f..d8c9e04d778 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -32,13 +32,9 @@ struct grpc_call; -namespace grpc_impl { - -class Channel; -} - namespace grpc { class ChannelArguments; +class Channel; class SecureChannelCredentials; class CallCredentials; class SecureCallCredentials; @@ -46,7 +42,7 @@ class SecureCallCredentials; class ChannelCredentials; namespace experimental { -std::shared_ptr<::grpc_impl::Channel> CreateCustomChannelWithInterceptors( +std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, @@ -74,12 +70,12 @@ class ChannelCredentials : private GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr<::grpc_impl::Channel> CreateCustomChannel( + friend std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args); - friend std::shared_ptr<::grpc_impl::Channel> + friend std::shared_ptr experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, @@ -88,12 +84,12 @@ class ChannelCredentials : private GrpcLibraryCodegen { std::unique_ptr> interceptor_creators); - virtual std::shared_ptr<::grpc_impl::Channel> CreateChannel( + virtual std::shared_ptr CreateChannel( const grpc::string& target, const ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is // implemented as a virtual function so that it does not break API. - virtual std::shared_ptr<::grpc_impl::Channel> CreateChannelWithInterceptors( + virtual std::shared_ptr CreateChannelWithInterceptors( const grpc::string& target, const ChannelArguments& args, std::vector< std::unique_ptr> diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 4682d141314..885bd8de8d7 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -27,7 +27,6 @@ #include #include -#include #include #include #include diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index e98abdd082a..b0046872502 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -145,11 +145,9 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, PrintIncludes(printer.get(), headers, params.use_system_headers, params.grpc_search_path); printer->Print(vars, "\n"); - printer->Print(vars, "namespace grpc_impl {\n"); - printer->Print(vars, "class Channel;\n"); - printer->Print(vars, "} // namespace grpc_impl\n\n"); printer->Print(vars, "namespace grpc {\n"); printer->Print(vars, "class CompletionQueue;\n"); + printer->Print(vars, "class Channel;\n"); printer->Print(vars, "class ServerCompletionQueue;\n"); printer->Print(vars, "class ServerContext;\n"); printer->Print(vars, "} // namespace grpc\n\n"); diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index b4bb1b41a21..a31d0b30b15 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -49,18 +49,14 @@ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/surface/completion_queue.h" -void grpc::experimental::ChannelResetConnectionBackoff( - ::grpc::Channel* channel) { - grpc_impl::experimental::ChannelResetConnectionBackoff(channel); -} +namespace grpc { -namespace grpc_impl { - -static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; -Channel::Channel(const grpc::string& host, grpc_channel* channel, - std::vector> - interceptor_creators) +static internal::GrpcLibraryInitializer g_gli_initializer; +Channel::Channel( + const grpc::string& host, grpc_channel* channel, + std::vector< + std::unique_ptr> + interceptor_creators) : host_(host), c_channel_(channel) { interceptor_creators_ = std::move(interceptor_creators); g_gli_initializer.summon(); @@ -76,8 +72,7 @@ Channel::~Channel() { namespace { inline grpc_slice SliceFromArray(const char* arr, size_t len) { - return ::grpc::g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, - len); + return g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); } grpc::string GetChannelInfoField(grpc_channel* channel, @@ -115,9 +110,10 @@ void ChannelResetConnectionBackoff(Channel* channel) { } // namespace experimental -::grpc::internal::Call Channel::CreateCallInternal( - const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq, size_t interceptor_pos) { +internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method, + ClientContext* context, + CompletionQueue* cq, + size_t interceptor_pos) { const bool kRegistered = method.channel_tag() && context->authority().empty(); grpc_call* c_call = nullptr; if (kRegistered) { @@ -126,7 +122,7 @@ void ChannelResetConnectionBackoff(Channel* channel) { context->propagation_options_.c_bitmask(), cq->cq(), method.channel_tag(), context->raw_deadline(), nullptr); } else { - const ::grpc::string* host_str = nullptr; + const string* host_str = nullptr; if (!context->authority_.empty()) { host_str = &context->authority_; } else if (!host_.empty()) { @@ -136,7 +132,7 @@ void ChannelResetConnectionBackoff(Channel* channel) { SliceFromArray(method.name(), strlen(method.name())); grpc_slice host_slice; if (host_str != nullptr) { - host_slice = ::grpc::SliceFromCopiedString(*host_str); + host_slice = SliceFromCopiedString(*host_str); } c_call = grpc_channel_create_call( c_channel_, context->propagate_from_call_, @@ -158,17 +154,17 @@ void ChannelResetConnectionBackoff(Channel* channel) { interceptor_creators_, interceptor_pos); context->set_call(c_call, shared_from_this()); - return ::grpc::internal::Call(c_call, this, cq, info); + return internal::Call(c_call, this, cq, info); } -::grpc::internal::Call Channel::CreateCall( - const ::grpc::internal::RpcMethod& method, ::grpc::ClientContext* context, - ::grpc::CompletionQueue* cq) { +internal::Call Channel::CreateCall(const internal::RpcMethod& method, + ClientContext* context, + CompletionQueue* cq) { return CreateCallInternal(method, context, cq, 0); } -void Channel::PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops, - ::grpc::internal::Call* call) { +void Channel::PerformOpsOnCall(internal::CallOpSetInterface* ops, + internal::Call* call) { ops->FillOps( call); // Make a copy of call. It's fine since Call just has pointers } @@ -184,7 +180,7 @@ grpc_connectivity_state Channel::GetState(bool try_to_connect) { namespace { -class TagSaver final : public ::grpc::internal::CompletionQueueTag { +class TagSaver final : public internal::CompletionQueueTag { public: explicit TagSaver(void* tag) : tag_(tag) {} ~TagSaver() override {} @@ -202,7 +198,7 @@ class TagSaver final : public ::grpc::internal::CompletionQueueTag { void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline, - ::grpc::CompletionQueue* cq, void* tag) { + CompletionQueue* cq, void* tag) { TagSaver* tag_saver = new TagSaver(tag); grpc_channel_watch_connectivity_state(c_channel_, last_observed, deadline, cq->cq(), tag_saver); @@ -210,7 +206,7 @@ void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) { - ::grpc::CompletionQueue cq; + CompletionQueue cq; bool ok = false; void* tag = nullptr; NotifyOnStateChangeImpl(last_observed, deadline, &cq, nullptr); @@ -225,7 +221,7 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { ShutdownCallback() { functor_run = &ShutdownCallback::Run; } // TakeCQ takes ownership of the cq into the shutdown callback // so that the shutdown callback will be responsible for destroying it - void TakeCQ(::grpc::CompletionQueue* cq) { cq_ = cq; } + void TakeCQ(CompletionQueue* cq) { cq_ = cq; } // The Run function will get invoked by the completion queue library // when the shutdown is actually complete @@ -236,17 +232,17 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { } private: - ::grpc::CompletionQueue* cq_ = nullptr; + CompletionQueue* cq_ = nullptr; }; } // namespace -::grpc::CompletionQueue* Channel::CallbackCQ() { +CompletionQueue* Channel::CallbackCQ() { // TODO(vjpai): Consider using a single global CQ for the default CQ // if there is no explicit per-channel CQ registered std::lock_guard l(mu_); if (callback_cq_ == nullptr) { auto* shutdown_callback = new ShutdownCallback; - callback_cq_ = new ::grpc::CompletionQueue(grpc_completion_queue_attributes{ + callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, shutdown_callback}); @@ -256,4 +252,4 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor { return callback_cq_; } -} // namespace grpc_impl +} // namespace grpc diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc index b3c52acd5f6..efb59c71a8c 100644 --- a/src/cpp/client/client_context.cc +++ b/src/cpp/client/client_context.cc @@ -30,11 +30,6 @@ #include #include -namespace grpc_impl { - -class Channel; -} - namespace grpc { class DefaultGlobalClientCallbacks final @@ -87,8 +82,8 @@ void ClientContext::AddMetadata(const grpc::string& meta_key, send_initial_metadata_.insert(std::make_pair(meta_key, meta_value)); } -void ClientContext::set_call( - grpc_call* call, const std::shared_ptr<::grpc_impl::Channel>& channel) { +void ClientContext::set_call(grpc_call* call, + const std::shared_ptr& channel) { std::unique_lock lock(mu_); GPR_ASSERT(call_ == nullptr); call_ = call; diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 409edd207f4..457daa674c7 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -40,7 +40,7 @@ std::shared_ptr CreateCustomChannel( const ChannelArguments& args) { GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds. return creds ? creds->CreateChannel(target, args) - : ::grpc_impl::CreateChannelInternal( + : CreateChannelInternal( "", grpc_lame_client_channel_create( nullptr, GRPC_STATUS_INVALID_ARGUMENT, @@ -70,7 +70,7 @@ std::shared_ptr CreateCustomChannelWithInterceptors( interceptor_creators) { return creds ? creds->CreateChannelWithInterceptors( target, args, std::move(interceptor_creators)) - : ::grpc_impl::CreateChannelInternal( + : CreateChannelInternal( "", grpc_lame_client_channel_create( nullptr, GRPC_STATUS_INVALID_ARGUMENT, diff --git a/src/cpp/client/create_channel_internal.cc b/src/cpp/client/create_channel_internal.cc index 77fd00fb3fe..a0efb97f7ef 100644 --- a/src/cpp/client/create_channel_internal.cc +++ b/src/cpp/client/create_channel_internal.cc @@ -22,15 +22,14 @@ struct grpc_channel; -namespace grpc_impl { +namespace grpc { std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::vector> + std::vector< + std::unique_ptr> interceptor_creators) { return std::shared_ptr( new Channel(host, c_channel, std::move(interceptor_creators))); } - -} // namespace grpc_impl +} // namespace grpc diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h index 7dab6473a9c..a90c92c518d 100644 --- a/src/cpp/client/create_channel_internal.h +++ b/src/cpp/client/create_channel_internal.h @@ -26,16 +26,15 @@ struct grpc_channel; -namespace grpc_impl { - +namespace grpc { class Channel; std::shared_ptr CreateChannelInternal( const grpc::string& host, grpc_channel* c_channel, - std::vector> + std::vector< + std::unique_ptr> interceptor_creators); -} // namespace grpc_impl +} // namespace grpc #endif // GRPC_INTERNAL_CPP_CLIENT_CREATE_CHANNEL_INTERNAL_H diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index 79bf10d2801..3affc1ef391 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -32,7 +32,7 @@ std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, int fd) { internal::GrpcLibrary init_lib; init_lib.init(); - return ::grpc_impl::CreateChannelInternal( + return CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr), std::vector< std::unique_ptr>()); @@ -44,7 +44,7 @@ std::shared_ptr CreateCustomInsecureChannelFromFd( init_lib.init(); grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return ::grpc_impl::CreateChannelInternal( + return CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), std::vector< @@ -62,7 +62,7 @@ std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( init_lib.init(); grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return ::grpc_impl::CreateChannelInternal( + return CreateChannelInternal( "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), std::move(interceptor_creators)); diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc index 0f8b988674b..b2801764f20 100644 --- a/src/cpp/client/cronet_credentials.cc +++ b/src/cpp/client/cronet_credentials.cc @@ -47,7 +47,7 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return ::grpc_impl::CreateChannelInternal( + return CreateChannelInternal( "", grpc_cronet_secure_channel_create(engine_, target.c_str(), &channel_args, nullptr), diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 1fa832528b1..241ce918034 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -45,7 +45,7 @@ class InsecureChannelCredentialsImpl final : public ChannelCredentials { interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return ::grpc_impl::CreateChannelInternal( + return CreateChannelInternal( "", grpc_insecure_channel_create(target.c_str(), &channel_args, nullptr), std::move(interceptor_creators)); diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 9ac07f58557..4d0ed355aba 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -50,7 +50,7 @@ SecureChannelCredentials::CreateChannelWithInterceptors( interceptor_creators) { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return ::grpc_impl::CreateChannelInternal( + return CreateChannelInternal( args.GetSslTargetNameOverride(), grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args, nullptr), diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 5db4af143b4..4918bd5a4d7 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -27,11 +27,6 @@ #include "src/core/lib/security/credentials/credentials.h" #include "src/cpp/server/thread_pool_interface.h" -namespace grpc_impl { - -class Channel; -} - namespace grpc { class SecureChannelCredentials final : public ChannelCredentials { @@ -42,13 +37,13 @@ class SecureChannelCredentials final : public ChannelCredentials { } grpc_channel_credentials* GetRawCreds() { return c_creds_; } - std::shared_ptr<::grpc_impl::Channel> CreateChannel( + std::shared_ptr CreateChannel( const string& target, const grpc::ChannelArguments& args) override; SecureChannelCredentials* AsSecureCredentials() override { return this; } private: - std::shared_ptr<::grpc_impl::Channel> CreateChannelWithInterceptors( + std::shared_ptr CreateChannelWithInterceptors( const string& target, const grpc::ChannelArguments& args, std::vector< std::unique_ptr> diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 8329d6a8d91..05f78dbe6fe 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -794,7 +794,7 @@ grpc_server* Server::c_server() { return server_; } std::shared_ptr Server::InProcessChannel( const ChannelArguments& args) { grpc_channel_args channel_args = args.c_channel_args(); - return ::grpc_impl::CreateChannelInternal( + return CreateChannelInternal( "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr), std::vector< std::unique_ptr>()); @@ -807,7 +807,7 @@ Server::experimental_type::InProcessChannelWithInterceptors( std::unique_ptr> interceptor_creators) { grpc_channel_args channel_args = args.c_channel_args(); - return ::grpc_impl::CreateChannelInternal( + return CreateChannelInternal( "inproc", grpc_inproc_channel_create(server_->server_, &channel_args, nullptr), std::move(interceptor_creators)); diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index de71dcd5cb1..1871e1375ed 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -40,12 +40,9 @@ #include #include -namespace grpc_impl { -class Channel; -} // namespace grpc_impl - namespace grpc { class CompletionQueue; +class Channel; class ServerCompletionQueue; class ServerContext; } // namespace grpc diff --git a/test/cpp/codegen/golden_file_test.cc b/test/cpp/codegen/golden_file_test.cc index 19f267dd4b5..bfd36494941 100644 --- a/test/cpp/codegen/golden_file_test.cc +++ b/test/cpp/codegen/golden_file_test.cc @@ -31,7 +31,7 @@ using namespace gflags; DEFINE_string( generated_file_path, "", - "path to the directory containing generated files compiler_test.grpc.pb.h " + "path to the directory containing generated files compiler_test.grpc.pb.h" "and compiler_test_mock.grpc.pb.h"); const char kGoldenFilePath[] = "test/cpp/codegen/compiler_test_golden"; diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 52ff5a3d79d..e57650fe5b7 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -131,7 +131,7 @@ static void* tag(int i) { static void BM_LameChannelCallCreateCpp(benchmark::State& state) { TrackCounters track_counters; auto stub = - grpc::testing::EchoTestService::NewStub(grpc_impl::CreateChannelInternal( + grpc::testing::EchoTestService::NewStub(grpc::CreateChannelInternal( "", grpc_lame_client_channel_create("localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah"), diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index 2d488d8b227..6bbf553bbd8 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -218,7 +218,7 @@ class EndpointPairFixture : public BaseFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport_); grpc_chttp2_transport_start_reading(client_transport_, nullptr, nullptr); - channel_ = ::grpc_impl::CreateChannelInternal( + channel_ = CreateChannelInternal( "", channel, std::vector>()); diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc index b531e08138a..7b22f23cf00 100644 --- a/test/cpp/performance/writes_per_rpc_test.cc +++ b/test/cpp/performance/writes_per_rpc_test.cc @@ -118,7 +118,7 @@ class EndpointPairFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); - channel_ = ::grpc_impl::CreateChannelInternal( + channel_ = CreateChannelInternal( "", channel, std::vector>()); diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index f94f0ac30a2..c615fb76536 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -23,12 +23,8 @@ #include -namespace grpc_impl { - -class Channel; -} - namespace grpc { +class Channel; namespace testing { @@ -36,31 +32,31 @@ typedef enum { INSECURE = 0, TLS, ALTS } transport_security; } // namespace testing -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, testing::transport_security security_type); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& override_hostname, testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& cred_type, const grpc::string& override_hostname, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args); -std::shared_ptr<::grpc_impl::Channel> CreateTestChannel( +std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& credential_type, const std::shared_ptr& creds); diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index cbc601921e1..9f17a25298a 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -927,7 +927,6 @@ include/grpc/support/workaround_list.h \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ -include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index a20e2a8d9bf..2c194c420f3 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -928,7 +928,6 @@ include/grpc/support/workaround_list.h \ include/grpcpp/alarm.h \ include/grpcpp/alarm_impl.h \ include/grpcpp/channel.h \ -include/grpcpp/channel_impl.h \ include/grpcpp/client_context.h \ include/grpcpp/completion_queue.h \ include/grpcpp/create_channel.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8f87daad295..823e17dd45a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11366,7 +11366,6 @@ "include/grpcpp/alarm.h", "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", - "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", @@ -11476,7 +11475,6 @@ "include/grpcpp/alarm.h", "include/grpcpp/alarm_impl.h", "include/grpcpp/channel.h", - "include/grpcpp/channel_impl.h", "include/grpcpp/client_context.h", "include/grpcpp/completion_queue.h", "include/grpcpp/create_channel.h", From a7cb65b119abb16b6e13d87b38e363a55688b5e6 Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 15 Feb 2019 13:32:34 -0800 Subject: [PATCH 403/814] Remove useless comment and add EOL --- templates/tools/dockerfile/php_valgrind.include | 4 +--- tools/dockerfile/test/php7_jessie_x64/Dockerfile | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/templates/tools/dockerfile/php_valgrind.include b/templates/tools/dockerfile/php_valgrind.include index aa2ed883f39..b5e6b534168 100644 --- a/templates/tools/dockerfile/php_valgrind.include +++ b/templates/tools/dockerfile/php_valgrind.include @@ -1,7 +1,5 @@ #================= # PHP Test dependencies - # Install dependencies - RUN apt-get update && apt-get install -y ${'\\'} - valgrind \ No newline at end of file + valgrind diff --git a/tools/dockerfile/test/php7_jessie_x64/Dockerfile b/tools/dockerfile/test/php7_jessie_x64/Dockerfile index 0c84ed3fe4c..fac9eb55517 100644 --- a/tools/dockerfile/test/php7_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/php7_jessie_x64/Dockerfile @@ -82,11 +82,10 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t #================= # PHP Test dependencies - # Install dependencies - RUN apt-get update && apt-get install -y \ valgrind + RUN mkdir /var/local/jenkins # Define the default command. From cecea9c5921c98a43d4a34b3ad1c8e8bdb4eedbb Mon Sep 17 00:00:00 2001 From: hcaseyal Date: Fri, 15 Feb 2019 13:36:02 -0800 Subject: [PATCH 404/814] Revert "Added test for RPCs over a flaky network" --- test/cpp/end2end/BUILD | 19 - test/cpp/end2end/flaky_network_test.cc | 441 ------------------ .../linux/grpc_bazel_privileged_docker.sh | 26 -- .../internal_ci/linux/grpc_flaky_network.cfg | 2 +- .../linux/grpc_flaky_network_in_docker.sh | 8 +- 5 files changed, 5 insertions(+), 491 deletions(-) delete mode 100644 test/cpp/end2end/flaky_network_test.cc delete mode 100755 tools/internal_ci/linux/grpc_bazel_privileged_docker.sh diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 64b3eae60da..cbf09354a03 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -553,25 +553,6 @@ grpc_cc_test( ], ) -grpc_cc_test( - name = "flaky_network_test", - srcs = ["flaky_network_test.cc"], - external_deps = [ - "gtest", - ], - tags = ["manual"], - deps = [ - ":test_service_impl", - "//:gpr", - "//:grpc", - "//:grpc++", - "//src/proto/grpc/testing:echo_messages_proto", - "//src/proto/grpc/testing:echo_proto", - "//test/core/util:grpc_test_util", - "//test/cpp/util:test_util", - ], -) - grpc_cc_test( name = "shutdown_test", srcs = ["shutdown_test.cc"], diff --git a/test/cpp/end2end/flaky_network_test.cc b/test/cpp/end2end/flaky_network_test.cc deleted file mode 100644 index 06eaf9e74ad..00000000000 --- a/test/cpp/end2end/flaky_network_test.cc +++ /dev/null @@ -1,441 +0,0 @@ -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/gpr/env.h" - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" - -#include - -#ifdef GPR_LINUX -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -namespace grpc { -namespace testing { -namespace { - -class FlakyNetworkTest : public ::testing::Test { - protected: - FlakyNetworkTest() - : server_host_("grpctest"), - interface_("lo:1"), - ipv4_address_("10.0.0.1"), - netmask_("/32"), - kRequestMessage_("🖖") {} - - void InterfaceUp() { - std::ostringstream cmd; - // create interface_ with address ipv4_address_ - cmd << "ip addr add " << ipv4_address_ << netmask_ << " dev " << interface_; - std::system(cmd.str().c_str()); - } - - void InterfaceDown() { - std::ostringstream cmd; - // remove interface_ - cmd << "ip addr del " << ipv4_address_ << netmask_ << " dev " << interface_; - std::system(cmd.str().c_str()); - } - - void DNSUp() { - std::ostringstream cmd; - // Add DNS entry for server_host_ in /etc/hosts - cmd << "echo '" << ipv4_address_ << " " << server_host_ - << "' >> /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void DNSDown() { - std::ostringstream cmd; - // Remove DNS entry for server_host_ from /etc/hosts - // NOTE: we can't do this in one step with sed -i because when we are - // running under docker, the file is mounted by docker so we can't change - // its inode from within the container (sed -i creates a new file and - // replaces the old file, which changes the inode) - cmd << "sed '/" << server_host_ << "/d' /etc/hosts > /etc/hosts.orig"; - std::system(cmd.str().c_str()); - - // clear the stream - cmd.str(""); - - cmd << "cat /etc/hosts.orig > /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void DropPackets() { - std::ostringstream cmd; - // drop packets with src IP = ipv4_address_ - cmd << "iptables -A INPUT -s " << ipv4_address_ << " -j DROP"; - - std::system(cmd.str().c_str()); - // clear the stream - cmd.str(""); - - // drop packets with dst IP = ipv4_address_ - cmd << "iptables -A INPUT -d " << ipv4_address_ << " -j DROP"; - } - - void RestoreNetwork() { - std::ostringstream cmd; - // remove iptables rule to drop packets with src IP = ipv4_address_ - cmd << "iptables -D INPUT -s " << ipv4_address_ << " -j DROP"; - std::system(cmd.str().c_str()); - // clear the stream - cmd.str(""); - // remove iptables rule to drop packets with dest IP = ipv4_address_ - cmd << "iptables -D INPUT -d " << ipv4_address_ << " -j DROP"; - } - - void FlakeNetwork() { - std::ostringstream cmd; - // Emulate a flaky network connection over interface_. Add a delay of 100ms - // +/- 590ms, 3% packet loss, 1% duplicates and 0.1% corrupt packets. - cmd << "tc qdisc replace dev " << interface_ - << " root netem delay 100ms 50ms distribution normal loss 3% duplicate " - "1% corrupt 0.1% "; - std::system(cmd.str().c_str()); - } - - void UnflakeNetwork() { - // Remove simulated network flake on interface_ - std::ostringstream cmd; - cmd << "tc qdisc del dev " << interface_ << " root netem"; - std::system(cmd.str().c_str()); - } - - void NetworkUp() { - InterfaceUp(); - DNSUp(); - } - - void NetworkDown() { - InterfaceDown(); - DNSDown(); - } - - void SetUp() override { - NetworkUp(); - grpc_init(); - StartServer(); - } - - void TearDown() override { - NetworkDown(); - StopServer(); - grpc_shutdown(); - } - - void StartServer() { - // TODO (pjaikumar): Ideally, we should allocate the port dynamically using - // grpc_pick_unused_port_or_die(). That doesn't work inside some docker - // containers because port_server listens on localhost which maps to - // ip6-looopback, but ipv6 support is not enabled by default in docker. - port_ = SERVER_PORT; - - server_.reset(new ServerData(port_)); - server_->Start(server_host_); - } - void StopServer() { server_->Shutdown(); } - - std::unique_ptr BuildStub( - const std::shared_ptr& channel) { - return grpc::testing::EchoTestService::NewStub(channel); - } - - std::shared_ptr BuildChannel( - const grpc::string& lb_policy_name, - ChannelArguments args = ChannelArguments()) { - if (lb_policy_name.size() > 0) { - args.SetLoadBalancingPolicyName(lb_policy_name); - } // else, default to pick first - std::ostringstream server_address; - server_address << server_host_ << ":" << port_; - return CreateCustomChannel(server_address.str(), - InsecureChannelCredentials(), args); - } - - bool SendRpc( - const std::unique_ptr& stub, - int timeout_ms = 0, bool wait_for_ready = false) { - auto response = std::unique_ptr(new EchoResponse()); - EchoRequest request; - request.set_message(kRequestMessage_); - ClientContext context; - if (timeout_ms > 0) { - context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); - } - // See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md for - // details of wait-for-ready semantics - if (wait_for_ready) { - context.set_wait_for_ready(true); - } - Status status = stub->Echo(&context, request, response.get()); - auto ok = status.ok(); - if (ok) { - gpr_log(GPR_DEBUG, "RPC returned %s\n", response->message().c_str()); - } else { - gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); - } - return ok; - } - - struct ServerData { - int port_; - std::unique_ptr server_; - TestServiceImpl service_; - std::unique_ptr thread_; - bool server_ready_ = false; - - explicit ServerData(int port) { port_ = port; } - - void Start(const grpc::string& server_host) { - gpr_log(GPR_INFO, "starting server on port %d", port_); - std::mutex mu; - std::unique_lock lock(mu); - std::condition_variable cond; - thread_.reset(new std::thread( - std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); - cond.wait(lock, [this] { return server_ready_; }); - server_ready_ = false; - gpr_log(GPR_INFO, "server startup complete"); - } - - void Serve(const grpc::string& server_host, std::mutex* mu, - std::condition_variable* cond) { - std::ostringstream server_address; - server_address << server_host << ":" << port_; - ServerBuilder builder; - builder.AddListeningPort(server_address.str(), - InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - std::lock_guard lock(*mu); - server_ready_ = true; - cond->notify_one(); - } - - void Shutdown(bool join = true) { - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - if (join) thread_->join(); - } - }; - - bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(false /* try_to_connect */)) == - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(true /* try_to_connect */)) != - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - private: - const grpc::string server_host_; - const grpc::string interface_; - const grpc::string ipv4_address_; - const grpc::string netmask_; - std::unique_ptr stub_; - std::unique_ptr server_; - const int SERVER_PORT = 32750; - int port_; - const grpc::string kRequestMessage_; -}; - -// Network interface connected to server flaps -TEST_F(FlakyNetworkTest, NetworkTransition) { - const int kKeepAliveTimeMs = 1000; - const int kKeepAliveTimeoutMs = 1000; - ChannelArguments args; - args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); - args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); - args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); - args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - - auto channel = BuildChannel("pick_first", args); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - std::atomic_bool shutdown{false}; - std::thread sender = std::thread([this, &stub, &shutdown]() { - while (true) { - if (shutdown.load()) { - return; - } - SendRpc(stub); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - }); - - // bring down network - NetworkDown(); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - // bring network interface back up - InterfaceUp(); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - // Restore DNS entry for server - DNSUp(); - EXPECT_TRUE(WaitForChannelReady(channel.get())); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - shutdown.store(true); - sender.join(); -} - -// Traffic to server server is blackholed temporarily with keepalives enabled -TEST_F(FlakyNetworkTest, ServerUnreachableWithKeepalive) { - const int kKeepAliveTimeMs = 1000; - const int kKeepAliveTimeoutMs = 1000; - ChannelArguments args; - args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); - args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); - args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); - args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - - auto channel = BuildChannel("pick_first", args); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - std::atomic_bool shutdown{false}; - std::thread sender = std::thread([this, &stub, &shutdown]() { - while (true) { - if (shutdown.load()) { - return; - } - SendRpc(stub); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - }); - - // break network connectivity - DropPackets(); - std::this_thread::sleep_for(std::chrono::milliseconds(10000)); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - // bring network interface back up - RestoreNetwork(); - EXPECT_TRUE(WaitForChannelReady(channel.get())); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - shutdown.store(true); - sender.join(); -} - -// -// Traffic to server server is blackholed temporarily with keepalives disabled -TEST_F(FlakyNetworkTest, ServerUnreachableNoKeepalive) { - auto channel = BuildChannel("pick_first", ChannelArguments()); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - // break network connectivity - DropPackets(); - - std::thread sender = std::thread([this, &stub]() { - // RPC with deadline should timeout - EXPECT_FALSE(SendRpc(stub, /*timeout_ms=*/500, /*wait_for_ready=*/true)); - // RPC without deadline forever until call finishes - EXPECT_TRUE(SendRpc(stub, /*timeout_ms=*/0, /*wait_for_ready=*/true)); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); - // bring network interface back up - RestoreNetwork(); - - // wait for RPC to finish - sender.join(); -} - -// Send RPCs over a flaky network connection -TEST_F(FlakyNetworkTest, FlakyNetwork) { - const int kKeepAliveTimeMs = 1000; - const int kKeepAliveTimeoutMs = 1000; - const int kMessageCount = 100; - ChannelArguments args; - args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); - args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); - args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); - args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - - auto channel = BuildChannel("pick_first", args); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - // simulate flaky network (packet loss, corruption and delays) - FlakeNetwork(); - for (int i = 0; i < kMessageCount; ++i) { - EXPECT_TRUE(SendRpc(stub)); - } - // remove network flakiness - UnflakeNetwork(); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); -} - -} // namespace -} // namespace testing -} // namespace grpc -#endif // GPR_LINUX - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc_test_init(argc, argv); - auto result = RUN_ALL_TESTS(); - return result; -} diff --git a/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh b/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh deleted file mode 100755 index ae1056d7c3d..00000000000 --- a/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2019 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -ex - -# change to grpc repo root -cd $(dirname $0)/../../.. - -source tools/internal_ci/helper_scripts/prepare_build_linux_rc - -export DOCKERFILE_DIR=tools/dockerfile/test/bazel -export DOCKER_RUN_SCRIPT=$BAZEL_SCRIPT -# NET_ADMIN capability allows tests to manipulate network interfaces -exec tools/run_tests/dockerize/build_and_run_docker.sh --cap-add NET_ADMIN diff --git a/tools/internal_ci/linux/grpc_flaky_network.cfg b/tools/internal_ci/linux/grpc_flaky_network.cfg index 07bedd79f94..de7a3b9cd8f 100644 --- a/tools/internal_ci/linux/grpc_flaky_network.cfg +++ b/tools/internal_ci/linux/grpc_flaky_network.cfg @@ -15,7 +15,7 @@ # Config file for the internal CI (in protobuf text format) # Location of the continuous shell script in repository. -build_file: "grpc/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh" +build_file: "grpc/tools/internal_ci/linux/grpc_bazel.sh" timeout_mins: 240 env_vars { key: "BAZEL_SCRIPT" diff --git a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh index 60bb49b639a..42b6d44c1cb 100755 --- a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh +++ b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh @@ -23,9 +23,9 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc (cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \ && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') -cd /var/local/git/grpc/test/cpp/end2end +cd /var/local/git/grpc -# iptables is used to drop traffic between client and server -apt-get install -y iptables +# TODO(jtattermusch): install prerequsites if needed -bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all :flaky_network_test +# TODO(jtattermusch): run the flaky network test instead +bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/... From 6177befe94cd98906daea492f04ed9248be6b4bb Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 15 Feb 2019 14:43:15 -0800 Subject: [PATCH 405/814] Re-add cfstream_test 2nd attempt at adding cfstream_test after fixing internal build failures caused by first attempt. --- BUILD | 7 + bazel/grpc_build_system.bzl | 23 +- test/cpp/end2end/BUILD | 21 ++ test/cpp/end2end/cfstream_test.cc | 278 ++++++++++++++++++ tools/internal_ci/macos/grpc_cfstream.cfg | 19 ++ .../internal_ci/macos/grpc_run_bazel_tests.sh | 29 ++ 6 files changed, 371 insertions(+), 6 deletions(-) create mode 100644 test/cpp/end2end/cfstream_test.cc create mode 100644 tools/internal_ci/macos/grpc_cfstream.cfg create mode 100644 tools/internal_ci/macos/grpc_run_bazel_tests.sh diff --git a/BUILD b/BUILD index f0de4399beb..b9c8ea1287b 100644 --- a/BUILD +++ b/BUILD @@ -63,6 +63,11 @@ config_setting( values = {"cpu": "x64_windows_msvc"}, ) +config_setting( + name = "mac_x86_64", + values = {"cpu": "darwin"}, +) + # This should be updated along with build.yaml g_stands_for = "godric" @@ -981,6 +986,7 @@ grpc_cc_library( ], language = "c++", public_hdrs = GRPC_PUBLIC_HDRS, + use_cfstream = True, deps = [ "gpr_base", "grpc_codegen", @@ -1044,6 +1050,7 @@ grpc_cc_library( "src/core/lib/iomgr/endpoint_cfstream.h", "src/core/lib/iomgr/error_cfstream.h", ], + use_cfstream = True, deps = [ ":gpr_base", ":grpc_base", diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index be85bc87324..3ea8e305ca5 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -35,6 +35,12 @@ def if_not_windows(a): "//conditions:default": a, }) +def if_mac(a): + return select({ + "//:mac_x86_64": a, + "//conditions:default": [], + }) + def _get_external_deps(external_deps): ret = [] for dep in external_deps: @@ -73,10 +79,16 @@ def grpc_cc_library( testonly = False, visibility = None, alwayslink = 0, - data = []): + data = [], + use_cfstream = False): copts = [] + if use_cfstream: + copts = if_mac(["-DGRPC_CFSTREAM"]) if language.upper() == "C": - copts = if_not_windows(["-std=c99"]) + copts = copts + if_not_windows(["-std=c99"]) + linkopts = if_not_windows(["-pthread"]) + if use_cfstream: + linkopts = linkopts + if_mac(["-framework CoreFoundation"]) native.cc_library( name = name, srcs = srcs, @@ -98,7 +110,7 @@ def grpc_cc_library( copts = copts, visibility = visibility, testonly = testonly, - linkopts = if_not_windows(["-pthread"]), + linkopts = linkopts, includes = [ "include", ], @@ -113,7 +125,6 @@ def grpc_proto_plugin(name, srcs = [], deps = []): deps = deps, ) - def grpc_proto_library( name, srcs = [], @@ -133,9 +144,9 @@ def grpc_proto_library( ) def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = None, tags = [], exec_compatible_with = []): - copts = [] + copts = if_mac(["-DGRPC_CFSTREAM"]) if language.upper() == "C": - copts = if_not_windows(["-std=c99"]) + copts = copts + if_not_windows(["-std=c99"]) args = { "name": name, "srcs": srcs, diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index cbf09354a03..c7be9279613 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -606,3 +606,24 @@ grpc_cc_test( "//test/cpp/util:test_util", ], ) + +grpc_cc_test( + name = "cfstream_test", + srcs = ["cfstream_test.cc"], + external_deps = [ + "gtest", + ], + tags = ["manual"], # test requires root, won't work with bazel RBE + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//:grpc_cfstream", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing:simple_messages_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) diff --git a/test/cpp/end2end/cfstream_test.cc b/test/cpp/end2end/cfstream_test.cc new file mode 100644 index 00000000000..9039329d815 --- /dev/null +++ b/test/cpp/end2end/cfstream_test.cc @@ -0,0 +1,278 @@ +/* + * + * Copyright 2019 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "src/core/lib/iomgr/port.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/gpr/env.h" + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#ifdef GRPC_CFSTREAM +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +class CFStreamTest : public ::testing::Test { + protected: + CFStreamTest() + : server_host_("grpctest"), + interface_("lo0"), + ipv4_address_("10.0.0.1"), + netmask_("/32"), + kRequestMessage_("🖖") {} + + void DNSUp() { + std::ostringstream cmd; + // Add DNS entry for server_host_ in /etc/hosts + cmd << "echo '" << ipv4_address_ << " " << server_host_ + << " ' | sudo tee -a /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DNSDown() { + std::ostringstream cmd; + // Remove DNS entry for server_host_ in /etc/hosts + cmd << "sudo sed -i '.bak' '/" << server_host_ << "/d' /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void InterfaceUp() { + std::ostringstream cmd; + cmd << "sudo /sbin/ifconfig " << interface_ << " alias " << ipv4_address_; + std::system(cmd.str().c_str()); + } + + void InterfaceDown() { + std::ostringstream cmd; + cmd << "sudo /sbin/ifconfig " << interface_ << " -alias " << ipv4_address_; + std::system(cmd.str().c_str()); + } + + void NetworkUp() { + InterfaceUp(); + DNSUp(); + } + + void NetworkDown() { + InterfaceDown(); + DNSDown(); + } + + void SetUp() override { + NetworkUp(); + grpc_init(); + StartServer(); + } + + void TearDown() override { + NetworkDown(); + StopServer(); + grpc_shutdown(); + } + + void StartServer() { + port_ = grpc_pick_unused_port_or_die(); + server_.reset(new ServerData(port_)); + server_->Start(server_host_); + } + void StopServer() { server_->Shutdown(); } + + std::unique_ptr BuildStub( + const std::shared_ptr& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr BuildChannel() { + std::ostringstream server_address; + server_address << server_host_ << ":" << port_; + return CreateCustomChannel( + server_address.str(), InsecureChannelCredentials(), ChannelArguments()); + } + + void SendRpc( + const std::unique_ptr& stub, + bool expect_success = false) { + auto response = std::unique_ptr(new EchoResponse()); + EchoRequest request; + request.set_message(kRequestMessage_); + ClientContext context; + Status status = stub->Echo(&context, request, response.get()); + if (status.ok()) { + gpr_log(GPR_DEBUG, "RPC returned %s\n", response->message().c_str()); + } else { + gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); + } + if (expect_success) { + EXPECT_TRUE(status.ok()); + } + } + + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 10) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + private: + struct ServerData { + int port_; + std::unique_ptr server_; + TestServiceImpl service_; + std::unique_ptr thread_; + bool server_ready_ = false; + + explicit ServerData(int port) { port_ = port; } + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting server on port %d", port_); + std::mutex mu; + std::unique_lock lock(mu); + std::condition_variable cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.wait(lock, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + + void Serve(const grpc::string& server_host, std::mutex* mu, + std::condition_variable* cond) { + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + builder.AddListeningPort(server_address.str(), + InsecureServerCredentials()); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + std::lock_guard lock(*mu); + server_ready_ = true; + cond->notify_one(); + } + + void Shutdown(bool join = true) { + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + if (join) thread_->join(); + } + }; + + const grpc::string server_host_; + const grpc::string interface_; + const grpc::string ipv4_address_; + const grpc::string netmask_; + std::unique_ptr stub_; + std::unique_ptr server_; + int port_; + const grpc::string kRequestMessage_; +}; + +// gRPC should automatically detech network flaps (without enabling keepalives) +// when CFStream is enabled +TEST_F(CFStreamTest, NetworkTransition) { + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + SendRpc(stub, /*expect_success=*/true); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // bring down network + NetworkDown(); + + // network going down should be detected by cfstream + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + + // bring network interface back up + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + NetworkUp(); + + // channel should reconnect + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); +} + +} // namespace +} // namespace testing +} // namespace grpc +#endif // GRPC_CFSTREAM + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_test_init(argc, argv); + gpr_setenv("grpc_cfstream", "1"); + // TODO (pjaikumar): remove the line below when + // https://github.com/grpc/grpc/issues/18080 has been fixed. + gpr_setenv("GRPC_DNS_RESOLVER", "native"); + const auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/tools/internal_ci/macos/grpc_cfstream.cfg b/tools/internal_ci/macos/grpc_cfstream.cfg new file mode 100644 index 00000000000..2b1ce0a89c7 --- /dev/null +++ b/tools/internal_ci/macos/grpc_cfstream.cfg @@ -0,0 +1,19 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_bazel_tests.sh" + diff --git a/tools/internal_ci/macos/grpc_run_bazel_tests.sh b/tools/internal_ci/macos/grpc_run_bazel_tests.sh new file mode 100644 index 00000000000..ef02a675d5b --- /dev/null +++ b/tools/internal_ci/macos/grpc_run_bazel_tests.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -ex + +# change to grpc repo root +cd $(dirname $0)/../../.. + + +./tools/run_tests/start_port_server.py + +# run cfstream_test separately because it messes with the network +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all //test/cpp/end2end:cfstream_test + +# kill port_server.py to prevent the build from hanging +ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9 + From 1ee4706c7d913bf683ec8e9cb48d17337d400a00 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 15 Feb 2019 15:05:23 -0800 Subject: [PATCH 406/814] Fixed cast in endpoint_cfstream.cc --- src/core/lib/iomgr/endpoint_cfstream.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index 7c4bc1ace2a..25146e7861c 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -182,7 +182,7 @@ static void ReadAction(void* arg, grpc_error* error) { GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), ep)); EP_UNREF(ep, "read"); } else { - if (read_size < len) { + if (read_size < static_cast(len)) { grpc_slice_buffer_trim_end(ep->read_slices, len - read_size, nullptr); } CallReadCb(ep, GRPC_ERROR_NONE); @@ -217,7 +217,7 @@ static void WriteAction(void* arg, grpc_error* error) { CallWriteCb(ep, error); EP_UNREF(ep, "write"); } else { - if (write_size < GRPC_SLICE_LENGTH(slice)) { + if (write_size < static_cast(GRPC_SLICE_LENGTH(slice))) { grpc_slice_buffer_undo_take_first( ep->write_slices, grpc_slice_sub(slice, write_size, slice_len)); } From 3c61849461adb38c794fadbc2c094e2dd01ebe1d Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 15 Feb 2019 15:48:52 -0800 Subject: [PATCH 407/814] python changes --- src/core/lib/iomgr/fork_posix.cc | 1 - src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi | 2 +- src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi | 2 +- .../grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi | 2 +- .../grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi | 8 ++++---- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi | 2 +- src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi | 2 +- src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi | 2 +- 8 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index 09e30f29d5b..86bfb01a4ef 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -49,7 +49,6 @@ bool registered_handlers = false; void grpc_prefork() { skipped_handler = true; - grpc_maybe_wait_for_async_shutdown(); // This may be called after core shuts down, so verify initialized before // instantiating an ExecCtx. if (!grpc_is_initialized()) { diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi index 24e85b08e72..0a31d9c52ff 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi @@ -87,7 +87,7 @@ cdef class Call: def __dealloc__(self): if self.c_call != NULL: grpc_call_unref(self.c_call) - grpc_shutdown() + grpc_shutdown_blocking() # The object *should* always be valid from Python. Used for debugging. @property diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index 70d4abb7308..24c11e63a6b 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -399,7 +399,7 @@ cdef _close(Channel channel, grpc_status_code code, object details, _destroy_c_completion_queue(state.c_connectivity_completion_queue) grpc_channel_destroy(state.c_channel) state.c_channel = NULL - grpc_shutdown() + grpc_shutdown_blocking() state.condition.notify_all() else: # Another call to close already completed in the past or is currently diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi index 3c33b46dbb8..a4d425ac564 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -118,4 +118,4 @@ cdef class CompletionQueue: self.c_completion_queue, c_deadline, NULL) self._interpret_event(event) grpc_completion_queue_destroy(self.c_completion_queue) - grpc_shutdown() + grpc_shutdown_blocking() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 2f51be40ce4..5fb9ddf7b7d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -61,7 +61,7 @@ cdef int _get_metadata( cdef void _destroy(void *state) with gil: cpython.Py_DECREF(state) - grpc_shutdown() + grpc_shutdown_blocking() cdef class MetadataPluginCallCredentials(CallCredentials): @@ -125,7 +125,7 @@ cdef class SSLSessionCacheLRU: def __dealloc__(self): if self._cache != NULL: grpc_ssl_session_cache_destroy(self._cache) - grpc_shutdown() + grpc_shutdown_blocking() cdef class SSLChannelCredentials(ChannelCredentials): @@ -191,7 +191,7 @@ cdef class ServerCertificateConfig: def __dealloc__(self): grpc_ssl_server_certificate_config_destroy(self.c_cert_config) gpr_free(self.c_ssl_pem_key_cert_pairs) - grpc_shutdown() + grpc_shutdown_blocking() cdef class ServerCredentials: @@ -207,7 +207,7 @@ cdef class ServerCredentials: def __dealloc__(self): if self.c_credentials != NULL: grpc_server_credentials_release(self.c_credentials) - grpc_shutdown() + grpc_shutdown_blocking() cdef const char* _get_c_pem_root_certs(pem_root_certs): if pem_root_certs is None: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index fc7a9ba4395..759479089d4 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -319,7 +319,7 @@ cdef extern from "grpc/grpc.h": grpc_op_data data void grpc_init() nogil - void grpc_shutdown() nogil + void grpc_shutdown_blocking() nogil int grpc_is_initialized() nogil ctypedef struct grpc_completion_queue_factory: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index fe98d559f34..d612199a482 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -134,7 +134,7 @@ cdef class CallDetails: def __dealloc__(self): with nogil: grpc_call_details_destroy(&self.c_details) - grpc_shutdown() + grpc_shutdown_blocking() @property def method(self): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index ef74f61e043..fe55ea885e4 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -151,4 +151,4 @@ cdef class Server: def __dealloc__(self): if self.c_server == NULL: - grpc_shutdown() + grpc_shutdown_blocking() From 86b23adc7f4f61a9616ecf1f1469069df78bf5b0 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 15 Feb 2019 16:25:11 -0800 Subject: [PATCH 408/814] Other comments --- include/grpc/grpc.h | 7 +++--- src/core/lib/gprpp/thd.h | 11 ++------- src/core/lib/gprpp/thd_posix.cc | 24 ++++++------------- src/core/lib/gprpp/thd_windows.cc | 15 +++++------- src/core/lib/surface/init.cc | 22 +++++++---------- .../resolvers/dns_resolver_cooldown_test.cc | 5 ++-- test/core/end2end/fuzzers/api_fuzzer.cc | 4 +--- test/core/end2end/fuzzers/client_fuzzer.cc | 2 +- .../readahead_handshaker_server_ssl.cc | 4 +--- test/core/json/fuzzer.cc | 6 +---- test/core/security/ssl_server_fuzzer.cc | 10 ++------ 11 files changed, 34 insertions(+), 76 deletions(-) diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index eb4248f8eb1..c4715ccc05e 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -75,10 +75,9 @@ GRPCAPI void grpc_init(void); The last call to grpc_shutdown will initiate cleaning up of grpc library internals, which can happen in another thread. Once the clean-up is done, - no memory is used by grpc after this call returns, nor are any instructions - executing within the grpc library. - Prior to calling, all application owned grpc objects must have been - destroyed. */ + no memory is used by grpc, nor are any instructions executing within the + grpc library. Prior to calling, all application owned grpc objects must + have been destroyed. */ GRPCAPI void grpc_shutdown(void); /** EXPERIMENTAL. Returns 1 if the grpc library has been initialized. diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index c9e2b9ce929..a15219a9ec6 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -49,23 +49,16 @@ class Thread { public: class Options { public: - Options() : joinable_(true), tracked_(true) {} + Options() : joinable_(true) {} + /// Set whether the thread is joinable or detached. Options& set_joinable(bool joinable) { joinable_ = joinable; return *this; } - Options& set_tracked(bool tracked) { - tracked_ = tracked; - return *this; - } bool joinable() const { return joinable_; } - bool tracked() const { return tracked_; } private: bool joinable_; - // Whether this thread is tracked by grpc internals. Should be true for most - // of threads. - bool tracked_; }; /// Default constructor only to allow use in structs that lack constructors /// Does not produce a validly-constructed thread; must later diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 9c42a049f42..915f0587f7d 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -45,11 +45,9 @@ struct thd_arg { void* arg; /* argument to a thread */ const char* name; /* name of thread. Can be nullptr. */ bool joinable; - bool tracked; }; -class ThreadInternalsPosix - : public grpc_core::internal::ThreadInternalsInterface { +class ThreadInternalsPosix : public internal::ThreadInternalsInterface { public: ThreadInternalsPosix(const char* thd_name, void (*thd_body)(void* arg), void* arg, bool* success, const Thread::Options& options) @@ -66,10 +64,7 @@ class ThreadInternalsPosix info->arg = arg; info->name = thd_name; info->joinable = options.joinable(); - info->tracked = options.tracked(); - if (options.tracked()) { - grpc_core::Fork::IncThreadCount(); - } + Fork::IncThreadCount(); GPR_ASSERT(pthread_attr_init(&attr) == 0); if (options.joinable()) { @@ -109,13 +104,11 @@ class ThreadInternalsPosix gpr_mu_unlock(&arg.thread->mu_); if (!arg.joinable) { - grpc_core::Delete(arg.thread); + Delete(arg.thread); } (*arg.body)(arg.arg); - if (arg.tracked) { - grpc_core::Fork::DecThreadCount(); - } + Fork::DecThreadCount(); return nullptr; }, info) == 0); @@ -125,9 +118,7 @@ class ThreadInternalsPosix if (!(*success)) { /* don't use gpr_free, as this was allocated using malloc (see above) */ free(info); - if (options.tracked()) { - grpc_core::Fork::DecThreadCount(); - } + Fork::DecThreadCount(); } } @@ -158,13 +149,12 @@ Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, bool* success, const Options& options) : options_(options) { bool outcome = false; - impl_ = grpc_core::New(thd_name, thd_body, arg, - &outcome, options); + impl_ = New(thd_name, thd_body, arg, &outcome, options); if (outcome) { state_ = ALIVE; } else { state_ = FAILED; - grpc_core::Delete(impl_); + Delete(impl_); impl_ = nullptr; } diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index b7828660eba..315f66f8269 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -41,6 +41,7 @@ #error "Unknown compiler - please file a bug report" #endif +namespace grpc_core { namespace { class ThreadInternalsWindows; struct thd_info { @@ -53,11 +54,10 @@ struct thd_info { thread_local struct thd_info* g_thd_info; -class ThreadInternalsWindows - : public grpc_core::internal::ThreadInternalsInterface { +class ThreadInternalsWindows : public internal::ThreadInternalsInterface { public: ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success, - const grpc_core::Thread::Options& options) + const Thread::Options& options) : started_(false) { gpr_mu_init(&mu_); gpr_cv_init(&ready_); @@ -88,7 +88,7 @@ class ThreadInternalsWindows } gpr_mu_unlock(&g_thd_info->thread->mu_); if (!g_thd_info->joinable) { - grpc_core::Delete(g_thd_info->thread); + Delete(g_thd_info->thread); g_thd_info->thread = nullptr; } g_thd_info->body(g_thd_info->arg); @@ -144,19 +144,16 @@ class ThreadInternalsWindows } // namespace -namespace grpc_core { - Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, bool* success, const Options& options) : options_(options) { bool outcome = false; - impl_ = - grpc_core::New(thd_body, arg, &outcome, options); + impl_ = New(thd_body, arg, &outcome, options); if (outcome) { state_ = ALIVE; } else { state_ = FAILED; - grpc_core::Delete(impl_); + Delete(impl_); impl_ = nullptr; } diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index d8eeaf1c424..4920ef81596 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -33,6 +33,7 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/fork.h" +#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/call_combiner.h" #include "src/core/lib/iomgr/combiner.h" @@ -123,7 +124,7 @@ void grpc_init(void) { int i; gpr_once_init(&g_basic_init, do_basic_init); - gpr_mu_lock(&g_init_mu); + grpc_core::MutexLock lock(&g_init_mu); if (++g_initializations == 1) { if (g_shutting_down) { g_shutting_down = false; @@ -159,7 +160,6 @@ void grpc_init(void) { grpc_channel_init_finalize(); grpc_iomgr_start(); } - gpr_mu_unlock(&g_init_mu); GRPC_API_TRACE("grpc_init(void)", 0, ()); } @@ -196,20 +196,18 @@ void grpc_shutdown_internal_locked(void) { void grpc_shutdown_internal(void* ignored) { GRPC_API_TRACE("grpc_shutdown_internal", 0, ()); - gpr_mu_lock(&g_init_mu); + grpc_core::MutexLock lock(&g_init_mu); // We have released lock from the shutdown thread and it is possible that // another grpc_init has been called, and do nothing if that is the case. if (--g_initializations != 0) { - gpr_mu_unlock(&g_init_mu); return; } grpc_shutdown_internal_locked(); - gpr_mu_unlock(&g_init_mu); } void grpc_shutdown(void) { GRPC_API_TRACE("grpc_shutdown(void)", 0, ()); - gpr_mu_lock(&g_init_mu); + grpc_core::MutexLock lock(&g_init_mu); if (--g_initializations == 0) { g_initializations++; g_shutting_down = true; @@ -217,37 +215,33 @@ void grpc_shutdown(void) { // currently in an executor thread. grpc_core::Thread cleanup_thread( "grpc_shutdown", grpc_shutdown_internal, nullptr, nullptr, - grpc_core::Thread::Options().set_joinable(false).set_tracked(false)); + grpc_core::Thread::Options().set_joinable(false)); cleanup_thread.Start(); } - gpr_mu_unlock(&g_init_mu); } void grpc_shutdown_blocking(void) { GRPC_API_TRACE("grpc_shutdown_blocking(void)", 0, ()); - gpr_mu_lock(&g_init_mu); + grpc_core::MutexLock lock(&g_init_mu); if (--g_initializations == 0) { g_shutting_down = true; grpc_shutdown_internal_locked(); } - gpr_mu_unlock(&g_init_mu); } int grpc_is_initialized(void) { int r; gpr_once_init(&g_basic_init, do_basic_init); - gpr_mu_lock(&g_init_mu); + grpc_core::MutexLock lock(&g_init_mu); r = g_initializations > 0; - gpr_mu_unlock(&g_init_mu); return r; } void grpc_maybe_wait_for_async_shutdown(void) { gpr_once_init(&g_basic_init, do_basic_init); - gpr_mu_lock(&g_init_mu); + grpc_core::MutexLock lock(&g_init_mu); while (g_shutting_down) { gpr_cv_wait(g_shutting_down_cv, &g_init_mu, gpr_inf_future(GPR_CLOCK_REALTIME)); } - gpr_mu_unlock(&g_init_mu); } diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index cd9d273c132..3157d6019f3 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -18,6 +18,7 @@ #include +#include #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" @@ -27,7 +28,6 @@ #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" -#include "src/core/lib/surface/init.h" #include "test/core/util/test_config.h" constexpr int kMinResolutionPeriodMs = 1000; @@ -282,8 +282,7 @@ int main(int argc, char** argv) { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); } - grpc_shutdown(); - grpc_maybe_wait_for_async_shutdown(); + grpc_shutdown_blocking(); GPR_ASSERT(g_all_callbacks_invoked); return 0; } diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index 1c89bdece56..74a30913b24 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -35,7 +35,6 @@ #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/timer_manager.h" #include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/surface/init.h" #include "src/core/lib/surface/server.h" #include "src/core/lib/transport/metadata.h" #include "test/core/end2end/data/ssl_test_data.h" @@ -1201,7 +1200,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_resource_quota_unref(g_resource_quota); - grpc_shutdown(); - grpc_maybe_wait_for_async_shutdown(); + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/end2end/fuzzers/client_fuzzer.cc b/test/core/end2end/fuzzers/client_fuzzer.cc index 5acf1dd27ef..55e6ce695ad 100644 --- a/test/core/end2end/fuzzers/client_fuzzer.cc +++ b/test/core/end2end/fuzzers/client_fuzzer.cc @@ -158,6 +158,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_byte_buffer_destroy(response_payload_recv); } } - grpc_shutdown(); + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc index 493f61c3ddf..d91f2d2fe63 100644 --- a/test/core/handshake/readahead_handshaker_server_ssl.cc +++ b/test/core/handshake/readahead_handshaker_server_ssl.cc @@ -37,7 +37,6 @@ #include "src/core/lib/channel/handshaker_factory.h" #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/security/transport/security_handshaker.h" -#include "src/core/lib/surface/init.h" #include "test/core/handshake/server_ssl_common.h" @@ -84,7 +83,6 @@ int main(int argc, char* argv[]) { UniquePtr(New())); const char* full_alpn_list[] = {"grpc-exp", "h2"}; GPR_ASSERT(server_ssl_test(full_alpn_list, 2, "grpc-exp")); - grpc_shutdown(); - grpc_maybe_wait_for_async_shutdown(); + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/json/fuzzer.cc b/test/core/json/fuzzer.cc index 6dafabb95b3..77a10a17678 100644 --- a/test/core/json/fuzzer.cc +++ b/test/core/json/fuzzer.cc @@ -31,8 +31,7 @@ bool leak_check = true; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { char* s; - struct grpc_memory_counters counters; - grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(leak_check); s = static_cast(gpr_malloc(size)); memcpy(s, data, size); grpc_json* x; @@ -40,8 +39,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_json_destroy(x); } gpr_free(s); - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); return 0; } diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc index 8533644aceb..5846964eb90 100644 --- a/test/core/security/ssl_server_fuzzer.cc +++ b/test/core/security/ssl_server_fuzzer.cc @@ -52,9 +52,8 @@ static void on_handshake_done(void* arg, grpc_error* error) { } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - if (leak_check) grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(leak_check); grpc_init(); { grpc_core::ExecCtx exec_ctx; @@ -118,11 +117,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_core::ExecCtx::Get()->Flush(); } - grpc_shutdown(); - if (leak_check) { - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); - } + grpc_shutdown_blocking(); return 0; } From ff0d2195cfe13545d7a59357590bae49498e0db0 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 15 Feb 2019 17:00:21 -0800 Subject: [PATCH 409/814] address comments --- .../grpcio_tests/tests/fork/_fork_interop_test.py | 2 +- src/python/grpcio_tests/tests/fork/methods.py | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/python/grpcio_tests/tests/fork/_fork_interop_test.py b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py index bbcfb7446a9..608148dfe46 100644 --- a/src/python/grpcio_tests/tests/fork/_fork_interop_test.py +++ b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py @@ -139,7 +139,7 @@ class ForkInteropTest(unittest.TestCase): out, err = process.communicate() except subprocess.TimeoutExpired: process.kill() - raise ValueError('Process failed to terminate') + raise RuntimeError('Process failed to terminate') finally: timer.cancel() self.assertEqual( diff --git a/src/python/grpcio_tests/tests/fork/methods.py b/src/python/grpcio_tests/tests/fork/methods.py index 9481d004cd9..a060ba6e581 100644 --- a/src/python/grpcio_tests/tests/fork/methods.py +++ b/src/python/grpcio_tests/tests/fork/methods.py @@ -136,7 +136,7 @@ class _ChildProcess(object): def finish(self): self._process.join(timeout=_CHILD_FINISH_TIMEOUT_S) if self._process.is_alive(): - raise ValueError('Child process did not terminate') + raise RuntimeError('Child process did not terminate') if self._process.exitcode != 0: raise ValueError('Child process failed with exitcode %d' % self._process.exitcode) @@ -236,6 +236,9 @@ def _close_channel_before_fork(channel, args): def _connectivity_watch(channel, args): + parent_states = [] + parent_channel_ready_event = threading.Event() + def child_target(): child_channel_ready_event = threading.Event() @@ -244,7 +247,6 @@ def _connectivity_watch(channel, args): if state is grpc.ChannelConnectivity.READY: child_channel_ready_event.set() - child_states = [] with _channel(args) as child_channel: child_stub = test_pb2_grpc.TestServiceStub(child_channel) child_channel.subscribe(child_connectivity_callback) @@ -257,9 +259,6 @@ def _connectivity_watch(channel, args): parent_states) child_channel.unsubscribe(child_connectivity_callback) - parent_states = [] - parent_channel_ready_event = threading.Event() - def parent_connectivity_callback(state): parent_states.append(state) if state is grpc.ChannelConnectivity.READY: @@ -275,11 +274,6 @@ def _connectivity_watch(channel, args): channel.unsubscribe(parent_connectivity_callback) child_process.finish() - # Need to unsubscribe or _channel.py in _poll_connectivity triggers a - # "Cannot invoke RPC on closed channel!" error. - # TODO(ericgribkoff) Fix issue with channel.close() and connectivity polling - channel.unsubscribe(parent_connectivity_callback) - def _ping_pong_with_child_processes_after_first_response( channel, args, child_target, run_after_close=True): From 6b67506bae17825fdbbea5b5e62118c7644add66 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 15 Feb 2019 21:50:39 -0800 Subject: [PATCH 410/814] Add back tracked --- src/core/lib/gprpp/thd.h | 10 +++++++++- src/core/lib/gprpp/thd_posix.cc | 14 +++++++++++--- src/core/lib/gprpp/thd_windows.cc | 6 +++++- src/core/lib/surface/init.cc | 2 +- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index a15219a9ec6..fca9afed1d7 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -49,7 +49,7 @@ class Thread { public: class Options { public: - Options() : joinable_(true) {} + Options() : joinable_(true), tracked_(true) {} /// Set whether the thread is joinable or detached. Options& set_joinable(bool joinable) { joinable_ = joinable; @@ -57,8 +57,16 @@ class Thread { } bool joinable() const { return joinable_; } + /// Set whether the thread is tracked for fork support. + Options& set_tracked(bool tracked) { + tracked_ = tracked; + return *this; + } + bool tracked() const { return tracked_; } + private: bool joinable_; + bool tracked_; }; /// Default constructor only to allow use in structs that lack constructors /// Does not produce a validly-constructed thread; must later diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 915f0587f7d..28932081538 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -45,6 +45,7 @@ struct thd_arg { void* arg; /* argument to a thread */ const char* name; /* name of thread. Can be nullptr. */ bool joinable; + bool tracked; }; class ThreadInternalsPosix : public internal::ThreadInternalsInterface { @@ -64,7 +65,10 @@ class ThreadInternalsPosix : public internal::ThreadInternalsInterface { info->arg = arg; info->name = thd_name; info->joinable = options.joinable(); - Fork::IncThreadCount(); + info->tracked = options.tracked(); + if (options.tracked()) { + Fork::IncThreadCount(); + } GPR_ASSERT(pthread_attr_init(&attr) == 0); if (options.joinable()) { @@ -108,7 +112,9 @@ class ThreadInternalsPosix : public internal::ThreadInternalsInterface { } (*arg.body)(arg.arg); - Fork::DecThreadCount(); + if (arg.tracked) { + Fork::DecThreadCount(); + } return nullptr; }, info) == 0); @@ -118,7 +124,9 @@ class ThreadInternalsPosix : public internal::ThreadInternalsInterface { if (!(*success)) { /* don't use gpr_free, as this was allocated using malloc (see above) */ free(info); - Fork::DecThreadCount(); + if (options.tracked()) { + Fork::DecThreadCount(); + } } } diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index 315f66f8269..5f555fecf5e 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -41,7 +41,6 @@ #error "Unknown compiler - please file a bug report" #endif -namespace grpc_core { namespace { class ThreadInternalsWindows; struct thd_info { @@ -54,6 +53,11 @@ struct thd_info { thread_local struct thd_info* g_thd_info; +} // namespace + +namespace grpc_core { +namespace { + class ThreadInternalsWindows : public internal::ThreadInternalsInterface { public: ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success, diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 4920ef81596..fdb584da68f 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -215,7 +215,7 @@ void grpc_shutdown(void) { // currently in an executor thread. grpc_core::Thread cleanup_thread( "grpc_shutdown", grpc_shutdown_internal, nullptr, nullptr, - grpc_core::Thread::Options().set_joinable(false)); + grpc_core::Thread::Options().set_joinable(false).set_tracked(false)); cleanup_thread.Start(); } } From 298cb4ed90bd14db961a2ce16ca5a0132c52a8e4 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 15 Feb 2019 22:29:13 -0800 Subject: [PATCH 411/814] Fix windows build --- src/core/lib/gprpp/thd_windows.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index 5f555fecf5e..492fa19283d 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -53,15 +53,11 @@ struct thd_info { thread_local struct thd_info* g_thd_info; -} // namespace - -namespace grpc_core { -namespace { - -class ThreadInternalsWindows : public internal::ThreadInternalsInterface { +class ThreadInternalsWindows + : public grpc_core::internal::ThreadInternalsInterface { public: ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success, - const Thread::Options& options) + const grpc_core::Thread::Options& options) : started_(false) { gpr_mu_init(&mu_); gpr_cv_init(&ready_); @@ -92,7 +88,7 @@ class ThreadInternalsWindows : public internal::ThreadInternalsInterface { } gpr_mu_unlock(&g_thd_info->thread->mu_); if (!g_thd_info->joinable) { - Delete(g_thd_info->thread); + grpc_core::Delete(g_thd_info->thread); g_thd_info->thread = nullptr; } g_thd_info->body(g_thd_info->arg); @@ -148,6 +144,8 @@ class ThreadInternalsWindows : public internal::ThreadInternalsInterface { } // namespace +namespace grpc_core { + Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, bool* success, const Options& options) : options_(options) { From 3227abf7176601fe0f4f7df13bc2e47ce6a19bbc Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 15 Feb 2019 22:57:44 -0800 Subject: [PATCH 412/814] fix percent en/decode fuzzers --- test/core/slice/percent_decode_fuzzer.cc | 29 ++++++++++--------- test/core/slice/percent_encode_fuzzer.cc | 36 +++++++++++++----------- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/test/core/slice/percent_decode_fuzzer.cc b/test/core/slice/percent_decode_fuzzer.cc index 762e86f23a3..11f71d92c46 100644 --- a/test/core/slice/percent_decode_fuzzer.cc +++ b/test/core/slice/percent_decode_fuzzer.cc @@ -31,20 +31,23 @@ bool squelch = true; bool leak_check = true; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - grpc_core::testing::LeakDetector leak_detector(true); grpc_init(); - grpc_slice input = grpc_slice_from_copied_buffer((const char*)data, size); - grpc_slice output; - if (grpc_strict_percent_decode_slice( - input, grpc_url_percent_encoding_unreserved_bytes, &output)) { - grpc_slice_unref(output); + { + grpc_core::testing::LeakDetector leak_detector(true); + grpc_slice input = grpc_slice_from_copied_buffer((const char*)data, size); + grpc_slice output; + if (grpc_strict_percent_decode_slice( + input, grpc_url_percent_encoding_unreserved_bytes, &output)) { + grpc_slice_unref(output); + } + if (grpc_strict_percent_decode_slice( + input, grpc_compatible_percent_encoding_unreserved_bytes, + &output)) { + grpc_slice_unref(output); + } + grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); + grpc_slice_unref(input); } - if (grpc_strict_percent_decode_slice( - input, grpc_compatible_percent_encoding_unreserved_bytes, &output)) { - grpc_slice_unref(output); - } - grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); - grpc_slice_unref(input); - grpc_shutdown(); + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/slice/percent_encode_fuzzer.cc b/test/core/slice/percent_encode_fuzzer.cc index 782149cd867..1da982bba28 100644 --- a/test/core/slice/percent_encode_fuzzer.cc +++ b/test/core/slice/percent_encode_fuzzer.cc @@ -31,24 +31,26 @@ bool squelch = true; bool leak_check = true; static void test(const uint8_t* data, size_t size, const uint8_t* dict) { - grpc_core::testing::LeakDetector leak_detector(true); grpc_init(); - grpc_slice input = - grpc_slice_from_copied_buffer(reinterpret_cast(data), size); - grpc_slice output = grpc_percent_encode_slice(input, dict); - grpc_slice decoded_output; - // encoder must always produce decodable output - GPR_ASSERT(grpc_strict_percent_decode_slice(output, dict, &decoded_output)); - grpc_slice permissive_decoded_output = - grpc_permissive_percent_decode_slice(output); - // and decoded output must always match the input - GPR_ASSERT(grpc_slice_eq(input, decoded_output)); - GPR_ASSERT(grpc_slice_eq(input, permissive_decoded_output)); - grpc_slice_unref(input); - grpc_slice_unref(output); - grpc_slice_unref(decoded_output); - grpc_slice_unref(permissive_decoded_output); - grpc_shutdown(); + { + grpc_core::testing::LeakDetector leak_detector(true); + grpc_slice input = grpc_slice_from_copied_buffer( + reinterpret_cast(data), size); + grpc_slice output = grpc_percent_encode_slice(input, dict); + grpc_slice decoded_output; + // encoder must always produce decodable output + GPR_ASSERT(grpc_strict_percent_decode_slice(output, dict, &decoded_output)); + grpc_slice permissive_decoded_output = + grpc_permissive_percent_decode_slice(output); + // and decoded output must always match the input + GPR_ASSERT(grpc_slice_eq(input, decoded_output)); + GPR_ASSERT(grpc_slice_eq(input, permissive_decoded_output)); + grpc_slice_unref(input); + grpc_slice_unref(output); + grpc_slice_unref(decoded_output); + grpc_slice_unref(permissive_decoded_output); + } + grpc_shutdown_blocking(); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { From cf5cffcc2d14ae3faa3fcc0d5a641e6579be4a49 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 16 Feb 2019 15:58:06 +0100 Subject: [PATCH 413/814] csproj cleanup --- src/csharp/Grpc.Auth/Grpc.Auth.csproj | 17 +++++++++-------- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 17 +++++++++-------- .../Grpc.Core.NativeDebug.csproj | 17 +++++++++-------- .../Grpc.Core.Testing/Grpc.Core.Testing.csproj | 18 +++++++++--------- .../Grpc.Core.Tests/Grpc.Core.Tests.csproj | 2 -- src/csharp/Grpc.Core/Grpc.Core.csproj | 17 +++++++++-------- .../Grpc.Examples.MathClient.csproj | 2 -- .../Grpc.Examples.MathServer.csproj | 2 -- .../Grpc.Examples.Tests.csproj | 2 -- src/csharp/Grpc.Examples/Grpc.Examples.csproj | 2 -- .../Grpc.HealthCheck.Tests.csproj | 2 -- .../Grpc.HealthCheck/Grpc.HealthCheck.csproj | 17 +++++++++-------- .../Grpc.IntegrationTesting.Client.csproj | 2 -- .../Grpc.IntegrationTesting.QpsWorker.csproj | 2 -- .../Grpc.IntegrationTesting.Server.csproj | 2 -- ...Grpc.IntegrationTesting.StressClient.csproj | 2 -- .../Grpc.IntegrationTesting.csproj | 2 -- .../Grpc.Microbenchmarks.csproj | 2 -- .../Grpc.Reflection.Tests.csproj | 2 -- .../Grpc.Reflection/Grpc.Reflection.csproj | 17 +++++++++-------- src/csharp/Grpc/Grpc.csproj | 17 +++++++++-------- 21 files changed, 72 insertions(+), 91 deletions(-) diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj index 5bbff389487..bf5b14061a5 100755 --- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj +++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj @@ -4,17 +4,18 @@ - Copyright 2015, Google Inc. - gRPC C# Auth - $(GrpcCsharpVersion) Google Inc. + Copyright 2015, Google Inc. + gRPC C# Authentication Library + https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc + gRPC RPC Protocol HTTP/2 Auth OAuth2 + $(GrpcCsharpVersion) + + + net45;netstandard1.5 $(DefineConstants);SIGNED - Grpc.Auth - Grpc.Auth - gRPC RPC Protocol HTTP/2 Auth OAuth2 - https://github.com/grpc/grpc - https://github.com/grpc/grpc/blob/master/LICENSE true true diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index eec8fc56de0..2fb8a2544ca 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -4,16 +4,17 @@ - Copyright 2019, Google Inc. - gRPC C# Surface API - $(GrpcCsharpVersion) Google Inc. - net45;netstandard1.5 - Grpc.Core.Api - Grpc.Core.Api - gRPC RPC Protocol HTTP/2 - https://github.com/grpc/grpc + Copyright 2019, Google Inc. + gRPC C# Surface API https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc + gRPC RPC Protocol HTTP/2 + $(GrpcCsharpVersion) + + + + net45;netstandard1.5 true true diff --git a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj index 5f1cac05425..71a35818632 100644 --- a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj +++ b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj @@ -4,16 +4,17 @@ - Copyright 2015, Google Inc. - Grpc.Core: Native Debug Symbols - Debug symbols for the native library contained in Grpc.Core - $(GrpcCsharpVersion) Google Inc. - net45;netstandard1.5 - Grpc.Core.NativeDebug - gRPC RPC Protocol HTTP/2 - https://github.com/grpc/grpc + Copyright 2015, Google Inc. + Debug symbols for the native library contained in Grpc.Core https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc + gRPC RPC Protocol HTTP/2 + $(GrpcCsharpVersion) + + + + net45;netstandard1.5 false true diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj index 40840d4da3e..0f184780663 100755 --- a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj +++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj @@ -4,17 +4,17 @@ - Copyright 2017, Google Inc. - gRPC C# Core Testing - $(GrpcCsharpVersion) Google Inc. - net45;netstandard1.5 - true - Grpc.Core.Testing - Grpc.Core.Testing - gRPC test testing - https://github.com/grpc/grpc + gRPC C#: Utility code for testing Grpc.Core + Copyright 2017, Google Inc. https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc + gRPC test testing + $(GrpcCsharpVersion) + + + + net45;netstandard1.5 true true diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index 178931a3d72..2a3e30174c0 100755 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.Core.Tests Exe - Grpc.Core.Tests true diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 43ace08e52c..3b34a7fab7e 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -4,16 +4,17 @@ - Copyright 2015, Google Inc. - gRPC C# Core - $(GrpcCsharpVersion) Google Inc. - net45;netstandard1.5 - Grpc.Core - Grpc.Core - gRPC RPC Protocol HTTP/2 - https://github.com/grpc/grpc + Copyright 2015, Google Inc. + C# implementation of gRPC - an RPC library and framework. https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc + gRPC RPC Protocol HTTP/2 + $(GrpcCsharpVersion) + + + + net45;netstandard1.5 true true diff --git a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj index 1afcd9fba0c..557f4639bd5 100755 --- a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj +++ b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.Examples.MathClient Exe - Grpc.Examples.MathClient true diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj index 75ef6d1008b..557f4639bd5 100755 --- a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj +++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.Examples.MathServer Exe - Grpc.Examples.MathServer true diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index 93d112a0c53..e2d988a8662 100755 --- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj +++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.Examples.Tests Exe - Grpc.Examples.Tests true diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj index 9ce2b59d036..5e532b11982 100755 --- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj +++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj @@ -5,8 +5,6 @@ net45;netcoreapp1.1 - Grpc.Examples - Grpc.Examples true diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj index 2a037a72e51..6b9e37b3e6c 100755 --- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj +++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.HealthCheck.Tests Exe - Grpc.HealthCheck.Tests true diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index da61253455a..cdbdfde60f3 100755 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -4,16 +4,17 @@ - Copyright 2015, Google Inc. - gRPC C# Healthchecking - $(GrpcCsharpVersion) Google Inc. - net45;netstandard1.5 - Grpc.HealthCheck - Grpc.HealthCheck - gRPC health check - https://github.com/grpc/grpc + Copyright 2015, Google Inc. + gRPC C# Health Checking Implementation https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc + gRPC health check + $(GrpcCsharpVersion) + + + + net45;netstandard1.5 true true diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj index 1cd4b83e1ed..5b29bf0a72f 100755 --- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.IntegrationTesting.Client Exe - Grpc.IntegrationTesting.Client true diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj index 2890a7df588..c8bd3e3f186 100755 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.IntegrationTesting.QpsWorker Exe - Grpc.IntegrationTesting.QpsWorker true true diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj index ee718958bcf..5b29bf0a72f 100755 --- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.IntegrationTesting.Server Exe - Grpc.IntegrationTesting.Server true diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj index 99926497e4e..5b29bf0a72f 100755 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.IntegrationTesting.StressClient Exe - Grpc.IntegrationTesting.StressClient true diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index c342f8a107c..6bf5d220e4b 100755 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.IntegrationTesting Exe - Grpc.IntegrationTesting true diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index 5b1656080ae..f30b90b5130 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.Microbenchmarks Exe - Grpc.Microbenchmarks true diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj index 8b586c6ecb7..0fb0726d7aa 100755 --- a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj +++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj @@ -5,9 +5,7 @@ net45;netcoreapp1.1 - Grpc.Reflection.Tests Exe - Grpc.Reflection.Tests true diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj index 862ecda5fd9..c533a0ab5a9 100755 --- a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj +++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj @@ -4,16 +4,17 @@ - Copyright 2016, Google Inc. - gRPC C# Reflection - $(GrpcCsharpVersion) Google Inc. - net45;netstandard1.5 - Grpc.Reflection - Grpc.Reflection - gRPC reflection - https://github.com/grpc/grpc + Copyright 2016, Google Inc. + gRPC C# Reflection https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc + gRPC reflection + $(GrpcCsharpVersion) + + + + net45;netstandard1.5 true true diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj index 9f17e319714..0d23dcc0234 100644 --- a/src/csharp/Grpc/Grpc.csproj +++ b/src/csharp/Grpc/Grpc.csproj @@ -4,16 +4,17 @@ - Copyright 2015, Google Inc. - gRPC C# - C# implementation of gRPC - an RPC library and framework. - $(GrpcCsharpVersion) Google Inc. - net45;netstandard1.5 - Grpc - gRPC RPC Protocol HTTP/2 - https://github.com/grpc/grpc + Copyright 2015, Google Inc. + C# implementation of gRPC - an RPC library and framework. https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc + gRPC RPC Protocol HTTP/2 + $(GrpcCsharpVersion) + + + + net45;netstandard1.5 false true From 7ace2a52401cb0170bf11bcfef3164d900fb84ee Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 16 Feb 2019 17:14:13 +0100 Subject: [PATCH 414/814] cleanup Grpc.Tools.csproj --- src/csharp/Grpc.Tools/Grpc.Tools.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index aa39dd0fe9b..d52655fe1bf 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -45,14 +45,14 @@ true true Grpc.Tools + gRPC authors + Copyright 2018 gRPC authors gRPC and Protocol Buffer compiler for managed C# and native C++ projects. Add this package to a project that contains .proto files to be compiled to code. It contains the compilers, include files and project system integration for gRPC and Protocol buffer service description files necessary to build them on Windows, Linux and MacOS. Managed runtime is supplied separately in the Grpc.Core package. - Copyright 2018 gRPC authors - gRPC authors https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc gRPC RPC protocol HTTP/2 From 2131798b7f0ff0575fb69263f8b42f635e021013 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 16 Feb 2019 16:36:07 +0100 Subject: [PATCH 415/814] update nuget package descriptions --- src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj | 2 +- src/csharp/Grpc.Core/Grpc.Core.csproj | 2 +- src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj | 2 +- src/csharp/Grpc.Reflection/Grpc.Reflection.csproj | 2 +- src/csharp/Grpc/Grpc.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj index 0f184780663..fc2b3045bf8 100755 --- a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj +++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj @@ -5,7 +5,7 @@ Google Inc. - gRPC C#: Utility code for testing Grpc.Core + Miscellaneous code for testing Grpc.Core Copyright 2017, Google Inc. https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 3b34a7fab7e..aca904e2a64 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -6,7 +6,7 @@ Google Inc. Copyright 2015, Google Inc. - C# implementation of gRPC - an RPC library and framework. + C# implementation of gRPC based on native gRPC C-core library. https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc gRPC RPC Protocol HTTP/2 diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index cdbdfde60f3..80a6747d8fd 100755 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -6,7 +6,7 @@ Google Inc. Copyright 2015, Google Inc. - gRPC C# Health Checking Implementation + gRPC C# Health Checking (for Grpc.Core) https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc gRPC health check diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj index c533a0ab5a9..a7eebe8b782 100755 --- a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj +++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj @@ -6,7 +6,7 @@ Google Inc. Copyright 2016, Google Inc. - gRPC C# Reflection + gRPC C# Server Reflection (for Grpc.Core) https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc gRPC reflection diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj index 0d23dcc0234..e9efe82d402 100644 --- a/src/csharp/Grpc/Grpc.csproj +++ b/src/csharp/Grpc/Grpc.csproj @@ -6,7 +6,7 @@ Google Inc. Copyright 2015, Google Inc. - C# implementation of gRPC - an RPC library and framework. + Metapackage for gRPC C# https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc gRPC RPC Protocol HTTP/2 From 966d49795c6cb5cee855d9e39c6d46e24bfa747e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 16 Feb 2019 16:49:58 +0100 Subject: [PATCH 416/814] change nuget package copyright to gRPC Authors --- src/csharp/Grpc.Auth/Grpc.Auth.csproj | 4 ++-- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 4 ++-- src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj | 4 ++-- src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj | 4 ++-- src/csharp/Grpc.Core/Grpc.Core.csproj | 4 ++-- src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj | 4 ++-- src/csharp/Grpc.Reflection/Grpc.Reflection.csproj | 4 ++-- src/csharp/Grpc.Tools/Grpc.Tools.csproj | 4 ++-- src/csharp/Grpc/Grpc.csproj | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj index bf5b14061a5..3788d272d6a 100755 --- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj +++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj @@ -4,8 +4,8 @@ - Google Inc. - Copyright 2015, Google Inc. + The gRPC Authors + Copyright 2015 The gRPC Authors gRPC C# Authentication Library https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index 2fb8a2544ca..c490f9fcc34 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -4,8 +4,8 @@ - Google Inc. - Copyright 2019, Google Inc. + The gRPC Authors + Copyright 2019 The gRPC Authors gRPC C# Surface API https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc diff --git a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj index 71a35818632..fd7b7317cae 100644 --- a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj +++ b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj @@ -4,8 +4,8 @@ - Google Inc. - Copyright 2015, Google Inc. + The gRPC Authors + Copyright 2015 The gRPC Authors Debug symbols for the native library contained in Grpc.Core https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj index fc2b3045bf8..7047a3b5849 100755 --- a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj +++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj @@ -4,9 +4,9 @@ - Google Inc. + The gRPC Authors Miscellaneous code for testing Grpc.Core - Copyright 2017, Google Inc. + Copyright 2017 The gRPC Authors https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc gRPC test testing diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index aca904e2a64..583fa46a089 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -4,8 +4,8 @@ - Google Inc. - Copyright 2015, Google Inc. + The gRPC Authors + Copyright 2015 The gRPC Authors C# implementation of gRPC based on native gRPC C-core library. https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index 80a6747d8fd..efccdf0a927 100755 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -4,8 +4,8 @@ - Google Inc. - Copyright 2015, Google Inc. + The gRPC Authors + Copyright 2015 The gRPC Authors gRPC C# Health Checking (for Grpc.Core) https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj index a7eebe8b782..bb82d267f93 100755 --- a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj +++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj @@ -4,8 +4,8 @@ - Google Inc. - Copyright 2016, Google Inc. + The gRPC Authors + Copyright 2016 The gRPC Authors gRPC C# Server Reflection (for Grpc.Core) https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index d52655fe1bf..ce4207cc9f1 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -45,8 +45,8 @@ true true Grpc.Tools - gRPC authors - Copyright 2018 gRPC authors + The gRPC Authors + Copyright 2018 The gRPC Authors gRPC and Protocol Buffer compiler for managed C# and native C++ projects. Add this package to a project that contains .proto files to be compiled to code. diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj index e9efe82d402..2f8cb658366 100644 --- a/src/csharp/Grpc/Grpc.csproj +++ b/src/csharp/Grpc/Grpc.csproj @@ -4,8 +4,8 @@ - Google Inc. - Copyright 2015, Google Inc. + The gRPC Authors + Copyright 2015 The gRPC Authors Metapackage for gRPC C# https://github.com/grpc/grpc/blob/master/LICENSE https://github.com/grpc/grpc From dd6951e9d80620408225267fd332569f58d2995f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 16 Feb 2019 17:09:32 +0100 Subject: [PATCH 417/814] nuget package icon, use recommended license tag --- src/csharp/Grpc.Auth/Grpc.Auth.csproj | 3 ++- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 3 ++- src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj | 3 ++- src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj | 3 ++- src/csharp/Grpc.Core/Grpc.Core.csproj | 3 ++- src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj | 3 ++- src/csharp/Grpc.Reflection/Grpc.Reflection.csproj | 3 ++- src/csharp/Grpc.Tools/Grpc.Tools.csproj | 3 ++- src/csharp/Grpc/Grpc.csproj | 3 ++- 9 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj index 3788d272d6a..85fa0dd9f5a 100755 --- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj +++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj @@ -7,7 +7,8 @@ The gRPC Authors Copyright 2015 The gRPC Authors gRPC C# Authentication Library - https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc gRPC RPC Protocol HTTP/2 Auth OAuth2 $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index c490f9fcc34..9ed1e53c32a 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -7,7 +7,8 @@ The gRPC Authors Copyright 2019 The gRPC Authors gRPC C# Surface API - https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc gRPC RPC Protocol HTTP/2 $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj index fd7b7317cae..704960be405 100644 --- a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj +++ b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj @@ -7,7 +7,8 @@ The gRPC Authors Copyright 2015 The gRPC Authors Debug symbols for the native library contained in Grpc.Core - https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc gRPC RPC Protocol HTTP/2 $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj index 7047a3b5849..90ed88201d0 100755 --- a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj +++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj @@ -7,7 +7,8 @@ The gRPC Authors Miscellaneous code for testing Grpc.Core Copyright 2017 The gRPC Authors - https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc gRPC test testing $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 583fa46a089..64a7a100d67 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -7,7 +7,8 @@ The gRPC Authors Copyright 2015 The gRPC Authors C# implementation of gRPC based on native gRPC C-core library. - https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc gRPC RPC Protocol HTTP/2 $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index efccdf0a927..4f3862deeb7 100755 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -7,7 +7,8 @@ The gRPC Authors Copyright 2015 The gRPC Authors gRPC C# Health Checking (for Grpc.Core) - https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc gRPC health check $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj index bb82d267f93..c5362252d00 100755 --- a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj +++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj @@ -7,7 +7,8 @@ The gRPC Authors Copyright 2016 The gRPC Authors gRPC C# Server Reflection (for Grpc.Core) - https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc gRPC reflection $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index ce4207cc9f1..31cd4599050 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -53,7 +53,8 @@ Add this package to a project that contains .proto files to be compiled to code. It contains the compilers, include files and project system integration for gRPC and Protocol buffer service description files necessary to build them on Windows, Linux and MacOS. Managed runtime is supplied separately in the Grpc.Core package. - https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc gRPC RPC protocol HTTP/2 diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj index 2f8cb658366..29c5faf7a4b 100644 --- a/src/csharp/Grpc/Grpc.csproj +++ b/src/csharp/Grpc/Grpc.csproj @@ -7,7 +7,8 @@ The gRPC Authors Copyright 2015 The gRPC Authors Metapackage for gRPC C# - https://github.com/grpc/grpc/blob/master/LICENSE + https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png + Apache-2.0 https://github.com/grpc/grpc gRPC RPC Protocol HTTP/2 $(GrpcCsharpVersion) From 96f4454ce7f491974c1a6443cb9c38ddb73d9c82 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 15 Feb 2019 00:35:44 +0100 Subject: [PATCH 418/814] update run_interop_tests.py script --- tools/run_tests/run_interop_tests.py | 43 ++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 448b53a7207..33128c87320 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -58,9 +58,10 @@ _SKIP_SERVER_COMPRESSION = [ _SKIP_COMPRESSION = _SKIP_CLIENT_COMPRESSION + _SKIP_SERVER_COMPRESSION -_SKIP_ADVANCED = [ - 'status_code_and_message', 'custom_metadata', 'unimplemented_method', - 'unimplemented_service' +_SKIP_UNIMPLEMENTED_HANDLERS = ['unimplemented_method', 'unimplemented_service'] + +_SKIP_ADVANCED = _SKIP_UNIMPLEMENTED_HANDLERS + [ + 'status_code_and_message', 'custom_metadata' ] _SKIP_SPECIAL_STATUS_MESSAGE = ['special_status_message'] @@ -173,6 +174,37 @@ class CSharpCoreCLRLanguage: return 'csharpcoreclr' +class AspNetCoreLanguage: + + def __init__(self): + self.client_cwd = '../grpc-dotnet' + self.server_cwd = '../grpc-dotnet/testassets/InteropTestsWebsite/bin/Debug/netcoreapp3.0' + self.safename = str(self) + + def cloud_to_prod_env(self): + return {} + + def client_cmd(self, args): + # attempt to run client should fail + return ['dotnet' 'exec', 'CLIENT_NOT_SUPPORTED'] + args + + def server_cmd(self, args): + return ['dotnet', 'exec', 'InteropTestsWebsite.dll'] + args + + def global_env(self): + return {} + + def unimplemented_test_cases(self): + # aspnetcore doesn't have a client so ignore all test cases. + return _TEST_CASES + _AUTH_TEST_CASES + + def unimplemented_test_cases_server(self): + return _SKIP_COMPRESSION + _SKIP_UNIMPLEMENTED_HANDLERS + _SKIP_SPECIAL_STATUS_MESSAGE + + def __str__(self): + return 'aspnetcore' + + class DartLanguage: def __init__(self): @@ -590,6 +622,7 @@ _LANGUAGES = { 'c++': CXXLanguage(), 'csharp': CSharpLanguage(), 'csharpcoreclr': CSharpCoreCLRLanguage(), + 'aspnetcore': AspNetCoreLanguage(), 'dart': DartLanguage(), 'go': GoLanguage(), 'java': JavaLanguage(), @@ -605,8 +638,8 @@ _LANGUAGES = { # languages supported as cloud_to_cloud servers _SERVERS = [ - 'c++', 'node', 'csharp', 'csharpcoreclr', 'java', 'go', 'ruby', 'python', - 'dart' + 'c++', 'node', 'csharp', 'csharpcoreclr', 'aspnetcore', 'java', 'go', + 'ruby', 'python', 'dart' ] _TEST_CASES = [ From 4645f0d299ebbaa49ab59df250fd4f7bdea3b4de Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Fri, 1 Feb 2019 19:45:39 -0800 Subject: [PATCH 419/814] Add UserState dictionary to C# ServerCallContext This commit adds a IDictionary UserState member to the ServerCallContext. Interceptors and call handlers can use this member to pass per-call state between themselves. Like other members of ServerCallContext, UserState is not thread-safe. UserState is initialized on demand so that calls that don't use UserState don't need to pay for it. Closes https://github.com/grpc/grpc/issues/17759 --- src/csharp/Grpc.Core.Api/ServerCallContext.cs | 11 ++++- .../TestServerCallContext.cs | 15 ++++++ .../Interceptors/ServerInterceptorTest.cs | 47 +++++++++++++++++++ .../Internal/DefaultServerCallContext.cs | 15 ++++++ 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core.Api/ServerCallContext.cs b/src/csharp/Grpc.Core.Api/ServerCallContext.cs index 90b6e9419f0..7149ba283fd 100644 --- a/src/csharp/Grpc.Core.Api/ServerCallContext.cs +++ b/src/csharp/Grpc.Core.Api/ServerCallContext.cs @@ -17,6 +17,7 @@ #endregion using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -113,6 +114,12 @@ namespace Grpc.Core /// public AuthContext AuthContext => AuthContextCore; + /// + /// Gets a dictionary that can be used by the various interceptors and handlers of this + /// call to store arbitrary state. + /// + public IDictionary UserSate => UserStateCore; + /// Provides implementation of a non-virtual public member. protected abstract Task WriteResponseHeadersAsyncCore(Metadata responseHeaders); /// Provides implementation of a non-virtual public member. @@ -135,7 +142,9 @@ namespace Grpc.Core protected abstract Status StatusCore { get; set; } /// Provides implementation of a non-virtual public member. protected abstract WriteOptions WriteOptionsCore { get; set; } - /// Provides implementation of a non-virtual public member. + /// Provides implementation of a non-virtual public member. protected abstract AuthContext AuthContextCore { get; } + /// Provides implementation of a non-virtual public member. + protected abstract IDictionary UserStateCore { get; } } } diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs index e6297e61226..54134fdb25b 100644 --- a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs +++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs @@ -17,6 +17,7 @@ #endregion using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -50,6 +51,7 @@ namespace Grpc.Core.Testing private Status status; private readonly string peer; private readonly AuthContext authContext; + private Dictionary userState; private readonly ContextPropagationToken contextPropagationToken; private readonly Func writeHeadersFunc; private readonly Func writeOptionsGetter; @@ -93,6 +95,19 @@ namespace Grpc.Core.Testing protected override AuthContext AuthContextCore => authContext; + protected override IDictionary UserStateCore + { + get + { + if (userState == null) + { + userState = new Dictionary(); + } + + return userState; + } + } + protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) { return contextPropagationToken; diff --git a/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs b/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs index e76f21d0985..f5e42f2312d 100644 --- a/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs +++ b/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs @@ -77,6 +77,53 @@ namespace Grpc.Core.Interceptors.Tests Assert.AreEqual("CB1B2B3A", stringBuilder.ToString()); } + [Test] + public void UserStateVisibleToAllInterceptors() + { + object key1 = new object(); + object value1 = new object(); + const string key2 = "Interceptor #2"; + const string value2 = "Important state"; + + var interceptor1 = new ServerCallContextInterceptor(ctx => { + // state starts off empty + Assert.AreEqual(0, ctx.UserSate.Count); + + ctx.UserSate.Add(key1, value1); + }); + + var interceptor2 = new ServerCallContextInterceptor(ctx => { + // second interceptor can see state set by the first + bool found = ctx.UserSate.TryGetValue(key1, out object storedValue1); + Assert.IsTrue(found); + Assert.AreEqual(value1, storedValue1); + + ctx.UserSate.Add(key2, value2); + }); + + var helper = new MockServiceHelper(Host); + helper.UnaryHandler = new UnaryServerMethod((request, context) => { + // call handler can see all the state + bool found = context.UserSate.TryGetValue(key1, out object storedValue1); + Assert.IsTrue(found); + Assert.AreEqual(value1, storedValue1); + + found = context.UserSate.TryGetValue(key2, out object storedValue2); + Assert.IsTrue(found); + Assert.AreEqual(value2, storedValue2); + + return Task.FromResult("PASS"); + }); + helper.ServiceDefinition = helper.ServiceDefinition + .Intercept(interceptor2) + .Intercept(interceptor1); + + var server = helper.GetServer(); + server.Start(); + var channel = helper.GetChannel(); + Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "")); + } + [Test] public void CheckNullInterceptorRegistrationFails() { diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs index b33cb631e26..15089caf5f4 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -17,6 +17,7 @@ #endregion using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -39,6 +40,7 @@ namespace Grpc.Core private Status status; private readonly IServerResponseStream serverResponseStream; private readonly Lazy authContext; + private Dictionary userState; /// /// Creates a new instance of ServerCallContext. @@ -99,6 +101,19 @@ namespace Grpc.Core protected override AuthContext AuthContextCore => authContext.Value; + protected override IDictionary UserStateCore + { + get + { + if (userState == null) + { + userState = new Dictionary(); + } + + return userState; + } + } + private AuthContext GetAuthContextEager() { using (var authContextNative = callHandle.GetAuthContext()) From 3421c9c4f9643f024290a4c8ded13c146406cffb Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Sat, 16 Feb 2019 18:35:52 -0800 Subject: [PATCH 420/814] Make ServerCallContext.UserData a virtual property --- src/csharp/Grpc.Core.Api/ServerCallContext.cs | 17 ++++++++++++++--- .../Grpc.Core.Testing/TestServerCallContext.cs | 15 --------------- .../Internal/DefaultServerCallContext.cs | 15 --------------- 3 files changed, 14 insertions(+), 33 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/ServerCallContext.cs b/src/csharp/Grpc.Core.Api/ServerCallContext.cs index 7149ba283fd..c37aa0f2c0f 100644 --- a/src/csharp/Grpc.Core.Api/ServerCallContext.cs +++ b/src/csharp/Grpc.Core.Api/ServerCallContext.cs @@ -28,6 +28,8 @@ namespace Grpc.Core /// public abstract class ServerCallContext { + private Dictionary userState; + /// /// Creates a new instance of ServerCallContext. /// @@ -118,7 +120,18 @@ namespace Grpc.Core /// Gets a dictionary that can be used by the various interceptors and handlers of this /// call to store arbitrary state. /// - public IDictionary UserSate => UserStateCore; + public virtual IDictionary UserSate + { + get + { + if (userState == null) + { + userState = new Dictionary(); + } + + return userState; + } + } /// Provides implementation of a non-virtual public member. protected abstract Task WriteResponseHeadersAsyncCore(Metadata responseHeaders); @@ -144,7 +157,5 @@ namespace Grpc.Core protected abstract WriteOptions WriteOptionsCore { get; set; } /// Provides implementation of a non-virtual public member. protected abstract AuthContext AuthContextCore { get; } - /// Provides implementation of a non-virtual public member. - protected abstract IDictionary UserStateCore { get; } } } diff --git a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs index 54134fdb25b..e6297e61226 100644 --- a/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs +++ b/src/csharp/Grpc.Core.Testing/TestServerCallContext.cs @@ -17,7 +17,6 @@ #endregion using System; -using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -51,7 +50,6 @@ namespace Grpc.Core.Testing private Status status; private readonly string peer; private readonly AuthContext authContext; - private Dictionary userState; private readonly ContextPropagationToken contextPropagationToken; private readonly Func writeHeadersFunc; private readonly Func writeOptionsGetter; @@ -95,19 +93,6 @@ namespace Grpc.Core.Testing protected override AuthContext AuthContextCore => authContext; - protected override IDictionary UserStateCore - { - get - { - if (userState == null) - { - userState = new Dictionary(); - } - - return userState; - } - } - protected override ContextPropagationToken CreatePropagationTokenCore(ContextPropagationOptions options) { return contextPropagationToken; diff --git a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs index 15089caf5f4..b33cb631e26 100644 --- a/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs +++ b/src/csharp/Grpc.Core/Internal/DefaultServerCallContext.cs @@ -17,7 +17,6 @@ #endregion using System; -using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -40,7 +39,6 @@ namespace Grpc.Core private Status status; private readonly IServerResponseStream serverResponseStream; private readonly Lazy authContext; - private Dictionary userState; /// /// Creates a new instance of ServerCallContext. @@ -101,19 +99,6 @@ namespace Grpc.Core protected override AuthContext AuthContextCore => authContext.Value; - protected override IDictionary UserStateCore - { - get - { - if (userState == null) - { - userState = new Dictionary(); - } - - return userState; - } - } - private AuthContext GetAuthContextEager() { using (var authContextNative = callHandle.GetAuthContext()) From 2adb48acf0b8e302e81cba61b7db53ff421672e6 Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Sat, 16 Feb 2019 23:24:07 -0800 Subject: [PATCH 421/814] Fix typo in ServerCallContext.UserState name --- src/csharp/Grpc.Core.Api/ServerCallContext.cs | 2 +- .../Interceptors/ServerInterceptorTest.cs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/ServerCallContext.cs b/src/csharp/Grpc.Core.Api/ServerCallContext.cs index c37aa0f2c0f..7cc03cb3a0b 100644 --- a/src/csharp/Grpc.Core.Api/ServerCallContext.cs +++ b/src/csharp/Grpc.Core.Api/ServerCallContext.cs @@ -120,7 +120,7 @@ namespace Grpc.Core /// Gets a dictionary that can be used by the various interceptors and handlers of this /// call to store arbitrary state. /// - public virtual IDictionary UserSate + public virtual IDictionary UserState { get { diff --git a/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs b/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs index f5e42f2312d..66990832124 100644 --- a/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs +++ b/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs @@ -87,28 +87,28 @@ namespace Grpc.Core.Interceptors.Tests var interceptor1 = new ServerCallContextInterceptor(ctx => { // state starts off empty - Assert.AreEqual(0, ctx.UserSate.Count); + Assert.AreEqual(0, ctx.UserState.Count); - ctx.UserSate.Add(key1, value1); + ctx.UserState.Add(key1, value1); }); var interceptor2 = new ServerCallContextInterceptor(ctx => { // second interceptor can see state set by the first - bool found = ctx.UserSate.TryGetValue(key1, out object storedValue1); + bool found = ctx.UserState.TryGetValue(key1, out object storedValue1); Assert.IsTrue(found); Assert.AreEqual(value1, storedValue1); - ctx.UserSate.Add(key2, value2); + ctx.UserState.Add(key2, value2); }); var helper = new MockServiceHelper(Host); helper.UnaryHandler = new UnaryServerMethod((request, context) => { // call handler can see all the state - bool found = context.UserSate.TryGetValue(key1, out object storedValue1); + bool found = context.UserState.TryGetValue(key1, out object storedValue1); Assert.IsTrue(found); Assert.AreEqual(value1, storedValue1); - found = context.UserSate.TryGetValue(key2, out object storedValue2); + found = context.UserState.TryGetValue(key2, out object storedValue2); Assert.IsTrue(found); Assert.AreEqual(value2, storedValue2); From f640a548b87882717b552df6ca66216507456859 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 18 Feb 2019 12:28:53 +0100 Subject: [PATCH 422/814] "protocol" is too general to be in nuget pkg tags --- src/csharp/Grpc.Auth/Grpc.Auth.csproj | 2 +- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 2 +- src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj | 2 +- src/csharp/Grpc.Core/Grpc.Core.csproj | 2 +- src/csharp/Grpc.Tools/Grpc.Tools.csproj | 2 +- src/csharp/Grpc/Grpc.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj index 85fa0dd9f5a..e9a6d2cc198 100755 --- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj +++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj @@ -10,7 +10,7 @@ https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png Apache-2.0 https://github.com/grpc/grpc - gRPC RPC Protocol HTTP/2 Auth OAuth2 + gRPC RPC HTTP/2 Auth OAuth2 $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index 9ed1e53c32a..4b772f6276a 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -10,7 +10,7 @@ https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png Apache-2.0 https://github.com/grpc/grpc - gRPC RPC Protocol HTTP/2 + gRPC RPC HTTP/2 $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj index 704960be405..df4f31dc421 100644 --- a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj +++ b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj @@ -10,7 +10,7 @@ https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png Apache-2.0 https://github.com/grpc/grpc - gRPC RPC Protocol HTTP/2 + gRPC RPC HTTP/2 $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 64a7a100d67..e6ccff823a4 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -10,7 +10,7 @@ https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png Apache-2.0 https://github.com/grpc/grpc - gRPC RPC Protocol HTTP/2 + gRPC RPC HTTP/2 $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index 31cd4599050..89307bfdd65 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -56,7 +56,7 @@ Linux and MacOS. Managed runtime is supplied separately in the Grpc.Core package https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png Apache-2.0 https://github.com/grpc/grpc - gRPC RPC protocol HTTP/2 + gRPC RPC HTTP/2 diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj index 29c5faf7a4b..c529c38e989 100644 --- a/src/csharp/Grpc/Grpc.csproj +++ b/src/csharp/Grpc/Grpc.csproj @@ -10,7 +10,7 @@ https://github.com/grpc/grpc.github.io/raw/master/img/grpc_square_reverse_4x.png Apache-2.0 https://github.com/grpc/grpc - gRPC RPC Protocol HTTP/2 + gRPC RPC HTTP/2 $(GrpcCsharpVersion) From 0f794e1e3c9f629a0bc7309eca5480469eaac98c Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Sat, 16 Feb 2019 03:54:46 +0000 Subject: [PATCH 423/814] Fix c-ares on Windows bug triggered by tracing --- .../dns/c_ares/grpc_ares_ev_driver_windows.cc | 15 +- .../ExternalDnsClientServerTest.cs | 74 ++++++++ .../ExternalDnsWithTracingClientServerTest.cs | 167 ++++++++++++++++++ src/csharp/tests.json | 2 + 4 files changed, 252 insertions(+), 6 deletions(-) create mode 100644 src/csharp/Grpc.IntegrationTesting/ExternalDnsClientServerTest.cs create mode 100644 src/csharp/Grpc.IntegrationTesting/ExternalDnsWithTracingClientServerTest.cs diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index 02121aa0ab4..9570e32c150 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -120,13 +120,14 @@ class GrpcPolledFdWindows : public GrpcPolledFd { nullptr, &flags, (sockaddr*)recv_from_source_addr_, &recv_from_source_addr_len_, &winsocket_->read_info.overlapped, nullptr)) { - char* msg = gpr_format_message(WSAGetLastError()); + int wsa_last_error = WSAGetLastError(); + char* msg = gpr_format_message(wsa_last_error); grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); GRPC_CARES_TRACE_LOG( "RegisterForOnReadableLocked: WSARecvFrom error:|%s|. fd:|%s|", msg, GetName()); gpr_free(msg); - if (WSAGetLastError() != WSA_IO_PENDING) { + if (wsa_last_error != WSA_IO_PENDING) { ScheduleAndNullReadClosure(error); return; } @@ -229,12 +230,13 @@ class GrpcPolledFdWindows : public GrpcPolledFd { ares_ssize_t total_sent; DWORD bytes_sent = 0; if (SendWriteBuf(&bytes_sent, nullptr) != 0) { - char* msg = gpr_format_message(WSAGetLastError()); + int wsa_last_error = WSAGetLastError(); + char* msg = gpr_format_message(wsa_last_error); GRPC_CARES_TRACE_LOG( "TrySendWriteBufSyncNonBlocking: SendWriteBuf error:|%s|. fd:|%s|", msg, GetName()); gpr_free(msg); - if (WSAGetLastError() == WSA_IO_PENDING) { + if (wsa_last_error == WSA_IO_PENDING) { WSASetLastError(WSAEWOULDBLOCK); write_state_ = WRITE_REQUESTED; } @@ -284,9 +286,10 @@ class GrpcPolledFdWindows : public GrpcPolledFd { int out = WSAConnect(s, target, target_len, nullptr, nullptr, nullptr, nullptr); if (out != 0) { - char* msg = gpr_format_message(WSAGetLastError()); + int wsa_last_error = WSAGetLastError(); + char* msg = gpr_format_message(wsa_last_error); GRPC_CARES_TRACE_LOG("Connect error code:|%d|, msg:|%s|. fd:|%s|", - WSAGetLastError(), msg, GetName()); + wsa_last_error, msg, GetName()); gpr_free(msg); // c-ares expects a posix-style connect API out = -1; diff --git a/src/csharp/Grpc.IntegrationTesting/ExternalDnsClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/ExternalDnsClientServerTest.cs new file mode 100644 index 00000000000..1360d2506bb --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting/ExternalDnsClientServerTest.cs @@ -0,0 +1,74 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Utils; +using Grpc.Testing; +using NUnit.Framework; + +namespace Grpc.IntegrationTesting +{ + /// + /// Runs interop tests in-process, with that client using a target + /// name that using a target name that triggers interaction with + /// external DNS servers (even though it resolves to the in-proc server). + /// This test is a trimmed-down sibling test to the one in + /// "ExternalDnsWithTracingClientServerTest", and is meant mostly for + /// comparison with that one. + /// + public class ExternalDnsClientServerTest + { + Server server; + Channel channel; + TestService.TestServiceClient client; + + [OneTimeSetUp] + public void Init() + { + // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 + server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) + { + Services = { TestService.BindService(new TestServiceImpl()) }, + Ports = { { "[::1]", ServerPort.PickUnused, ServerCredentials.Insecure } } + }; + server.Start(); + + int port = server.Ports.Single().BoundPort; + channel = new Channel("loopback6.unittest.grpc.io", port, ChannelCredentials.Insecure); + client = new TestService.TestServiceClient(channel); + } + + [OneTimeTearDown] + public void Cleanup() + { + channel.ShutdownAsync().Wait(); + server.ShutdownAsync().Wait(); + } + + [Test] + public void EmptyUnary() + { + InteropClient.RunEmptyUnary(client); + } + } +} diff --git a/src/csharp/Grpc.IntegrationTesting/ExternalDnsWithTracingClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/ExternalDnsWithTracingClientServerTest.cs new file mode 100644 index 00000000000..f9fdcc3f9c9 --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting/ExternalDnsWithTracingClientServerTest.cs @@ -0,0 +1,167 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Logging; +using Grpc.Core.Utils; +using Grpc.Testing; +using NUnit.Framework; + +namespace Grpc.IntegrationTesting +{ + /// + /// See https://github.com/grpc/issues/18074, this test is meant to + /// try to trigger the described bug. + /// Runs interop tests in-process, with that client using a target + /// name that using a target name that triggers interaction with + /// external DNS servers (even though it resolves to the in-proc server). + /// + public class ExternalDnsWithTracingClientServerTest + { + Server server; + Channel channel; + TestService.TestServiceClient client; + SocketUsingLogger newLogger; + + [OneTimeSetUp] + public void Init() + { + // TODO(https://github.com/grpc/grpc/issues/14963): on linux, setting + // these environment variables might not actually have any affect. + // This is OK because we only really care about running this test on + // Windows, however, a fix made for $14963 should be applied here. + Environment.SetEnvironmentVariable("GRPC_TRACE", "all"); + Environment.SetEnvironmentVariable("GRPC_VERBOSITY", "DEBUG"); + newLogger = new SocketUsingLogger(GrpcEnvironment.Logger); + GrpcEnvironment.SetLogger(newLogger); + // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 + server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) + { + Services = { TestService.BindService(new TestServiceImpl()) }, + Ports = { { "[::1]", ServerPort.PickUnused, ServerCredentials.Insecure } } + }; + server.Start(); + + int port = server.Ports.Single().BoundPort; + channel = new Channel("loopback6.unittest.grpc.io", port, ChannelCredentials.Insecure); + client = new TestService.TestServiceClient(channel); + } + + [OneTimeTearDown] + public void Cleanup() + { + channel.ShutdownAsync().Wait(); + server.ShutdownAsync().Wait(); + } + + [Test] + public void EmptyUnary() + { + InteropClient.RunEmptyUnary(client); + } + } + + /// + /// Logger which does some socket operation after delegating + /// actual logging to its delegate logger. The main goal is to + /// reset the current thread's WSA error status. + /// The only reason for the delegateLogger is to continue + /// to have this test display debug logs. + /// + internal sealed class SocketUsingLogger : ILogger + { + private ILogger delegateLogger; + + public SocketUsingLogger(ILogger delegateLogger) { + this.delegateLogger = delegateLogger; + } + + public void Debug(string message) + { + MyLog(() => delegateLogger.Debug(message)); + } + + public void Debug(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Debug(format, formatArgs)); + } + + public void Error(string message) + { + MyLog(() => delegateLogger.Error(message)); + } + + public void Error(Exception exception, string message) + { + MyLog(() => delegateLogger.Error(exception, message)); + } + + public void Error(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Error(format, formatArgs)); + } + + public ILogger ForType() + { + return this; + } + + public void Info(string message) + { + MyLog(() => delegateLogger.Info(message)); + } + + public void Info(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Info(format, formatArgs)); + } + + public void Warning(string message) + { + MyLog(() => delegateLogger.Warning(message)); + } + + public void Warning(Exception exception, string message) + { + MyLog(() => delegateLogger.Warning(exception, message)); + } + + public void Warning(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Warning(format, formatArgs)); + } + + private void MyLog(Action delegateLog) + { + delegateLog(); + // Create and close a socket, just in order to affect + // the WSA (on Windows) error status of the current thread. + Socket s = new Socket(AddressFamily.InterNetwork, + SocketType.Stream, + ProtocolType.Tcp); + + s.Dispose(); + } + } +} diff --git a/src/csharp/tests.json b/src/csharp/tests.json index 760776f9e70..c1e7fc1a6bf 100644 --- a/src/csharp/tests.json +++ b/src/csharp/tests.json @@ -53,6 +53,8 @@ ], "Grpc.IntegrationTesting": [ "Grpc.IntegrationTesting.CustomErrorDetailsTest", + "Grpc.IntegrationTesting.ExternalDnsClientServerTest", + "Grpc.IntegrationTesting.ExternalDnsWithTracingClientServerTest", "Grpc.IntegrationTesting.GeneratedClientTest", "Grpc.IntegrationTesting.GeneratedServiceBaseTest", "Grpc.IntegrationTesting.HistogramTest", From 5b11769ab0af4c654930ed77c5aafea3de0314d7 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Sat, 16 Feb 2019 03:54:46 +0000 Subject: [PATCH 424/814] Fix c-ares on Windows bug triggered by tracing --- .../dns/c_ares/grpc_ares_ev_driver_windows.cc | 15 +- .../ExternalDnsClientServerTest.cs | 74 ++++++++ .../ExternalDnsWithTracingClientServerTest.cs | 167 ++++++++++++++++++ src/csharp/tests.json | 2 + 4 files changed, 252 insertions(+), 6 deletions(-) create mode 100644 src/csharp/Grpc.IntegrationTesting/ExternalDnsClientServerTest.cs create mode 100644 src/csharp/Grpc.IntegrationTesting/ExternalDnsWithTracingClientServerTest.cs diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index 02121aa0ab4..9570e32c150 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -120,13 +120,14 @@ class GrpcPolledFdWindows : public GrpcPolledFd { nullptr, &flags, (sockaddr*)recv_from_source_addr_, &recv_from_source_addr_len_, &winsocket_->read_info.overlapped, nullptr)) { - char* msg = gpr_format_message(WSAGetLastError()); + int wsa_last_error = WSAGetLastError(); + char* msg = gpr_format_message(wsa_last_error); grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); GRPC_CARES_TRACE_LOG( "RegisterForOnReadableLocked: WSARecvFrom error:|%s|. fd:|%s|", msg, GetName()); gpr_free(msg); - if (WSAGetLastError() != WSA_IO_PENDING) { + if (wsa_last_error != WSA_IO_PENDING) { ScheduleAndNullReadClosure(error); return; } @@ -229,12 +230,13 @@ class GrpcPolledFdWindows : public GrpcPolledFd { ares_ssize_t total_sent; DWORD bytes_sent = 0; if (SendWriteBuf(&bytes_sent, nullptr) != 0) { - char* msg = gpr_format_message(WSAGetLastError()); + int wsa_last_error = WSAGetLastError(); + char* msg = gpr_format_message(wsa_last_error); GRPC_CARES_TRACE_LOG( "TrySendWriteBufSyncNonBlocking: SendWriteBuf error:|%s|. fd:|%s|", msg, GetName()); gpr_free(msg); - if (WSAGetLastError() == WSA_IO_PENDING) { + if (wsa_last_error == WSA_IO_PENDING) { WSASetLastError(WSAEWOULDBLOCK); write_state_ = WRITE_REQUESTED; } @@ -284,9 +286,10 @@ class GrpcPolledFdWindows : public GrpcPolledFd { int out = WSAConnect(s, target, target_len, nullptr, nullptr, nullptr, nullptr); if (out != 0) { - char* msg = gpr_format_message(WSAGetLastError()); + int wsa_last_error = WSAGetLastError(); + char* msg = gpr_format_message(wsa_last_error); GRPC_CARES_TRACE_LOG("Connect error code:|%d|, msg:|%s|. fd:|%s|", - WSAGetLastError(), msg, GetName()); + wsa_last_error, msg, GetName()); gpr_free(msg); // c-ares expects a posix-style connect API out = -1; diff --git a/src/csharp/Grpc.IntegrationTesting/ExternalDnsClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/ExternalDnsClientServerTest.cs new file mode 100644 index 00000000000..1360d2506bb --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting/ExternalDnsClientServerTest.cs @@ -0,0 +1,74 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Utils; +using Grpc.Testing; +using NUnit.Framework; + +namespace Grpc.IntegrationTesting +{ + /// + /// Runs interop tests in-process, with that client using a target + /// name that using a target name that triggers interaction with + /// external DNS servers (even though it resolves to the in-proc server). + /// This test is a trimmed-down sibling test to the one in + /// "ExternalDnsWithTracingClientServerTest", and is meant mostly for + /// comparison with that one. + /// + public class ExternalDnsClientServerTest + { + Server server; + Channel channel; + TestService.TestServiceClient client; + + [OneTimeSetUp] + public void Init() + { + // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 + server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) + { + Services = { TestService.BindService(new TestServiceImpl()) }, + Ports = { { "[::1]", ServerPort.PickUnused, ServerCredentials.Insecure } } + }; + server.Start(); + + int port = server.Ports.Single().BoundPort; + channel = new Channel("loopback6.unittest.grpc.io", port, ChannelCredentials.Insecure); + client = new TestService.TestServiceClient(channel); + } + + [OneTimeTearDown] + public void Cleanup() + { + channel.ShutdownAsync().Wait(); + server.ShutdownAsync().Wait(); + } + + [Test] + public void EmptyUnary() + { + InteropClient.RunEmptyUnary(client); + } + } +} diff --git a/src/csharp/Grpc.IntegrationTesting/ExternalDnsWithTracingClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/ExternalDnsWithTracingClientServerTest.cs new file mode 100644 index 00000000000..f9fdcc3f9c9 --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting/ExternalDnsWithTracingClientServerTest.cs @@ -0,0 +1,167 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Logging; +using Grpc.Core.Utils; +using Grpc.Testing; +using NUnit.Framework; + +namespace Grpc.IntegrationTesting +{ + /// + /// See https://github.com/grpc/issues/18074, this test is meant to + /// try to trigger the described bug. + /// Runs interop tests in-process, with that client using a target + /// name that using a target name that triggers interaction with + /// external DNS servers (even though it resolves to the in-proc server). + /// + public class ExternalDnsWithTracingClientServerTest + { + Server server; + Channel channel; + TestService.TestServiceClient client; + SocketUsingLogger newLogger; + + [OneTimeSetUp] + public void Init() + { + // TODO(https://github.com/grpc/grpc/issues/14963): on linux, setting + // these environment variables might not actually have any affect. + // This is OK because we only really care about running this test on + // Windows, however, a fix made for $14963 should be applied here. + Environment.SetEnvironmentVariable("GRPC_TRACE", "all"); + Environment.SetEnvironmentVariable("GRPC_VERBOSITY", "DEBUG"); + newLogger = new SocketUsingLogger(GrpcEnvironment.Logger); + GrpcEnvironment.SetLogger(newLogger); + // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 + server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) + { + Services = { TestService.BindService(new TestServiceImpl()) }, + Ports = { { "[::1]", ServerPort.PickUnused, ServerCredentials.Insecure } } + }; + server.Start(); + + int port = server.Ports.Single().BoundPort; + channel = new Channel("loopback6.unittest.grpc.io", port, ChannelCredentials.Insecure); + client = new TestService.TestServiceClient(channel); + } + + [OneTimeTearDown] + public void Cleanup() + { + channel.ShutdownAsync().Wait(); + server.ShutdownAsync().Wait(); + } + + [Test] + public void EmptyUnary() + { + InteropClient.RunEmptyUnary(client); + } + } + + /// + /// Logger which does some socket operation after delegating + /// actual logging to its delegate logger. The main goal is to + /// reset the current thread's WSA error status. + /// The only reason for the delegateLogger is to continue + /// to have this test display debug logs. + /// + internal sealed class SocketUsingLogger : ILogger + { + private ILogger delegateLogger; + + public SocketUsingLogger(ILogger delegateLogger) { + this.delegateLogger = delegateLogger; + } + + public void Debug(string message) + { + MyLog(() => delegateLogger.Debug(message)); + } + + public void Debug(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Debug(format, formatArgs)); + } + + public void Error(string message) + { + MyLog(() => delegateLogger.Error(message)); + } + + public void Error(Exception exception, string message) + { + MyLog(() => delegateLogger.Error(exception, message)); + } + + public void Error(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Error(format, formatArgs)); + } + + public ILogger ForType() + { + return this; + } + + public void Info(string message) + { + MyLog(() => delegateLogger.Info(message)); + } + + public void Info(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Info(format, formatArgs)); + } + + public void Warning(string message) + { + MyLog(() => delegateLogger.Warning(message)); + } + + public void Warning(Exception exception, string message) + { + MyLog(() => delegateLogger.Warning(exception, message)); + } + + public void Warning(string format, params object[] formatArgs) + { + MyLog(() => delegateLogger.Warning(format, formatArgs)); + } + + private void MyLog(Action delegateLog) + { + delegateLog(); + // Create and close a socket, just in order to affect + // the WSA (on Windows) error status of the current thread. + Socket s = new Socket(AddressFamily.InterNetwork, + SocketType.Stream, + ProtocolType.Tcp); + + s.Dispose(); + } + } +} diff --git a/src/csharp/tests.json b/src/csharp/tests.json index 760776f9e70..c1e7fc1a6bf 100644 --- a/src/csharp/tests.json +++ b/src/csharp/tests.json @@ -53,6 +53,8 @@ ], "Grpc.IntegrationTesting": [ "Grpc.IntegrationTesting.CustomErrorDetailsTest", + "Grpc.IntegrationTesting.ExternalDnsClientServerTest", + "Grpc.IntegrationTesting.ExternalDnsWithTracingClientServerTest", "Grpc.IntegrationTesting.GeneratedClientTest", "Grpc.IntegrationTesting.GeneratedServiceBaseTest", "Grpc.IntegrationTesting.HistogramTest", From 275296c594cec6cb3b1901e366beb07170a54b13 Mon Sep 17 00:00:00 2001 From: hcaseyal Date: Tue, 19 Feb 2019 11:05:52 -0800 Subject: [PATCH 425/814] Revert "LB policy picker API" --- BUILD | 4 +- CMakeLists.txt | 12 +- Makefile | 12 +- build.yaml | 4 +- config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 2 +- gRPC-Core.podspec | 6 +- grpc.gemspec | 4 +- grpc.gyp | 8 +- package.xml | 4 +- .../filters/client_channel/client_channel.cc | 683 ++++--------- .../ext/filters/client_channel/lb_policy.cc | 26 +- .../ext/filters/client_channel/lb_policy.h | 298 ++---- .../client_channel/lb_policy/grpclb/grpclb.cc | 851 ++++++++++------ .../lb_policy/grpclb/grpclb_client_stats.cc | 2 +- .../lb_policy/grpclb/grpclb_client_stats.h | 2 +- .../lb_policy/pick_first/pick_first.cc | 228 +++-- .../lb_policy/round_robin/round_robin.cc | 341 +++++-- .../lb_policy/subchannel_list.h | 13 +- .../client_channel/lb_policy/xds/xds.cc | 539 +++++++--- .../filters/client_channel/request_routing.cc | 946 ++++++++++++++++++ .../filters/client_channel/request_routing.h | 181 ++++ .../client_channel/resolving_lb_policy.cc | 460 --------- .../client_channel/resolving_lb_policy.h | 137 --- .../ext/filters/client_channel/subchannel.cc | 23 +- src/core/lib/gprpp/orphanable.h | 5 +- src/core/lib/gprpp/ref_counted.h | 5 +- src/python/grpcio/grpc_core_dependencies.py | 2 +- .../channel/channel_stack_builder_test.cc | 18 +- test/core/util/test_lb_policies.cc | 146 +-- test/cpp/microbenchmarks/bm_call_create.cc | 1 - tools/doxygen/Doxyfile.core.internal | 4 +- .../generated/sources_and_headers.json | 6 +- 34 files changed, 2936 insertions(+), 2041 deletions(-) create mode 100644 src/core/ext/filters/client_channel/request_routing.cc create mode 100644 src/core/ext/filters/client_channel/request_routing.h delete mode 100644 src/core/ext/filters/client_channel/resolving_lb_policy.cc delete mode 100644 src/core/ext/filters/client_channel/resolving_lb_policy.h diff --git a/BUILD b/BUILD index f0de4399beb..a566057e926 100644 --- a/BUILD +++ b/BUILD @@ -1070,10 +1070,10 @@ grpc_cc_library( "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/proxy_mapper.cc", "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", + "src/core/ext/filters/client_channel/request_routing.cc", "src/core/ext/filters/client_channel/resolver.cc", "src/core/ext/filters/client_channel/resolver_registry.cc", "src/core/ext/filters/client_channel/resolver_result_parsing.cc", - "src/core/ext/filters/client_channel/resolving_lb_policy.cc", "src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/server_address.cc", "src/core/ext/filters/client_channel/subchannel.cc", @@ -1096,11 +1096,11 @@ grpc_cc_library( "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", + "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.h", - "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 458e9b88b74..f494ef0094c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1232,10 +1232,10 @@ add_library(grpc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc - src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -1587,10 +1587,10 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc - src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -1965,10 +1965,10 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc - src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -2290,10 +2290,10 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc - src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -2626,10 +2626,10 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc - src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -3483,10 +3483,10 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc + src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc - src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc diff --git a/Makefile b/Makefile index 9d0b37b687a..7cfe37384aa 100644 --- a/Makefile +++ b/Makefile @@ -3758,10 +3758,10 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ - src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -4107,10 +4107,10 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ - src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -4478,10 +4478,10 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ - src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -4790,10 +4790,10 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ - src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -5100,10 +5100,10 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ - src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -5934,10 +5934,10 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ - src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ diff --git a/build.yaml b/build.yaml index d347bcd8189..77ad81ddda2 100644 --- a/build.yaml +++ b/build.yaml @@ -587,11 +587,11 @@ filegroups: - src/core/ext/filters/client_channel/parse_address.h - src/core/ext/filters/client_channel/proxy_mapper.h - src/core/ext/filters/client_channel/proxy_mapper_registry.h + - src/core/ext/filters/client_channel/request_routing.h - src/core/ext/filters/client_channel/resolver.h - src/core/ext/filters/client_channel/resolver_factory.h - src/core/ext/filters/client_channel/resolver_registry.h - src/core/ext/filters/client_channel/resolver_result_parsing.h - - src/core/ext/filters/client_channel/resolving_lb_policy.h - src/core/ext/filters/client_channel/retry_throttle.h - src/core/ext/filters/client_channel/server_address.h - src/core/ext/filters/client_channel/subchannel.h @@ -614,10 +614,10 @@ filegroups: - src/core/ext/filters/client_channel/parse_address.cc - src/core/ext/filters/client_channel/proxy_mapper.cc - src/core/ext/filters/client_channel/proxy_mapper_registry.cc + - src/core/ext/filters/client_channel/request_routing.cc - src/core/ext/filters/client_channel/resolver.cc - src/core/ext/filters/client_channel/resolver_registry.cc - src/core/ext/filters/client_channel/resolver_result_parsing.cc - - src/core/ext/filters/client_channel/resolving_lb_policy.cc - src/core/ext/filters/client_channel/retry_throttle.cc - src/core/ext/filters/client_channel/server_address.cc - src/core/ext/filters/client_channel/subchannel.cc diff --git a/config.m4 b/config.m4 index 2616803d9b0..5746caf694a 100644 --- a/config.m4 +++ b/config.m4 @@ -355,10 +355,10 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ + src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ - src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ diff --git a/config.w32 b/config.w32 index 64eca2a8472..5659d8b8408 100644 --- a/config.w32 +++ b/config.w32 @@ -330,10 +330,10 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\parse_address.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " + + "src\\core\\ext\\filters\\client_channel\\request_routing.cc " + "src\\core\\ext\\filters\\client_channel\\resolver.cc " + "src\\core\\ext\\filters\\client_channel\\resolver_registry.cc " + "src\\core\\ext\\filters\\client_channel\\resolver_result_parsing.cc " + - "src\\core\\ext\\filters\\client_channel\\resolving_lb_policy.cc " + "src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " + "src\\core\\ext\\filters\\client_channel\\server_address.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 272e41f8223..15ce090bd9b 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -360,11 +360,11 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', + 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', - 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 61409e9c133..92626f3e84b 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -354,11 +354,11 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', + 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', - 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', @@ -801,10 +801,10 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', - 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -984,11 +984,11 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', + 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', - 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', diff --git a/grpc.gemspec b/grpc.gemspec index 0ab718a0668..a4e25d7bb22 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -288,11 +288,11 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/parse_address.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h ) + s.files += %w( src/core/ext/filters/client_channel/request_routing.h ) s.files += %w( src/core/ext/filters/client_channel/resolver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_factory.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.h ) - s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.h ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h ) s.files += %w( src/core/ext/filters/client_channel/server_address.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel.h ) @@ -738,10 +738,10 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/parse_address.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.cc ) + s.files += %w( src/core/ext/filters/client_channel/request_routing.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver_registry.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.cc ) - s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.cc ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc ) s.files += %w( src/core/ext/filters/client_channel/server_address.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel.cc ) diff --git a/grpc.gyp b/grpc.gyp index ca9d017dbbe..113c17f0d09 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -537,10 +537,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', - 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -801,10 +801,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', - 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -1046,10 +1046,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', - 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -1302,10 +1302,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', - 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', diff --git a/package.xml b/package.xml index e6b793fd1d1..7a1d26c47c5 100644 --- a/package.xml +++ b/package.xml @@ -293,11 +293,11 @@ + - @@ -743,10 +743,10 @@ + - diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 6de27369ea4..38525dbf97e 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -32,14 +32,12 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" -#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" +#include "src/core/ext/filters/client_channel/request_routing.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" -#include "src/core/ext/filters/client_channel/resolving_lb_policy.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/deadline/deadline_filter.h" @@ -70,8 +68,6 @@ using grpc_core::internal::ClientChannelMethodParamsTable; using grpc_core::internal::ProcessedResolverResult; using grpc_core::internal::ServerRetryThrottleData; -using grpc_core::LoadBalancingPolicy; - /* Client channel implementation */ // By default, we buffer 256 KiB per RPC for retries. @@ -90,171 +86,44 @@ grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel"); struct external_connectivity_watcher; -struct QueuedPick { - LoadBalancingPolicy::PickState pick; - grpc_call_element* elem; - QueuedPick* next = nullptr; -}; - typedef struct client_channel_channel_data { + grpc_core::ManualConstructor request_router; + bool deadline_checking_enabled; bool enable_retries; size_t per_rpc_retry_buffer_size; /** combiner protecting all variables below in this data structure */ grpc_combiner* combiner; + /** retry throttle data */ + grpc_core::RefCountedPtr retry_throttle_data; + /** maps method names to method_parameters structs */ + grpc_core::RefCountedPtr method_params_table; /** owning stack */ grpc_channel_stack* owning_stack; /** interested parties (owned) */ grpc_pollset_set* interested_parties; - // Client channel factory. Holds a ref. - grpc_client_channel_factory* client_channel_factory; - // Subchannel pool. - grpc_core::RefCountedPtr subchannel_pool; - - grpc_core::channelz::ClientChannelNode* channelz_node; - - // Resolving LB policy. - grpc_core::OrphanablePtr resolving_lb_policy; - // Subchannel picker from LB policy. - grpc_core::UniquePtr picker; - // Linked list of queued picks. - QueuedPick* queued_picks; - - bool have_service_config; - /** retry throttle data from service config */ - grpc_core::RefCountedPtr retry_throttle_data; - /** per-method service config data */ - grpc_core::RefCountedPtr method_params_table; - - /* the following properties are guarded by a mutex since APIs require them - to be instantaneously available */ - gpr_mu info_mu; - grpc_core::UniquePtr info_lb_policy_name; - grpc_core::UniquePtr info_service_config_json; - - grpc_connectivity_state_tracker state_tracker; - grpc_error* disconnect_error; /* external_connectivity_watcher_list head is guarded by its own mutex, since * counts need to be grabbed immediately without polling on a cq */ gpr_mu external_connectivity_watcher_list_mu; struct external_connectivity_watcher* external_connectivity_watcher_list_head; + + /* the following properties are guarded by a mutex since APIs require them + to be instantaneously available */ + gpr_mu info_mu; + grpc_core::UniquePtr info_lb_policy_name; + /** service config in JSON form */ + grpc_core::UniquePtr info_service_config_json; } channel_data; -// Forward declarations. -static void start_pick_locked(void* arg, grpc_error* ignored); -static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem); - -static const char* get_channel_connectivity_state_change_string( - grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "Channel state change to IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "Channel state change to CONNECTING"; - case GRPC_CHANNEL_READY: - return "Channel state change to READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "Channel state change to TRANSIENT_FAILURE"; - case GRPC_CHANNEL_SHUTDOWN: - return "Channel state change to SHUTDOWN"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -static void set_connectivity_state_and_picker_locked( - channel_data* chand, grpc_connectivity_state state, grpc_error* state_error, - const char* reason, - grpc_core::UniquePtr picker) { - // Update connectivity state. - grpc_connectivity_state_set(&chand->state_tracker, state, state_error, - reason); - if (chand->channelz_node != nullptr) { - chand->channelz_node->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - get_channel_connectivity_state_change_string(state))); - } - // Update picker. - chand->picker = std::move(picker); - // Re-process queued picks. - for (QueuedPick* pick = chand->queued_picks; pick != nullptr; - pick = pick->next) { - start_pick_locked(pick->elem, GRPC_ERROR_NONE); - } -} - -namespace grpc_core { -namespace { - -class ClientChannelControlHelper - : public LoadBalancingPolicy::ChannelControlHelper { - public: - explicit ClientChannelControlHelper(channel_data* chand) : chand_(chand) { - GRPC_CHANNEL_STACK_REF(chand_->owning_stack, "ClientChannelControlHelper"); - } - - ~ClientChannelControlHelper() override { - GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack, - "ClientChannelControlHelper"); - } - - Subchannel* CreateSubchannel(const grpc_channel_args& args) override { - grpc_arg arg = SubchannelPoolInterface::CreateChannelArg( - chand_->subchannel_pool.get()); - grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(&args, &arg, 1); - Subchannel* subchannel = grpc_client_channel_factory_create_subchannel( - chand_->client_channel_factory, new_args); - grpc_channel_args_destroy(new_args); - return subchannel; - } - - grpc_channel* CreateChannel(const char* target, grpc_client_channel_type type, - const grpc_channel_args& args) override { - return grpc_client_channel_factory_create_channel( - chand_->client_channel_factory, target, type, &args); - } - - void UpdateState( - grpc_connectivity_state state, grpc_error* state_error, - UniquePtr picker) override { - if (grpc_client_channel_trace.enabled()) { - const char* extra = chand_->disconnect_error == GRPC_ERROR_NONE - ? "" - : " (ignoring -- channel shutting down)"; - gpr_log(GPR_INFO, "chand=%p: update: state=%s error=%s picker=%p%s", - chand_, grpc_connectivity_state_name(state), - grpc_error_string(state_error), picker.get(), extra); - } - // Do update only if not shutting down. - if (chand_->disconnect_error == GRPC_ERROR_NONE) { - set_connectivity_state_and_picker_locked(chand_, state, state_error, - "helper", std::move(picker)); - } else { - GRPC_ERROR_UNREF(state_error); - } - } - - // No-op -- we should never get this from ResolvingLoadBalancingPolicy. - void RequestReresolution() override {} - - private: - channel_data* chand_; -}; - -} // namespace -} // namespace grpc_core - -// Synchronous callback from chand->resolving_lb_policy to process a resolver +// Synchronous callback from chand->request_router to process a resolver // result update. static bool process_resolver_result_locked(void* arg, const grpc_channel_args& args, const char** lb_policy_name, grpc_json** lb_policy_config) { channel_data* chand = static_cast(arg); - chand->have_service_config = true; ProcessedResolverResult resolver_result(args, chand->enable_retries); grpc_core::UniquePtr service_config_json = resolver_result.service_config_json(); @@ -279,38 +148,9 @@ static bool process_resolver_result_locked(void* arg, // Return results. *lb_policy_name = chand->info_lb_policy_name.get(); *lb_policy_config = resolver_result.lb_policy_config(); - // Apply service config to queued picks. - for (QueuedPick* pick = chand->queued_picks; pick != nullptr; - pick = pick->next) { - maybe_apply_service_config_to_call_locked(pick->elem); - } return service_config_changed; } -static grpc_error* do_ping_locked(channel_data* chand, grpc_transport_op* op) { - grpc_error* error = GRPC_ERROR_NONE; - grpc_connectivity_state state = - grpc_connectivity_state_get(&chand->state_tracker, &error); - if (state != GRPC_CHANNEL_READY) { - grpc_error* new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "channel not connected", &error, 1); - GRPC_ERROR_UNREF(error); - return new_error; - } - LoadBalancingPolicy::PickState pick; - chand->picker->Pick(&pick, &error); - if (pick.connected_subchannel != nullptr) { - pick.connected_subchannel->Ping(op->send_ping.on_initiate, - op->send_ping.on_ack); - } else { - if (error == GRPC_ERROR_NONE) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "LB policy dropped call on ping"); - } - } - return error; -} - static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { grpc_transport_op* op = static_cast(arg); grpc_channel_element* elem = @@ -318,40 +158,47 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { channel_data* chand = static_cast(elem->channel_data); if (op->on_connectivity_state_change != nullptr) { - grpc_connectivity_state_notify_on_state_change( - &chand->state_tracker, op->connectivity_state, - op->on_connectivity_state_change); + chand->request_router->NotifyOnConnectivityStateChange( + op->connectivity_state, op->on_connectivity_state_change); op->on_connectivity_state_change = nullptr; op->connectivity_state = nullptr; } if (op->send_ping.on_initiate != nullptr || op->send_ping.on_ack != nullptr) { - grpc_error* error = do_ping_locked(chand, op); - if (error != GRPC_ERROR_NONE) { + if (chand->request_router->lb_policy() == nullptr) { + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"); GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error)); GRPC_CLOSURE_SCHED(op->send_ping.on_ack, error); + } else { + grpc_error* error = GRPC_ERROR_NONE; + grpc_core::LoadBalancingPolicy::PickState pick_state; + // Pick must return synchronously, because pick_state.on_complete is null. + GPR_ASSERT( + chand->request_router->lb_policy()->PickLocked(&pick_state, &error)); + if (pick_state.connected_subchannel != nullptr) { + pick_state.connected_subchannel->Ping(op->send_ping.on_initiate, + op->send_ping.on_ack); + } else { + if (error == GRPC_ERROR_NONE) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "LB policy dropped call on ping"); + } + GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error)); + GRPC_CLOSURE_SCHED(op->send_ping.on_ack, error); + } + op->bind_pollset = nullptr; } - op->bind_pollset = nullptr; op->send_ping.on_initiate = nullptr; op->send_ping.on_ack = nullptr; } - if (op->reset_connect_backoff) { - chand->resolving_lb_policy->ResetBackoffLocked(); + if (op->disconnect_with_error != GRPC_ERROR_NONE) { + chand->request_router->ShutdownLocked(op->disconnect_with_error); } - if (op->disconnect_with_error != GRPC_ERROR_NONE) { - chand->disconnect_error = op->disconnect_with_error; - grpc_pollset_set_del_pollset_set( - chand->resolving_lb_policy->interested_parties(), - chand->interested_parties); - chand->resolving_lb_policy.reset(); - set_connectivity_state_and_picker_locked( - chand, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(op->disconnect_with_error), - "shutdown from API", - grpc_core::UniquePtr( - grpc_core::New( - GRPC_ERROR_REF(op->disconnect_with_error)))); + if (op->reset_connect_backoff) { + chand->request_router->ResetConnectionBackoffLocked(); } GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "start_transport_op"); @@ -397,9 +244,6 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, GPR_ASSERT(elem->filter == &grpc_client_channel_filter); // Initialize data members. chand->combiner = grpc_combiner_create(); - grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, - "client_channel"); - chand->disconnect_error = GRPC_ERROR_NONE; gpr_mu_init(&chand->info_mu); gpr_mu_init(&chand->external_connectivity_watcher_list_mu); @@ -431,9 +275,8 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "client channel factory arg must be a pointer"); } - chand->client_channel_factory = + grpc_client_channel_factory* client_channel_factory = static_cast(arg->value.pointer.p); - grpc_client_channel_factory_ref(chand->client_channel_factory); // Get server name to resolve, using proxy mapper if needed. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI); if (arg == nullptr) { @@ -448,71 +291,26 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, grpc_channel_args* new_args = nullptr; grpc_proxy_mappers_map_name(arg->value.string, args->channel_args, &proxy_name, &new_args); - grpc_core::UniquePtr target_uri( - proxy_name != nullptr ? proxy_name : gpr_strdup(arg->value.string)); - // Instantiate subchannel pool. - arg = grpc_channel_args_find(args->channel_args, - GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL); - if (grpc_channel_arg_get_bool(arg, false)) { - chand->subchannel_pool = - grpc_core::MakeRefCounted(); - } else { - chand->subchannel_pool = grpc_core::GlobalSubchannelPool::instance(); - } - // Instantiate resolving LB policy. - LoadBalancingPolicy::Args lb_args; - lb_args.combiner = chand->combiner; - lb_args.channel_control_helper = - grpc_core::UniquePtr( - grpc_core::New(chand)); - lb_args.args = new_args != nullptr ? new_args : args->channel_args; + // Instantiate request router. + grpc_client_channel_factory_ref(client_channel_factory); grpc_error* error = GRPC_ERROR_NONE; - chand->resolving_lb_policy.reset( - grpc_core::New( - std::move(lb_args), &grpc_client_channel_trace, std::move(target_uri), - process_resolver_result_locked, chand, &error)); + chand->request_router.Init( + chand->owning_stack, chand->combiner, client_channel_factory, + chand->interested_parties, &grpc_client_channel_trace, + process_resolver_result_locked, chand, + proxy_name != nullptr ? proxy_name : arg->value.string /* target_uri */, + new_args != nullptr ? new_args : args->channel_args, &error); + gpr_free(proxy_name); grpc_channel_args_destroy(new_args); - if (error != GRPC_ERROR_NONE) { - // Orphan the resolving LB policy and flush the exec_ctx to ensure - // that it finishes shutting down. This ensures that if we are - // failing, we destroy the ClientChannelControlHelper (and thus - // unref the channel stack) before we return. - // TODO(roth): This is not a complete solution, because it only - // catches the case where channel stack initialization fails in this - // particular filter. If there is a failure in a different filter, we - // will leave a dangling ref here, which can cause a crash. Fortunately, - // in practice, there are no other filters that can cause failures in - // channel stack initialization, so this works for now. - chand->resolving_lb_policy.reset(); - grpc_core::ExecCtx::Get()->Flush(); - } else { - grpc_pollset_set_add_pollset_set( - chand->resolving_lb_policy->interested_parties(), - chand->interested_parties); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", chand, - chand->resolving_lb_policy.get()); - } - } return error; } /* Destructor for channel_data */ static void cc_destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); - if (chand->resolving_lb_policy != nullptr) { - grpc_pollset_set_del_pollset_set( - chand->resolving_lb_policy->interested_parties(), - chand->interested_parties); - chand->resolving_lb_policy.reset(); - } + chand->request_router.Destroy(); // TODO(roth): Once we convert the filter API to C++, there will no // longer be any need to explicitly reset these smart pointer data members. - chand->picker.reset(); - chand->subchannel_pool.reset(); - if (chand->client_channel_factory != nullptr) { - grpc_client_channel_factory_unref(chand->client_channel_factory); - } chand->info_lb_policy_name.reset(); chand->info_service_config_json.reset(); chand->retry_throttle_data.reset(); @@ -520,8 +318,6 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { grpc_client_channel_stop_backup_polling(chand->interested_parties); grpc_pollset_set_destroy(chand->interested_parties); GRPC_COMBINER_UNREF(chand->combiner, "client_channel"); - GRPC_ERROR_UNREF(chand->disconnect_error); - grpc_connectivity_state_destroy(&chand->state_tracker); gpr_mu_destroy(&chand->info_mu); gpr_mu_destroy(&chand->external_connectivity_watcher_list_mu); } @@ -575,12 +371,6 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { // (census filter is on top of this one) // - add census stats for retries -namespace grpc_core { -namespace { -class QueuedPickCanceller; -} // namespace -} // namespace grpc_core - namespace { struct call_data; @@ -719,11 +509,8 @@ struct call_data { for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches); ++i) { GPR_ASSERT(pending_batches[i].batch == nullptr); } - for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) { - if (pick.pick.subchannel_call_context[i].destroy != nullptr) { - pick.pick.subchannel_call_context[i].destroy( - pick.pick.subchannel_call_context[i].value); - } + if (have_request) { + request.Destroy(); } } @@ -750,10 +537,8 @@ struct call_data { // Set when we get a cancel_stream op. grpc_error* cancel_error = GRPC_ERROR_NONE; - QueuedPick pick; - bool pick_queued = false; - bool service_config_applied = false; - grpc_core::QueuedPickCanceller* pick_canceller = nullptr; + grpc_core::ManualConstructor request; + bool have_request = false; grpc_closure pick_closure; grpc_polling_entity* pollent = nullptr; @@ -815,7 +600,7 @@ static void retry_commit(grpc_call_element* elem, static void start_internal_recv_trailing_metadata(grpc_call_element* elem); static void on_complete(void* arg, grpc_error* error); static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored); -static void remove_call_from_queued_picks_locked(grpc_call_element* elem); +static void start_pick_locked(void* arg, grpc_error* ignored); // // send op data caching @@ -943,7 +728,7 @@ static void free_cached_send_op_data_for_completed_batch( // void maybe_inject_recv_trailing_metadata_ready_for_lb( - const LoadBalancingPolicy::PickState& pick, + const grpc_core::LoadBalancingPolicy::PickState& pick, grpc_transport_stream_op_batch* batch) { if (pick.recv_trailing_metadata_ready != nullptr) { *pick.original_recv_trailing_metadata_ready = @@ -1061,25 +846,10 @@ static void fail_pending_batch_in_call_combiner(void* arg, grpc_error* error) { } // This is called via the call combiner, so access to calld is synchronized. -// If yield_call_combiner_predicate returns true, assumes responsibility for -// yielding the call combiner. -typedef bool (*YieldCallCombinerPredicate)( - const grpc_core::CallCombinerClosureList& closures); -static bool yield_call_combiner( - const grpc_core::CallCombinerClosureList& closures) { - return true; -} -static bool no_yield_call_combiner( - const grpc_core::CallCombinerClosureList& closures) { - return false; -} -static bool yield_call_combiner_if_pending_batches_found( - const grpc_core::CallCombinerClosureList& closures) { - return closures.size() > 0; -} -static void pending_batches_fail( - grpc_call_element* elem, grpc_error* error, - YieldCallCombinerPredicate yield_call_combiner_predicate) { +// If yield_call_combiner is true, assumes responsibility for yielding +// the call combiner. +static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, + bool yield_call_combiner) { GPR_ASSERT(error != GRPC_ERROR_NONE); call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_trace.enabled()) { @@ -1096,9 +866,9 @@ static void pending_batches_fail( pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { - if (batch->recv_trailing_metadata) { - maybe_inject_recv_trailing_metadata_ready_for_lb(calld->pick.pick, - batch); + if (batch->recv_trailing_metadata && calld->have_request) { + maybe_inject_recv_trailing_metadata_ready_for_lb( + *calld->request->pick(), batch); } batch->handler_private.extra_arg = calld; GRPC_CLOSURE_INIT(&batch->handler_private.closure, @@ -1109,7 +879,7 @@ static void pending_batches_fail( pending_batch_clear(calld, pending); } } - if (yield_call_combiner_predicate(closures)) { + if (yield_call_combiner) { closures.RunClosures(calld->call_combiner); } else { closures.RunClosuresWithoutYielding(calld->call_combiner); @@ -1153,8 +923,8 @@ static void pending_batches_resume(grpc_call_element* elem) { grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { if (batch->recv_trailing_metadata) { - maybe_inject_recv_trailing_metadata_ready_for_lb(calld->pick.pick, - batch); + maybe_inject_recv_trailing_metadata_ready_for_lb( + *calld->request->pick(), batch); } batch->handler_private.extra_arg = calld->subchannel_call.get(); GRPC_CLOSURE_INIT(&batch->handler_private.closure, @@ -1245,9 +1015,11 @@ static void do_retry(grpc_call_element* elem, const ClientChannelMethodParams::RetryPolicy* retry_policy = calld->method_params->retry_policy(); GPR_ASSERT(retry_policy != nullptr); - // Reset subchannel call and connected subchannel. calld->subchannel_call.reset(); - calld->pick.pick.connected_subchannel.reset(); + if (calld->have_request) { + calld->have_request = false; + calld->request.Destroy(); + } // Compute backoff delay. grpc_millis next_attempt_time; if (server_pushback_ms >= 0) { @@ -2166,7 +1938,7 @@ static void add_retriable_recv_trailing_metadata_op( batch_data->batch.payload->recv_trailing_metadata .recv_trailing_metadata_ready = &retry_state->recv_trailing_metadata_ready; - maybe_inject_recv_trailing_metadata_ready_for_lb(calld->pick.pick, + maybe_inject_recv_trailing_metadata_ready_for_lb(*calld->request->pick(), &batch_data->batch); } @@ -2435,38 +2207,41 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { // LB pick // -static void create_subchannel_call(grpc_call_element* elem) { +static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); const size_t parent_data_size = calld->enable_retries ? sizeof(subchannel_call_retry_state) : 0; const grpc_core::ConnectedSubchannel::CallArgs call_args = { - calld->pollent, // pollent - calld->path, // path - calld->call_start_time, // start_time - calld->deadline, // deadline - calld->arena, // arena - calld->pick.pick.subchannel_call_context, // context - calld->call_combiner, // call_combiner - parent_data_size // parent_data_size + calld->pollent, // pollent + calld->path, // path + calld->call_start_time, // start_time + calld->deadline, // deadline + calld->arena, // arena + calld->request->pick()->subchannel_call_context, // context + calld->call_combiner, // call_combiner + parent_data_size // parent_data_size }; - grpc_error* error = GRPC_ERROR_NONE; + grpc_error* new_error = GRPC_ERROR_NONE; calld->subchannel_call = - calld->pick.pick.connected_subchannel->CreateCall(call_args, &error); + calld->request->pick()->connected_subchannel->CreateCall(call_args, + &new_error); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, calld, calld->subchannel_call.get(), - grpc_error_string(error)); + grpc_error_string(new_error)); } - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - pending_batches_fail(elem, error, yield_call_combiner); + if (GPR_UNLIKELY(new_error != GRPC_ERROR_NONE)) { + new_error = grpc_error_add_child(new_error, error); + pending_batches_fail(elem, new_error, true /* yield_call_combiner */); } else { if (parent_data_size > 0) { - new (calld->subchannel_call->GetParentData()) - subchannel_call_retry_state(calld->pick.pick.subchannel_call_context); + new (calld->subchannel_call->GetParentData()) subchannel_call_retry_state( + calld->request->pick()->subchannel_call_context); } pending_batches_resume(elem); } + GRPC_ERROR_UNREF(error); } // Invoked when a pick is completed, on both success or failure. @@ -2474,106 +2249,54 @@ static void pick_done(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (error != GRPC_ERROR_NONE) { - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: failed to pick subchannel: error=%s", chand, - calld, grpc_error_string(error)); - } - pending_batches_fail(elem, GRPC_ERROR_REF(error), yield_call_combiner); - return; - } - create_subchannel_call(elem); -} - -namespace grpc_core { -namespace { - -// A class to handle the call combiner cancellation callback for a -// queued pick. -class QueuedPickCanceller { - public: - explicit QueuedPickCanceller(grpc_call_element* elem) : elem_(elem) { - auto* calld = static_cast(elem->call_data); - auto* chand = static_cast(elem->channel_data); - GRPC_CALL_STACK_REF(calld->owning_call, "QueuedPickCanceller"); - GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this, - grpc_combiner_scheduler(chand->combiner)); - grpc_call_combiner_set_notify_on_cancel(calld->call_combiner, &closure_); - } - - private: - static void CancelLocked(void* arg, grpc_error* error) { - auto* self = static_cast(arg); - auto* chand = static_cast(self->elem_->channel_data); - auto* calld = static_cast(self->elem_->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: cancelling queued pick: " - "error=%s self=%p calld->pick_canceller=%p", - chand, calld, grpc_error_string(error), self, - calld->pick_canceller); - } - if (calld->pick_canceller == self && error != GRPC_ERROR_NONE) { - // Remove pick from list of queued picks. - remove_call_from_queued_picks_locked(self->elem_); - // Fail pending batches on the call. - pending_batches_fail(self->elem_, GRPC_ERROR_REF(error), - yield_call_combiner_if_pending_batches_found); - } - GRPC_CALL_STACK_UNREF(calld->owning_call, "QueuedPickCanceller"); - Delete(self); - } - - grpc_call_element* elem_; - grpc_closure closure_; -}; - -} // namespace -} // namespace grpc_core - -// Removes the call from the channel's list of queued picks. -static void remove_call_from_queued_picks_locked(grpc_call_element* elem) { - auto* chand = static_cast(elem->channel_data); - auto* calld = static_cast(elem->call_data); - for (QueuedPick** pick = &chand->queued_picks; *pick != nullptr; - pick = &(*pick)->next) { - if (*pick == &calld->pick) { + if (GPR_UNLIKELY(calld->request->pick()->connected_subchannel == nullptr)) { + // Failed to create subchannel. + // If there was no error, this is an LB policy drop, in which case + // we return an error; otherwise, we may retry. + grpc_status_code status = GRPC_STATUS_OK; + grpc_error_get_status(error, calld->deadline, &status, nullptr, nullptr, + nullptr); + if (error == GRPC_ERROR_NONE || !calld->enable_retries || + !maybe_retry(elem, nullptr /* batch_data */, status, + nullptr /* server_pushback_md */)) { + grpc_error* new_error = + error == GRPC_ERROR_NONE + ? GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Call dropped by load balancing policy") + : GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Failed to create subchannel", &error, 1); if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: removing from queued picks list", - chand, calld); + gpr_log(GPR_INFO, + "chand=%p calld=%p: failed to create subchannel: error=%s", + chand, calld, grpc_error_string(new_error)); } - calld->pick_queued = false; - *pick = calld->pick.next; - // Remove call's pollent from channel's interested_parties. - grpc_polling_entity_del_from_pollset_set(calld->pollent, - chand->interested_parties); - // Lame the call combiner canceller. - calld->pick_canceller = nullptr; - break; + pending_batches_fail(elem, new_error, true /* yield_call_combiner */); } + } else { + /* Create call on subchannel. */ + create_subchannel_call(elem, GRPC_ERROR_REF(error)); } } -// Adds the call to the channel's list of queued picks. -static void add_call_to_queued_picks_locked(grpc_call_element* elem) { - auto* chand = static_cast(elem->channel_data); - auto* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, "chand=%p calld=%p: adding to queued picks list", chand, - calld); +// If the channel is in TRANSIENT_FAILURE and the call is not +// wait_for_ready=true, fails the call and returns true. +static bool fail_call_if_in_transient_failure(grpc_call_element* elem) { + channel_data* chand = static_cast(elem->channel_data); + call_data* calld = static_cast(elem->call_data); + grpc_transport_stream_op_batch* batch = calld->pending_batches[0].batch; + if (chand->request_router->GetConnectivityState() == + GRPC_CHANNEL_TRANSIENT_FAILURE && + (batch->payload->send_initial_metadata.send_initial_metadata_flags & + GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) { + pending_batches_fail( + elem, + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "channel is in state TRANSIENT_FAILURE"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), + true /* yield_call_combiner */); + return true; } - calld->pick_queued = true; - // Add call to queued picks list. - calld->pick.elem = elem; - calld->pick.next = chand->queued_picks; - chand->queued_picks = &calld->pick; - // Add call's pollent to channel's interested_parties, so that I/O - // can be done under the call's CQ. - grpc_polling_entity_add_to_pollset_set(calld->pollent, - chand->interested_parties); - // Register call combiner cancellation callback. - calld->pick_canceller = grpc_core::New(elem); + return false; } // Applies service config to the call. Must be invoked once we know @@ -2633,37 +2356,36 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) { } // Invoked once resolver results are available. -static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); +static bool maybe_apply_service_config_to_call_locked(void* arg) { + grpc_call_element* elem = static_cast(arg); call_data* calld = static_cast(elem->call_data); - // Apply service config data to the call only once, and only if the - // channel has the data available. - if (GPR_LIKELY(chand->have_service_config && - !calld->service_config_applied)) { - calld->service_config_applied = true; + // Only get service config data on the first attempt. + if (GPR_LIKELY(calld->num_attempts_completed == 0)) { apply_service_config_to_call_locked(elem); + // Check this after applying service config, since it may have + // affected the call's wait_for_ready value. + if (fail_call_if_in_transient_failure(elem)) return false; } + return true; } -static const char* pick_result_name( - LoadBalancingPolicy::SubchannelPicker::PickResult result) { - switch (result) { - case LoadBalancingPolicy::SubchannelPicker::PICK_COMPLETE: - return "COMPLETE"; - case LoadBalancingPolicy::SubchannelPicker::PICK_QUEUE: - return "QUEUE"; - case LoadBalancingPolicy::SubchannelPicker::PICK_TRANSIENT_FAILURE: - return "TRANSIENT_FAILURE"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -static void start_pick_locked(void* arg, grpc_error* error) { +static void start_pick_locked(void* arg, grpc_error* ignored) { grpc_call_element* elem = static_cast(arg); call_data* calld = static_cast(elem->call_data); channel_data* chand = static_cast(elem->channel_data); - GPR_ASSERT(calld->pick.pick.connected_subchannel == nullptr); + GPR_ASSERT(!calld->have_request); GPR_ASSERT(calld->subchannel_call == nullptr); + // Normally, we want to do this check until after we've processed the + // service config, so that we can honor the wait_for_ready setting in + // the service config. However, if the channel is in TRANSIENT_FAILURE + // and we don't have an LB policy at this point, that means that the + // resolver has returned a failure, so we're not going to get a service + // config right away. In that case, we fail the call now based on the + // wait_for_ready value passed in from the application. + if (chand->request_router->lb_policy() == nullptr && + fail_call_if_in_transient_failure(elem)) { + return; + } // If this is a retry, use the send_initial_metadata payload that // we've cached; otherwise, use the pending batch. The // send_initial_metadata batch will be the first pending batch in the @@ -2674,78 +2396,25 @@ static void start_pick_locked(void* arg, grpc_error* error) { // allocate the subchannel batch earlier so that we can give the // subchannel's copy of the metadata batch (which is copied for each // attempt) to the LB policy instead the one from the parent channel. - calld->pick.pick.initial_metadata = + grpc_metadata_batch* initial_metadata = calld->seen_send_initial_metadata ? &calld->send_initial_metadata : calld->pending_batches[0] .batch->payload->send_initial_metadata.send_initial_metadata; - uint32_t* send_initial_metadata_flags = + uint32_t* initial_metadata_flags = calld->seen_send_initial_metadata ? &calld->send_initial_metadata_flags : &calld->pending_batches[0] .batch->payload->send_initial_metadata .send_initial_metadata_flags; - // Apply service config to call if needed. - maybe_apply_service_config_to_call_locked(elem); - // When done, we schedule this closure to leave the channel combiner. GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem, grpc_schedule_on_exec_ctx); - // Attempt pick. - error = GRPC_ERROR_NONE; - auto pick_result = chand->picker->Pick(&calld->pick.pick, &error); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: LB pick returned %s (connected_subchannel=%p, " - "error=%s)", - chand, calld, pick_result_name(pick_result), - calld->pick.pick.connected_subchannel.get(), - grpc_error_string(error)); - } - switch (pick_result) { - case LoadBalancingPolicy::SubchannelPicker::PICK_TRANSIENT_FAILURE: - // If we're shutting down, fail all RPCs. - if (chand->disconnect_error != GRPC_ERROR_NONE) { - GRPC_ERROR_UNREF(error); - GRPC_CLOSURE_SCHED(&calld->pick_closure, - GRPC_ERROR_REF(chand->disconnect_error)); - break; - } - // If wait_for_ready is false, then the error indicates the RPC - // attempt's final status. - if ((*send_initial_metadata_flags & - GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) { - // Retry if appropriate; otherwise, fail. - grpc_status_code status = GRPC_STATUS_OK; - grpc_error_get_status(error, calld->deadline, &status, nullptr, nullptr, - nullptr); - if (!calld->enable_retries || - !maybe_retry(elem, nullptr /* batch_data */, status, - nullptr /* server_pushback_md */)) { - grpc_error* new_error = - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Failed to create subchannel", &error, 1); - GRPC_ERROR_UNREF(error); - GRPC_CLOSURE_SCHED(&calld->pick_closure, new_error); - } - if (calld->pick_queued) remove_call_from_queued_picks_locked(elem); - break; - } - // If wait_for_ready is true, then queue to retry when we get a new - // picker. - GRPC_ERROR_UNREF(error); - // Fallthrough - case LoadBalancingPolicy::SubchannelPicker::PICK_QUEUE: - if (!calld->pick_queued) add_call_to_queued_picks_locked(elem); - break; - default: // PICK_COMPLETE - // Handle drops. - if (GPR_UNLIKELY(calld->pick.pick.connected_subchannel == nullptr)) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Call dropped by load balancing policy"); - } - GRPC_CLOSURE_SCHED(&calld->pick_closure, error); - if (calld->pick_queued) remove_call_from_queued_picks_locked(elem); - } + calld->request.Init(calld->owning_call, calld->call_combiner, calld->pollent, + initial_metadata, initial_metadata_flags, + maybe_apply_service_config_to_call_locked, elem, + &calld->pick_closure); + calld->have_request = true; + chand->request_router->RouteCallLocked(calld->request.get()); } // @@ -2789,10 +2458,8 @@ static void cc_start_transport_stream_op_batch( // been started), fail all pending batches. Otherwise, send the // cancellation down to the subchannel call. if (calld->subchannel_call == nullptr) { - // TODO(roth): If there is a pending retry callback, do we need to - // cancel it here? pending_batches_fail(elem, GRPC_ERROR_REF(calld->cancel_error), - no_yield_call_combiner); + false /* yield_call_combiner */); // Note: This will release the call combiner. grpc_transport_stream_op_batch_finish_with_failure( batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner); @@ -2889,8 +2556,7 @@ const grpc_channel_filter grpc_client_channel_filter = { void grpc_client_channel_set_channelz_node( grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node) { channel_data* chand = static_cast(elem->channel_data); - chand->channelz_node = node; - chand->resolving_lb_policy->set_channelz_node(node->Ref()); + chand->request_router->set_channelz_node(node); } void grpc_client_channel_populate_child_refs( @@ -2898,23 +2564,22 @@ void grpc_client_channel_populate_child_refs( grpc_core::channelz::ChildRefsList* child_subchannels, grpc_core::channelz::ChildRefsList* child_channels) { channel_data* chand = static_cast(elem->channel_data); - if (chand->resolving_lb_policy != nullptr) { - chand->resolving_lb_policy->FillChildRefsForChannelz(child_subchannels, - child_channels); + if (chand->request_router->lb_policy() != nullptr) { + chand->request_router->lb_policy()->FillChildRefsForChannelz( + child_subchannels, child_channels); } } static void try_to_connect_locked(void* arg, grpc_error* error_ignored) { channel_data* chand = static_cast(arg); - chand->resolving_lb_policy->ExitIdleLocked(); + chand->request_router->ExitIdleLocked(); GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "try_to_connect"); } grpc_connectivity_state grpc_client_channel_check_connectivity_state( grpc_channel_element* elem, int try_to_connect) { channel_data* chand = static_cast(elem->channel_data); - grpc_connectivity_state out = - grpc_connectivity_state_check(&chand->state_tracker); + grpc_connectivity_state out = chand->request_router->GetConnectivityState(); if (out == GRPC_CHANNEL_IDLE && try_to_connect) { GRPC_CHANNEL_STACK_REF(chand->owning_stack, "try_to_connect"); GRPC_CLOSURE_SCHED( @@ -3023,15 +2688,15 @@ static void watch_connectivity_state_locked(void* arg, GRPC_CLOSURE_RUN(w->watcher_timer_init, GRPC_ERROR_NONE); GRPC_CLOSURE_INIT(&w->my_closure, on_external_watch_complete_locked, w, grpc_combiner_scheduler(w->chand->combiner)); - grpc_connectivity_state_notify_on_state_change(&w->chand->state_tracker, - w->state, &w->my_closure); + w->chand->request_router->NotifyOnConnectivityStateChange(w->state, + &w->my_closure); } else { GPR_ASSERT(w->watcher_timer_init == nullptr); found = lookup_external_connectivity_watcher(w->chand, w->on_complete); if (found) { GPR_ASSERT(found->on_complete == w->on_complete); - grpc_connectivity_state_notify_on_state_change( - &found->chand->state_tracker, nullptr, &found->my_closure); + found->chand->request_router->NotifyOnConnectivityStateChange( + nullptr, &found->my_closure); } grpc_polling_entity_del_from_pollset_set(&w->pollent, w->chand->interested_parties); diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 9e3477b9ed5..d9b3927d1ca 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -54,15 +54,35 @@ grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( return nullptr; } -LoadBalancingPolicy::LoadBalancingPolicy(Args args, intptr_t initial_refcount) - : InternallyRefCounted(&grpc_trace_lb_policy_refcount, initial_refcount), +LoadBalancingPolicy::LoadBalancingPolicy(Args args) + : InternallyRefCounted(&grpc_trace_lb_policy_refcount), combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), + client_channel_factory_(args.client_channel_factory), + subchannel_pool_(std::move(args.subchannel_pool)), interested_parties_(grpc_pollset_set_create()), - channel_control_helper_(std::move(args.channel_control_helper)) {} + request_reresolution_(nullptr) {} LoadBalancingPolicy::~LoadBalancingPolicy() { grpc_pollset_set_destroy(interested_parties_); GRPC_COMBINER_UNREF(combiner_, "lb_policy"); } +void LoadBalancingPolicy::TryReresolutionLocked( + grpc_core::TraceFlag* grpc_lb_trace, grpc_error* error) { + if (request_reresolution_ != nullptr) { + GRPC_CLOSURE_SCHED(request_reresolution_, error); + request_reresolution_ = nullptr; + if (grpc_lb_trace->enabled()) { + gpr_log(GPR_INFO, + "%s %p: scheduling re-resolution closure with error=%s.", + grpc_lb_trace->name(), this, grpc_error_string(error)); + } + } else { + if (grpc_lb_trace->enabled()) { + gpr_log(GPR_INFO, "%s %p: no available re-resolution closure.", + grpc_lb_trace->name(), this); + } + } +} + } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index aeb8138a12e..56bf1951cfb 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -24,6 +24,7 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -42,179 +43,8 @@ namespace grpc_core { /// /// Any I/O done by the LB policy should be done under the pollset_set /// returned by \a interested_parties(). -// TODO(roth): Once we move to EventManager-based polling, remove the -// interested_parties() hooks from the API. class LoadBalancingPolicy : public InternallyRefCounted { public: - /// State used for an LB pick. - struct PickState { - /// Initial metadata associated with the picking call. - /// This is both an input and output parameter; the LB policy may - /// use metadata here to influence its routing decision, and it may - /// add new metadata here to be sent with the call to the chosen backend. - grpc_metadata_batch* initial_metadata = nullptr; - /// Storage for LB token in \a initial_metadata, or nullptr if not used. - // TODO(roth): Remove this from the API. Maybe have the LB policy - // allocate this on the arena instead? - grpc_linked_mdelem lb_token_mdelem_storage; - /// Callback set by lb policy to be notified of trailing metadata. - /// The callback must be scheduled on grpc_schedule_on_exec_ctx. - grpc_closure* recv_trailing_metadata_ready = nullptr; - /// The address that will be set to point to the original - /// recv_trailing_metadata_ready callback, to be invoked by the LB - /// policy's recv_trailing_metadata_ready callback when complete. - /// Must be non-null if recv_trailing_metadata_ready is non-null. - grpc_closure** original_recv_trailing_metadata_ready = nullptr; - /// If this is not nullptr, then the client channel will point it to the - /// call's trailing metadata before invoking recv_trailing_metadata_ready. - /// If this is nullptr, then the callback will still be called. - /// The lb does not have ownership of the metadata. - grpc_metadata_batch** recv_trailing_metadata = nullptr; - /// Will be set to the selected subchannel, or nullptr on failure or when - /// the LB policy decides to drop the call. - RefCountedPtr connected_subchannel; - /// Will be populated with context to pass to the subchannel call, if - /// needed. - // TODO(roth): Remove this from the API, especially since it's not - // working properly anyway (see https://github.com/grpc/grpc/issues/15927). - grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; - }; - - /// A picker is the object used to actual perform picks. - /// - /// Pickers are intended to encapsulate all of the state and logic - /// needed on the data plane (i.e., to actually process picks for - /// individual RPCs sent on the channel) while excluding all of the - /// state and logic needed on the control plane (i.e., resolver - /// updates, connectivity state notifications, etc); the latter should - /// live in the LB policy object itself. - /// - /// Currently, pickers are always accessed from within the - /// client_channel combiner, so they do not have to be thread-safe. - // TODO(roth): In a subsequent PR, split the data plane work (i.e., - // the interaction with the picker) and the control plane work (i.e., - // the interaction with the LB policy) into two different - // synchronization mechanisms, to avoid lock contention between the two. - class SubchannelPicker { - public: - enum PickResult { - // Pick complete. If connected_subchannel is non-null, client channel - // can immediately proceed with the call on connected_subchannel; - // otherwise, call should be dropped. - PICK_COMPLETE, - // Pick cannot be completed until something changes on the control - // plane. Client channel will queue the pick and try again the - // next time the picker is updated. - PICK_QUEUE, - // LB policy is in transient failure. If the pick is wait_for_ready, - // client channel will wait for the next picker and try again; - // otherwise, the call will be failed immediately (although it may - // be retried if the client channel is configured to do so). - // The Pick() method will set its error parameter if this value is - // returned. - PICK_TRANSIENT_FAILURE, - }; - - SubchannelPicker() = default; - virtual ~SubchannelPicker() = default; - - virtual PickResult Pick(PickState* pick, grpc_error** error) GRPC_ABSTRACT; - - GRPC_ABSTRACT_BASE_CLASS - }; - - // A picker that returns PICK_QUEUE for all picks. - // Also calls the parent LB policy's ExitIdleLocked() method when the - // first pick is seen. - class QueuePicker : public SubchannelPicker { - public: - explicit QueuePicker(RefCountedPtr parent) - : parent_(std::move(parent)) {} - - PickResult Pick(PickState* pick, grpc_error** error) override { - // We invoke the parent's ExitIdleLocked() via a closure instead - // of doing it directly here, for two reasons: - // 1. ExitIdleLocked() may cause the policy's state to change and - // a new picker to be delivered to the channel. If that new - // picker is delivered before ExitIdleLocked() returns, then by - // the time this function returns, the pick will already have - // been processed, and we'll be trying to re-process the same - // pick again, leading to a crash. - // 2. In a subsequent PR, we will split the data plane and control - // plane synchronization into separate combiners, at which - // point this will need to hop from the data plane combiner into - // the control plane combiner. - if (!exit_idle_called_) { - exit_idle_called_ = true; - parent_->Ref().release(); // ref held by closure. - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(&CallExitIdle, parent_.get(), - grpc_combiner_scheduler(parent_->combiner())), - GRPC_ERROR_NONE); - } - return PICK_QUEUE; - } - - private: - static void CallExitIdle(void* arg, grpc_error* error) { - LoadBalancingPolicy* parent = static_cast(arg); - parent->ExitIdleLocked(); - parent->Unref(); - } - - RefCountedPtr parent_; - bool exit_idle_called_ = false; - }; - - // A picker that returns PICK_TRANSIENT_FAILURE for all picks. - class TransientFailurePicker : public SubchannelPicker { - public: - explicit TransientFailurePicker(grpc_error* error) : error_(error) {} - ~TransientFailurePicker() { GRPC_ERROR_UNREF(error_); } - - PickResult Pick(PickState* pick, grpc_error** error) override { - *error = GRPC_ERROR_REF(error_); - return PICK_TRANSIENT_FAILURE; - } - - private: - grpc_error* error_; - }; - - /// A proxy object used by the LB policy to communicate with the client - /// channel. - class ChannelControlHelper { - public: - ChannelControlHelper() = default; - virtual ~ChannelControlHelper() = default; - - /// Creates a new subchannel with the specified channel args. - virtual Subchannel* CreateSubchannel(const grpc_channel_args& args) - GRPC_ABSTRACT; - - /// Creates a channel with the specified target, type, and channel args. - virtual grpc_channel* CreateChannel( - const char* target, grpc_client_channel_type type, - const grpc_channel_args& args) GRPC_ABSTRACT; - - /// Sets the connectivity state and returns a new picker to be used - /// by the client channel. - virtual void UpdateState(grpc_connectivity_state state, - grpc_error* state_error, - UniquePtr picker) { - std::move(picker); // Suppress clang-tidy complaint. - // The rest of this is copied from the GRPC_ABSTRACT macro. - gpr_log(GPR_ERROR, "Function marked GRPC_ABSTRACT was not implemented"); - GPR_ASSERT(false); - } - - /// Requests that the resolver re-resolve. - virtual void RequestReresolution() GRPC_ABSTRACT; - - GRPC_ABSTRACT_BASE_CLASS - }; - - /// Args used to instantiate an LB policy. struct Args { /// The combiner under which all LB policy calls will be run. /// Policy does NOT take ownership of the reference to the combiner. @@ -222,16 +52,54 @@ class LoadBalancingPolicy : public InternallyRefCounted { // API should change to take a smart pointer that does pass ownership // of a reference. grpc_combiner* combiner = nullptr; - /// Channel control helper. - UniquePtr channel_control_helper; + /// Used to create channels and subchannels. + grpc_client_channel_factory* client_channel_factory = nullptr; + /// Subchannel pool. + RefCountedPtr subchannel_pool; /// Channel args from the resolver. /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. - const grpc_channel_args* args = nullptr; + grpc_channel_args* args = nullptr; /// Load balancing config from the resolver. grpc_json* lb_config = nullptr; }; + /// State used for an LB pick. + struct PickState { + /// Initial metadata associated with the picking call. + grpc_metadata_batch* initial_metadata = nullptr; + /// Pointer to bitmask used for selective cancelling. See + /// \a CancelMatchingPicksLocked() and \a GRPC_INITIAL_METADATA_* in + /// grpc_types.h. + uint32_t* initial_metadata_flags = nullptr; + /// Storage for LB token in \a initial_metadata, or nullptr if not used. + grpc_linked_mdelem lb_token_mdelem_storage; + /// Closure to run when pick is complete, if not completed synchronously. + /// If null, pick will fail if a result is not available synchronously. + grpc_closure* on_complete = nullptr; + // Callback set by lb policy to be notified of trailing metadata. + // The callback must be scheduled on grpc_schedule_on_exec_ctx. + grpc_closure* recv_trailing_metadata_ready = nullptr; + // The address that will be set to point to the original + // recv_trailing_metadata_ready callback, to be invoked by the LB + // policy's recv_trailing_metadata_ready callback when complete. + // Must be non-null if recv_trailing_metadata_ready is non-null. + grpc_closure** original_recv_trailing_metadata_ready = nullptr; + // If this is not nullptr, then the client channel will point it to the + // call's trailing metadata before invoking recv_trailing_metadata_ready. + // If this is nullptr, then the callback will still be called. + // The lb does not have ownership of the metadata. + grpc_metadata_batch** recv_trailing_metadata = nullptr; + /// Will be set to the selected subchannel, or nullptr on failure or when + /// the LB policy decides to drop the call. + RefCountedPtr connected_subchannel; + /// Will be populated with context to pass to the subchannel call, if + /// needed. + grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; + /// Next pointer. For internal use by LB policy. + PickState* next = nullptr; + }; + // Not copyable nor movable. LoadBalancingPolicy(const LoadBalancingPolicy&) = delete; LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete; @@ -245,6 +113,48 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) GRPC_ABSTRACT; + /// Finds an appropriate subchannel for a call, based on data in \a pick. + /// \a pick must remain alive until the pick is complete. + /// + /// If a result is known immediately, returns true, setting \a *error + /// upon failure. Otherwise, \a pick->on_complete will be invoked once + /// the pick is complete with its error argument set to indicate success + /// or failure. + /// + /// If \a pick->on_complete is null and no result is known immediately, + /// a synchronous failure will be returned (i.e., \a *error will be + /// set and true will be returned). + virtual bool PickLocked(PickState* pick, grpc_error** error) GRPC_ABSTRACT; + + /// Cancels \a pick. + /// The \a on_complete callback of the pending pick will be invoked with + /// \a pick->connected_subchannel set to null. + virtual void CancelPickLocked(PickState* pick, + grpc_error* error) GRPC_ABSTRACT; + + /// Cancels all pending picks for which their \a initial_metadata_flags (as + /// given in the call to \a PickLocked()) matches + /// \a initial_metadata_flags_eq when ANDed with + /// \a initial_metadata_flags_mask. + virtual void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) GRPC_ABSTRACT; + + /// Requests a notification when the connectivity state of the policy + /// changes from \a *state. When that happens, sets \a *state to the + /// new state and schedules \a closure. + virtual void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) GRPC_ABSTRACT; + + /// Returns the policy's current connectivity state. Sets \a error to + /// the associated error, if any. + virtual grpc_connectivity_state CheckConnectivityLocked( + grpc_error** connectivity_error) GRPC_ABSTRACT; + + /// Hands off pending picks to \a new_policy. + virtual void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) + GRPC_ABSTRACT; + /// Tries to enter a READY connectivity state. /// TODO(roth): As part of restructuring how we handle IDLE state, /// consider whether this method is still needed. @@ -273,11 +183,18 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// given the JSON node of a LoadBalancingConfig array. static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array); + /// Sets the re-resolution closure to \a request_reresolution. + void SetReresolutionClosureLocked(grpc_closure* request_reresolution) { + GPR_ASSERT(request_reresolution_ == nullptr); + request_reresolution_ = request_reresolution; + } + grpc_pollset_set* interested_parties() const { return interested_parties_; } - void set_channelz_node( - RefCountedPtr channelz_node) { - channelz_node_ = std::move(channelz_node); + // Callers that need their own reference can call the returned + // object's Ref() method. + SubchannelPoolInterface* subchannel_pool() const { + return subchannel_pool_.get(); } GRPC_ABSTRACT_BASE_CLASS @@ -285,18 +202,12 @@ class LoadBalancingPolicy : public InternallyRefCounted { protected: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - explicit LoadBalancingPolicy(Args args, intptr_t initial_refcount = 1); + explicit LoadBalancingPolicy(Args args); virtual ~LoadBalancingPolicy(); grpc_combiner* combiner() const { return combiner_; } - - // Note: This will return null after ShutdownLocked() has been called. - ChannelControlHelper* channel_control_helper() const { - return channel_control_helper_.get(); - } - - channelz::ClientChannelNode* channelz_node() const { - return channelz_node_.get(); + grpc_client_channel_factory* client_channel_factory() const { + return client_channel_factory_; } /// Shuts down the policy. Any pending picks that have not been @@ -304,22 +215,27 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// failed. virtual void ShutdownLocked() GRPC_ABSTRACT; + /// Tries to request a re-resolution. + void TryReresolutionLocked(grpc_core::TraceFlag* grpc_lb_trace, + grpc_error* error); + private: static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) { LoadBalancingPolicy* policy = static_cast(arg); policy->ShutdownLocked(); - policy->channel_control_helper_.reset(); policy->Unref(); } /// Combiner under which LB policy actions take place. grpc_combiner* combiner_; + /// Client channel factory, used to create channels and subchannels. + grpc_client_channel_factory* client_channel_factory_; + /// Subchannel pool. + RefCountedPtr subchannel_pool_; /// Owned pointer to interested parties in load balancing decisions. grpc_pollset_set* interested_parties_; - /// Channel control helper. - UniquePtr channel_control_helper_; - /// Channelz node. - RefCountedPtr channelz_node_; + /// Callback to force a re-resolution. + grpc_closure* request_reresolution_; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index fa1ca6d127a..63e381d64c7 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -74,6 +74,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" @@ -130,6 +131,16 @@ class GrpcLb : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; + bool PickLocked(PickState* pick, grpc_error** error) override; + void CancelPickLocked(PickState* pick, grpc_error* error) override; + void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) override; + void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) override; + grpc_connectivity_state CheckConnectivityLocked( + grpc_error** connectivity_error) override; + void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( @@ -137,6 +148,31 @@ class GrpcLb : public LoadBalancingPolicy { channelz::ChildRefsList* child_channels) override; private: + /// Linked list of pending pick requests. It stores all information needed to + /// eventually call (Round Robin's) pick() on them. They mainly stay pending + /// waiting for the RR policy to be created. + /// + /// Note that when a pick is sent to the RR policy, we inject our own + /// on_complete callback, so that we can intercept the result before + /// invoking the original on_complete callback. This allows us to set the + /// LB token metadata and add client_stats to the call context. + /// See \a pending_pick_complete() for details. + struct PendingPick { + // The grpclb instance that created the wrapping. This instance is not + // owned; reference counts are untouched. It's used only for logging + // purposes. + GrpcLb* grpclb_policy; + // The original pick. + PickState* pick; + // Our on_complete closure and the original one. + grpc_closure on_complete; + grpc_closure* original_on_complete; + // Stats for client-side load reporting. + RefCountedPtr client_stats; + // Next pending pick. + PendingPick* next = nullptr; + }; + /// Contains a call to the LB server and all the data related to the call. class BalancerCallState : public InternallyRefCounted { public: @@ -212,80 +248,6 @@ class GrpcLb : public LoadBalancingPolicy { grpc_closure client_load_report_closure_; }; - class Serverlist : public RefCounted { - public: - // Takes ownership of serverlist. - explicit Serverlist(grpc_grpclb_serverlist* serverlist) - : serverlist_(serverlist) {} - - ~Serverlist() { grpc_grpclb_destroy_serverlist(serverlist_); } - - bool operator==(const Serverlist& other) const; - - const grpc_grpclb_serverlist* serverlist() const { return serverlist_; } - - // Returns a text representation suitable for logging. - UniquePtr AsText() const; - - // Extracts all non-drop entries into a ServerAddressList. - ServerAddressList GetServerAddressList() const; - - // Returns true if the serverlist contains at least one drop entry and - // no backend address entries. - bool ContainsAllDropEntries() const; - - // Returns the LB token to use for a drop, or null if the call - // should not be dropped. - // Intended to be called from picker, so calls will be externally - // synchronized. - const char* ShouldDrop(); - - private: - grpc_grpclb_serverlist* serverlist_; - size_t drop_index_ = 0; - }; - - class Picker : public SubchannelPicker { - public: - Picker(GrpcLb* parent, RefCountedPtr serverlist, - UniquePtr child_picker, - RefCountedPtr client_stats) - : parent_(parent), - serverlist_(std::move(serverlist)), - child_picker_(std::move(child_picker)), - client_stats_(std::move(client_stats)) {} - - PickResult Pick(PickState* pick, grpc_error** error) override; - - private: - // Storing the address for logging, but not holding a ref. - // DO NOT DEFERENCE! - GrpcLb* parent_; - - // Serverlist to be used for determining drops. - RefCountedPtr serverlist_; - - UniquePtr child_picker_; - RefCountedPtr client_stats_; - }; - - class Helper : public ChannelControlHelper { - public: - explicit Helper(RefCountedPtr parent) - : parent_(std::move(parent)) {} - - Subchannel* CreateSubchannel(const grpc_channel_args& args) override; - grpc_channel* CreateChannel(const char* target, - grpc_client_channel_type type, - const grpc_channel_args& args) override; - void UpdateState(grpc_connectivity_state state, grpc_error* state_error, - UniquePtr picker) override; - void RequestReresolution() override; - - private: - RefCountedPtr parent_; - }; - ~GrpcLb(); void ShutdownLocked() override; @@ -302,10 +264,24 @@ class GrpcLb : public LoadBalancingPolicy { static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); + // Pending pick methods. + static void PendingPickSetMetadataAndContext(PendingPick* pp); + PendingPick* PendingPickCreate(PickState* pick); + void AddPendingPick(PendingPick* pp); + static void OnPendingPickComplete(void* arg, grpc_error* error); + // Methods for dealing with the RR policy. void CreateOrUpdateRoundRobinPolicyLocked(); grpc_channel_args* CreateRoundRobinPolicyArgsLocked(); void CreateRoundRobinPolicyLocked(Args args); + bool PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, + grpc_error** error); + void UpdateConnectivityStateFromRoundRobinPolicyLocked( + grpc_error* rr_state_error); + static void OnRoundRobinConnectivityChangedLocked(void* arg, + grpc_error* error); + static void OnRoundRobinRequestReresolutionLocked(void* arg, + grpc_error* error); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -316,6 +292,7 @@ class GrpcLb : public LoadBalancingPolicy { // Internal state. bool started_picking_ = false; bool shutting_down_ = false; + grpc_connectivity_state_tracker state_tracker_; // The channel for communicating with the LB server. grpc_channel* lb_channel_ = nullptr; @@ -344,7 +321,11 @@ class GrpcLb : public LoadBalancingPolicy { // The deserialized response from the balancer. May be nullptr until one // such response has arrived. - RefCountedPtr serverlist_; + grpc_grpclb_serverlist* serverlist_ = nullptr; + // Index into serverlist for next pick. + // If the server at this index is a drop, we return a drop. + // Otherwise, we delegate to the RR policy. + size_t serverlist_index_ = 0; // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. @@ -356,65 +337,20 @@ class GrpcLb : public LoadBalancingPolicy { grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; + // Pending picks that are waiting on the RR policy's connectivity. + PendingPick* pending_picks_ = nullptr; + // The RR policy to use for the backends. OrphanablePtr rr_policy_; + grpc_connectivity_state rr_connectivity_state_; + grpc_closure on_rr_connectivity_changed_; + grpc_closure on_rr_request_reresolution_; }; // -// GrpcLb::Serverlist +// serverlist parsing code // -bool GrpcLb::Serverlist::operator==(const Serverlist& other) const { - return grpc_grpclb_serverlist_equals(serverlist_, other.serverlist_); -} - -void ParseServer(const grpc_grpclb_server* server, - grpc_resolved_address* addr) { - memset(addr, 0, sizeof(*addr)); - if (server->drop) return; - const uint16_t netorder_port = grpc_htons((uint16_t)server->port); - /* the addresses are given in binary format (a in(6)_addr struct) in - * server->ip_address.bytes. */ - const grpc_grpclb_ip_address* ip = &server->ip_address; - if (ip->size == 4) { - addr->len = static_cast(sizeof(grpc_sockaddr_in)); - grpc_sockaddr_in* addr4 = reinterpret_cast(&addr->addr); - addr4->sin_family = GRPC_AF_INET; - memcpy(&addr4->sin_addr, ip->bytes, ip->size); - addr4->sin_port = netorder_port; - } else if (ip->size == 16) { - addr->len = static_cast(sizeof(grpc_sockaddr_in6)); - grpc_sockaddr_in6* addr6 = (grpc_sockaddr_in6*)&addr->addr; - addr6->sin6_family = GRPC_AF_INET6; - memcpy(&addr6->sin6_addr, ip->bytes, ip->size); - addr6->sin6_port = netorder_port; - } -} - -UniquePtr GrpcLb::Serverlist::AsText() const { - gpr_strvec entries; - gpr_strvec_init(&entries); - for (size_t i = 0; i < serverlist_->num_servers; ++i) { - const auto* server = serverlist_->servers[i]; - char* ipport; - if (server->drop) { - ipport = gpr_strdup("(drop)"); - } else { - grpc_resolved_address addr; - ParseServer(server, &addr); - grpc_sockaddr_to_string(&ipport, &addr, false); - } - char* entry; - gpr_asprintf(&entry, " %" PRIuPTR ": %s token=%s\n", i, ipport, - server->load_balance_token); - gpr_free(ipport); - gpr_strvec_add(&entries, entry); - } - UniquePtr result(gpr_strvec_flatten(&entries, nullptr)); - gpr_strvec_destroy(&entries); - return result; -} - // vtable for LB token channel arg. void* lb_token_copy(void* token) { return token == nullptr @@ -457,12 +393,35 @@ bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) { return true; } -// Returns addresses extracted from the serverlist. -ServerAddressList GrpcLb::Serverlist::GetServerAddressList() const { +void ParseServer(const grpc_grpclb_server* server, + grpc_resolved_address* addr) { + memset(addr, 0, sizeof(*addr)); + if (server->drop) return; + const uint16_t netorder_port = grpc_htons((uint16_t)server->port); + /* the addresses are given in binary format (a in(6)_addr struct) in + * server->ip_address.bytes. */ + const grpc_grpclb_ip_address* ip = &server->ip_address; + if (ip->size == 4) { + addr->len = static_cast(sizeof(grpc_sockaddr_in)); + grpc_sockaddr_in* addr4 = reinterpret_cast(&addr->addr); + addr4->sin_family = GRPC_AF_INET; + memcpy(&addr4->sin_addr, ip->bytes, ip->size); + addr4->sin_port = netorder_port; + } else if (ip->size == 16) { + addr->len = static_cast(sizeof(grpc_sockaddr_in6)); + grpc_sockaddr_in6* addr6 = (grpc_sockaddr_in6*)&addr->addr; + addr6->sin6_family = GRPC_AF_INET6; + memcpy(&addr6->sin6_addr, ip->bytes, ip->size); + addr6->sin6_port = netorder_port; + } +} + +// Returns addresses extracted from \a serverlist. +ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { ServerAddressList addresses; - for (size_t i = 0; i < serverlist_->num_servers; ++i) { - const grpc_grpclb_server* server = serverlist_->servers[i]; - if (!IsServerValid(serverlist_->servers[i], i, false)) continue; + for (size_t i = 0; i < serverlist->num_servers; ++i) { + const grpc_grpclb_server* server = serverlist->servers[i]; + if (!IsServerValid(serverlist->servers[i], i, false)) continue; // Address processing. grpc_resolved_address addr; ParseServer(server, &addr); @@ -497,176 +456,6 @@ ServerAddressList GrpcLb::Serverlist::GetServerAddressList() const { return addresses; } -bool GrpcLb::Serverlist::ContainsAllDropEntries() const { - if (serverlist_->num_servers == 0) return false; - for (size_t i = 0; i < serverlist_->num_servers; ++i) { - if (!serverlist_->servers[i]->drop) return false; - } - return true; -} - -const char* GrpcLb::Serverlist::ShouldDrop() { - if (serverlist_->num_servers == 0) return nullptr; - grpc_grpclb_server* server = serverlist_->servers[drop_index_]; - drop_index_ = (drop_index_ + 1) % serverlist_->num_servers; - return server->drop ? server->load_balance_token : nullptr; -} - -// -// GrpcLb::Picker -// - -// Adds lb_token of selected subchannel (address) to the call's initial -// metadata. -grpc_error* AddLbTokenToInitialMetadata( - grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage, - grpc_metadata_batch* initial_metadata) { - GPR_ASSERT(lb_token_mdelem_storage != nullptr); - GPR_ASSERT(!GRPC_MDISNULL(lb_token)); - return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage, - lb_token); -} - -// Destroy function used when embedding client stats in call context. -void DestroyClientStats(void* arg) { - static_cast(arg)->Unref(); -} - -GrpcLb::Picker::PickResult GrpcLb::Picker::Pick(PickState* pick, - grpc_error** error) { - // Check if we should drop the call. - const char* drop_token = serverlist_->ShouldDrop(); - if (drop_token != nullptr) { - // Update client load reporting stats to indicate the number of - // dropped calls. Note that we have to do this here instead of in - // the client_load_reporting filter, because we do not create a - // subchannel call (and therefore no client_load_reporting filter) - // for dropped calls. - if (client_stats_ != nullptr) { - client_stats_->AddCallDroppedLocked(drop_token); - } - return PICK_COMPLETE; - } - // Forward pick to child policy. - PickResult result = child_picker_->Pick(pick, error); - // If pick succeeded, add LB token to initial metadata. - if (result == PickResult::PICK_COMPLETE && - pick->connected_subchannel != nullptr) { - const grpc_arg* arg = grpc_channel_args_find( - pick->connected_subchannel->args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); - if (arg == nullptr) { - gpr_log(GPR_ERROR, - "[grpclb %p picker %p] No LB token for connected subchannel " - "pick %p", - parent_, this, pick); - abort(); - } - grpc_mdelem lb_token = {reinterpret_cast(arg->value.pointer.p)}; - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(lb_token), - &pick->lb_token_mdelem_storage, - pick->initial_metadata); - // Pass on client stats via context. Passes ownership of the reference. - if (client_stats_ != nullptr) { - pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = - client_stats_->Ref().release(); - pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = - DestroyClientStats; - } - } - return result; -} - -// -// GrpcLb::Helper -// - -Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { - if (parent_->shutting_down_) return nullptr; - return parent_->channel_control_helper()->CreateSubchannel(args); -} - -grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, - grpc_client_channel_type type, - const grpc_channel_args& args) { - if (parent_->shutting_down_) return nullptr; - return parent_->channel_control_helper()->CreateChannel(target, type, args); -} - -void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, - grpc_error* state_error, - UniquePtr picker) { - if (parent_->shutting_down_) { - GRPC_ERROR_UNREF(state_error); - return; - } - // There are three cases to consider here: - // 1. We're in fallback mode. In this case, we're always going to use - // RR's result, so we pass its picker through as-is. - // 2. The serverlist contains only drop entries. In this case, we - // want to use our own picker so that we can return the drops. - // 3. Not in fallback mode and serverlist is not all drops (i.e., it - // may be empty or contain at least one backend address). There are - // two sub-cases: - // a. RR is reporting state READY. In this case, we wrap RR's - // picker in our own, so that we can handle drops and LB token - // metadata for each pick. - // b. RR is reporting a state other than READY. In this case, we - // don't want to use our own picker, because we don't want to - // process drops for picks that yield a QUEUE result; this would - // result in dropping too many calls, since we will see the - // queued picks multiple times, and we'd consider each one a - // separate call for the drop calculation. - // - // Cases 1 and 3b: return picker from RR as-is. - if (parent_->serverlist_ == nullptr || - (!parent_->serverlist_->ContainsAllDropEntries() && - state != GRPC_CHANNEL_READY)) { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p helper %p] state=%s passing RR picker %p as-is", - parent_.get(), this, grpc_connectivity_state_name(state), - picker.get()); - } - parent_->channel_control_helper()->UpdateState(state, state_error, - std::move(picker)); - return; - } - // Cases 2 and 3a: wrap picker from RR in our own picker. - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping RR picker %p", - parent_.get(), this, grpc_connectivity_state_name(state), - picker.get()); - } - RefCountedPtr client_stats; - if (parent_->lb_calld_ != nullptr && - parent_->lb_calld_->client_stats() != nullptr) { - client_stats = parent_->lb_calld_->client_stats()->Ref(); - } - parent_->channel_control_helper()->UpdateState( - state, state_error, - UniquePtr( - New(parent_.get(), parent_->serverlist_, std::move(picker), - std::move(client_stats)))); -} - -void GrpcLb::Helper::RequestReresolution() { - if (parent_->shutting_down_) return; - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] Re-resolution requested from the internal RR policy " - "(%p).", - parent_.get(), parent_->rr_policy_.get()); - } - // If we are talking to a balancer, we expect to get updated addresses - // from the balancer, so we can ignore the re-resolution request from - // the RR policy. Otherwise, pass the re-resolution request up to the - // channel. - if (parent_->lb_calld_ == nullptr || - !parent_->lb_calld_->seen_initial_response()) { - parent_->channel_control_helper()->RequestReresolution(); - } -} - // // GrpcLb::BalancerCallState // @@ -965,20 +754,27 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( response_slice)) != nullptr) { // Have seen initial response, look for serverlist. GPR_ASSERT(lb_calld->lb_call_ != nullptr); - auto serverlist_wrapper = MakeRefCounted(serverlist); if (grpc_lb_glb_trace.enabled()) { - UniquePtr serverlist_text = serverlist_wrapper->AsText(); gpr_log(GPR_INFO, "[grpclb %p] lb_calld=%p: Serverlist with %" PRIuPTR - " servers received:\n%s", - grpclb_policy, lb_calld, serverlist->num_servers, - serverlist_text.get()); + " servers received", + grpclb_policy, lb_calld, serverlist->num_servers); + for (size_t i = 0; i < serverlist->num_servers; ++i) { + grpc_resolved_address addr; + ParseServer(serverlist->servers[i], &addr); + char* ipport; + grpc_sockaddr_to_string(&ipport, &addr, false); + gpr_log(GPR_INFO, + "[grpclb %p] lb_calld=%p: Serverlist[%" PRIuPTR "]: %s", + grpclb_policy, lb_calld, i, ipport); + gpr_free(ipport); + } } // Start sending client load report only after we start using the // serverlist returned from the current LB call. if (lb_calld->client_stats_report_interval_ > 0 && lb_calld->client_stats_ == nullptr) { - lb_calld->client_stats_ = MakeRefCounted(); + lb_calld->client_stats_.reset(New()); // TODO(roth): We currently track this ref manually. Once the // ClosureRef API is ready, we should pass the RefCountedPtr<> along // with the callback. @@ -987,16 +783,19 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( lb_calld->ScheduleNextClientLoadReportLocked(); } // Check if the serverlist differs from the previous one. - if (grpclb_policy->serverlist_ != nullptr && - *grpclb_policy->serverlist_ == *serverlist_wrapper) { + if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_, serverlist)) { if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, "[grpclb %p] lb_calld=%p: Incoming server list identical to " "current, ignoring.", grpclb_policy, lb_calld); } + grpc_grpclb_destroy_serverlist(serverlist); } else { // New serverlist. - if (grpclb_policy->serverlist_ == nullptr) { + if (grpclb_policy->serverlist_ != nullptr) { + // Dispose of the old serverlist. + grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_); + } else { // Dispose of the fallback. grpclb_policy->fallback_backend_addresses_.reset(); if (grpclb_policy->fallback_timer_callback_pending_) { @@ -1006,7 +805,8 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( // Update the serverlist in the GrpcLb instance. This serverlist // instance will be destroyed either upon the next update or when the // GrpcLb instance is destroyed. - grpclb_policy->serverlist_ = std::move(serverlist_wrapper); + grpclb_policy->serverlist_ = serverlist; + grpclb_policy->serverlist_index_ = 0; grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); } } else { @@ -1053,13 +853,13 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( lb_calld->lb_call_, grpc_error_string(error)); gpr_free(status_details); } + grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE); // If this lb_calld is still in use, this call ended because of a failure so // we want to retry connecting. Otherwise, we have deliberately ended this // call and no further action is required. if (lb_calld == grpclb_policy->lb_calld_.get()) { grpclb_policy->lb_calld_.reset(); GPR_ASSERT(!grpclb_policy->shutting_down_); - grpclb_policy->channel_control_helper()->RequestReresolution(); if (lb_calld->seen_initial_response_) { // If we lose connection to the LB server, reset the backoff and restart // the LB call immediately. @@ -1191,6 +991,13 @@ GrpcLb::GrpcLb(LoadBalancingPolicy::Args args) GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); + GRPC_CLOSURE_INIT(&on_rr_connectivity_changed_, + &GrpcLb::OnRoundRobinConnectivityChangedLocked, this, + grpc_combiner_scheduler(args.combiner)); + GRPC_CLOSURE_INIT(&on_rr_request_reresolution_, + &GrpcLb::OnRoundRobinRequestReresolutionLocked, this, + grpc_combiner_scheduler(args.combiner)); + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "grpclb"); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -1213,18 +1020,20 @@ GrpcLb::GrpcLb(LoadBalancingPolicy::Args args) arg, {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX}); // Process channel args. ProcessChannelArgsLocked(*args.args); - // Initialize channel with a picker that will start us connecting. - channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, - UniquePtr(New(Ref()))); } GrpcLb::~GrpcLb() { + GPR_ASSERT(pending_picks_ == nullptr); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); + grpc_connectivity_state_destroy(&state_tracker_); + if (serverlist_ != nullptr) { + grpc_grpclb_destroy_serverlist(serverlist_); + } } void GrpcLb::ShutdownLocked() { + grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); shutting_down_ = true; lb_calld_.reset(); if (retry_timer_callback_pending_) { @@ -1234,6 +1043,7 @@ void GrpcLb::ShutdownLocked() { grpc_timer_cancel(&lb_fallback_timer_); } rr_policy_.reset(); + TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_CANCELLED); // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -1243,12 +1053,109 @@ void GrpcLb::ShutdownLocked() { lb_channel_ = nullptr; gpr_atm_no_barrier_store(&lb_channel_uuid_, 0); } + grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, + GRPC_ERROR_REF(error), "grpclb_shutdown"); + // Clear pending picks. + PendingPick* pp; + while ((pp = pending_picks_) != nullptr) { + pending_picks_ = pp->next; + pp->pick->connected_subchannel.reset(); + // Note: pp is deleted in this callback. + GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error)); + } + GRPC_ERROR_UNREF(error); } // // public methods // +void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { + PendingPick* pp; + while ((pp = pending_picks_) != nullptr) { + pending_picks_ = pp->next; + pp->pick->on_complete = pp->original_on_complete; + grpc_error* error = GRPC_ERROR_NONE; + if (new_policy->PickLocked(pp->pick, &error)) { + // Synchronous return; schedule closure. + GRPC_CLOSURE_SCHED(pp->pick->on_complete, error); + } + Delete(pp); + } +} + +// Cancel a specific pending pick. +// +// A grpclb pick progresses as follows: +// - If there's a Round Robin policy (rr_policy_) available, it'll be +// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From +// that point onwards, it'll be RR's responsibility. For cancellations, that +// implies the pick needs also be cancelled by the RR instance. +// - Otherwise, without an RR instance, picks stay pending at this policy's +// level (grpclb), inside the pending_picks_ list. To cancel these, +// we invoke the completion closure and set the pick's connected +// subchannel to nullptr right here. +void GrpcLb::CancelPickLocked(PickState* pick, grpc_error* error) { + PendingPick* pp = pending_picks_; + pending_picks_ = nullptr; + while (pp != nullptr) { + PendingPick* next = pp->next; + if (pp->pick == pick) { + pick->connected_subchannel.reset(); + // Note: pp is deleted in this callback. + GRPC_CLOSURE_SCHED(&pp->on_complete, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick Cancelled", &error, 1)); + } else { + pp->next = pending_picks_; + pending_picks_ = pp; + } + pp = next; + } + if (rr_policy_ != nullptr) { + rr_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error)); + } + GRPC_ERROR_UNREF(error); +} + +// Cancel all pending picks. +// +// A grpclb pick progresses as follows: +// - If there's a Round Robin policy (rr_policy_) available, it'll be +// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From +// that point onwards, it'll be RR's responsibility. For cancellations, that +// implies the pick needs also be cancelled by the RR instance. +// - Otherwise, without an RR instance, picks stay pending at this policy's +// level (grpclb), inside the pending_picks_ list. To cancel these, +// we invoke the completion closure and set the pick's connected +// subchannel to nullptr right here. +void GrpcLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) { + PendingPick* pp = pending_picks_; + pending_picks_ = nullptr; + while (pp != nullptr) { + PendingPick* next = pp->next; + if ((*pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == + initial_metadata_flags_eq) { + // Note: pp is deleted in this callback. + GRPC_CLOSURE_SCHED(&pp->on_complete, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick Cancelled", &error, 1)); + } else { + pp->next = pending_picks_; + pending_picks_ = pp; + } + pp = next; + } + if (rr_policy_ != nullptr) { + rr_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask, + initial_metadata_flags_eq, + GRPC_ERROR_REF(error)); + } + GRPC_ERROR_UNREF(error); +} + void GrpcLb::ExitIdleLocked() { if (!started_picking_) { StartPickingLocked(); @@ -1264,6 +1171,37 @@ void GrpcLb::ResetBackoffLocked() { } } +bool GrpcLb::PickLocked(PickState* pick, grpc_error** error) { + PendingPick* pp = PendingPickCreate(pick); + bool pick_done = false; + if (rr_policy_ != nullptr) { + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, "[grpclb %p] about to PICK from RR %p", this, + rr_policy_.get()); + } + pick_done = + PickFromRoundRobinPolicyLocked(false /* force_async */, pp, error); + } else { // rr_policy_ == NULL + if (pick->on_complete == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "No pick result available but synchronous result required."); + pick_done = true; + } else { + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, + "[grpclb %p] No RR policy. Adding to grpclb's pending picks", + this); + } + AddPendingPick(pp); + if (!started_picking_) { + StartPickingLocked(); + } + pick_done = false; + } + } + return pick_done; +} + void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { @@ -1277,6 +1215,17 @@ void GrpcLb::FillChildRefsForChannelz( } } +grpc_connectivity_state GrpcLb::CheckConnectivityLocked( + grpc_error** connectivity_error) { + return grpc_connectivity_state_get(&state_tracker_, connectivity_error); +} + +void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, + grpc_closure* notify) { + grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, + notify); +} + // Returns the backend addresses extracted from the given addresses. UniquePtr ExtractBackendAddresses( const ServerAddressList& addresses) { @@ -1322,8 +1271,9 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { if (lb_channel_ == nullptr) { char* uri_str; gpr_asprintf(&uri_str, "fake:///%s", server_name_); - lb_channel_ = channel_control_helper()->CreateChannel( - uri_str, GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, *lb_channel_args); + lb_channel_ = grpc_client_channel_factory_create_channel( + client_channel_factory(), uri_str, + GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args); GPR_ASSERT(lb_channel_ != nullptr); grpc_core::channelz::ChannelNode* channel_node = grpc_channel_get_channelz_node(lb_channel_); @@ -1504,10 +1454,143 @@ void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, } } +// +// PendingPick +// + +// Adds lb_token of selected subchannel (address) to the call's initial +// metadata. +grpc_error* AddLbTokenToInitialMetadata( + grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage, + grpc_metadata_batch* initial_metadata) { + GPR_ASSERT(lb_token_mdelem_storage != nullptr); + GPR_ASSERT(!GRPC_MDISNULL(lb_token)); + return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage, + lb_token); +} + +// Destroy function used when embedding client stats in call context. +void DestroyClientStats(void* arg) { + static_cast(arg)->Unref(); +} + +void GrpcLb::PendingPickSetMetadataAndContext(PendingPick* pp) { + // If connected_subchannel is nullptr, no pick has been made by the RR + // policy (e.g., all addresses failed to connect). There won't be any + // LB token available. + if (pp->pick->connected_subchannel != nullptr) { + const grpc_arg* arg = + grpc_channel_args_find(pp->pick->connected_subchannel->args(), + GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); + if (arg != nullptr) { + grpc_mdelem lb_token = { + reinterpret_cast(arg->value.pointer.p)}; + AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(lb_token), + &pp->pick->lb_token_mdelem_storage, + pp->pick->initial_metadata); + } else { + gpr_log(GPR_ERROR, + "[grpclb %p] No LB token for connected subchannel pick %p", + pp->grpclb_policy, pp->pick); + abort(); + } + // Pass on client stats via context. Passes ownership of the reference. + if (pp->client_stats != nullptr) { + pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = + pp->client_stats.release(); + pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = + DestroyClientStats; + } + } else { + pp->client_stats.reset(); + } +} + +/* The \a on_complete closure passed as part of the pick requires keeping a + * reference to its associated round robin instance. We wrap this closure in + * order to unref the round robin instance upon its invocation */ +void GrpcLb::OnPendingPickComplete(void* arg, grpc_error* error) { + PendingPick* pp = static_cast(arg); + PendingPickSetMetadataAndContext(pp); + GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); + Delete(pp); +} + +GrpcLb::PendingPick* GrpcLb::PendingPickCreate(PickState* pick) { + PendingPick* pp = New(); + pp->grpclb_policy = this; + pp->pick = pick; + GRPC_CLOSURE_INIT(&pp->on_complete, &GrpcLb::OnPendingPickComplete, pp, + grpc_schedule_on_exec_ctx); + pp->original_on_complete = pick->on_complete; + pick->on_complete = &pp->on_complete; + return pp; +} + +void GrpcLb::AddPendingPick(PendingPick* pp) { + pp->next = pending_picks_; + pending_picks_ = pp; +} + // // code for interacting with the RR policy // +// Performs a pick over \a rr_policy_. Given that a pick can return +// immediately (ignoring its completion callback), we need to perform the +// cleanups this callback would otherwise be responsible for. +// If \a force_async is true, then we will manually schedule the +// completion callback even if the pick is available immediately. +bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, + grpc_error** error) { + // Check for drops if we are not using fallback backend addresses. + if (serverlist_ != nullptr && serverlist_->num_servers > 0) { + // Look at the index into the serverlist to see if we should drop this call. + grpc_grpclb_server* server = serverlist_->servers[serverlist_index_++]; + if (serverlist_index_ == serverlist_->num_servers) { + serverlist_index_ = 0; // Wrap-around. + } + if (server->drop) { + // Update client load reporting stats to indicate the number of + // dropped calls. Note that we have to do this here instead of in + // the client_load_reporting filter, because we do not create a + // subchannel call (and therefore no client_load_reporting filter) + // for dropped calls. + if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { + lb_calld_->client_stats()->AddCallDroppedLocked( + server->load_balance_token); + } + if (force_async) { + GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_NONE); + Delete(pp); + return false; + } + Delete(pp); + return true; + } + } + // Set client_stats. + if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { + pp->client_stats = lb_calld_->client_stats()->Ref(); + } + // Pick via the RR policy. + bool pick_done = rr_policy_->PickLocked(pp->pick, error); + if (pick_done) { + PendingPickSetMetadataAndContext(pp); + if (force_async) { + GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); + *error = GRPC_ERROR_NONE; + pick_done = false; + } + Delete(pp); + } + // else, the pending pick will be registered and taken care of by the + // pending pick list inside the RR policy. Eventually, + // OnPendingPickComplete() will be called, which will (among other + // things) add the LB token to the call's initial metadata. + return pick_done; +} + void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { GPR_ASSERT(rr_policy_ == nullptr); rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( @@ -1521,12 +1604,40 @@ void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, rr_policy_.get()); } + // TODO(roth): We currently track this ref manually. Once the new + // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. + auto self = Ref(DEBUG_LOCATION, "on_rr_reresolution_requested"); + self.release(); + rr_policy_->SetReresolutionClosureLocked(&on_rr_request_reresolution_); + grpc_error* rr_state_error = nullptr; + rr_connectivity_state_ = rr_policy_->CheckConnectivityLocked(&rr_state_error); + // Connectivity state is a function of the RR policy updated/created. + UpdateConnectivityStateFromRoundRobinPolicyLocked(rr_state_error); // Add the gRPC LB's interested_parties pollset_set to that of the newly // created RR policy. This will make the RR policy progress upon activity on // gRPC LB, which in turn is tied to the application's call. grpc_pollset_set_add_pollset_set(rr_policy_->interested_parties(), interested_parties()); + // Subscribe to changes to the connectivity of the new RR. + // TODO(roth): We currently track this ref manually. Once the new + // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. + self = Ref(DEBUG_LOCATION, "on_rr_connectivity_changed"); + self.release(); + rr_policy_->NotifyOnStateChangeLocked(&rr_connectivity_state_, + &on_rr_connectivity_changed_); rr_policy_->ExitIdleLocked(); + // Send pending picks to RR policy. + PendingPick* pp; + while ((pp = pending_picks_)) { + pending_picks_ = pp->next; + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, + "[grpclb %p] Pending pick about to (async) PICK from RR %p", this, + rr_policy_.get()); + } + grpc_error* error = GRPC_ERROR_NONE; + PickFromRoundRobinPolicyLocked(true /* force_async */, pp, &error); + } } grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { @@ -1534,7 +1645,7 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { ServerAddressList* addresses = &tmp_addresses; bool is_backend_from_grpclb_load_balancer = false; if (serverlist_ != nullptr) { - tmp_addresses = serverlist_->GetServerAddressList(); + tmp_addresses = ProcessServerlist(serverlist_); is_backend_from_grpclb_load_balancer = true; } else { // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't @@ -1583,14 +1694,110 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { } else { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); + lb_policy_args.client_channel_factory = client_channel_factory(); lb_policy_args.args = args; - lb_policy_args.channel_control_helper = - UniquePtr(New(Ref())); + lb_policy_args.subchannel_pool = subchannel_pool()->Ref(); CreateRoundRobinPolicyLocked(std::move(lb_policy_args)); } grpc_channel_args_destroy(args); } +void GrpcLb::OnRoundRobinRequestReresolutionLocked(void* arg, + grpc_error* error) { + GrpcLb* grpclb_policy = static_cast(arg); + if (grpclb_policy->shutting_down_ || error != GRPC_ERROR_NONE) { + grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_reresolution_requested"); + return; + } + if (grpc_lb_glb_trace.enabled()) { + gpr_log( + GPR_INFO, + "[grpclb %p] Re-resolution requested from the internal RR policy (%p).", + grpclb_policy, grpclb_policy->rr_policy_.get()); + } + // If we are talking to a balancer, we expect to get updated addresses form + // the balancer, so we can ignore the re-resolution request from the RR + // policy. Otherwise, handle the re-resolution request using the + // grpclb policy's original re-resolution closure. + if (grpclb_policy->lb_calld_ == nullptr || + !grpclb_policy->lb_calld_->seen_initial_response()) { + grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE); + } + // Give back the wrapper closure to the RR policy. + grpclb_policy->rr_policy_->SetReresolutionClosureLocked( + &grpclb_policy->on_rr_request_reresolution_); +} + +void GrpcLb::UpdateConnectivityStateFromRoundRobinPolicyLocked( + grpc_error* rr_state_error) { + const grpc_connectivity_state curr_glb_state = + grpc_connectivity_state_check(&state_tracker_); + /* The new connectivity status is a function of the previous one and the new + * input coming from the status of the RR policy. + * + * current state (grpclb's) + * | + * v || I | C | R | TF | SD | <- new state (RR's) + * ===++====+=====+=====+======+======+ + * I || I | C | R | [I] | [I] | + * ---++----+-----+-----+------+------+ + * C || I | C | R | [C] | [C] | + * ---++----+-----+-----+------+------+ + * R || I | C | R | [R] | [R] | + * ---++----+-----+-----+------+------+ + * TF || I | C | R | [TF] | [TF] | + * ---++----+-----+-----+------+------+ + * SD || NA | NA | NA | NA | NA | (*) + * ---++----+-----+-----+------+------+ + * + * A [STATE] indicates that the old RR policy is kept. In those cases, STATE + * is the current state of grpclb, which is left untouched. + * + * In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to + * the previous RR instance. + * + * Note that the status is never updated to SHUTDOWN as a result of calling + * this function. Only glb_shutdown() has the power to set that state. + * + * (*) This function mustn't be called during shutting down. */ + GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN); + switch (rr_connectivity_state_) { + case GRPC_CHANNEL_TRANSIENT_FAILURE: + case GRPC_CHANNEL_SHUTDOWN: + GPR_ASSERT(rr_state_error != GRPC_ERROR_NONE); + break; + case GRPC_CHANNEL_IDLE: + case GRPC_CHANNEL_CONNECTING: + case GRPC_CHANNEL_READY: + GPR_ASSERT(rr_state_error == GRPC_ERROR_NONE); + } + if (grpc_lb_glb_trace.enabled()) { + gpr_log( + GPR_INFO, + "[grpclb %p] Setting grpclb's state to %s from new RR policy %p state.", + this, grpc_connectivity_state_name(rr_connectivity_state_), + rr_policy_.get()); + } + grpc_connectivity_state_set(&state_tracker_, rr_connectivity_state_, + rr_state_error, + "update_lb_connectivity_status_locked"); +} + +void GrpcLb::OnRoundRobinConnectivityChangedLocked(void* arg, + grpc_error* error) { + GrpcLb* grpclb_policy = static_cast(arg); + if (grpclb_policy->shutting_down_) { + grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_connectivity_changed"); + return; + } + grpclb_policy->UpdateConnectivityStateFromRoundRobinPolicyLocked( + GRPC_ERROR_REF(error)); + // Resubscribe. Reuse the "on_rr_connectivity_changed" ref. + grpclb_policy->rr_policy_->NotifyOnStateChangeLocked( + &grpclb_policy->rr_connectivity_state_, + &grpclb_policy->on_rr_connectivity_changed_); +} + // // factory // diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc index 1c7ed871d74..087cd8f276e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc @@ -43,7 +43,7 @@ void GrpcLbClientStats::AddCallFinished( } } -void GrpcLbClientStats::AddCallDroppedLocked(const char* token) { +void GrpcLbClientStats::AddCallDroppedLocked(char* token) { // Increment num_calls_started and num_calls_finished. gpr_atm_full_fetch_add(&num_calls_started_, (gpr_atm)1); gpr_atm_full_fetch_add(&num_calls_finished_, (gpr_atm)1); diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h index 45ca40942ca..18ab2c94529 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h @@ -48,7 +48,7 @@ class GrpcLbClientStats : public RefCounted { bool finished_known_received); // This method is not thread-safe; caller must synchronize. - void AddCallDroppedLocked(const char* token); + void AddCallDroppedLocked(char* token); // This method is not thread-safe; caller must synchronize. void GetLocked(int64_t* num_calls_started, int64_t* num_calls_finished, diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index bf1c5bd7914..dc716a6adac 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -52,6 +52,16 @@ class PickFirst : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; + bool PickLocked(PickState* pick, grpc_error** error) override; + void CancelPickLocked(PickState* pick, grpc_error* error) override; + void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) override; + void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) override; + grpc_connectivity_state CheckConnectivityLocked( + grpc_error** connectivity_error) override; + void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -89,9 +99,10 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, + grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - policy->channel_control_helper(), args) { + client_channel_factory, args) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' // pollset_sets will include the LB policy's pollset_set. @@ -104,20 +115,6 @@ class PickFirst : public LoadBalancingPolicy { } }; - class Picker : public SubchannelPicker { - public: - explicit Picker(RefCountedPtr connected_subchannel) - : connected_subchannel_(std::move(connected_subchannel)) {} - - PickResult Pick(PickState* pick, grpc_error** error) override { - pick->connected_subchannel = connected_subchannel_; - return PICK_COMPLETE; - } - - private: - RefCountedPtr connected_subchannel_; - }; - // Helper class to ensure that any function that modifies the child refs // data structures will update the channelz snapshot data structures before // returning. @@ -145,6 +142,10 @@ class PickFirst : public LoadBalancingPolicy { bool started_picking_ = false; // Are we shut down? bool shutdown_ = false; + // List of picks that are waiting on connectivity. + PickState* pending_picks_ = nullptr; + // Our connectivity state tracker. + grpc_connectivity_state_tracker state_tracker_; /// Lock and data used to capture snapshots of this channels child /// channels and subchannels. This data is consumed by channelz. @@ -154,15 +155,13 @@ class PickFirst : public LoadBalancingPolicy { }; PickFirst::PickFirst(Args args) : LoadBalancingPolicy(std::move(args)) { + GPR_ASSERT(args.client_channel_factory != nullptr); gpr_mu_init(&child_refs_mu_); + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, + "pick_first"); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p created.", this); } - // Initialize channel with a picker that will start us connecting upon - // the first pick. - channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, - UniquePtr(New(Ref()))); UpdateLocked(*args.args, args.lb_config); } @@ -173,16 +172,81 @@ PickFirst::~PickFirst() { gpr_mu_destroy(&child_refs_mu_); GPR_ASSERT(subchannel_list_ == nullptr); GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); + GPR_ASSERT(pending_picks_ == nullptr); + grpc_connectivity_state_destroy(&state_tracker_); +} + +void PickFirst::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { + PickState* pick; + while ((pick = pending_picks_) != nullptr) { + pending_picks_ = pick->next; + grpc_error* error = GRPC_ERROR_NONE; + if (new_policy->PickLocked(pick, &error)) { + // Synchronous return, schedule closure. + GRPC_CLOSURE_SCHED(pick->on_complete, error); + } + } } void PickFirst::ShutdownLocked() { AutoChildRefsUpdater guard(this); + grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p Shutting down", this); } shutdown_ = true; + PickState* pick; + while ((pick = pending_picks_) != nullptr) { + pending_picks_ = pick->next; + pick->connected_subchannel.reset(); + GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error)); + } + grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, + GRPC_ERROR_REF(error), "shutdown"); subchannel_list_.reset(); latest_pending_subchannel_list_.reset(); + TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_CANCELLED); + GRPC_ERROR_UNREF(error); +} + +void PickFirst::CancelPickLocked(PickState* pick, grpc_error* error) { + PickState* pp = pending_picks_; + pending_picks_ = nullptr; + while (pp != nullptr) { + PickState* next = pp->next; + if (pp == pick) { + pick->connected_subchannel.reset(); + GRPC_CLOSURE_SCHED(pick->on_complete, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick Cancelled", &error, 1)); + } else { + pp->next = pending_picks_; + pending_picks_ = pp; + } + pp = next; + } + GRPC_ERROR_UNREF(error); +} + +void PickFirst::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) { + PickState* pick = pending_picks_; + pending_picks_ = nullptr; + while (pick != nullptr) { + PickState* next = pick->next; + if ((*pick->initial_metadata_flags & initial_metadata_flags_mask) == + initial_metadata_flags_eq) { + GRPC_CLOSURE_SCHED(pick->on_complete, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick Cancelled", &error, 1)); + } else { + pick->next = pending_picks_; + pending_picks_ = pick; + } + pick = next; + } + GRPC_ERROR_UNREF(error); } void PickFirst::StartPickingLocked() { @@ -206,6 +270,36 @@ void PickFirst::ResetBackoffLocked() { } } +bool PickFirst::PickLocked(PickState* pick, grpc_error** error) { + // If we have a selected subchannel already, return synchronously. + if (selected_ != nullptr) { + pick->connected_subchannel = selected_->connected_subchannel()->Ref(); + return true; + } + // No subchannel selected yet, so handle asynchronously. + if (pick->on_complete == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "No pick result available but synchronous result required."); + return true; + } + pick->next = pending_picks_; + pending_picks_ = pick; + if (!started_picking_) { + StartPickingLocked(); + } + return false; +} + +grpc_connectivity_state PickFirst::CheckConnectivityLocked(grpc_error** error) { + return grpc_connectivity_state_get(&state_tracker_, error); +} + +void PickFirst::NotifyOnStateChangeLocked(grpc_connectivity_state* current, + grpc_closure* notify) { + grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, + notify); +} + void PickFirst::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels_to_fill, channelz::ChildRefsList* ignored) { @@ -247,11 +341,10 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, if (addresses == nullptr) { if (subchannel_list_ == nullptr) { // If we don't have a current subchannel list, go into TRANSIENT FAILURE. - grpc_error* error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - UniquePtr(New(error))); + grpc_connectivity_state_set( + &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"), + "pf_update_missing"); } else { // otherwise, keep using the current subchannel list (ignore this update). gpr_log(GPR_ERROR, @@ -271,17 +364,18 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, grpc_channel_args* new_args = grpc_channel_args_copy_and_add(&args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, *addresses, combiner(), *new_args); + this, &grpc_lb_pick_first_trace, *addresses, combiner(), + client_channel_factory(), *new_args); grpc_channel_args_destroy(new_args); if (subchannel_list->num_subchannels() == 0) { // Empty update or no valid subchannels. Unsubscribe from all current // subchannels and put the channel in TRANSIENT_FAILURE. + grpc_connectivity_state_set( + &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), + "pf_update_empty"); subchannel_list_ = std::move(subchannel_list); // Empty list. selected_ = nullptr; - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - UniquePtr(New(error))); return; } // If one of the subchannels in the new list is already in state @@ -359,8 +453,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( if (p->selected_ == this) { if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, - "Pick First %p selected subchannel connectivity changed to %s", p, - grpc_connectivity_state_name(connectivity_state)); + "Pick First %p connectivity changed for selected subchannel", p); } // If the new state is anything other than READY and there is a // pending update, switch to the pending update. @@ -376,12 +469,14 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->selected_ = nullptr; StopConnectivityWatchLocked(); p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); - grpc_error* new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "selected subchannel not ready; switching to pending update", &error, - 1); - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), - UniquePtr(New(new_error))); + grpc_connectivity_state_set( + &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, + error != GRPC_ERROR_NONE + ? GRPC_ERROR_REF(error) + : GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "selected subchannel not ready; switching to pending " + "update"), + "selected_not_ready+switch_to_update"); } else { if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { // If the selected subchannel goes bad, request a re-resolution. We also @@ -389,28 +484,17 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // is that if the new state is TRANSIENT_FAILURE due to a GOAWAY // reception we don't want to connect to the re-resolved backends until // we leave the IDLE state. + grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_IDLE, + GRPC_ERROR_NONE, + "selected_changed+reresolve"); p->started_picking_ = false; - p->channel_control_helper()->RequestReresolution(); + p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE); // In transient failure. Rely on re-resolution to recover. p->selected_ = nullptr; StopConnectivityWatchLocked(); - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, - UniquePtr(New(p->Ref()))); } else { - // This is unlikely but can happen when a subchannel has been asked - // to reconnect by a different channel and this channel has dropped - // some connectivity state notifications. - if (connectivity_state == GRPC_CHANNEL_READY) { - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, GRPC_ERROR_NONE, - UniquePtr( - New(connected_subchannel()->Ref()))); - } else { // CONNECTING - p->channel_control_helper()->UpdateState( - connectivity_state, GRPC_ERROR_REF(error), - UniquePtr(New(p->Ref()))); - } + grpc_connectivity_state_set(&p->state_tracker_, connectivity_state, + GRPC_ERROR_REF(error), "selected_changed"); // Renew notification. RenewConnectivityWatchLocked(); } @@ -443,14 +527,10 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // Case 1: Only set state to TRANSIENT_FAILURE if we've tried // all subchannels. if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) { - p->channel_control_helper()->RequestReresolution(); - grpc_error* new_error = - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "failed to connect to all addresses", &error, 1); - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), - UniquePtr( - New(new_error))); + p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE); + grpc_connectivity_state_set( + &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_REF(error), "exhausted_subchannels"); } sd->CheckConnectivityStateAndStartWatchingLocked(); break; @@ -459,9 +539,9 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( case GRPC_CHANNEL_IDLE: { // Only update connectivity state in case 1. if (subchannel_list() == p->subchannel_list_.get()) { - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, - UniquePtr(New(p->Ref()))); + grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING, + GRPC_ERROR_REF(error), + "connecting_changed"); } // Renew notification. RenewConnectivityWatchLocked(); @@ -498,13 +578,23 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); } // Cases 1 and 2. + grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY, + GRPC_ERROR_NONE, "subchannel_ready"); p->selected_ = this; - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, GRPC_ERROR_NONE, - UniquePtr(New(connected_subchannel()->Ref()))); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); } + // Update any calls that were waiting for a pick. + PickState* pick; + while ((pick = p->pending_picks_)) { + p->pending_picks_ = pick->next; + pick->connected_subchannel = p->selected_->connected_subchannel()->Ref(); + if (grpc_lb_pick_first_trace.enabled()) { + gpr_log(GPR_INFO, "Servicing pending pick with selected subchannel %p", + p->selected_->subchannel()); + } + GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); + } } void PickFirst::PickFirstSubchannelData:: diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 0406efb71d3..aab6dd68216 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -26,7 +26,6 @@ #include -#include #include #include @@ -63,6 +62,16 @@ class RoundRobin : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; + bool PickLocked(PickState* pick, grpc_error** error) override; + void CancelPickLocked(PickState* pick, grpc_error* error) override; + void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) override; + void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) override; + grpc_connectivity_state CheckConnectivityLocked( + grpc_error** connectivity_error) override; + void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -108,12 +117,14 @@ class RoundRobin : public LoadBalancingPolicy { : public SubchannelList { public: - RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer, - const ServerAddressList& addresses, - grpc_combiner* combiner, - const grpc_channel_args& args) + RoundRobinSubchannelList( + RoundRobin* policy, TraceFlag* tracer, + const ServerAddressList& addresses, grpc_combiner* combiner, + grpc_client_channel_factory* client_channel_factory, + const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - policy->channel_control_helper(), args) { + client_channel_factory, args), + last_ready_index_(num_subchannels() - 1) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' // pollset_sets will include the LB policy's pollset_set. @@ -146,25 +157,15 @@ class RoundRobin : public LoadBalancingPolicy { // subchannels in each state. void UpdateRoundRobinStateFromSubchannelStateCountsLocked(); + size_t GetNextReadySubchannelIndexLocked(); + void UpdateLastReadySubchannelIndexLocked(size_t last_ready_index); + private: size_t num_ready_ = 0; size_t num_connecting_ = 0; size_t num_transient_failure_ = 0; grpc_error* last_transient_failure_error_ = GRPC_ERROR_NONE; - }; - - class Picker : public SubchannelPicker { - public: - Picker(RoundRobin* parent, RoundRobinSubchannelList* subchannel_list); - - PickResult Pick(PickState* pick, grpc_error** error) override; - - private: - // Using pointer value only, no ref held -- do not dereference! - RoundRobin* parent_; - - size_t last_picked_index_; - InlinedVector, 10> subchannels_; + size_t last_ready_index_; // Index into list of last pick. }; // Helper class to ensure that any function that modifies the child refs @@ -182,6 +183,8 @@ class RoundRobin : public LoadBalancingPolicy { void ShutdownLocked() override; void StartPickingLocked(); + bool DoPickLocked(PickState* pick); + void DrainPendingPicksLocked(); void UpdateChildRefsLocked(); /** list of subchannels */ @@ -196,6 +199,10 @@ class RoundRobin : public LoadBalancingPolicy { bool started_picking_ = false; /** are we shutting down? */ bool shutdown_ = false; + /** List of picks that are waiting on connectivity */ + PickState* pending_picks_ = nullptr; + /** our connectivity state tracker */ + grpc_connectivity_state_tracker state_tracker_; /// Lock and data used to capture snapshots of this channel's child /// channels and subchannels. This data is consumed by channelz. gpr_mu child_refs_mu_; @@ -203,62 +210,16 @@ class RoundRobin : public LoadBalancingPolicy { channelz::ChildRefsList child_channels_; }; -// -// RoundRobin::Picker -// - -RoundRobin::Picker::Picker(RoundRobin* parent, - RoundRobinSubchannelList* subchannel_list) - : parent_(parent) { - for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { - auto* connected_subchannel = - subchannel_list->subchannel(i)->connected_subchannel(); - if (connected_subchannel != nullptr) { - subchannels_.push_back(connected_subchannel->Ref()); - } - } - // For discussion on why we generate a random starting index for - // the picker, see https://github.com/grpc/grpc-go/issues/2580. - // TODO(roth): rand(3) is not thread-safe. This should be replaced with - // something better as part of https://github.com/grpc/grpc/issues/17891. - last_picked_index_ = rand() % subchannels_.size(); - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, - "[RR %p picker %p] created picker from subchannel_list=%p " - "with %" PRIuPTR " READY subchannels; last_picked_index_=%" PRIuPTR, - parent_, this, subchannel_list, subchannels_.size(), - last_picked_index_); - } -} - -RoundRobin::Picker::PickResult RoundRobin::Picker::Pick(PickState* pick, - grpc_error** error) { - last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size(); - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, - "[RR %p picker %p] returning index %" PRIuPTR - ", connected_subchannel=%p", - parent_, this, last_picked_index_, - subchannels_[last_picked_index_].get()); - } - pick->connected_subchannel = subchannels_[last_picked_index_]; - return PICK_COMPLETE; -} - -// -// RoundRobin -// - RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) { + GPR_ASSERT(args.client_channel_factory != nullptr); gpr_mu_init(&child_refs_mu_); - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, "[RR %p] Created", this); - } - // Initialize channel with a picker that will start us connecting. - channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, - UniquePtr(New(Ref()))); + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, + "round_robin"); UpdateLocked(*args.args, args.lb_config); + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, "[RR %p] Created with %" PRIuPTR " subchannels", this, + subchannel_list_->num_subchannels()); + } } RoundRobin::~RoundRobin() { @@ -268,16 +229,82 @@ RoundRobin::~RoundRobin() { gpr_mu_destroy(&child_refs_mu_); GPR_ASSERT(subchannel_list_ == nullptr); GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); + GPR_ASSERT(pending_picks_ == nullptr); + grpc_connectivity_state_destroy(&state_tracker_); +} + +void RoundRobin::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { + PickState* pick; + while ((pick = pending_picks_) != nullptr) { + pending_picks_ = pick->next; + grpc_error* error = GRPC_ERROR_NONE; + if (new_policy->PickLocked(pick, &error)) { + // Synchronous return, schedule closure. + GRPC_CLOSURE_SCHED(pick->on_complete, error); + } + } } void RoundRobin::ShutdownLocked() { AutoChildRefsUpdater guard(this); + grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] Shutting down", this); } shutdown_ = true; + PickState* pick; + while ((pick = pending_picks_) != nullptr) { + pending_picks_ = pick->next; + pick->connected_subchannel.reset(); + GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error)); + } + grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, + GRPC_ERROR_REF(error), "rr_shutdown"); subchannel_list_.reset(); latest_pending_subchannel_list_.reset(); + TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_CANCELLED); + GRPC_ERROR_UNREF(error); +} + +void RoundRobin::CancelPickLocked(PickState* pick, grpc_error* error) { + PickState* pp = pending_picks_; + pending_picks_ = nullptr; + while (pp != nullptr) { + PickState* next = pp->next; + if (pp == pick) { + pick->connected_subchannel.reset(); + GRPC_CLOSURE_SCHED(pick->on_complete, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick Cancelled", &error, 1)); + } else { + pp->next = pending_picks_; + pending_picks_ = pp; + } + pp = next; + } + GRPC_ERROR_UNREF(error); +} + +void RoundRobin::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) { + PickState* pick = pending_picks_; + pending_picks_ = nullptr; + while (pick != nullptr) { + PickState* next = pick->next; + if ((*pick->initial_metadata_flags & initial_metadata_flags_mask) == + initial_metadata_flags_eq) { + pick->connected_subchannel.reset(); + GRPC_CLOSURE_SCHED(pick->on_complete, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick Cancelled", &error, 1)); + } else { + pick->next = pending_picks_; + pending_picks_ = pick; + } + pick = next; + } + GRPC_ERROR_UNREF(error); } void RoundRobin::StartPickingLocked() { @@ -298,6 +325,60 @@ void RoundRobin::ResetBackoffLocked() { } } +bool RoundRobin::DoPickLocked(PickState* pick) { + const size_t next_ready_index = + subchannel_list_->GetNextReadySubchannelIndexLocked(); + if (next_ready_index < subchannel_list_->num_subchannels()) { + /* readily available, report right away */ + RoundRobinSubchannelData* sd = + subchannel_list_->subchannel(next_ready_index); + GPR_ASSERT(sd->connected_subchannel() != nullptr); + pick->connected_subchannel = sd->connected_subchannel()->Ref(); + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, + "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, " + "index %" PRIuPTR ")", + this, sd->subchannel(), pick->connected_subchannel.get(), + sd->subchannel_list(), next_ready_index); + } + /* only advance the last picked pointer if the selection was used */ + subchannel_list_->UpdateLastReadySubchannelIndexLocked(next_ready_index); + return true; + } + return false; +} + +void RoundRobin::DrainPendingPicksLocked() { + PickState* pick; + while ((pick = pending_picks_)) { + pending_picks_ = pick->next; + GPR_ASSERT(DoPickLocked(pick)); + GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); + } +} + +bool RoundRobin::PickLocked(PickState* pick, grpc_error** error) { + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, "[RR %p] Trying to pick (shutdown: %d)", this, shutdown_); + } + GPR_ASSERT(!shutdown_); + if (subchannel_list_ != nullptr) { + if (DoPickLocked(pick)) return true; + } + if (pick->on_complete == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "No pick result available but synchronous result required."); + return true; + } + /* no pick currently available. Save for later in list of pending picks */ + pick->next = pending_picks_; + pending_picks_ = pick; + if (!started_picking_) { + StartPickingLocked(); + } + return false; +} + void RoundRobin::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels_to_fill, channelz::ChildRefsList* ignored) { @@ -381,8 +462,8 @@ void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked( last_transient_failure_error_ = transient_failure_error; } -// Sets the RR policy's connectivity state and generates a new picker based -// on the current subchannel list. +// Sets the RR policy's connectivity state based on the current +// subchannel list. void RoundRobin::RoundRobinSubchannelList:: MaybeUpdateRoundRobinConnectivityStateLocked() { RoundRobin* p = static_cast(policy()); @@ -404,21 +485,18 @@ void RoundRobin::RoundRobinSubchannelList:: */ if (num_ready_ > 0) { /* 1) READY */ - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_READY, GRPC_ERROR_NONE, - UniquePtr(New(p, this))); + grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY, + GRPC_ERROR_NONE, "rr_ready"); } else if (num_connecting_ > 0) { /* 2) CONNECTING */ - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, - UniquePtr(New(p->Ref()))); + grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING, + GRPC_ERROR_NONE, "rr_connecting"); } else if (num_transient_failure_ == num_subchannels()) { /* 3) TRANSIENT_FAILURE */ - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(last_transient_failure_error_), - UniquePtr(New( - GRPC_ERROR_REF(last_transient_failure_error_)))); + grpc_connectivity_state_set(&p->state_tracker_, + GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_REF(last_transient_failure_error_), + "rr_exhausted_subchannels"); } } @@ -447,6 +525,8 @@ void RoundRobin::RoundRobinSubchannelList:: } p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); } + // Drain pending picks. + p->DrainPendingPicksLocked(); } // Update the RR policy's connectivity state if needed. MaybeUpdateRoundRobinConnectivityStateLocked(); @@ -486,7 +566,7 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( "Requesting re-resolution", p, subchannel()); } - p->channel_control_helper()->RequestReresolution(); + p->TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_NONE); } // Update state counters. UpdateConnectivityStateLocked(connectivity_state, error); @@ -495,6 +575,73 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( RenewConnectivityWatchLocked(); } +/** Returns the index into p->subchannel_list->subchannels of the next + * subchannel in READY state, or p->subchannel_list->num_subchannels if no + * subchannel is READY. + * + * Note that this function does *not* update p->last_ready_subchannel_index. + * The caller must do that if it returns a pick. */ +size_t +RoundRobin::RoundRobinSubchannelList::GetNextReadySubchannelIndexLocked() { + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, + "[RR %p] getting next ready subchannel (out of %" PRIuPTR + "), last_ready_index=%" PRIuPTR, + policy(), num_subchannels(), last_ready_index_); + } + for (size_t i = 0; i < num_subchannels(); ++i) { + const size_t index = (i + last_ready_index_ + 1) % num_subchannels(); + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log( + GPR_INFO, + "[RR %p] checking subchannel %p, subchannel_list %p, index %" PRIuPTR + ": state=%s", + policy(), subchannel(index)->subchannel(), this, index, + grpc_connectivity_state_name( + subchannel(index)->connectivity_state())); + } + if (subchannel(index)->connectivity_state() == GRPC_CHANNEL_READY) { + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, + "[RR %p] found next ready subchannel (%p) at index %" PRIuPTR + " of subchannel_list %p", + policy(), subchannel(index)->subchannel(), index, this); + } + return index; + } + } + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, "[RR %p] no subchannels in ready state", this); + } + return num_subchannels(); +} + +// Sets last_ready_index_ to last_ready_index. +void RoundRobin::RoundRobinSubchannelList::UpdateLastReadySubchannelIndexLocked( + size_t last_ready_index) { + GPR_ASSERT(last_ready_index < num_subchannels()); + last_ready_index_ = last_ready_index; + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, + "[RR %p] setting last_ready_subchannel_index=%" PRIuPTR + " (SC %p, CSC %p)", + policy(), last_ready_index, + subchannel(last_ready_index)->subchannel(), + subchannel(last_ready_index)->connected_subchannel()); + } +} + +grpc_connectivity_state RoundRobin::CheckConnectivityLocked( + grpc_error** error) { + return grpc_connectivity_state_get(&state_tracker_, error); +} + +void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current, + grpc_closure* notify) { + grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, + notify); +} + void RoundRobin::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { AutoChildRefsUpdater guard(this); @@ -504,11 +651,10 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, // If we don't have a current subchannel list, go into TRANSIENT_FAILURE. // Otherwise, keep using the current subchannel list (ignore this update). if (subchannel_list_ == nullptr) { - grpc_error* error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - UniquePtr(New(error))); + grpc_connectivity_state_set( + &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"), + "rr_update_missing"); } return; } @@ -525,16 +671,17 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, *addresses, combiner(), args); + this, &grpc_lb_round_robin_trace, *addresses, combiner(), + client_channel_factory(), args); // If we haven't started picking yet or the new list is empty, // immediately promote the new list to the current list. if (!started_picking_ || latest_pending_subchannel_list_->num_subchannels() == 0) { if (latest_pending_subchannel_list_->num_subchannels() == 0) { - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - UniquePtr(New(error))); + grpc_connectivity_state_set( + &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), + "rr_update_empty"); } subchannel_list_ = std::move(latest_pending_subchannel_list_); } else { diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index c262dfe60f5..0174a98a73d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -232,7 +232,7 @@ class SubchannelList : public InternallyRefCounted { protected: SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - LoadBalancingPolicy::ChannelControlHelper* helper, + grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args); virtual ~SubchannelList(); @@ -486,7 +486,7 @@ template SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - LoadBalancingPolicy::ChannelControlHelper* helper, + grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : InternallyRefCounted(tracer), policy_(policy), @@ -509,8 +509,12 @@ SubchannelList::SubchannelList( GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. for (size_t i = 0; i < addresses.size(); i++) { + // If there were any balancer addresses, we would have chosen grpclb + // policy, which does not use a SubchannelList. GPR_ASSERT(!addresses[i].IsBalancer()); - InlinedVector args_to_add; + InlinedVector args_to_add; + args_to_add.emplace_back( + SubchannelPoolInterface::CreateChannelArg(policy_->subchannel_pool())); const size_t subchannel_address_arg_index = args_to_add.size(); args_to_add.emplace_back( Subchannel::CreateSubchannelAddressArg(&addresses[i].address())); @@ -523,7 +527,8 @@ SubchannelList::SubchannelList( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); gpr_free(args_to_add[subchannel_address_arg_index].value.string); - Subchannel* subchannel = helper->CreateSubchannel(*new_args); + Subchannel* subchannel = grpc_client_channel_factory_create_subchannel( + client_channel_factory, new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) { // Subchannel could not be created. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 4b3f2882424..678b4d75eb9 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -70,6 +70,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" @@ -124,6 +125,16 @@ class XdsLb : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; + bool PickLocked(PickState* pick, grpc_error** error) override; + void CancelPickLocked(PickState* pick, grpc_error* error) override; + void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) override; + void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) override; + grpc_connectivity_state CheckConnectivityLocked( + grpc_error** connectivity_error) override; + void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( @@ -131,6 +142,31 @@ class XdsLb : public LoadBalancingPolicy { channelz::ChildRefsList* child_channels) override; private: + /// Linked list of pending pick requests. It stores all information needed to + /// eventually call pick() on them. They mainly stay pending waiting for the + /// child policy to be created. + /// + /// Note that when a pick is sent to the child policy, we inject our own + /// on_complete callback, so that we can intercept the result before + /// invoking the original on_complete callback. This allows us to set the + /// LB token metadata and add client_stats to the call context. + /// See \a pending_pick_complete() for details. + struct PendingPick { + // The xds lb instance that created the wrapping. This instance is not + // owned; reference counts are untouched. It's used only for logging + // purposes. + XdsLb* xdslb_policy; + // The original pick. + PickState* pick; + // Our on_complete closure and the original one. + grpc_closure on_complete; + grpc_closure* original_on_complete; + // Stats for client-side load reporting. + RefCountedPtr client_stats; + // Next pending pick. + PendingPick* next = nullptr; + }; + /// Contains a call to the LB server and all the data related to the call. class BalancerCallState : public InternallyRefCounted { public: @@ -205,36 +241,6 @@ class XdsLb : public LoadBalancingPolicy { grpc_closure client_load_report_closure_; }; - class Picker : public SubchannelPicker { - public: - Picker(UniquePtr child_picker, - RefCountedPtr client_stats) - : child_picker_(std::move(child_picker)), - client_stats_(std::move(client_stats)) {} - - PickResult Pick(PickState* pick, grpc_error** error) override; - - private: - UniquePtr child_picker_; - RefCountedPtr client_stats_; - }; - - class Helper : public ChannelControlHelper { - public: - explicit Helper(RefCountedPtr parent) : parent_(std::move(parent)) {} - - Subchannel* CreateSubchannel(const grpc_channel_args& args) override; - grpc_channel* CreateChannel(const char* target, - grpc_client_channel_type type, - const grpc_channel_args& args) override; - void UpdateState(grpc_connectivity_state state, grpc_error* state_error, - UniquePtr picker) override; - void RequestReresolution() override; - - private: - RefCountedPtr parent_; - }; - ~XdsLb(); void ShutdownLocked() override; @@ -257,10 +263,24 @@ class XdsLb : public LoadBalancingPolicy { static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); + // Pending pick methods. + static void PendingPickCleanup(PendingPick* pp); + PendingPick* PendingPickCreate(PickState* pick); + void AddPendingPick(PendingPick* pp); + static void OnPendingPickComplete(void* arg, grpc_error* error); + // Methods for dealing with the child policy. void CreateOrUpdateChildPolicyLocked(); grpc_channel_args* CreateChildPolicyArgsLocked(); void CreateChildPolicyLocked(const char* name, Args args); + bool PickFromChildPolicyLocked(bool force_async, PendingPick* pp, + grpc_error** error); + void UpdateConnectivityStateFromChildPolicyLocked( + grpc_error* child_state_error); + static void OnChildPolicyConnectivityChangedLocked(void* arg, + grpc_error* error); + static void OnChildPolicyRequestReresolutionLocked(void* arg, + grpc_error* error); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -274,6 +294,7 @@ class XdsLb : public LoadBalancingPolicy { // Internal state. bool started_picking_ = false; bool shutting_down_ = false; + grpc_connectivity_state_tracker state_tracker_; // The channel for communicating with the LB server. grpc_channel* lb_channel_ = nullptr; @@ -316,91 +337,17 @@ class XdsLb : public LoadBalancingPolicy { grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; + // Pending picks that are waiting on the xDS policy's connectivity. + PendingPick* pending_picks_ = nullptr; + // The policy to use for the backends. OrphanablePtr child_policy_; UniquePtr child_policy_json_string_; + grpc_connectivity_state child_connectivity_state_; + grpc_closure on_child_connectivity_changed_; + grpc_closure on_child_request_reresolution_; }; -// -// XdsLb::Picker -// - -// Destroy function used when embedding client stats in call context. -void DestroyClientStats(void* arg) { - static_cast(arg)->Unref(); -} - -XdsLb::Picker::PickResult XdsLb::Picker::Pick(PickState* pick, - grpc_error** error) { - // TODO(roth): Add support for drop handling. - // Forward pick to child policy. - PickResult result = child_picker_->Pick(pick, error); - // If pick succeeded, add client stats. - if (result == PickResult::PICK_COMPLETE && - pick->connected_subchannel != nullptr && client_stats_ != nullptr) { - pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = - client_stats_->Ref().release(); - pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = - DestroyClientStats; - } - return result; -} - -// -// XdsLb::Helper -// - -Subchannel* XdsLb::Helper::CreateSubchannel(const grpc_channel_args& args) { - if (parent_->shutting_down_) return nullptr; - return parent_->channel_control_helper()->CreateSubchannel(args); -} - -grpc_channel* XdsLb::Helper::CreateChannel(const char* target, - grpc_client_channel_type type, - const grpc_channel_args& args) { - if (parent_->shutting_down_) return nullptr; - return parent_->channel_control_helper()->CreateChannel(target, type, args); -} - -void XdsLb::Helper::UpdateState(grpc_connectivity_state state, - grpc_error* state_error, - UniquePtr picker) { - if (parent_->shutting_down_) { - GRPC_ERROR_UNREF(state_error); - return; - } - // TODO(juanlishen): When in fallback mode, pass the child picker - // through without wrapping it. (Or maybe use a different helper for - // the fallback policy?) - RefCountedPtr client_stats; - if (parent_->lb_calld_ != nullptr && - parent_->lb_calld_->client_stats() != nullptr) { - client_stats = parent_->lb_calld_->client_stats()->Ref(); - } - parent_->channel_control_helper()->UpdateState( - state, state_error, - UniquePtr( - New(std::move(picker), std::move(client_stats)))); -} - -void XdsLb::Helper::RequestReresolution() { - if (parent_->shutting_down_) return; - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Re-resolution requested from the internal RR policy " - "(%p).", - parent_.get(), parent_->child_policy_.get()); - } - // If we are talking to a balancer, we expect to get updated addresses - // from the balancer, so we can ignore the re-resolution request from - // the RR policy. Otherwise, pass the re-resolution request up to the - // channel. - if (parent_->lb_calld_ == nullptr || - !parent_->lb_calld_->seen_initial_response()) { - parent_->channel_control_helper()->RequestReresolution(); - } -} - // // serverlist parsing code // @@ -762,7 +709,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( // serverlist returned from the current LB call. if (lb_calld->client_stats_report_interval_ > 0 && lb_calld->client_stats_ == nullptr) { - lb_calld->client_stats_ = MakeRefCounted(); + lb_calld->client_stats_.reset(New()); // TODO(roth): We currently track this ref manually. Once the // ClosureRef API is ready, we should pass the RefCountedPtr<> along // with the callback. @@ -845,13 +792,13 @@ void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked( lb_calld->lb_call_, grpc_error_string(error)); gpr_free(status_details); } + xdslb_policy->TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_NONE); // If this lb_calld is still in use, this call ended because of a failure so // we want to retry connecting. Otherwise, we have deliberately ended this // call and no further action is required. if (lb_calld == xdslb_policy->lb_calld_.get()) { xdslb_policy->lb_calld_.reset(); GPR_ASSERT(!xdslb_policy->shutting_down_); - xdslb_policy->channel_control_helper()->RequestReresolution(); if (lb_calld->seen_initial_response_) { // If we lose connection to the LB server, reset the backoff and restart // the LB call immediately. @@ -972,6 +919,13 @@ XdsLb::XdsLb(LoadBalancingPolicy::Args args) GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &XdsLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); + GRPC_CLOSURE_INIT(&on_child_connectivity_changed_, + &XdsLb::OnChildPolicyConnectivityChangedLocked, this, + grpc_combiner_scheduler(args.combiner)); + GRPC_CLOSURE_INIT(&on_child_request_reresolution_, + &XdsLb::OnChildPolicyRequestReresolutionLocked, this, + grpc_combiner_scheduler(args.combiner)); + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "xds"); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -996,22 +950,21 @@ XdsLb::XdsLb(LoadBalancingPolicy::Args args) ParseLbConfig(args.lb_config); // Process channel args. ProcessChannelArgsLocked(*args.args); - // Initialize channel with a picker that will start us connecting. - channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, - UniquePtr(New(Ref()))); } XdsLb::~XdsLb() { + GPR_ASSERT(pending_picks_ == nullptr); gpr_mu_destroy(&lb_channel_mu_); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); + grpc_connectivity_state_destroy(&state_tracker_); if (serverlist_ != nullptr) { xds_grpclb_destroy_serverlist(serverlist_); } } void XdsLb::ShutdownLocked() { + grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); shutting_down_ = true; lb_calld_.reset(); if (retry_timer_callback_pending_) { @@ -1021,6 +974,7 @@ void XdsLb::ShutdownLocked() { grpc_timer_cancel(&lb_fallback_timer_); } child_policy_.reset(); + TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_CANCELLED); // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -1031,12 +985,109 @@ void XdsLb::ShutdownLocked() { lb_channel_ = nullptr; gpr_mu_unlock(&lb_channel_mu_); } + grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, + GRPC_ERROR_REF(error), "xds_shutdown"); + // Clear pending picks. + PendingPick* pp; + while ((pp = pending_picks_) != nullptr) { + pending_picks_ = pp->next; + pp->pick->connected_subchannel.reset(); + // Note: pp is deleted in this callback. + GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error)); + } + GRPC_ERROR_UNREF(error); } // // public methods // +void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { + PendingPick* pp; + while ((pp = pending_picks_) != nullptr) { + pending_picks_ = pp->next; + pp->pick->on_complete = pp->original_on_complete; + grpc_error* error = GRPC_ERROR_NONE; + if (new_policy->PickLocked(pp->pick, &error)) { + // Synchronous return; schedule closure. + GRPC_CLOSURE_SCHED(pp->pick->on_complete, error); + } + Delete(pp); + } +} + +// Cancel a specific pending pick. +// +// A pick progresses as follows: +// - If there's a child policy available, it'll be handed over to child policy +// (in CreateChildPolicyLocked()). From that point onwards, it'll be the +// child policy's responsibility. For cancellations, that implies the pick +// needs to be also cancelled by the child policy instance. +// - Otherwise, without a child policy instance, picks stay pending at this +// policy's level (xds), inside the pending_picks_ list. To cancel these, +// we invoke the completion closure and set the pick's connected +// subchannel to nullptr right here. +void XdsLb::CancelPickLocked(PickState* pick, grpc_error* error) { + PendingPick* pp = pending_picks_; + pending_picks_ = nullptr; + while (pp != nullptr) { + PendingPick* next = pp->next; + if (pp->pick == pick) { + pick->connected_subchannel.reset(); + // Note: pp is deleted in this callback. + GRPC_CLOSURE_SCHED(&pp->on_complete, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick Cancelled", &error, 1)); + } else { + pp->next = pending_picks_; + pending_picks_ = pp; + } + pp = next; + } + if (child_policy_ != nullptr) { + child_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error)); + } + GRPC_ERROR_UNREF(error); +} + +// Cancel all pending picks. +// +// A pick progresses as follows: +// - If there's a child policy available, it'll be handed over to child policy +// (in CreateChildPolicyLocked()). From that point onwards, it'll be the +// child policy's responsibility. For cancellations, that implies the pick +// needs to be also cancelled by the child policy instance. +// - Otherwise, without a child policy instance, picks stay pending at this +// policy's level (xds), inside the pending_picks_ list. To cancel these, +// we invoke the completion closure and set the pick's connected +// subchannel to nullptr right here. +void XdsLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) { + PendingPick* pp = pending_picks_; + pending_picks_ = nullptr; + while (pp != nullptr) { + PendingPick* next = pp->next; + if ((*pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == + initial_metadata_flags_eq) { + // Note: pp is deleted in this callback. + GRPC_CLOSURE_SCHED(&pp->on_complete, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick Cancelled", &error, 1)); + } else { + pp->next = pending_picks_; + pending_picks_ = pp; + } + pp = next; + } + if (child_policy_ != nullptr) { + child_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask, + initial_metadata_flags_eq, + GRPC_ERROR_REF(error)); + } + GRPC_ERROR_UNREF(error); +} + void XdsLb::ExitIdleLocked() { if (!started_picking_) { StartPickingLocked(); @@ -1052,6 +1103,36 @@ void XdsLb::ResetBackoffLocked() { } } +bool XdsLb::PickLocked(PickState* pick, grpc_error** error) { + PendingPick* pp = PendingPickCreate(pick); + bool pick_done = false; + if (child_policy_ != nullptr) { + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, "[xdslb %p] about to PICK from policy %p", this, + child_policy_.get()); + } + pick_done = PickFromChildPolicyLocked(false /* force_async */, pp, error); + } else { // child_policy_ == NULL + if (pick->on_complete == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "No pick result available but synchronous result required."); + pick_done = true; + } else { + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] No child policy. Adding to xds's pending picks", + this); + } + AddPendingPick(pp); + if (!started_picking_) { + StartPickingLocked(); + } + pick_done = false; + } + } + return pick_done; +} + void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { // delegate to the child_policy_ to fill the children subchannels. @@ -1066,6 +1147,17 @@ void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, } } +grpc_connectivity_state XdsLb::CheckConnectivityLocked( + grpc_error** connectivity_error) { + return grpc_connectivity_state_get(&state_tracker_, connectivity_error); +} + +void XdsLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, + grpc_closure* closure) { + grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, + closure); +} + void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); if (addresses == nullptr) { @@ -1093,8 +1185,9 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { char* uri_str; gpr_asprintf(&uri_str, "fake:///%s", server_name_); gpr_mu_lock(&lb_channel_mu_); - lb_channel_ = channel_control_helper()->CreateChannel( - uri_str, GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, *lb_channel_args); + lb_channel_ = grpc_client_channel_factory_create_channel( + client_channel_factory(), uri_str, + GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args); gpr_mu_unlock(&lb_channel_mu_); GPR_ASSERT(lb_channel_ != nullptr); gpr_free(uri_str); @@ -1309,10 +1402,90 @@ void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg, } } +// +// PendingPick +// + +// Destroy function used when embedding client stats in call context. +void DestroyClientStats(void* arg) { + static_cast(arg)->Unref(); +} + +void XdsLb::PendingPickCleanup(PendingPick* pp) { + // If connected_subchannel is nullptr, no pick has been made by the + // child policy (e.g., all addresses failed to connect). + if (pp->pick->connected_subchannel != nullptr) { + // Pass on client stats via context. Passes ownership of the reference. + if (pp->client_stats != nullptr) { + pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = + pp->client_stats.release(); + pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = + DestroyClientStats; + } + } else { + pp->client_stats.reset(); + } +} + +/* The \a on_complete closure passed as part of the pick requires keeping a + * reference to its associated child policy instance. We wrap this closure in + * order to unref the child policy instance upon its invocation */ +void XdsLb::OnPendingPickComplete(void* arg, grpc_error* error) { + PendingPick* pp = static_cast(arg); + PendingPickCleanup(pp); + GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); + Delete(pp); +} + +XdsLb::PendingPick* XdsLb::PendingPickCreate(PickState* pick) { + PendingPick* pp = New(); + pp->xdslb_policy = this; + pp->pick = pick; + GRPC_CLOSURE_INIT(&pp->on_complete, &XdsLb::OnPendingPickComplete, pp, + grpc_schedule_on_exec_ctx); + pp->original_on_complete = pick->on_complete; + pick->on_complete = &pp->on_complete; + return pp; +} + +void XdsLb::AddPendingPick(PendingPick* pp) { + pp->next = pending_picks_; + pending_picks_ = pp; +} + // // code for interacting with the child policy // +// Performs a pick over \a child_policy_. Given that a pick can return +// immediately (ignoring its completion callback), we need to perform the +// cleanups this callback would otherwise be responsible for. +// If \a force_async is true, then we will manually schedule the +// completion callback even if the pick is available immediately. +bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp, + grpc_error** error) { + // Set client_stats. + if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { + pp->client_stats = lb_calld_->client_stats()->Ref(); + } + // Pick via the child policy. + bool pick_done = child_policy_->PickLocked(pp->pick, error); + if (pick_done) { + PendingPickCleanup(pp); + if (force_async) { + GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); + *error = GRPC_ERROR_NONE; + pick_done = false; + } + Delete(pp); + } + // else, the pending pick will be registered and taken care of by the + // pending pick list inside the child policy. Eventually, + // OnPendingPickComplete() will be called, which will (among other + // things) add the LB token to the call's initial metadata. + return pick_done; +} + void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { GPR_ASSERT(child_policy_ == nullptr); child_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( @@ -1321,12 +1494,42 @@ void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { gpr_log(GPR_ERROR, "[xdslb %p] Failure creating a child policy", this); return; } + // TODO(roth): We currently track this ref manually. Once the new + // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. + auto self = Ref(DEBUG_LOCATION, "on_child_reresolution_requested"); + self.release(); + child_policy_->SetReresolutionClosureLocked(&on_child_request_reresolution_); + grpc_error* child_state_error = nullptr; + child_connectivity_state_ = + child_policy_->CheckConnectivityLocked(&child_state_error); + // Connectivity state is a function of the child policy updated/created. + UpdateConnectivityStateFromChildPolicyLocked(child_state_error); // Add the xDS's interested_parties pollset_set to that of the newly created // child policy. This will make the child policy progress upon activity on // xDS LB, which in turn is tied to the application's call. grpc_pollset_set_add_pollset_set(child_policy_->interested_parties(), interested_parties()); + // Subscribe to changes to the connectivity of the new child policy. + // TODO(roth): We currently track this ref manually. Once the new + // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. + self = Ref(DEBUG_LOCATION, "on_child_connectivity_changed"); + self.release(); + child_policy_->NotifyOnStateChangeLocked(&child_connectivity_state_, + &on_child_connectivity_changed_); child_policy_->ExitIdleLocked(); + // Send pending picks to child policy. + PendingPick* pp; + while ((pp = pending_picks_)) { + pending_picks_ = pp->next; + if (grpc_lb_xds_trace.enabled()) { + gpr_log( + GPR_INFO, + "[xdslb %p] Pending pick about to (async) PICK from child policy %p", + this, child_policy_.get()); + } + grpc_error* error = GRPC_ERROR_NONE; + PickFromChildPolicyLocked(true /* force_async */, pp, &error); + } } grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { @@ -1384,9 +1587,9 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { } else { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); + lb_policy_args.client_channel_factory = client_channel_factory(); + lb_policy_args.subchannel_pool = subchannel_pool()->Ref(); lb_policy_args.args = args; - lb_policy_args.channel_control_helper = - UniquePtr(New(Ref())); lb_policy_args.lb_config = child_policy_config; CreateChildPolicyLocked(child_policy_name, std::move(lb_policy_args)); if (grpc_lb_xds_trace.enabled()) { @@ -1398,6 +1601,102 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { grpc_json_destroy(child_policy_json); } +void XdsLb::OnChildPolicyRequestReresolutionLocked(void* arg, + grpc_error* error) { + XdsLb* xdslb_policy = static_cast(arg); + if (xdslb_policy->shutting_down_ || error != GRPC_ERROR_NONE) { + xdslb_policy->Unref(DEBUG_LOCATION, "on_child_reresolution_requested"); + return; + } + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] Re-resolution requested from child policy " + "(%p).", + xdslb_policy, xdslb_policy->child_policy_.get()); + } + // If we are talking to a balancer, we expect to get updated addresses form + // the balancer, so we can ignore the re-resolution request from the child + // policy. + // Otherwise, handle the re-resolution request using the xds policy's + // original re-resolution closure. + if (xdslb_policy->lb_calld_ == nullptr || + !xdslb_policy->lb_calld_->seen_initial_response()) { + xdslb_policy->TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_NONE); + } + // Give back the wrapper closure to the child policy. + xdslb_policy->child_policy_->SetReresolutionClosureLocked( + &xdslb_policy->on_child_request_reresolution_); +} + +void XdsLb::UpdateConnectivityStateFromChildPolicyLocked( + grpc_error* child_state_error) { + const grpc_connectivity_state curr_glb_state = + grpc_connectivity_state_check(&state_tracker_); + /* The new connectivity status is a function of the previous one and the new + * input coming from the status of the child policy. + * + * current state (xds's) + * | + * v || I | C | R | TF | SD | <- new state (child policy's) + * ===++====+=====+=====+======+======+ + * I || I | C | R | [I] | [I] | + * ---++----+-----+-----+------+------+ + * C || I | C | R | [C] | [C] | + * ---++----+-----+-----+------+------+ + * R || I | C | R | [R] | [R] | + * ---++----+-----+-----+------+------+ + * TF || I | C | R | [TF] | [TF] | + * ---++----+-----+-----+------+------+ + * SD || NA | NA | NA | NA | NA | (*) + * ---++----+-----+-----+------+------+ + * + * A [STATE] indicates that the old child policy is kept. In those cases, + * STATE is the current state of xds, which is left untouched. + * + * In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to + * the previous child policy instance. + * + * Note that the status is never updated to SHUTDOWN as a result of calling + * this function. Only glb_shutdown() has the power to set that state. + * + * (*) This function mustn't be called during shutting down. */ + GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN); + switch (child_connectivity_state_) { + case GRPC_CHANNEL_TRANSIENT_FAILURE: + case GRPC_CHANNEL_SHUTDOWN: + GPR_ASSERT(child_state_error != GRPC_ERROR_NONE); + break; + case GRPC_CHANNEL_IDLE: + case GRPC_CHANNEL_CONNECTING: + case GRPC_CHANNEL_READY: + GPR_ASSERT(child_state_error == GRPC_ERROR_NONE); + } + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] Setting xds's state to %s from child policy %p state.", + this, grpc_connectivity_state_name(child_connectivity_state_), + child_policy_.get()); + } + grpc_connectivity_state_set(&state_tracker_, child_connectivity_state_, + child_state_error, + "update_lb_connectivity_status_locked"); +} + +void XdsLb::OnChildPolicyConnectivityChangedLocked(void* arg, + grpc_error* error) { + XdsLb* xdslb_policy = static_cast(arg); + if (xdslb_policy->shutting_down_) { + xdslb_policy->Unref(DEBUG_LOCATION, "on_child_connectivity_changed"); + return; + } + xdslb_policy->UpdateConnectivityStateFromChildPolicyLocked( + GRPC_ERROR_REF(error)); + // Resubscribe. Reuse the "on_child_connectivity_changed" ref. + xdslb_policy->child_policy_->NotifyOnStateChangeLocked( + &xdslb_policy->child_connectivity_state_, + &xdslb_policy->on_child_connectivity_changed_); +} + // // factory // diff --git a/src/core/ext/filters/client_channel/request_routing.cc b/src/core/ext/filters/client_channel/request_routing.cc new file mode 100644 index 00000000000..d6ff34c99b5 --- /dev/null +++ b/src/core/ext/filters/client_channel/request_routing.cc @@ -0,0 +1,946 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/ext/filters/client_channel/request_routing.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" +#include "src/core/ext/filters/client_channel/http_connect_handshaker.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" +#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" +#include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/retry_throttle.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/ext/filters/deadline/deadline_filter.h" +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/status_util.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/error_utils.h" +#include "src/core/lib/transport/metadata.h" +#include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/transport/service_config.h" +#include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/status_metadata.h" + +namespace grpc_core { + +// +// RequestRouter::Request::ResolverResultWaiter +// + +// Handles waiting for a resolver result. +// Used only for the first call on an idle channel. +class RequestRouter::Request::ResolverResultWaiter { + public: + explicit ResolverResultWaiter(Request* request) + : request_router_(request->request_router_), + request_(request), + tracer_enabled_(request_router_->tracer_->enabled()) { + if (tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: deferring pick pending resolver " + "result", + request_router_, request); + } + // Add closure to be run when a resolver result is available. + GRPC_CLOSURE_INIT(&done_closure_, &DoneLocked, this, + grpc_combiner_scheduler(request_router_->combiner_)); + AddToWaitingList(); + // Set cancellation closure, so that we abort if the call is cancelled. + GRPC_CLOSURE_INIT(&cancel_closure_, &CancelLocked, this, + grpc_combiner_scheduler(request_router_->combiner_)); + grpc_call_combiner_set_notify_on_cancel(request->call_combiner_, + &cancel_closure_); + } + + private: + // Adds done_closure_ to + // request_router_->waiting_for_resolver_result_closures_. + void AddToWaitingList() { + grpc_closure_list_append( + &request_router_->waiting_for_resolver_result_closures_, &done_closure_, + GRPC_ERROR_NONE); + } + + // Invoked when a resolver result is available. + static void DoneLocked(void* arg, grpc_error* error) { + ResolverResultWaiter* self = static_cast(arg); + RequestRouter* request_router = self->request_router_; + // If CancelLocked() has already run, delete ourselves without doing + // anything. Note that the call stack may have already been destroyed, + // so it's not safe to access anything in state_. + if (GPR_UNLIKELY(self->finished_)) { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p: call cancelled before resolver result", + request_router); + } + Delete(self); + return; + } + // Otherwise, process the resolver result. + Request* request = self->request_; + if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: resolver failed to return data", + request_router, request); + } + GRPC_CLOSURE_RUN(request->on_route_done_, GRPC_ERROR_REF(error)); + } else if (GPR_UNLIKELY(request_router->resolver_ == nullptr)) { + // Shutting down. + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, "request_router=%p request=%p: resolver disconnected", + request_router, request); + } + GRPC_CLOSURE_RUN(request->on_route_done_, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); + } else if (GPR_UNLIKELY(request_router->lb_policy_ == nullptr)) { + // Transient resolver failure. + // If call has wait_for_ready=true, try again; otherwise, fail. + if (*request->pick_.initial_metadata_flags & + GRPC_INITIAL_METADATA_WAIT_FOR_READY) { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: resolver returned but no LB " + "policy; wait_for_ready=true; trying again", + request_router, request); + } + // Re-add ourselves to the waiting list. + self->AddToWaitingList(); + // Return early so that we don't set finished_ to true below. + return; + } else { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: resolver returned but no LB " + "policy; wait_for_ready=false; failing", + request_router, request); + } + GRPC_CLOSURE_RUN( + request->on_route_done_, + grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Name resolution failure"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); + } + } else { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: resolver returned, doing LB " + "pick", + request_router, request); + } + request->ProcessServiceConfigAndStartLbPickLocked(); + } + self->finished_ = true; + } + + // Invoked when the call is cancelled. + // Note: This runs under the client_channel combiner, but will NOT be + // holding the call combiner. + static void CancelLocked(void* arg, grpc_error* error) { + ResolverResultWaiter* self = static_cast(arg); + RequestRouter* request_router = self->request_router_; + // If DoneLocked() has already run, delete ourselves without doing anything. + if (self->finished_) { + Delete(self); + return; + } + Request* request = self->request_; + // If we are being cancelled, immediately invoke on_route_done_ + // to propagate the error back to the caller. + if (error != GRPC_ERROR_NONE) { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: cancelling call waiting for " + "name resolution", + request_router, request); + } + // Note: Although we are not in the call combiner here, we are + // basically stealing the call combiner from the pending pick, so + // it's safe to run on_route_done_ here -- we are essentially + // calling it here instead of calling it in DoneLocked(). + GRPC_CLOSURE_RUN(request->on_route_done_, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Pick cancelled", &error, 1)); + } + self->finished_ = true; + } + + RequestRouter* request_router_; + Request* request_; + const bool tracer_enabled_; + grpc_closure done_closure_; + grpc_closure cancel_closure_; + bool finished_ = false; +}; + +// +// RequestRouter::Request::AsyncPickCanceller +// + +// Handles the call combiner cancellation callback for an async LB pick. +class RequestRouter::Request::AsyncPickCanceller { + public: + explicit AsyncPickCanceller(Request* request) + : request_router_(request->request_router_), + request_(request), + tracer_enabled_(request_router_->tracer_->enabled()) { + GRPC_CALL_STACK_REF(request->owning_call_, "pick_callback_cancel"); + // Set cancellation closure, so that we abort if the call is cancelled. + GRPC_CLOSURE_INIT(&cancel_closure_, &CancelLocked, this, + grpc_combiner_scheduler(request_router_->combiner_)); + grpc_call_combiner_set_notify_on_cancel(request->call_combiner_, + &cancel_closure_); + } + + void MarkFinishedLocked() { + finished_ = true; + GRPC_CALL_STACK_UNREF(request_->owning_call_, "pick_callback_cancel"); + } + + private: + // Invoked when the call is cancelled. + // Note: This runs under the client_channel combiner, but will NOT be + // holding the call combiner. + static void CancelLocked(void* arg, grpc_error* error) { + AsyncPickCanceller* self = static_cast(arg); + Request* request = self->request_; + RequestRouter* request_router = self->request_router_; + if (!self->finished_) { + // Note: request_router->lb_policy_ may have changed since we started our + // pick, in which case we will be cancelling the pick on a policy other + // than the one we started it on. However, this will just be a no-op. + if (error != GRPC_ERROR_NONE && request_router->lb_policy_ != nullptr) { + if (self->tracer_enabled_) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: cancelling pick from LB " + "policy %p", + request_router, request, request_router->lb_policy_.get()); + } + request_router->lb_policy_->CancelPickLocked(&request->pick_, + GRPC_ERROR_REF(error)); + } + request->pick_canceller_ = nullptr; + GRPC_CALL_STACK_UNREF(request->owning_call_, "pick_callback_cancel"); + } + Delete(self); + } + + RequestRouter* request_router_; + Request* request_; + const bool tracer_enabled_; + grpc_closure cancel_closure_; + bool finished_ = false; +}; + +// +// RequestRouter::Request +// + +RequestRouter::Request::Request(grpc_call_stack* owning_call, + grpc_call_combiner* call_combiner, + grpc_polling_entity* pollent, + grpc_metadata_batch* send_initial_metadata, + uint32_t* send_initial_metadata_flags, + ApplyServiceConfigCallback apply_service_config, + void* apply_service_config_user_data, + grpc_closure* on_route_done) + : owning_call_(owning_call), + call_combiner_(call_combiner), + pollent_(pollent), + apply_service_config_(apply_service_config), + apply_service_config_user_data_(apply_service_config_user_data), + on_route_done_(on_route_done) { + pick_.initial_metadata = send_initial_metadata; + pick_.initial_metadata_flags = send_initial_metadata_flags; +} + +RequestRouter::Request::~Request() { + if (pick_.connected_subchannel != nullptr) { + pick_.connected_subchannel.reset(); + } + for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) { + if (pick_.subchannel_call_context[i].destroy != nullptr) { + pick_.subchannel_call_context[i].destroy( + pick_.subchannel_call_context[i].value); + } + } +} + +// Invoked once resolver results are available. +void RequestRouter::Request::ProcessServiceConfigAndStartLbPickLocked() { + // Get service config data if needed. + if (!apply_service_config_(apply_service_config_user_data_)) return; + // Start LB pick. + StartLbPickLocked(); +} + +void RequestRouter::Request::MaybeAddCallToInterestedPartiesLocked() { + if (!pollent_added_to_interested_parties_) { + pollent_added_to_interested_parties_ = true; + grpc_polling_entity_add_to_pollset_set( + pollent_, request_router_->interested_parties_); + } +} + +void RequestRouter::Request::MaybeRemoveCallFromInterestedPartiesLocked() { + if (pollent_added_to_interested_parties_) { + pollent_added_to_interested_parties_ = false; + grpc_polling_entity_del_from_pollset_set( + pollent_, request_router_->interested_parties_); + } +} + +// Starts a pick on the LB policy. +void RequestRouter::Request::StartLbPickLocked() { + if (request_router_->tracer_->enabled()) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: starting pick on lb_policy=%p", + request_router_, this, request_router_->lb_policy_.get()); + } + GRPC_CLOSURE_INIT(&on_pick_done_, &LbPickDoneLocked, this, + grpc_combiner_scheduler(request_router_->combiner_)); + pick_.on_complete = &on_pick_done_; + GRPC_CALL_STACK_REF(owning_call_, "pick_callback"); + grpc_error* error = GRPC_ERROR_NONE; + const bool pick_done = + request_router_->lb_policy_->PickLocked(&pick_, &error); + if (pick_done) { + // Pick completed synchronously. + if (request_router_->tracer_->enabled()) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: pick completed synchronously", + request_router_, this); + } + GRPC_CLOSURE_RUN(on_route_done_, error); + GRPC_CALL_STACK_UNREF(owning_call_, "pick_callback"); + } else { + // Pick will be returned asynchronously. + // Add the request's polling entity to the request_router's + // interested_parties, so that the I/O of the LB policy can be done + // under it. It will be removed in LbPickDoneLocked(). + MaybeAddCallToInterestedPartiesLocked(); + // Request notification on call cancellation. + // We allocate a separate object to track cancellation, since the + // cancellation closure might still be pending when we need to reuse + // the memory in which this Request object is stored for a subsequent + // retry attempt. + pick_canceller_ = New(this); + } +} + +// Callback invoked by LoadBalancingPolicy::PickLocked() for async picks. +// Unrefs the LB policy and invokes on_route_done_. +void RequestRouter::Request::LbPickDoneLocked(void* arg, grpc_error* error) { + Request* self = static_cast(arg); + RequestRouter* request_router = self->request_router_; + if (request_router->tracer_->enabled()) { + gpr_log(GPR_INFO, + "request_router=%p request=%p: pick completed asynchronously", + request_router, self); + } + self->MaybeRemoveCallFromInterestedPartiesLocked(); + if (self->pick_canceller_ != nullptr) { + self->pick_canceller_->MarkFinishedLocked(); + } + GRPC_CLOSURE_RUN(self->on_route_done_, GRPC_ERROR_REF(error)); + GRPC_CALL_STACK_UNREF(self->owning_call_, "pick_callback"); +} + +// +// RequestRouter::LbConnectivityWatcher +// + +class RequestRouter::LbConnectivityWatcher { + public: + LbConnectivityWatcher(RequestRouter* request_router, + grpc_connectivity_state state, + LoadBalancingPolicy* lb_policy, + grpc_channel_stack* owning_stack, + grpc_combiner* combiner) + : request_router_(request_router), + state_(state), + lb_policy_(lb_policy), + owning_stack_(owning_stack) { + GRPC_CHANNEL_STACK_REF(owning_stack_, "LbConnectivityWatcher"); + GRPC_CLOSURE_INIT(&on_changed_, &OnLbPolicyStateChangedLocked, this, + grpc_combiner_scheduler(combiner)); + lb_policy_->NotifyOnStateChangeLocked(&state_, &on_changed_); + } + + ~LbConnectivityWatcher() { + GRPC_CHANNEL_STACK_UNREF(owning_stack_, "LbConnectivityWatcher"); + } + + private: + static void OnLbPolicyStateChangedLocked(void* arg, grpc_error* error) { + LbConnectivityWatcher* self = static_cast(arg); + // If the notification is not for the current policy, we're stale, + // so delete ourselves. + if (self->lb_policy_ != self->request_router_->lb_policy_.get()) { + Delete(self); + return; + } + // Otherwise, process notification. + if (self->request_router_->tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: lb_policy=%p state changed to %s", + self->request_router_, self->lb_policy_, + grpc_connectivity_state_name(self->state_)); + } + self->request_router_->SetConnectivityStateLocked( + self->state_, GRPC_ERROR_REF(error), "lb_changed"); + // If shutting down, terminate watch. + if (self->state_ == GRPC_CHANNEL_SHUTDOWN) { + Delete(self); + return; + } + // Renew watch. + self->lb_policy_->NotifyOnStateChangeLocked(&self->state_, + &self->on_changed_); + } + + RequestRouter* request_router_; + grpc_connectivity_state state_; + // LB policy address. No ref held, so not safe to dereference unless + // it happens to match request_router->lb_policy_. + LoadBalancingPolicy* lb_policy_; + grpc_channel_stack* owning_stack_; + grpc_closure on_changed_; +}; + +// +// RequestRounter::ReresolutionRequestHandler +// + +class RequestRouter::ReresolutionRequestHandler { + public: + ReresolutionRequestHandler(RequestRouter* request_router, + LoadBalancingPolicy* lb_policy, + grpc_channel_stack* owning_stack, + grpc_combiner* combiner) + : request_router_(request_router), + lb_policy_(lb_policy), + owning_stack_(owning_stack) { + GRPC_CHANNEL_STACK_REF(owning_stack_, "ReresolutionRequestHandler"); + GRPC_CLOSURE_INIT(&closure_, &OnRequestReresolutionLocked, this, + grpc_combiner_scheduler(combiner)); + lb_policy_->SetReresolutionClosureLocked(&closure_); + } + + private: + static void OnRequestReresolutionLocked(void* arg, grpc_error* error) { + ReresolutionRequestHandler* self = + static_cast(arg); + RequestRouter* request_router = self->request_router_; + // If this invocation is for a stale LB policy, treat it as an LB shutdown + // signal. + if (self->lb_policy_ != request_router->lb_policy_.get() || + error != GRPC_ERROR_NONE || request_router->resolver_ == nullptr) { + GRPC_CHANNEL_STACK_UNREF(request_router->owning_stack_, + "ReresolutionRequestHandler"); + Delete(self); + return; + } + if (request_router->tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: started name re-resolving", + request_router); + } + request_router->resolver_->RequestReresolutionLocked(); + // Give back the closure to the LB policy. + self->lb_policy_->SetReresolutionClosureLocked(&self->closure_); + } + + RequestRouter* request_router_; + // LB policy address. No ref held, so not safe to dereference unless + // it happens to match request_router->lb_policy_. + LoadBalancingPolicy* lb_policy_; + grpc_channel_stack* owning_stack_; + grpc_closure closure_; +}; + +// +// RequestRouter +// + +RequestRouter::RequestRouter( + grpc_channel_stack* owning_stack, grpc_combiner* combiner, + grpc_client_channel_factory* client_channel_factory, + grpc_pollset_set* interested_parties, TraceFlag* tracer, + ProcessResolverResultCallback process_resolver_result, + void* process_resolver_result_user_data, const char* target_uri, + const grpc_channel_args* args, grpc_error** error) + : owning_stack_(owning_stack), + combiner_(combiner), + client_channel_factory_(client_channel_factory), + interested_parties_(interested_parties), + tracer_(tracer), + process_resolver_result_(process_resolver_result), + process_resolver_result_user_data_(process_resolver_result_user_data) { + // Get subchannel pool. + const grpc_arg* arg = + grpc_channel_args_find(args, GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL); + if (grpc_channel_arg_get_bool(arg, false)) { + subchannel_pool_ = MakeRefCounted(); + } else { + subchannel_pool_ = GlobalSubchannelPool::instance(); + } + GRPC_CLOSURE_INIT(&on_resolver_result_changed_, + &RequestRouter::OnResolverResultChangedLocked, this, + grpc_combiner_scheduler(combiner)); + grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, + "request_router"); + grpc_channel_args* new_args = nullptr; + if (process_resolver_result == nullptr) { + grpc_arg arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), 0); + new_args = grpc_channel_args_copy_and_add(args, &arg, 1); + } + resolver_ = ResolverRegistry::CreateResolver( + target_uri, (new_args == nullptr ? args : new_args), interested_parties_, + combiner_); + grpc_channel_args_destroy(new_args); + if (resolver_ == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); + } +} + +RequestRouter::~RequestRouter() { + if (resolver_ != nullptr) { + // The only way we can get here is if we never started resolving, + // because we take a ref to the channel stack when we start + // resolving and do not release it until the resolver callback is + // invoked after the resolver shuts down. + resolver_.reset(); + } + if (lb_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties_); + lb_policy_.reset(); + } + if (client_channel_factory_ != nullptr) { + grpc_client_channel_factory_unref(client_channel_factory_); + } + grpc_connectivity_state_destroy(&state_tracker_); +} + +namespace { + +const char* GetChannelConnectivityStateChangeString( + grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "Channel state change to IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "Channel state change to CONNECTING"; + case GRPC_CHANNEL_READY: + return "Channel state change to READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "Channel state change to TRANSIENT_FAILURE"; + case GRPC_CHANNEL_SHUTDOWN: + return "Channel state change to SHUTDOWN"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +} // namespace + +void RequestRouter::SetConnectivityStateLocked(grpc_connectivity_state state, + grpc_error* error, + const char* reason) { + if (lb_policy_ != nullptr) { + if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) { + // Cancel picks with wait_for_ready=false. + lb_policy_->CancelMatchingPicksLocked( + /* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY, + /* check= */ 0, GRPC_ERROR_REF(error)); + } else if (state == GRPC_CHANNEL_SHUTDOWN) { + // Cancel all picks. + lb_policy_->CancelMatchingPicksLocked(/* mask= */ 0, /* check= */ 0, + GRPC_ERROR_REF(error)); + } + } + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: setting connectivity state to %s", + this, grpc_connectivity_state_name(state)); + } + if (channelz_node_ != nullptr) { + channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + GetChannelConnectivityStateChangeString(state))); + } + grpc_connectivity_state_set(&state_tracker_, state, error, reason); +} + +void RequestRouter::StartResolvingLocked() { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: starting name resolution", this); + } + GPR_ASSERT(!started_resolving_); + started_resolving_ = true; + GRPC_CHANNEL_STACK_REF(owning_stack_, "resolver"); + resolver_->NextLocked(&resolver_result_, &on_resolver_result_changed_); +} + +// Invoked from the resolver NextLocked() callback when the resolver +// is shutting down. +void RequestRouter::OnResolverShutdownLocked(grpc_error* error) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: shutting down", this); + } + if (lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: shutting down lb_policy=%p", this, + lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties_); + lb_policy_.reset(); + } + if (resolver_ != nullptr) { + // This should never happen; it can only be triggered by a resolver + // implementation spotaneously deciding to report shutdown without + // being orphaned. This code is included just to be defensive. + if (tracer_->enabled()) { + gpr_log(GPR_INFO, + "request_router=%p: spontaneous shutdown from resolver %p", this, + resolver_.get()); + } + resolver_.reset(); + SetConnectivityStateLocked(GRPC_CHANNEL_SHUTDOWN, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Resolver spontaneous shutdown", &error, 1), + "resolver_spontaneous_shutdown"); + } + grpc_closure_list_fail_all(&waiting_for_resolver_result_closures_, + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Channel disconnected", &error, 1)); + GRPC_CLOSURE_LIST_SCHED(&waiting_for_resolver_result_closures_); + GRPC_CHANNEL_STACK_UNREF(owning_stack_, "resolver"); + grpc_channel_args_destroy(resolver_result_); + resolver_result_ = nullptr; + GRPC_ERROR_UNREF(error); +} + +// Creates a new LB policy, replacing any previous one. +// If the new policy is created successfully, sets *connectivity_state and +// *connectivity_error to its initial connectivity state; otherwise, +// leaves them unchanged. +void RequestRouter::CreateNewLbPolicyLocked( + const char* lb_policy_name, grpc_json* lb_config, + grpc_connectivity_state* connectivity_state, + grpc_error** connectivity_error, TraceStringVector* trace_strings) { + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = combiner_; + lb_policy_args.client_channel_factory = client_channel_factory_; + lb_policy_args.subchannel_pool = subchannel_pool_; + lb_policy_args.args = resolver_result_; + lb_policy_args.lb_config = lb_config; + OrphanablePtr new_lb_policy = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(lb_policy_name, + lb_policy_args); + if (GPR_UNLIKELY(new_lb_policy == nullptr)) { + gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); + if (channelz_node_ != nullptr) { + char* str; + gpr_asprintf(&str, "Could not create LB policy \'%s\'", lb_policy_name); + trace_strings->push_back(str); + } + } else { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: created new LB policy \"%s\" (%p)", + this, lb_policy_name, new_lb_policy.get()); + } + if (channelz_node_ != nullptr) { + char* str; + gpr_asprintf(&str, "Created new LB policy \'%s\'", lb_policy_name); + trace_strings->push_back(str); + } + // Swap out the LB policy and update the fds in interested_parties_. + if (lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: shutting down lb_policy=%p", this, + lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties_); + lb_policy_->HandOffPendingPicksLocked(new_lb_policy.get()); + } + lb_policy_ = std::move(new_lb_policy); + grpc_pollset_set_add_pollset_set(lb_policy_->interested_parties(), + interested_parties_); + // Create re-resolution request handler for the new LB policy. It + // will delete itself when no longer needed. + New(this, lb_policy_.get(), owning_stack_, + combiner_); + // Get the new LB policy's initial connectivity state and start a + // connectivity watch. + GRPC_ERROR_UNREF(*connectivity_error); + *connectivity_state = + lb_policy_->CheckConnectivityLocked(connectivity_error); + if (exit_idle_when_lb_policy_arrives_) { + lb_policy_->ExitIdleLocked(); + exit_idle_when_lb_policy_arrives_ = false; + } + // Create new watcher. It will delete itself when done. + New(this, *connectivity_state, lb_policy_.get(), + owning_stack_, combiner_); + } +} + +void RequestRouter::MaybeAddTraceMessagesForAddressChangesLocked( + TraceStringVector* trace_strings) { + const ServerAddressList* addresses = + FindServerAddressListChannelArg(resolver_result_); + const bool resolution_contains_addresses = + addresses != nullptr && addresses->size() > 0; + if (!resolution_contains_addresses && + previous_resolution_contained_addresses_) { + trace_strings->push_back(gpr_strdup("Address list became empty")); + } else if (resolution_contains_addresses && + !previous_resolution_contained_addresses_) { + trace_strings->push_back(gpr_strdup("Address list became non-empty")); + } + previous_resolution_contained_addresses_ = resolution_contains_addresses; +} + +void RequestRouter::ConcatenateAndAddChannelTraceLocked( + TraceStringVector* trace_strings) const { + if (!trace_strings->empty()) { + gpr_strvec v; + gpr_strvec_init(&v); + gpr_strvec_add(&v, gpr_strdup("Resolution event: ")); + bool is_first = 1; + for (size_t i = 0; i < trace_strings->size(); ++i) { + if (!is_first) gpr_strvec_add(&v, gpr_strdup(", ")); + is_first = false; + gpr_strvec_add(&v, (*trace_strings)[i]); + } + char* flat; + size_t flat_len = 0; + flat = gpr_strvec_flatten(&v, &flat_len); + channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info, + grpc_slice_new(flat, flat_len, gpr_free)); + gpr_strvec_destroy(&v); + } +} + +// Callback invoked when a resolver result is available. +void RequestRouter::OnResolverResultChangedLocked(void* arg, + grpc_error* error) { + RequestRouter* self = static_cast(arg); + if (self->tracer_->enabled()) { + const char* disposition = + self->resolver_result_ != nullptr + ? "" + : (error == GRPC_ERROR_NONE ? " (transient error)" + : " (resolver shutdown)"); + gpr_log(GPR_INFO, + "request_router=%p: got resolver result: resolver_result=%p " + "error=%s%s", + self, self->resolver_result_, grpc_error_string(error), + disposition); + } + // Handle shutdown. + if (error != GRPC_ERROR_NONE || self->resolver_ == nullptr) { + self->OnResolverShutdownLocked(GRPC_ERROR_REF(error)); + return; + } + // Data used to set the channel's connectivity state. + bool set_connectivity_state = true; + // We only want to trace the address resolution in the follow cases: + // (a) Address resolution resulted in service config change. + // (b) Address resolution that causes number of backends to go from + // zero to non-zero. + // (c) Address resolution that causes number of backends to go from + // non-zero to zero. + // (d) Address resolution that causes a new LB policy to be created. + // + // we track a list of strings to eventually be concatenated and traced. + TraceStringVector trace_strings; + grpc_connectivity_state connectivity_state = GRPC_CHANNEL_TRANSIENT_FAILURE; + grpc_error* connectivity_error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy"); + // resolver_result_ will be null in the case of a transient + // resolution error. In that case, we don't have any new result to + // process, which means that we keep using the previous result (if any). + if (self->resolver_result_ == nullptr) { + if (self->tracer_->enabled()) { + gpr_log(GPR_INFO, "request_router=%p: resolver transient failure", self); + } + // Don't override connectivity state if we already have an LB policy. + if (self->lb_policy_ != nullptr) set_connectivity_state = false; + } else { + // Parse the resolver result. + const char* lb_policy_name = nullptr; + grpc_json* lb_policy_config = nullptr; + const bool service_config_changed = self->process_resolver_result_( + self->process_resolver_result_user_data_, *self->resolver_result_, + &lb_policy_name, &lb_policy_config); + GPR_ASSERT(lb_policy_name != nullptr); + // Check to see if we're already using the right LB policy. + const bool lb_policy_name_changed = + self->lb_policy_ == nullptr || + strcmp(self->lb_policy_->name(), lb_policy_name) != 0; + if (self->lb_policy_ != nullptr && !lb_policy_name_changed) { + // Continue using the same LB policy. Update with new addresses. + if (self->tracer_->enabled()) { + gpr_log(GPR_INFO, + "request_router=%p: updating existing LB policy \"%s\" (%p)", + self, lb_policy_name, self->lb_policy_.get()); + } + self->lb_policy_->UpdateLocked(*self->resolver_result_, lb_policy_config); + // No need to set the channel's connectivity state; the existing + // watch on the LB policy will take care of that. + set_connectivity_state = false; + } else { + // Instantiate new LB policy. + self->CreateNewLbPolicyLocked(lb_policy_name, lb_policy_config, + &connectivity_state, &connectivity_error, + &trace_strings); + } + // Add channel trace event. + if (self->channelz_node_ != nullptr) { + if (service_config_changed) { + // TODO(ncteisen): might be worth somehow including a snippet of the + // config in the trace, at the risk of bloating the trace logs. + trace_strings.push_back(gpr_strdup("Service config changed")); + } + self->MaybeAddTraceMessagesForAddressChangesLocked(&trace_strings); + self->ConcatenateAndAddChannelTraceLocked(&trace_strings); + } + // Clean up. + grpc_channel_args_destroy(self->resolver_result_); + self->resolver_result_ = nullptr; + } + // Set the channel's connectivity state if needed. + if (set_connectivity_state) { + self->SetConnectivityStateLocked(connectivity_state, connectivity_error, + "resolver_result"); + } else { + GRPC_ERROR_UNREF(connectivity_error); + } + // Invoke closures that were waiting for results and renew the watch. + GRPC_CLOSURE_LIST_SCHED(&self->waiting_for_resolver_result_closures_); + self->resolver_->NextLocked(&self->resolver_result_, + &self->on_resolver_result_changed_); +} + +void RequestRouter::RouteCallLocked(Request* request) { + GPR_ASSERT(request->pick_.connected_subchannel == nullptr); + request->request_router_ = this; + if (lb_policy_ != nullptr) { + // We already have resolver results, so process the service config + // and start an LB pick. + request->ProcessServiceConfigAndStartLbPickLocked(); + } else if (resolver_ == nullptr) { + GRPC_CLOSURE_RUN(request->on_route_done_, + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); + } else { + // We do not yet have an LB policy, so wait for a resolver result. + if (!started_resolving_) { + StartResolvingLocked(); + } + // Create a new waiter, which will delete itself when done. + New(request); + // Add the request's polling entity to the request_router's + // interested_parties, so that the I/O of the resolver can be done + // under it. It will be removed in LbPickDoneLocked(). + request->MaybeAddCallToInterestedPartiesLocked(); + } +} + +void RequestRouter::ShutdownLocked(grpc_error* error) { + if (resolver_ != nullptr) { + SetConnectivityStateLocked(GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), + "disconnect"); + resolver_.reset(); + if (!started_resolving_) { + grpc_closure_list_fail_all(&waiting_for_resolver_result_closures_, + GRPC_ERROR_REF(error)); + GRPC_CLOSURE_LIST_SCHED(&waiting_for_resolver_result_closures_); + } + if (lb_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties_); + lb_policy_.reset(); + } + } + GRPC_ERROR_UNREF(error); +} + +grpc_connectivity_state RequestRouter::GetConnectivityState() { + return grpc_connectivity_state_check(&state_tracker_); +} + +void RequestRouter::NotifyOnConnectivityStateChange( + grpc_connectivity_state* state, grpc_closure* closure) { + grpc_connectivity_state_notify_on_state_change(&state_tracker_, state, + closure); +} + +void RequestRouter::ExitIdleLocked() { + if (lb_policy_ != nullptr) { + lb_policy_->ExitIdleLocked(); + } else { + exit_idle_when_lb_policy_arrives_ = true; + if (!started_resolving_ && resolver_ != nullptr) { + StartResolvingLocked(); + } + } +} + +void RequestRouter::ResetConnectionBackoffLocked() { + if (resolver_ != nullptr) { + resolver_->ResetBackoffLocked(); + resolver_->RequestReresolutionLocked(); + } + if (lb_policy_ != nullptr) { + lb_policy_->ResetBackoffLocked(); + } +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/request_routing.h b/src/core/ext/filters/client_channel/request_routing.h new file mode 100644 index 00000000000..0027163869e --- /dev/null +++ b/src/core/ext/filters/client_channel/request_routing.h @@ -0,0 +1,181 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H + +#include + +#include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/ext/filters/client_channel/client_channel_factory.h" +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/iomgr/call_combiner.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/metadata_batch.h" + +namespace grpc_core { + +class RequestRouter { + public: + class Request { + public: + // Synchronous callback that applies the service config to a call. + // Returns false if the call should be failed. + typedef bool (*ApplyServiceConfigCallback)(void* user_data); + + Request(grpc_call_stack* owning_call, grpc_call_combiner* call_combiner, + grpc_polling_entity* pollent, + grpc_metadata_batch* send_initial_metadata, + uint32_t* send_initial_metadata_flags, + ApplyServiceConfigCallback apply_service_config, + void* apply_service_config_user_data, grpc_closure* on_route_done); + + ~Request(); + + // TODO(roth): It seems a bit ugly to expose this member in a + // non-const way. Find a better API to avoid this. + LoadBalancingPolicy::PickState* pick() { return &pick_; } + + private: + friend class RequestRouter; + + class ResolverResultWaiter; + class AsyncPickCanceller; + + void ProcessServiceConfigAndStartLbPickLocked(); + void StartLbPickLocked(); + static void LbPickDoneLocked(void* arg, grpc_error* error); + + void MaybeAddCallToInterestedPartiesLocked(); + void MaybeRemoveCallFromInterestedPartiesLocked(); + + // Populated by caller. + grpc_call_stack* owning_call_; + grpc_call_combiner* call_combiner_; + grpc_polling_entity* pollent_; + ApplyServiceConfigCallback apply_service_config_; + void* apply_service_config_user_data_; + grpc_closure* on_route_done_; + LoadBalancingPolicy::PickState pick_; + + // Internal state. + RequestRouter* request_router_ = nullptr; + bool pollent_added_to_interested_parties_ = false; + grpc_closure on_pick_done_; + AsyncPickCanceller* pick_canceller_ = nullptr; + }; + + // Synchronous callback that takes the service config JSON string and + // LB policy name. + // Returns true if the service config has changed since the last result. + typedef bool (*ProcessResolverResultCallback)(void* user_data, + const grpc_channel_args& args, + const char** lb_policy_name, + grpc_json** lb_policy_config); + + RequestRouter(grpc_channel_stack* owning_stack, grpc_combiner* combiner, + grpc_client_channel_factory* client_channel_factory, + grpc_pollset_set* interested_parties, TraceFlag* tracer, + ProcessResolverResultCallback process_resolver_result, + void* process_resolver_result_user_data, const char* target_uri, + const grpc_channel_args* args, grpc_error** error); + + ~RequestRouter(); + + void set_channelz_node(channelz::ClientChannelNode* channelz_node) { + channelz_node_ = channelz_node; + } + + void RouteCallLocked(Request* request); + + // TODO(roth): Add methods to cancel picks. + + void ShutdownLocked(grpc_error* error); + + void ExitIdleLocked(); + void ResetConnectionBackoffLocked(); + + grpc_connectivity_state GetConnectivityState(); + void NotifyOnConnectivityStateChange(grpc_connectivity_state* state, + grpc_closure* closure); + + LoadBalancingPolicy* lb_policy() const { return lb_policy_.get(); } + + private: + using TraceStringVector = InlinedVector; + + class ReresolutionRequestHandler; + class LbConnectivityWatcher; + + void StartResolvingLocked(); + void OnResolverShutdownLocked(grpc_error* error); + void CreateNewLbPolicyLocked(const char* lb_policy_name, grpc_json* lb_config, + grpc_connectivity_state* connectivity_state, + grpc_error** connectivity_error, + TraceStringVector* trace_strings); + void MaybeAddTraceMessagesForAddressChangesLocked( + TraceStringVector* trace_strings); + void ConcatenateAndAddChannelTraceLocked( + TraceStringVector* trace_strings) const; + static void OnResolverResultChangedLocked(void* arg, grpc_error* error); + + void SetConnectivityStateLocked(grpc_connectivity_state state, + grpc_error* error, const char* reason); + + // Passed in from caller at construction time. + grpc_channel_stack* owning_stack_; + grpc_combiner* combiner_; + grpc_client_channel_factory* client_channel_factory_; + grpc_pollset_set* interested_parties_; + TraceFlag* tracer_; + + channelz::ClientChannelNode* channelz_node_ = nullptr; + + // Resolver and associated state. + OrphanablePtr resolver_; + ProcessResolverResultCallback process_resolver_result_; + void* process_resolver_result_user_data_; + bool started_resolving_ = false; + grpc_channel_args* resolver_result_ = nullptr; + bool previous_resolution_contained_addresses_ = false; + grpc_closure_list waiting_for_resolver_result_closures_; + grpc_closure on_resolver_result_changed_; + + // LB policy and associated state. + OrphanablePtr lb_policy_; + bool exit_idle_when_lb_policy_arrives_ = false; + + // Subchannel pool to pass to LB policy. + RefCountedPtr subchannel_pool_; + + grpc_connectivity_state_tracker state_tracker_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H */ diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc deleted file mode 100644 index ad9720fdda9..00000000000 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ /dev/null @@ -1,460 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/ext/filters/client_channel/resolving_lb_policy.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/ext/filters/client_channel/http_connect_handshaker.h" -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" -#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" -#include "src/core/ext/filters/client_channel/resolver_registry.h" -#include "src/core/ext/filters/client_channel/retry_throttle.h" -#include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/ext/filters/deadline/deadline_filter.h" -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/channel/status_util.h" -#include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/inlined_vector.h" -#include "src/core/lib/gprpp/manual_constructor.h" -#include "src/core/lib/iomgr/combiner.h" -#include "src/core/lib/iomgr/iomgr.h" -#include "src/core/lib/iomgr/polling_entity.h" -#include "src/core/lib/profiling/timers.h" -#include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/surface/channel.h" -#include "src/core/lib/transport/connectivity_state.h" -#include "src/core/lib/transport/error_utils.h" -#include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/metadata_batch.h" -#include "src/core/lib/transport/service_config.h" -#include "src/core/lib/transport/static_metadata.h" -#include "src/core/lib/transport/status_metadata.h" - -namespace grpc_core { - -// -// ResolvingLoadBalancingPolicy::ResolvingControlHelper -// - -class ResolvingLoadBalancingPolicy::ResolvingControlHelper - : public LoadBalancingPolicy::ChannelControlHelper { - public: - explicit ResolvingControlHelper( - RefCountedPtr parent) - : parent_(std::move(parent)) {} - - Subchannel* CreateSubchannel(const grpc_channel_args& args) override { - if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. - return parent_->channel_control_helper()->CreateSubchannel(args); - } - - grpc_channel* CreateChannel(const char* target, grpc_client_channel_type type, - const grpc_channel_args& args) override { - if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. - return parent_->channel_control_helper()->CreateChannel(target, type, args); - } - - void UpdateState(grpc_connectivity_state state, grpc_error* state_error, - UniquePtr picker) override { - if (parent_->resolver_ == nullptr) { - // shutting down. - GRPC_ERROR_UNREF(state_error); - return; - } - parent_->channel_control_helper()->UpdateState(state, state_error, - std::move(picker)); - } - - void RequestReresolution() override { - if (parent_->tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: started name re-resolving", - parent_.get()); - } - if (parent_->resolver_ != nullptr) { - parent_->resolver_->RequestReresolutionLocked(); - } - } - - private: - RefCountedPtr parent_; -}; - -// -// ResolvingLoadBalancingPolicy -// - -ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( - Args args, TraceFlag* tracer, UniquePtr target_uri, - UniquePtr child_policy_name, grpc_json* child_lb_config, - grpc_error** error) - : LoadBalancingPolicy(std::move(args)), - tracer_(tracer), - target_uri_(std::move(target_uri)), - child_policy_name_(std::move(child_policy_name)), - child_lb_config_str_(grpc_json_dump_to_string(child_lb_config, 0)), - child_lb_config_(grpc_json_parse_string(child_lb_config_str_.get())) { - GPR_ASSERT(child_policy_name_ != nullptr); - // Don't fetch service config, since this ctor is for use in nested LB - // policies, not at the top level, and we only fetch the service - // config at the top level. - grpc_arg arg = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), 0); - grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(args.args, &arg, 1); - *error = Init(*new_args); - grpc_channel_args_destroy(new_args); -} - -ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( - Args args, TraceFlag* tracer, UniquePtr target_uri, - ProcessResolverResultCallback process_resolver_result, - void* process_resolver_result_user_data, grpc_error** error) - : LoadBalancingPolicy(std::move(args)), - tracer_(tracer), - target_uri_(std::move(target_uri)), - process_resolver_result_(process_resolver_result), - process_resolver_result_user_data_(process_resolver_result_user_data) { - GPR_ASSERT(process_resolver_result != nullptr); - *error = Init(*args.args); -} - -grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) { - GRPC_CLOSURE_INIT( - &on_resolver_result_changed_, - &ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked, this, - grpc_combiner_scheduler(combiner())); - resolver_ = ResolverRegistry::CreateResolver( - target_uri_.get(), &args, interested_parties(), combiner()); - if (resolver_ == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); - } - // Return our picker to the channel. - channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, - UniquePtr(New(Ref()))); - return GRPC_ERROR_NONE; -} - -ResolvingLoadBalancingPolicy::~ResolvingLoadBalancingPolicy() { - GPR_ASSERT(resolver_ == nullptr); - GPR_ASSERT(lb_policy_ == nullptr); - grpc_json_destroy(child_lb_config_); -} - -void ResolvingLoadBalancingPolicy::ShutdownLocked() { - if (resolver_ != nullptr) { - resolver_.reset(); - if (lb_policy_ != nullptr) { - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties()); - lb_policy_.reset(); - } - } -} - -void ResolvingLoadBalancingPolicy::ExitIdleLocked() { - if (lb_policy_ != nullptr) { - lb_policy_->ExitIdleLocked(); - } else { - if (!started_resolving_ && resolver_ != nullptr) { - StartResolvingLocked(); - } - } -} - -void ResolvingLoadBalancingPolicy::ResetBackoffLocked() { - if (resolver_ != nullptr) { - resolver_->ResetBackoffLocked(); - resolver_->RequestReresolutionLocked(); - } - if (lb_policy_ != nullptr) { - lb_policy_->ResetBackoffLocked(); - } -} - -void ResolvingLoadBalancingPolicy::FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) { - if (lb_policy_ != nullptr) { - lb_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); - } -} - -void ResolvingLoadBalancingPolicy::StartResolvingLocked() { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: starting name resolution", this); - } - GPR_ASSERT(!started_resolving_); - started_resolving_ = true; - Ref().release(); - resolver_->NextLocked(&resolver_result_, &on_resolver_result_changed_); -} - -// Invoked from the resolver NextLocked() callback when the resolver -// is shutting down. -void ResolvingLoadBalancingPolicy::OnResolverShutdownLocked(grpc_error* error) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: shutting down", this); - } - if (lb_policy_ != nullptr) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, - lb_policy_.get()); - } - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties()); - lb_policy_.reset(); - } - if (resolver_ != nullptr) { - // This should never happen; it can only be triggered by a resolver - // implementation spotaneously deciding to report shutdown without - // being orphaned. This code is included just to be defensive. - if (tracer_->enabled()) { - gpr_log(GPR_INFO, - "resolving_lb=%p: spontaneous shutdown from resolver %p", this, - resolver_.get()); - } - resolver_.reset(); - grpc_error* error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Resolver spontaneous shutdown", &error, 1); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), - UniquePtr(New(error))); - } - grpc_channel_args_destroy(resolver_result_); - resolver_result_ = nullptr; - GRPC_ERROR_UNREF(error); - Unref(); -} - -// Creates a new LB policy, replacing any previous one. -// Updates trace_strings to indicate what was done. -void ResolvingLoadBalancingPolicy::CreateNewLbPolicyLocked( - const char* lb_policy_name, grpc_json* lb_config, - TraceStringVector* trace_strings) { - LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = combiner(); - lb_policy_args.channel_control_helper = - UniquePtr(New(Ref())); - lb_policy_args.args = resolver_result_; - lb_policy_args.lb_config = lb_config; - OrphanablePtr new_lb_policy = - LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - lb_policy_name, std::move(lb_policy_args)); - if (GPR_UNLIKELY(new_lb_policy == nullptr)) { - gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); - if (channelz_node() != nullptr) { - char* str; - gpr_asprintf(&str, "Could not create LB policy \"%s\"", lb_policy_name); - trace_strings->push_back(str); - } - } else { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: created new LB policy \"%s\" (%p)", - this, lb_policy_name, new_lb_policy.get()); - } - if (channelz_node() != nullptr) { - char* str; - gpr_asprintf(&str, "Created new LB policy \"%s\"", lb_policy_name); - trace_strings->push_back(str); - } - // Propagate channelz node. - auto* channelz = channelz_node(); - if (channelz != nullptr) { - new_lb_policy->set_channelz_node(channelz->Ref()); - } - // Swap out the LB policy and update the fds in interested_parties_. - if (lb_policy_ != nullptr) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, - lb_policy_.get()); - } - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties()); - } - lb_policy_ = std::move(new_lb_policy); - grpc_pollset_set_add_pollset_set(lb_policy_->interested_parties(), - interested_parties()); - lb_policy_->ExitIdleLocked(); - } -} - -void ResolvingLoadBalancingPolicy::MaybeAddTraceMessagesForAddressChangesLocked( - TraceStringVector* trace_strings) { - const ServerAddressList* addresses = - FindServerAddressListChannelArg(resolver_result_); - const bool resolution_contains_addresses = - addresses != nullptr && addresses->size() > 0; - if (!resolution_contains_addresses && - previous_resolution_contained_addresses_) { - trace_strings->push_back(gpr_strdup("Address list became empty")); - } else if (resolution_contains_addresses && - !previous_resolution_contained_addresses_) { - trace_strings->push_back(gpr_strdup("Address list became non-empty")); - } - previous_resolution_contained_addresses_ = resolution_contains_addresses; -} - -void ResolvingLoadBalancingPolicy::ConcatenateAndAddChannelTraceLocked( - TraceStringVector* trace_strings) const { - if (!trace_strings->empty()) { - gpr_strvec v; - gpr_strvec_init(&v); - gpr_strvec_add(&v, gpr_strdup("Resolution event: ")); - bool is_first = 1; - for (size_t i = 0; i < trace_strings->size(); ++i) { - if (!is_first) gpr_strvec_add(&v, gpr_strdup(", ")); - is_first = false; - gpr_strvec_add(&v, (*trace_strings)[i]); - } - char* flat; - size_t flat_len = 0; - flat = gpr_strvec_flatten(&v, &flat_len); - channelz_node()->AddTraceEvent(channelz::ChannelTrace::Severity::Info, - grpc_slice_new(flat, flat_len, gpr_free)); - gpr_strvec_destroy(&v); - } -} - -// Callback invoked when a resolver result is available. -void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( - void* arg, grpc_error* error) { - auto* self = static_cast(arg); - if (self->tracer_->enabled()) { - const char* disposition = - self->resolver_result_ != nullptr - ? "" - : (error == GRPC_ERROR_NONE ? " (transient error)" - : " (resolver shutdown)"); - gpr_log(GPR_INFO, - "resolving_lb=%p: got resolver result: resolver_result=%p " - "error=%s%s", - self, self->resolver_result_, grpc_error_string(error), - disposition); - } - // Handle shutdown. - if (error != GRPC_ERROR_NONE || self->resolver_ == nullptr) { - self->OnResolverShutdownLocked(GRPC_ERROR_REF(error)); - return; - } - // We only want to trace the address resolution in the follow cases: - // (a) Address resolution resulted in service config change. - // (b) Address resolution that causes number of backends to go from - // zero to non-zero. - // (c) Address resolution that causes number of backends to go from - // non-zero to zero. - // (d) Address resolution that causes a new LB policy to be created. - // - // we track a list of strings to eventually be concatenated and traced. - TraceStringVector trace_strings; - // resolver_result_ will be null in the case of a transient - // resolution error. In that case, we don't have any new result to - // process, which means that we keep using the previous result (if any). - if (self->resolver_result_ == nullptr) { - if (self->tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: resolver transient failure", self); - } - // If we already have an LB policy from a previous resolution - // result, then we continue to let it set the connectivity state. - // Otherwise, we go into TRANSIENT_FAILURE. - if (self->lb_policy_ == nullptr) { - // TODO(roth): When we change the resolver API to be able to - // return transient errors in a cleaner way, we should make it the - // resolver's responsibility to attach a status to the error, - // rather than doing it centrally here. - grpc_error* state_error = grpc_error_set_int( - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Resolver transient failure", &error, 1), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); - self->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(state_error), - UniquePtr( - New(state_error))); - } - } else { - // Parse the resolver result. - const char* lb_policy_name = nullptr; - grpc_json* lb_policy_config = nullptr; - bool service_config_changed = false; - if (self->process_resolver_result_ != nullptr) { - service_config_changed = self->process_resolver_result_( - self->process_resolver_result_user_data_, *self->resolver_result_, - &lb_policy_name, &lb_policy_config); - } else { - lb_policy_name = self->child_policy_name_.get(); - lb_policy_config = self->child_lb_config_; - } - GPR_ASSERT(lb_policy_name != nullptr); - // Check to see if we're already using the right LB policy. - const bool lb_policy_name_changed = - self->lb_policy_ == nullptr || - strcmp(self->lb_policy_->name(), lb_policy_name) != 0; - if (self->lb_policy_ != nullptr && !lb_policy_name_changed) { - // Continue using the same LB policy. Update with new addresses. - if (self->tracer_->enabled()) { - gpr_log(GPR_INFO, - "resolving_lb=%p: updating existing LB policy \"%s\" (%p)", - self, lb_policy_name, self->lb_policy_.get()); - } - self->lb_policy_->UpdateLocked(*self->resolver_result_, lb_policy_config); - } else { - // Instantiate new LB policy. - if (self->tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: creating new LB policy \"%s\"", - self, lb_policy_name); - } - self->CreateNewLbPolicyLocked(lb_policy_name, lb_policy_config, - &trace_strings); - } - // Add channel trace event. - if (self->channelz_node() != nullptr) { - if (service_config_changed) { - // TODO(ncteisen): might be worth somehow including a snippet of the - // config in the trace, at the risk of bloating the trace logs. - trace_strings.push_back(gpr_strdup("Service config changed")); - } - self->MaybeAddTraceMessagesForAddressChangesLocked(&trace_strings); - self->ConcatenateAndAddChannelTraceLocked(&trace_strings); - } - // Clean up. - grpc_channel_args_destroy(self->resolver_result_); - self->resolver_result_ = nullptr; - } - // Renew resolver callback. - self->resolver_->NextLocked(&self->resolver_result_, - &self->on_resolver_result_changed_); -} - -} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h deleted file mode 100644 index c302ae5d975..00000000000 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H - -#include - -#include "src/core/ext/filters/client_channel/client_channel_channelz.h" -#include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/ext/filters/client_channel/resolver.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/channel_stack.h" -#include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/inlined_vector.h" -#include "src/core/lib/gprpp/orphanable.h" -#include "src/core/lib/iomgr/call_combiner.h" -#include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/polling_entity.h" -#include "src/core/lib/iomgr/pollset_set.h" -#include "src/core/lib/transport/connectivity_state.h" -#include "src/core/lib/transport/metadata_batch.h" - -namespace grpc_core { - -// An LB policy that wraps a resolver and a child LB policy to make use -// of the addresses returned by the resolver. -// -// When used in the client_channel code, the resolver will attempt to -// fetch the service config, and the child LB policy name and config -// will be determined based on the service config. -// -// When used in an LB policy implementation that needs to do another -// round of resolution before creating a child policy, the resolver does -// not fetch the service config, and the caller must pre-determine the -// child LB policy and config to use. -class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { - public: - // If error is set when this returns, then construction failed, and - // the caller may not use the new object. - ResolvingLoadBalancingPolicy(Args args, TraceFlag* tracer, - UniquePtr target_uri, - UniquePtr child_policy_name, - grpc_json* child_lb_config, grpc_error** error); - - // Private ctor, to be used by client_channel only! - // - // Synchronous callback that takes the resolver result and sets - // lb_policy_name and lb_policy_config to point to the right data. - // Returns true if the service config has changed since the last result. - typedef bool (*ProcessResolverResultCallback)(void* user_data, - const grpc_channel_args& args, - const char** lb_policy_name, - grpc_json** lb_policy_config); - // If error is set when this returns, then construction failed, and - // the caller may not use the new object. - ResolvingLoadBalancingPolicy( - Args args, TraceFlag* tracer, UniquePtr target_uri, - ProcessResolverResultCallback process_resolver_result, - void* process_resolver_result_user_data, grpc_error** error); - - virtual const char* name() const override { return "resolving_lb"; } - - // No-op -- should never get updates from the channel. - // TODO(roth): Need to support updating child LB policy's config. - // For xds policy, will also need to support updating config - // independently of args from resolver, since they will be coming from - // different places. Maybe change LB policy API to support that? - void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override {} - - void ExitIdleLocked() override; - - void ResetBackoffLocked() override; - - void FillChildRefsForChannelz( - channelz::ChildRefsList* child_subchannels, - channelz::ChildRefsList* child_channels) override; - - private: - using TraceStringVector = InlinedVector; - - class ResolvingControlHelper; - - ~ResolvingLoadBalancingPolicy(); - - grpc_error* Init(const grpc_channel_args& args); - void ShutdownLocked() override; - - void StartResolvingLocked(); - void OnResolverShutdownLocked(grpc_error* error); - void CreateNewLbPolicyLocked(const char* lb_policy_name, grpc_json* lb_config, - TraceStringVector* trace_strings); - void MaybeAddTraceMessagesForAddressChangesLocked( - TraceStringVector* trace_strings); - void ConcatenateAndAddChannelTraceLocked( - TraceStringVector* trace_strings) const; - static void OnResolverResultChangedLocked(void* arg, grpc_error* error); - - // Passed in from caller at construction time. - TraceFlag* tracer_; - UniquePtr target_uri_; - ProcessResolverResultCallback process_resolver_result_ = nullptr; - void* process_resolver_result_user_data_ = nullptr; - UniquePtr child_policy_name_; - UniquePtr child_lb_config_str_; - grpc_json* child_lb_config_ = nullptr; - - // Resolver and associated state. - OrphanablePtr resolver_; - bool started_resolving_ = false; - grpc_channel_args* resolver_result_ = nullptr; - bool previous_resolution_contained_addresses_ = false; - grpc_closure on_resolver_result_changed_; - - // Child LB policy and associated state. - OrphanablePtr lb_policy_; -}; - -} // namespace grpc_core - -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H */ diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index e2e19a32fd6..1a07edad09c 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -956,17 +956,22 @@ void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) { } else if (c->disconnected_) { GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } else { - const char* errmsg = grpc_error_string(error); - gpr_log(GPR_INFO, "Connect failed: %s", errmsg); - error = + c->SetConnectivityStateLocked( + GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Connect Failed", &error, 1), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); - c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(error), "connect_failed"); - grpc_connectivity_state_set(&c->state_and_health_tracker_, - GRPC_CHANNEL_TRANSIENT_FAILURE, error, - "connect_failed"); + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), + "connect_failed"); + grpc_connectivity_state_set( + &c->state_and_health_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, + grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Connect Failed", &error, 1), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), + "connect_failed"); + + const char* errmsg = grpc_error_string(error); + gpr_log(GPR_INFO, "Connect failed: %s", errmsg); + c->MaybeStartConnectingLocked(); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h index dda5026cbca..9053c60111f 100644 --- a/src/core/lib/gprpp/orphanable.h +++ b/src/core/lib/gprpp/orphanable.h @@ -94,9 +94,8 @@ class InternallyRefCounted : public Orphanable { // Note: RefCount tracing is only enabled on debug builds, even when a // TraceFlag is used. template - explicit InternallyRefCounted(TraceFlagT* trace_flag = nullptr, - intptr_t initial_refcount = 1) - : refs_(initial_refcount, trace_flag) {} + explicit InternallyRefCounted(TraceFlagT* trace_flag = nullptr) + : refs_(1, trace_flag) {} virtual ~InternallyRefCounted() = default; RefCountedPtr Ref() GRPC_MUST_USE_RESULT { diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index 761b77baf58..fa97ffcfed2 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -221,9 +221,8 @@ class RefCounted : public Impl { // Note: RefCount tracing is only enabled on debug builds, even when a // TraceFlag is used. template - explicit RefCounted(TraceFlagT* trace_flag = nullptr, - intptr_t initial_refcount = 1) - : refs_(initial_refcount, trace_flag) {} + explicit RefCounted(TraceFlagT* trace_flag = nullptr) + : refs_(1, trace_flag) {} // Note: Depending on the Impl used, this dtor can be implicitly virtual. ~RefCounted() = default; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index a9d045281ec..71de0c4abe0 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -329,10 +329,10 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', + 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', - 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', diff --git a/test/core/channel/channel_stack_builder_test.cc b/test/core/channel/channel_stack_builder_test.cc index efe616ab7fd..b5598e63f9f 100644 --- a/test/core/channel/channel_stack_builder_test.cc +++ b/test/core/channel/channel_stack_builder_test.cc @@ -45,6 +45,16 @@ static void call_destroy_func(grpc_call_element* elem, const grpc_call_final_info* final_info, grpc_closure* ignored) {} +static void call_func(grpc_call_element* elem, + grpc_transport_stream_op_batch* op) {} + +static void channel_func(grpc_channel_element* elem, grpc_transport_op* op) { + if (op->disconnect_with_error != GRPC_ERROR_NONE) { + GRPC_ERROR_UNREF(op->disconnect_with_error); + } + GRPC_CLOSURE_SCHED(op->on_consumed, GRPC_ERROR_NONE); +} + bool g_replacement_fn_called = false; bool g_original_fn_called = false; void set_arg_once_fn(grpc_channel_stack* channel_stack, @@ -67,8 +77,8 @@ static void test_channel_stack_builder_filter_replace(void) { } const grpc_channel_filter replacement_filter = { - grpc_call_next_op, - grpc_channel_next_op, + call_func, + channel_func, 0, call_init_func, grpc_call_stack_ignore_set_pollset_or_pollset_set, @@ -80,8 +90,8 @@ const grpc_channel_filter replacement_filter = { "filter_name"}; const grpc_channel_filter original_filter = { - grpc_call_next_op, - grpc_channel_next_op, + call_func, + channel_func, 0, call_init_func, grpc_call_stack_ignore_set_pollset_or_pollset_set, diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 77b354740e5..d6d072101ac 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -48,19 +48,25 @@ namespace { // A minimal forwarding class to avoid implementing a standalone test LB. class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { public: - ForwardingLoadBalancingPolicy( - UniquePtr delegating_helper, Args args, - const std::string& delegate_policy_name, intptr_t initial_refcount = 1) - : LoadBalancingPolicy(std::move(args), initial_refcount) { + ForwardingLoadBalancingPolicy(Args args, + const std::string& delegate_policy_name) + : LoadBalancingPolicy(std::move(args)) { Args delegate_args; delegate_args.combiner = combiner(); - delegate_args.channel_control_helper = std::move(delegating_helper); + delegate_args.client_channel_factory = client_channel_factory(); + delegate_args.subchannel_pool = subchannel_pool()->Ref(); delegate_args.args = args.args; delegate_args.lb_config = args.lb_config; delegate_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( delegate_policy_name.c_str(), std::move(delegate_args)); grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), interested_parties()); + // Give re-resolution closure to delegate. + GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, + OnDelegateRequestReresolutionLocked, this, + grpc_combiner_scheduler(combiner())); + Ref().release(); // held by callback. + delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); } ~ForwardingLoadBalancingPolicy() override = default; @@ -70,6 +76,35 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { delegate_->UpdateLocked(args, lb_config); } + bool PickLocked(PickState* pick, grpc_error** error) override { + return delegate_->PickLocked(pick, error); + } + + void CancelPickLocked(PickState* pick, grpc_error* error) override { + delegate_->CancelPickLocked(pick, error); + } + + void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq, + grpc_error* error) override { + delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, + initial_metadata_flags_eq, error); + } + + void NotifyOnStateChangeLocked(grpc_connectivity_state* state, + grpc_closure* closure) override { + delegate_->NotifyOnStateChangeLocked(state, closure); + } + + grpc_connectivity_state CheckConnectivityLocked( + grpc_error** connectivity_error) override { + return delegate_->CheckConnectivityLocked(connectivity_error); + } + + void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { + delegate_->HandOffPendingPicksLocked(new_policy); + } + void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } @@ -81,9 +116,26 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { } private: - void ShutdownLocked() override { delegate_.reset(); } + void ShutdownLocked() override { + delegate_.reset(); + TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_CANCELLED); + } + + static void OnDelegateRequestReresolutionLocked(void* arg, + grpc_error* error) { + ForwardingLoadBalancingPolicy* self = + static_cast(arg); + if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { + self->Unref(); + return; + } + self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); + self->delegate_->SetReresolutionClosureLocked( + &self->on_delegate_request_reresolution_); + } OrphanablePtr delegate_; + grpc_closure on_delegate_request_reresolution_; }; // @@ -98,13 +150,10 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy public: InterceptRecvTrailingMetadataLoadBalancingPolicy( Args args, InterceptRecvTrailingMetadataCallback cb, void* user_data) - : ForwardingLoadBalancingPolicy( - UniquePtr(New( - RefCountedPtr( - this), - cb, user_data)), - std::move(args), /*delegate_lb_policy_name=*/"pick_first", - /*initial_refcount=*/2) {} + : ForwardingLoadBalancingPolicy(std::move(args), + /*delegate_lb_policy_name=*/"pick_first"), + cb_(cb), + user_data_(user_data) {} ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; @@ -112,65 +161,17 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy return kInterceptRecvTrailingMetadataLbPolicyName; } + bool PickLocked(PickState* pick, grpc_error** error) override { + bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); + // Note: This assumes that the delegate policy does not + // intercepting recv_trailing_metadata. If we ever need to use + // this with a delegate policy that does, then we'll need to + // handle async pick returns separately. + New(pick, cb_, user_data_); // deletes itself + return ret; + } + private: - class Picker : public SubchannelPicker { - public: - explicit Picker(UniquePtr delegate_picker, - InterceptRecvTrailingMetadataCallback cb, void* user_data) - : delegate_picker_(std::move(delegate_picker)), - cb_(cb), - user_data_(user_data) {} - - PickResult Pick(PickState* pick, grpc_error** error) override { - PickResult result = delegate_picker_->Pick(pick, error); - if (result == PICK_COMPLETE && pick->connected_subchannel != nullptr) { - New(pick, cb_, user_data_); // deletes itself - } - return result; - } - - private: - UniquePtr delegate_picker_; - InterceptRecvTrailingMetadataCallback cb_; - void* user_data_; - }; - - class Helper : public ChannelControlHelper { - public: - Helper( - RefCountedPtr parent, - InterceptRecvTrailingMetadataCallback cb, void* user_data) - : parent_(std::move(parent)), cb_(cb), user_data_(user_data) {} - - Subchannel* CreateSubchannel(const grpc_channel_args& args) override { - return parent_->channel_control_helper()->CreateSubchannel(args); - } - - grpc_channel* CreateChannel(const char* target, - grpc_client_channel_type type, - const grpc_channel_args& args) override { - return parent_->channel_control_helper()->CreateChannel(target, type, - args); - } - - void UpdateState(grpc_connectivity_state state, grpc_error* state_error, - UniquePtr picker) override { - parent_->channel_control_helper()->UpdateState( - state, state_error, - UniquePtr( - New(std::move(picker), cb_, user_data_))); - } - - void RequestReresolution() override { - parent_->channel_control_helper()->RequestReresolution(); - } - - private: - RefCountedPtr parent_; - InterceptRecvTrailingMetadataCallback cb_; - void* user_data_; - }; - class TrailingMetadataHandler { public: TrailingMetadataHandler(PickState* pick, @@ -203,6 +204,9 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; grpc_metadata_batch* recv_trailing_metadata_ = nullptr; }; + + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; }; class InterceptTrailingFactory : public LoadBalancingPolicyFactory { diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index e57650fe5b7..973f47beaf7 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -570,7 +570,6 @@ static void BM_IsolatedFilter(benchmark::State& state) { } gpr_arena_destroy(call_args.arena); grpc_channel_stack_destroy(channel_stack); - grpc_core::ExecCtx::Get()->Flush(); gpr_free(channel_stack); gpr_free(call_stack); diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 3533c7c00c5..d1a2debd7e3 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -936,6 +936,8 @@ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper.h \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.h \ +src/core/ext/filters/client_channel/request_routing.cc \ +src/core/ext/filters/client_channel/request_routing.h \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver.h \ src/core/ext/filters/client_channel/resolver/README.md \ @@ -960,8 +962,6 @@ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_registry.h \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.h \ -src/core/ext/filters/client_channel/resolving_lb_policy.cc \ -src/core/ext/filters/client_channel/resolving_lb_policy.h \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/retry_throttle.h \ src/core/ext/filters/client_channel/server_address.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 823e17dd45a..84d5c45095f 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9968,11 +9968,11 @@ "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", + "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.h", - "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", @@ -10015,6 +10015,8 @@ "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", + "src/core/ext/filters/client_channel/request_routing.cc", + "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.cc", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", @@ -10022,8 +10024,6 @@ "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.cc", "src/core/ext/filters/client_channel/resolver_result_parsing.h", - "src/core/ext/filters/client_channel/resolving_lb_policy.cc", - "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.cc", From aa149fedbb4ba0ef3307abdb5cdcc7aa3f0c6741 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 19 Feb 2019 13:19:24 -0800 Subject: [PATCH 426/814] Revert "Merge pull request #18093 from grpc/revert-17770-lb_policy_picker_api" This reverts commit f327b8370652a14ac112be3c88ab08fcdf1c839a, reversing changes made to b3b5d634231ce2c5c0ec0c557b6844e1a43b482e. --- BUILD | 4 +- CMakeLists.txt | 12 +- Makefile | 12 +- build.yaml | 4 +- config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 2 +- gRPC-Core.podspec | 6 +- grpc.gemspec | 4 +- grpc.gyp | 8 +- package.xml | 4 +- .../filters/client_channel/client_channel.cc | 683 +++++++++---- .../ext/filters/client_channel/lb_policy.cc | 26 +- .../ext/filters/client_channel/lb_policy.h | 298 ++++-- .../client_channel/lb_policy/grpclb/grpclb.cc | 851 ++++++---------- .../lb_policy/grpclb/grpclb_client_stats.cc | 2 +- .../lb_policy/grpclb/grpclb_client_stats.h | 2 +- .../lb_policy/pick_first/pick_first.cc | 228 ++--- .../lb_policy/round_robin/round_robin.cc | 345 ++----- .../lb_policy/subchannel_list.h | 13 +- .../client_channel/lb_policy/xds/xds.cc | 539 +++------- .../filters/client_channel/request_routing.cc | 946 ------------------ .../filters/client_channel/request_routing.h | 181 ---- .../client_channel/resolving_lb_policy.cc | 460 +++++++++ .../client_channel/resolving_lb_policy.h | 137 +++ .../ext/filters/client_channel/subchannel.cc | 23 +- src/core/lib/gprpp/orphanable.h | 5 +- src/core/lib/gprpp/ref_counted.h | 5 +- src/python/grpcio/grpc_core_dependencies.py | 2 +- .../channel/channel_stack_builder_test.cc | 18 +- test/core/util/test_lb_policies.cc | 146 ++- test/cpp/microbenchmarks/bm_call_create.cc | 1 + tools/doxygen/Doxyfile.core.internal | 4 +- .../generated/sources_and_headers.json | 6 +- 34 files changed, 2043 insertions(+), 2938 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/request_routing.cc delete mode 100644 src/core/ext/filters/client_channel/request_routing.h create mode 100644 src/core/ext/filters/client_channel/resolving_lb_policy.cc create mode 100644 src/core/ext/filters/client_channel/resolving_lb_policy.h diff --git a/BUILD b/BUILD index a566057e926..f0de4399beb 100644 --- a/BUILD +++ b/BUILD @@ -1070,10 +1070,10 @@ grpc_cc_library( "src/core/ext/filters/client_channel/parse_address.cc", "src/core/ext/filters/client_channel/proxy_mapper.cc", "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", - "src/core/ext/filters/client_channel/request_routing.cc", "src/core/ext/filters/client_channel/resolver.cc", "src/core/ext/filters/client_channel/resolver_registry.cc", "src/core/ext/filters/client_channel/resolver_result_parsing.cc", + "src/core/ext/filters/client_channel/resolving_lb_policy.cc", "src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/server_address.cc", "src/core/ext/filters/client_channel/subchannel.cc", @@ -1096,11 +1096,11 @@ grpc_cc_library( "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", - "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index f494ef0094c..458e9b88b74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1232,10 +1232,10 @@ add_library(grpc src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -1587,10 +1587,10 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -1965,10 +1965,10 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -2290,10 +2290,10 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -2626,10 +2626,10 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc @@ -3483,10 +3483,10 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/parse_address.cc src/core/ext/filters/client_channel/proxy_mapper.cc src/core/ext/filters/client_channel/proxy_mapper_registry.cc - src/core/ext/filters/client_channel/request_routing.cc src/core/ext/filters/client_channel/resolver.cc src/core/ext/filters/client_channel/resolver_registry.cc src/core/ext/filters/client_channel/resolver_result_parsing.cc + src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/subchannel.cc diff --git a/Makefile b/Makefile index 7cfe37384aa..9d0b37b687a 100644 --- a/Makefile +++ b/Makefile @@ -3758,10 +3758,10 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -4107,10 +4107,10 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -4478,10 +4478,10 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -4790,10 +4790,10 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -5100,10 +5100,10 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ @@ -5934,10 +5934,10 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ diff --git a/build.yaml b/build.yaml index 77ad81ddda2..d347bcd8189 100644 --- a/build.yaml +++ b/build.yaml @@ -587,11 +587,11 @@ filegroups: - src/core/ext/filters/client_channel/parse_address.h - src/core/ext/filters/client_channel/proxy_mapper.h - src/core/ext/filters/client_channel/proxy_mapper_registry.h - - src/core/ext/filters/client_channel/request_routing.h - src/core/ext/filters/client_channel/resolver.h - src/core/ext/filters/client_channel/resolver_factory.h - src/core/ext/filters/client_channel/resolver_registry.h - src/core/ext/filters/client_channel/resolver_result_parsing.h + - src/core/ext/filters/client_channel/resolving_lb_policy.h - src/core/ext/filters/client_channel/retry_throttle.h - src/core/ext/filters/client_channel/server_address.h - src/core/ext/filters/client_channel/subchannel.h @@ -614,10 +614,10 @@ filegroups: - src/core/ext/filters/client_channel/parse_address.cc - src/core/ext/filters/client_channel/proxy_mapper.cc - src/core/ext/filters/client_channel/proxy_mapper_registry.cc - - src/core/ext/filters/client_channel/request_routing.cc - src/core/ext/filters/client_channel/resolver.cc - src/core/ext/filters/client_channel/resolver_registry.cc - src/core/ext/filters/client_channel/resolver_result_parsing.cc + - src/core/ext/filters/client_channel/resolving_lb_policy.cc - src/core/ext/filters/client_channel/retry_throttle.cc - src/core/ext/filters/client_channel/server_address.cc - src/core/ext/filters/client_channel/subchannel.cc diff --git a/config.m4 b/config.m4 index 5746caf694a..2616803d9b0 100644 --- a/config.m4 +++ b/config.m4 @@ -355,10 +355,10 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/parse_address.cc \ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ - src/core/ext/filters/client_channel/request_routing.cc \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ + src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/subchannel.cc \ diff --git a/config.w32 b/config.w32 index 5659d8b8408..64eca2a8472 100644 --- a/config.w32 +++ b/config.w32 @@ -330,10 +330,10 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\parse_address.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " + "src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " + - "src\\core\\ext\\filters\\client_channel\\request_routing.cc " + "src\\core\\ext\\filters\\client_channel\\resolver.cc " + "src\\core\\ext\\filters\\client_channel\\resolver_registry.cc " + "src\\core\\ext\\filters\\client_channel\\resolver_result_parsing.cc " + + "src\\core\\ext\\filters\\client_channel\\resolving_lb_policy.cc " + "src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " + "src\\core\\ext\\filters\\client_channel\\server_address.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 15ce090bd9b..272e41f8223 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -360,11 +360,11 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', - 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', + 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 92626f3e84b..61409e9c133 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -354,11 +354,11 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', - 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', + 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', @@ -801,10 +801,10 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -984,11 +984,11 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/parse_address.h', 'src/core/ext/filters/client_channel/proxy_mapper.h', 'src/core/ext/filters/client_channel/proxy_mapper_registry.h', - 'src/core/ext/filters/client_channel/request_routing.h', 'src/core/ext/filters/client_channel/resolver.h', 'src/core/ext/filters/client_channel/resolver_factory.h', 'src/core/ext/filters/client_channel/resolver_registry.h', 'src/core/ext/filters/client_channel/resolver_result_parsing.h', + 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', 'src/core/ext/filters/client_channel/subchannel.h', diff --git a/grpc.gemspec b/grpc.gemspec index a4e25d7bb22..0ab718a0668 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -288,11 +288,11 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/parse_address.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h ) - s.files += %w( src/core/ext/filters/client_channel/request_routing.h ) s.files += %w( src/core/ext/filters/client_channel/resolver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_factory.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h ) s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.h ) + s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.h ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h ) s.files += %w( src/core/ext/filters/client_channel/server_address.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel.h ) @@ -738,10 +738,10 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/parse_address.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc ) s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.cc ) - s.files += %w( src/core/ext/filters/client_channel/request_routing.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver_registry.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.cc ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc ) s.files += %w( src/core/ext/filters/client_channel/server_address.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel.cc ) diff --git a/grpc.gyp b/grpc.gyp index 113c17f0d09..ca9d017dbbe 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -537,10 +537,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -801,10 +801,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -1046,10 +1046,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', @@ -1302,10 +1302,10 @@ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', diff --git a/package.xml b/package.xml index 7a1d26c47c5..e6b793fd1d1 100644 --- a/package.xml +++ b/package.xml @@ -293,11 +293,11 @@ - + @@ -743,10 +743,10 @@ - + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 38525dbf97e..6de27369ea4 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -32,12 +32,14 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" -#include "src/core/ext/filters/client_channel/request_routing.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" +#include "src/core/ext/filters/client_channel/resolving_lb_policy.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/deadline/deadline_filter.h" @@ -68,6 +70,8 @@ using grpc_core::internal::ClientChannelMethodParamsTable; using grpc_core::internal::ProcessedResolverResult; using grpc_core::internal::ServerRetryThrottleData; +using grpc_core::LoadBalancingPolicy; + /* Client channel implementation */ // By default, we buffer 256 KiB per RPC for retries. @@ -86,44 +90,171 @@ grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel"); struct external_connectivity_watcher; -typedef struct client_channel_channel_data { - grpc_core::ManualConstructor request_router; +struct QueuedPick { + LoadBalancingPolicy::PickState pick; + grpc_call_element* elem; + QueuedPick* next = nullptr; +}; +typedef struct client_channel_channel_data { bool deadline_checking_enabled; bool enable_retries; size_t per_rpc_retry_buffer_size; /** combiner protecting all variables below in this data structure */ grpc_combiner* combiner; - /** retry throttle data */ - grpc_core::RefCountedPtr retry_throttle_data; - /** maps method names to method_parameters structs */ - grpc_core::RefCountedPtr method_params_table; /** owning stack */ grpc_channel_stack* owning_stack; /** interested parties (owned) */ grpc_pollset_set* interested_parties; + // Client channel factory. Holds a ref. + grpc_client_channel_factory* client_channel_factory; + // Subchannel pool. + grpc_core::RefCountedPtr subchannel_pool; - /* external_connectivity_watcher_list head is guarded by its own mutex, since - * counts need to be grabbed immediately without polling on a cq */ - gpr_mu external_connectivity_watcher_list_mu; - struct external_connectivity_watcher* external_connectivity_watcher_list_head; + grpc_core::channelz::ClientChannelNode* channelz_node; + + // Resolving LB policy. + grpc_core::OrphanablePtr resolving_lb_policy; + // Subchannel picker from LB policy. + grpc_core::UniquePtr picker; + // Linked list of queued picks. + QueuedPick* queued_picks; + + bool have_service_config; + /** retry throttle data from service config */ + grpc_core::RefCountedPtr retry_throttle_data; + /** per-method service config data */ + grpc_core::RefCountedPtr method_params_table; /* the following properties are guarded by a mutex since APIs require them to be instantaneously available */ gpr_mu info_mu; grpc_core::UniquePtr info_lb_policy_name; - /** service config in JSON form */ grpc_core::UniquePtr info_service_config_json; + + grpc_connectivity_state_tracker state_tracker; + grpc_error* disconnect_error; + + /* external_connectivity_watcher_list head is guarded by its own mutex, since + * counts need to be grabbed immediately without polling on a cq */ + gpr_mu external_connectivity_watcher_list_mu; + struct external_connectivity_watcher* external_connectivity_watcher_list_head; } channel_data; -// Synchronous callback from chand->request_router to process a resolver +// Forward declarations. +static void start_pick_locked(void* arg, grpc_error* ignored); +static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem); + +static const char* get_channel_connectivity_state_change_string( + grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "Channel state change to IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "Channel state change to CONNECTING"; + case GRPC_CHANNEL_READY: + return "Channel state change to READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "Channel state change to TRANSIENT_FAILURE"; + case GRPC_CHANNEL_SHUTDOWN: + return "Channel state change to SHUTDOWN"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +static void set_connectivity_state_and_picker_locked( + channel_data* chand, grpc_connectivity_state state, grpc_error* state_error, + const char* reason, + grpc_core::UniquePtr picker) { + // Update connectivity state. + grpc_connectivity_state_set(&chand->state_tracker, state, state_error, + reason); + if (chand->channelz_node != nullptr) { + chand->channelz_node->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + get_channel_connectivity_state_change_string(state))); + } + // Update picker. + chand->picker = std::move(picker); + // Re-process queued picks. + for (QueuedPick* pick = chand->queued_picks; pick != nullptr; + pick = pick->next) { + start_pick_locked(pick->elem, GRPC_ERROR_NONE); + } +} + +namespace grpc_core { +namespace { + +class ClientChannelControlHelper + : public LoadBalancingPolicy::ChannelControlHelper { + public: + explicit ClientChannelControlHelper(channel_data* chand) : chand_(chand) { + GRPC_CHANNEL_STACK_REF(chand_->owning_stack, "ClientChannelControlHelper"); + } + + ~ClientChannelControlHelper() override { + GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack, + "ClientChannelControlHelper"); + } + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + grpc_arg arg = SubchannelPoolInterface::CreateChannelArg( + chand_->subchannel_pool.get()); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(&args, &arg, 1); + Subchannel* subchannel = grpc_client_channel_factory_create_subchannel( + chand_->client_channel_factory, new_args); + grpc_channel_args_destroy(new_args); + return subchannel; + } + + grpc_channel* CreateChannel(const char* target, grpc_client_channel_type type, + const grpc_channel_args& args) override { + return grpc_client_channel_factory_create_channel( + chand_->client_channel_factory, target, type, &args); + } + + void UpdateState( + grpc_connectivity_state state, grpc_error* state_error, + UniquePtr picker) override { + if (grpc_client_channel_trace.enabled()) { + const char* extra = chand_->disconnect_error == GRPC_ERROR_NONE + ? "" + : " (ignoring -- channel shutting down)"; + gpr_log(GPR_INFO, "chand=%p: update: state=%s error=%s picker=%p%s", + chand_, grpc_connectivity_state_name(state), + grpc_error_string(state_error), picker.get(), extra); + } + // Do update only if not shutting down. + if (chand_->disconnect_error == GRPC_ERROR_NONE) { + set_connectivity_state_and_picker_locked(chand_, state, state_error, + "helper", std::move(picker)); + } else { + GRPC_ERROR_UNREF(state_error); + } + } + + // No-op -- we should never get this from ResolvingLoadBalancingPolicy. + void RequestReresolution() override {} + + private: + channel_data* chand_; +}; + +} // namespace +} // namespace grpc_core + +// Synchronous callback from chand->resolving_lb_policy to process a resolver // result update. static bool process_resolver_result_locked(void* arg, const grpc_channel_args& args, const char** lb_policy_name, grpc_json** lb_policy_config) { channel_data* chand = static_cast(arg); + chand->have_service_config = true; ProcessedResolverResult resolver_result(args, chand->enable_retries); grpc_core::UniquePtr service_config_json = resolver_result.service_config_json(); @@ -148,9 +279,38 @@ static bool process_resolver_result_locked(void* arg, // Return results. *lb_policy_name = chand->info_lb_policy_name.get(); *lb_policy_config = resolver_result.lb_policy_config(); + // Apply service config to queued picks. + for (QueuedPick* pick = chand->queued_picks; pick != nullptr; + pick = pick->next) { + maybe_apply_service_config_to_call_locked(pick->elem); + } return service_config_changed; } +static grpc_error* do_ping_locked(channel_data* chand, grpc_transport_op* op) { + grpc_error* error = GRPC_ERROR_NONE; + grpc_connectivity_state state = + grpc_connectivity_state_get(&chand->state_tracker, &error); + if (state != GRPC_CHANNEL_READY) { + grpc_error* new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "channel not connected", &error, 1); + GRPC_ERROR_UNREF(error); + return new_error; + } + LoadBalancingPolicy::PickState pick; + chand->picker->Pick(&pick, &error); + if (pick.connected_subchannel != nullptr) { + pick.connected_subchannel->Ping(op->send_ping.on_initiate, + op->send_ping.on_ack); + } else { + if (error == GRPC_ERROR_NONE) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "LB policy dropped call on ping"); + } + } + return error; +} + static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { grpc_transport_op* op = static_cast(arg); grpc_channel_element* elem = @@ -158,47 +318,40 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { channel_data* chand = static_cast(elem->channel_data); if (op->on_connectivity_state_change != nullptr) { - chand->request_router->NotifyOnConnectivityStateChange( - op->connectivity_state, op->on_connectivity_state_change); + grpc_connectivity_state_notify_on_state_change( + &chand->state_tracker, op->connectivity_state, + op->on_connectivity_state_change); op->on_connectivity_state_change = nullptr; op->connectivity_state = nullptr; } if (op->send_ping.on_initiate != nullptr || op->send_ping.on_ack != nullptr) { - if (chand->request_router->lb_policy() == nullptr) { - grpc_error* error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"); + grpc_error* error = do_ping_locked(chand, op); + if (error != GRPC_ERROR_NONE) { GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error)); GRPC_CLOSURE_SCHED(op->send_ping.on_ack, error); - } else { - grpc_error* error = GRPC_ERROR_NONE; - grpc_core::LoadBalancingPolicy::PickState pick_state; - // Pick must return synchronously, because pick_state.on_complete is null. - GPR_ASSERT( - chand->request_router->lb_policy()->PickLocked(&pick_state, &error)); - if (pick_state.connected_subchannel != nullptr) { - pick_state.connected_subchannel->Ping(op->send_ping.on_initiate, - op->send_ping.on_ack); - } else { - if (error == GRPC_ERROR_NONE) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "LB policy dropped call on ping"); - } - GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error)); - GRPC_CLOSURE_SCHED(op->send_ping.on_ack, error); - } - op->bind_pollset = nullptr; } + op->bind_pollset = nullptr; op->send_ping.on_initiate = nullptr; op->send_ping.on_ack = nullptr; } - if (op->disconnect_with_error != GRPC_ERROR_NONE) { - chand->request_router->ShutdownLocked(op->disconnect_with_error); + if (op->reset_connect_backoff) { + chand->resolving_lb_policy->ResetBackoffLocked(); } - if (op->reset_connect_backoff) { - chand->request_router->ResetConnectionBackoffLocked(); + if (op->disconnect_with_error != GRPC_ERROR_NONE) { + chand->disconnect_error = op->disconnect_with_error; + grpc_pollset_set_del_pollset_set( + chand->resolving_lb_policy->interested_parties(), + chand->interested_parties); + chand->resolving_lb_policy.reset(); + set_connectivity_state_and_picker_locked( + chand, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(op->disconnect_with_error), + "shutdown from API", + grpc_core::UniquePtr( + grpc_core::New( + GRPC_ERROR_REF(op->disconnect_with_error)))); } GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "start_transport_op"); @@ -244,6 +397,9 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, GPR_ASSERT(elem->filter == &grpc_client_channel_filter); // Initialize data members. chand->combiner = grpc_combiner_create(); + grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, + "client_channel"); + chand->disconnect_error = GRPC_ERROR_NONE; gpr_mu_init(&chand->info_mu); gpr_mu_init(&chand->external_connectivity_watcher_list_mu); @@ -275,8 +431,9 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "client channel factory arg must be a pointer"); } - grpc_client_channel_factory* client_channel_factory = + chand->client_channel_factory = static_cast(arg->value.pointer.p); + grpc_client_channel_factory_ref(chand->client_channel_factory); // Get server name to resolve, using proxy mapper if needed. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI); if (arg == nullptr) { @@ -291,26 +448,71 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, grpc_channel_args* new_args = nullptr; grpc_proxy_mappers_map_name(arg->value.string, args->channel_args, &proxy_name, &new_args); - // Instantiate request router. - grpc_client_channel_factory_ref(client_channel_factory); + grpc_core::UniquePtr target_uri( + proxy_name != nullptr ? proxy_name : gpr_strdup(arg->value.string)); + // Instantiate subchannel pool. + arg = grpc_channel_args_find(args->channel_args, + GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL); + if (grpc_channel_arg_get_bool(arg, false)) { + chand->subchannel_pool = + grpc_core::MakeRefCounted(); + } else { + chand->subchannel_pool = grpc_core::GlobalSubchannelPool::instance(); + } + // Instantiate resolving LB policy. + LoadBalancingPolicy::Args lb_args; + lb_args.combiner = chand->combiner; + lb_args.channel_control_helper = + grpc_core::UniquePtr( + grpc_core::New(chand)); + lb_args.args = new_args != nullptr ? new_args : args->channel_args; grpc_error* error = GRPC_ERROR_NONE; - chand->request_router.Init( - chand->owning_stack, chand->combiner, client_channel_factory, - chand->interested_parties, &grpc_client_channel_trace, - process_resolver_result_locked, chand, - proxy_name != nullptr ? proxy_name : arg->value.string /* target_uri */, - new_args != nullptr ? new_args : args->channel_args, &error); - gpr_free(proxy_name); + chand->resolving_lb_policy.reset( + grpc_core::New( + std::move(lb_args), &grpc_client_channel_trace, std::move(target_uri), + process_resolver_result_locked, chand, &error)); grpc_channel_args_destroy(new_args); + if (error != GRPC_ERROR_NONE) { + // Orphan the resolving LB policy and flush the exec_ctx to ensure + // that it finishes shutting down. This ensures that if we are + // failing, we destroy the ClientChannelControlHelper (and thus + // unref the channel stack) before we return. + // TODO(roth): This is not a complete solution, because it only + // catches the case where channel stack initialization fails in this + // particular filter. If there is a failure in a different filter, we + // will leave a dangling ref here, which can cause a crash. Fortunately, + // in practice, there are no other filters that can cause failures in + // channel stack initialization, so this works for now. + chand->resolving_lb_policy.reset(); + grpc_core::ExecCtx::Get()->Flush(); + } else { + grpc_pollset_set_add_pollset_set( + chand->resolving_lb_policy->interested_parties(), + chand->interested_parties); + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", chand, + chand->resolving_lb_policy.get()); + } + } return error; } /* Destructor for channel_data */ static void cc_destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); - chand->request_router.Destroy(); + if (chand->resolving_lb_policy != nullptr) { + grpc_pollset_set_del_pollset_set( + chand->resolving_lb_policy->interested_parties(), + chand->interested_parties); + chand->resolving_lb_policy.reset(); + } // TODO(roth): Once we convert the filter API to C++, there will no // longer be any need to explicitly reset these smart pointer data members. + chand->picker.reset(); + chand->subchannel_pool.reset(); + if (chand->client_channel_factory != nullptr) { + grpc_client_channel_factory_unref(chand->client_channel_factory); + } chand->info_lb_policy_name.reset(); chand->info_service_config_json.reset(); chand->retry_throttle_data.reset(); @@ -318,6 +520,8 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { grpc_client_channel_stop_backup_polling(chand->interested_parties); grpc_pollset_set_destroy(chand->interested_parties); GRPC_COMBINER_UNREF(chand->combiner, "client_channel"); + GRPC_ERROR_UNREF(chand->disconnect_error); + grpc_connectivity_state_destroy(&chand->state_tracker); gpr_mu_destroy(&chand->info_mu); gpr_mu_destroy(&chand->external_connectivity_watcher_list_mu); } @@ -371,6 +575,12 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { // (census filter is on top of this one) // - add census stats for retries +namespace grpc_core { +namespace { +class QueuedPickCanceller; +} // namespace +} // namespace grpc_core + namespace { struct call_data; @@ -509,8 +719,11 @@ struct call_data { for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches); ++i) { GPR_ASSERT(pending_batches[i].batch == nullptr); } - if (have_request) { - request.Destroy(); + for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) { + if (pick.pick.subchannel_call_context[i].destroy != nullptr) { + pick.pick.subchannel_call_context[i].destroy( + pick.pick.subchannel_call_context[i].value); + } } } @@ -537,8 +750,10 @@ struct call_data { // Set when we get a cancel_stream op. grpc_error* cancel_error = GRPC_ERROR_NONE; - grpc_core::ManualConstructor request; - bool have_request = false; + QueuedPick pick; + bool pick_queued = false; + bool service_config_applied = false; + grpc_core::QueuedPickCanceller* pick_canceller = nullptr; grpc_closure pick_closure; grpc_polling_entity* pollent = nullptr; @@ -600,7 +815,7 @@ static void retry_commit(grpc_call_element* elem, static void start_internal_recv_trailing_metadata(grpc_call_element* elem); static void on_complete(void* arg, grpc_error* error); static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored); -static void start_pick_locked(void* arg, grpc_error* ignored); +static void remove_call_from_queued_picks_locked(grpc_call_element* elem); // // send op data caching @@ -728,7 +943,7 @@ static void free_cached_send_op_data_for_completed_batch( // void maybe_inject_recv_trailing_metadata_ready_for_lb( - const grpc_core::LoadBalancingPolicy::PickState& pick, + const LoadBalancingPolicy::PickState& pick, grpc_transport_stream_op_batch* batch) { if (pick.recv_trailing_metadata_ready != nullptr) { *pick.original_recv_trailing_metadata_ready = @@ -846,10 +1061,25 @@ static void fail_pending_batch_in_call_combiner(void* arg, grpc_error* error) { } // This is called via the call combiner, so access to calld is synchronized. -// If yield_call_combiner is true, assumes responsibility for yielding -// the call combiner. -static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, - bool yield_call_combiner) { +// If yield_call_combiner_predicate returns true, assumes responsibility for +// yielding the call combiner. +typedef bool (*YieldCallCombinerPredicate)( + const grpc_core::CallCombinerClosureList& closures); +static bool yield_call_combiner( + const grpc_core::CallCombinerClosureList& closures) { + return true; +} +static bool no_yield_call_combiner( + const grpc_core::CallCombinerClosureList& closures) { + return false; +} +static bool yield_call_combiner_if_pending_batches_found( + const grpc_core::CallCombinerClosureList& closures) { + return closures.size() > 0; +} +static void pending_batches_fail( + grpc_call_element* elem, grpc_error* error, + YieldCallCombinerPredicate yield_call_combiner_predicate) { GPR_ASSERT(error != GRPC_ERROR_NONE); call_data* calld = static_cast(elem->call_data); if (grpc_client_channel_trace.enabled()) { @@ -866,9 +1096,9 @@ static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { - if (batch->recv_trailing_metadata && calld->have_request) { - maybe_inject_recv_trailing_metadata_ready_for_lb( - *calld->request->pick(), batch); + if (batch->recv_trailing_metadata) { + maybe_inject_recv_trailing_metadata_ready_for_lb(calld->pick.pick, + batch); } batch->handler_private.extra_arg = calld; GRPC_CLOSURE_INIT(&batch->handler_private.closure, @@ -879,7 +1109,7 @@ static void pending_batches_fail(grpc_call_element* elem, grpc_error* error, pending_batch_clear(calld, pending); } } - if (yield_call_combiner) { + if (yield_call_combiner_predicate(closures)) { closures.RunClosures(calld->call_combiner); } else { closures.RunClosuresWithoutYielding(calld->call_combiner); @@ -923,8 +1153,8 @@ static void pending_batches_resume(grpc_call_element* elem) { grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { if (batch->recv_trailing_metadata) { - maybe_inject_recv_trailing_metadata_ready_for_lb( - *calld->request->pick(), batch); + maybe_inject_recv_trailing_metadata_ready_for_lb(calld->pick.pick, + batch); } batch->handler_private.extra_arg = calld->subchannel_call.get(); GRPC_CLOSURE_INIT(&batch->handler_private.closure, @@ -1015,11 +1245,9 @@ static void do_retry(grpc_call_element* elem, const ClientChannelMethodParams::RetryPolicy* retry_policy = calld->method_params->retry_policy(); GPR_ASSERT(retry_policy != nullptr); + // Reset subchannel call and connected subchannel. calld->subchannel_call.reset(); - if (calld->have_request) { - calld->have_request = false; - calld->request.Destroy(); - } + calld->pick.pick.connected_subchannel.reset(); // Compute backoff delay. grpc_millis next_attempt_time; if (server_pushback_ms >= 0) { @@ -1938,7 +2166,7 @@ static void add_retriable_recv_trailing_metadata_op( batch_data->batch.payload->recv_trailing_metadata .recv_trailing_metadata_ready = &retry_state->recv_trailing_metadata_ready; - maybe_inject_recv_trailing_metadata_ready_for_lb(*calld->request->pick(), + maybe_inject_recv_trailing_metadata_ready_for_lb(calld->pick.pick, &batch_data->batch); } @@ -2207,41 +2435,38 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { // LB pick // -static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { +static void create_subchannel_call(grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); const size_t parent_data_size = calld->enable_retries ? sizeof(subchannel_call_retry_state) : 0; const grpc_core::ConnectedSubchannel::CallArgs call_args = { - calld->pollent, // pollent - calld->path, // path - calld->call_start_time, // start_time - calld->deadline, // deadline - calld->arena, // arena - calld->request->pick()->subchannel_call_context, // context - calld->call_combiner, // call_combiner - parent_data_size // parent_data_size + calld->pollent, // pollent + calld->path, // path + calld->call_start_time, // start_time + calld->deadline, // deadline + calld->arena, // arena + calld->pick.pick.subchannel_call_context, // context + calld->call_combiner, // call_combiner + parent_data_size // parent_data_size }; - grpc_error* new_error = GRPC_ERROR_NONE; + grpc_error* error = GRPC_ERROR_NONE; calld->subchannel_call = - calld->request->pick()->connected_subchannel->CreateCall(call_args, - &new_error); + calld->pick.pick.connected_subchannel->CreateCall(call_args, &error); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, calld, calld->subchannel_call.get(), - grpc_error_string(new_error)); + grpc_error_string(error)); } - if (GPR_UNLIKELY(new_error != GRPC_ERROR_NONE)) { - new_error = grpc_error_add_child(new_error, error); - pending_batches_fail(elem, new_error, true /* yield_call_combiner */); + if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { + pending_batches_fail(elem, error, yield_call_combiner); } else { if (parent_data_size > 0) { - new (calld->subchannel_call->GetParentData()) subchannel_call_retry_state( - calld->request->pick()->subchannel_call_context); + new (calld->subchannel_call->GetParentData()) + subchannel_call_retry_state(calld->pick.pick.subchannel_call_context); } pending_batches_resume(elem); } - GRPC_ERROR_UNREF(error); } // Invoked when a pick is completed, on both success or failure. @@ -2249,54 +2474,106 @@ static void pick_done(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (GPR_UNLIKELY(calld->request->pick()->connected_subchannel == nullptr)) { - // Failed to create subchannel. - // If there was no error, this is an LB policy drop, in which case - // we return an error; otherwise, we may retry. - grpc_status_code status = GRPC_STATUS_OK; - grpc_error_get_status(error, calld->deadline, &status, nullptr, nullptr, - nullptr); - if (error == GRPC_ERROR_NONE || !calld->enable_retries || - !maybe_retry(elem, nullptr /* batch_data */, status, - nullptr /* server_pushback_md */)) { - grpc_error* new_error = - error == GRPC_ERROR_NONE - ? GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Call dropped by load balancing policy") - : GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Failed to create subchannel", &error, 1); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: failed to create subchannel: error=%s", - chand, calld, grpc_error_string(new_error)); - } - pending_batches_fail(elem, new_error, true /* yield_call_combiner */); + if (error != GRPC_ERROR_NONE) { + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: failed to pick subchannel: error=%s", chand, + calld, grpc_error_string(error)); + } + pending_batches_fail(elem, GRPC_ERROR_REF(error), yield_call_combiner); + return; + } + create_subchannel_call(elem); +} + +namespace grpc_core { +namespace { + +// A class to handle the call combiner cancellation callback for a +// queued pick. +class QueuedPickCanceller { + public: + explicit QueuedPickCanceller(grpc_call_element* elem) : elem_(elem) { + auto* calld = static_cast(elem->call_data); + auto* chand = static_cast(elem->channel_data); + GRPC_CALL_STACK_REF(calld->owning_call, "QueuedPickCanceller"); + GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this, + grpc_combiner_scheduler(chand->combiner)); + grpc_call_combiner_set_notify_on_cancel(calld->call_combiner, &closure_); + } + + private: + static void CancelLocked(void* arg, grpc_error* error) { + auto* self = static_cast(arg); + auto* chand = static_cast(self->elem_->channel_data); + auto* calld = static_cast(self->elem_->call_data); + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: cancelling queued pick: " + "error=%s self=%p calld->pick_canceller=%p", + chand, calld, grpc_error_string(error), self, + calld->pick_canceller); + } + if (calld->pick_canceller == self && error != GRPC_ERROR_NONE) { + // Remove pick from list of queued picks. + remove_call_from_queued_picks_locked(self->elem_); + // Fail pending batches on the call. + pending_batches_fail(self->elem_, GRPC_ERROR_REF(error), + yield_call_combiner_if_pending_batches_found); + } + GRPC_CALL_STACK_UNREF(calld->owning_call, "QueuedPickCanceller"); + Delete(self); + } + + grpc_call_element* elem_; + grpc_closure closure_; +}; + +} // namespace +} // namespace grpc_core + +// Removes the call from the channel's list of queued picks. +static void remove_call_from_queued_picks_locked(grpc_call_element* elem) { + auto* chand = static_cast(elem->channel_data); + auto* calld = static_cast(elem->call_data); + for (QueuedPick** pick = &chand->queued_picks; *pick != nullptr; + pick = &(*pick)->next) { + if (*pick == &calld->pick) { + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, "chand=%p calld=%p: removing from queued picks list", + chand, calld); + } + calld->pick_queued = false; + *pick = calld->pick.next; + // Remove call's pollent from channel's interested_parties. + grpc_polling_entity_del_from_pollset_set(calld->pollent, + chand->interested_parties); + // Lame the call combiner canceller. + calld->pick_canceller = nullptr; + break; } - } else { - /* Create call on subchannel. */ - create_subchannel_call(elem, GRPC_ERROR_REF(error)); } } -// If the channel is in TRANSIENT_FAILURE and the call is not -// wait_for_ready=true, fails the call and returns true. -static bool fail_call_if_in_transient_failure(grpc_call_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - grpc_transport_stream_op_batch* batch = calld->pending_batches[0].batch; - if (chand->request_router->GetConnectivityState() == - GRPC_CHANNEL_TRANSIENT_FAILURE && - (batch->payload->send_initial_metadata.send_initial_metadata_flags & - GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) { - pending_batches_fail( - elem, - grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "channel is in state TRANSIENT_FAILURE"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), - true /* yield_call_combiner */); - return true; +// Adds the call to the channel's list of queued picks. +static void add_call_to_queued_picks_locked(grpc_call_element* elem) { + auto* chand = static_cast(elem->channel_data); + auto* calld = static_cast(elem->call_data); + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, "chand=%p calld=%p: adding to queued picks list", chand, + calld); } - return false; + calld->pick_queued = true; + // Add call to queued picks list. + calld->pick.elem = elem; + calld->pick.next = chand->queued_picks; + chand->queued_picks = &calld->pick; + // Add call's pollent to channel's interested_parties, so that I/O + // can be done under the call's CQ. + grpc_polling_entity_add_to_pollset_set(calld->pollent, + chand->interested_parties); + // Register call combiner cancellation callback. + calld->pick_canceller = grpc_core::New(elem); } // Applies service config to the call. Must be invoked once we know @@ -2356,36 +2633,37 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) { } // Invoked once resolver results are available. -static bool maybe_apply_service_config_to_call_locked(void* arg) { - grpc_call_element* elem = static_cast(arg); +static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem) { + channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - // Only get service config data on the first attempt. - if (GPR_LIKELY(calld->num_attempts_completed == 0)) { + // Apply service config data to the call only once, and only if the + // channel has the data available. + if (GPR_LIKELY(chand->have_service_config && + !calld->service_config_applied)) { + calld->service_config_applied = true; apply_service_config_to_call_locked(elem); - // Check this after applying service config, since it may have - // affected the call's wait_for_ready value. - if (fail_call_if_in_transient_failure(elem)) return false; } - return true; } -static void start_pick_locked(void* arg, grpc_error* ignored) { +static const char* pick_result_name( + LoadBalancingPolicy::SubchannelPicker::PickResult result) { + switch (result) { + case LoadBalancingPolicy::SubchannelPicker::PICK_COMPLETE: + return "COMPLETE"; + case LoadBalancingPolicy::SubchannelPicker::PICK_QUEUE: + return "QUEUE"; + case LoadBalancingPolicy::SubchannelPicker::PICK_TRANSIENT_FAILURE: + return "TRANSIENT_FAILURE"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +static void start_pick_locked(void* arg, grpc_error* error) { grpc_call_element* elem = static_cast(arg); call_data* calld = static_cast(elem->call_data); channel_data* chand = static_cast(elem->channel_data); - GPR_ASSERT(!calld->have_request); + GPR_ASSERT(calld->pick.pick.connected_subchannel == nullptr); GPR_ASSERT(calld->subchannel_call == nullptr); - // Normally, we want to do this check until after we've processed the - // service config, so that we can honor the wait_for_ready setting in - // the service config. However, if the channel is in TRANSIENT_FAILURE - // and we don't have an LB policy at this point, that means that the - // resolver has returned a failure, so we're not going to get a service - // config right away. In that case, we fail the call now based on the - // wait_for_ready value passed in from the application. - if (chand->request_router->lb_policy() == nullptr && - fail_call_if_in_transient_failure(elem)) { - return; - } // If this is a retry, use the send_initial_metadata payload that // we've cached; otherwise, use the pending batch. The // send_initial_metadata batch will be the first pending batch in the @@ -2396,25 +2674,78 @@ static void start_pick_locked(void* arg, grpc_error* ignored) { // allocate the subchannel batch earlier so that we can give the // subchannel's copy of the metadata batch (which is copied for each // attempt) to the LB policy instead the one from the parent channel. - grpc_metadata_batch* initial_metadata = + calld->pick.pick.initial_metadata = calld->seen_send_initial_metadata ? &calld->send_initial_metadata : calld->pending_batches[0] .batch->payload->send_initial_metadata.send_initial_metadata; - uint32_t* initial_metadata_flags = + uint32_t* send_initial_metadata_flags = calld->seen_send_initial_metadata ? &calld->send_initial_metadata_flags : &calld->pending_batches[0] .batch->payload->send_initial_metadata .send_initial_metadata_flags; + // Apply service config to call if needed. + maybe_apply_service_config_to_call_locked(elem); + // When done, we schedule this closure to leave the channel combiner. GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem, grpc_schedule_on_exec_ctx); - calld->request.Init(calld->owning_call, calld->call_combiner, calld->pollent, - initial_metadata, initial_metadata_flags, - maybe_apply_service_config_to_call_locked, elem, - &calld->pick_closure); - calld->have_request = true; - chand->request_router->RouteCallLocked(calld->request.get()); + // Attempt pick. + error = GRPC_ERROR_NONE; + auto pick_result = chand->picker->Pick(&calld->pick.pick, &error); + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: LB pick returned %s (connected_subchannel=%p, " + "error=%s)", + chand, calld, pick_result_name(pick_result), + calld->pick.pick.connected_subchannel.get(), + grpc_error_string(error)); + } + switch (pick_result) { + case LoadBalancingPolicy::SubchannelPicker::PICK_TRANSIENT_FAILURE: + // If we're shutting down, fail all RPCs. + if (chand->disconnect_error != GRPC_ERROR_NONE) { + GRPC_ERROR_UNREF(error); + GRPC_CLOSURE_SCHED(&calld->pick_closure, + GRPC_ERROR_REF(chand->disconnect_error)); + break; + } + // If wait_for_ready is false, then the error indicates the RPC + // attempt's final status. + if ((*send_initial_metadata_flags & + GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) { + // Retry if appropriate; otherwise, fail. + grpc_status_code status = GRPC_STATUS_OK; + grpc_error_get_status(error, calld->deadline, &status, nullptr, nullptr, + nullptr); + if (!calld->enable_retries || + !maybe_retry(elem, nullptr /* batch_data */, status, + nullptr /* server_pushback_md */)) { + grpc_error* new_error = + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Failed to create subchannel", &error, 1); + GRPC_ERROR_UNREF(error); + GRPC_CLOSURE_SCHED(&calld->pick_closure, new_error); + } + if (calld->pick_queued) remove_call_from_queued_picks_locked(elem); + break; + } + // If wait_for_ready is true, then queue to retry when we get a new + // picker. + GRPC_ERROR_UNREF(error); + // Fallthrough + case LoadBalancingPolicy::SubchannelPicker::PICK_QUEUE: + if (!calld->pick_queued) add_call_to_queued_picks_locked(elem); + break; + default: // PICK_COMPLETE + // Handle drops. + if (GPR_UNLIKELY(calld->pick.pick.connected_subchannel == nullptr)) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Call dropped by load balancing policy"); + } + GRPC_CLOSURE_SCHED(&calld->pick_closure, error); + if (calld->pick_queued) remove_call_from_queued_picks_locked(elem); + } } // @@ -2458,8 +2789,10 @@ static void cc_start_transport_stream_op_batch( // been started), fail all pending batches. Otherwise, send the // cancellation down to the subchannel call. if (calld->subchannel_call == nullptr) { + // TODO(roth): If there is a pending retry callback, do we need to + // cancel it here? pending_batches_fail(elem, GRPC_ERROR_REF(calld->cancel_error), - false /* yield_call_combiner */); + no_yield_call_combiner); // Note: This will release the call combiner. grpc_transport_stream_op_batch_finish_with_failure( batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner); @@ -2556,7 +2889,8 @@ const grpc_channel_filter grpc_client_channel_filter = { void grpc_client_channel_set_channelz_node( grpc_channel_element* elem, grpc_core::channelz::ClientChannelNode* node) { channel_data* chand = static_cast(elem->channel_data); - chand->request_router->set_channelz_node(node); + chand->channelz_node = node; + chand->resolving_lb_policy->set_channelz_node(node->Ref()); } void grpc_client_channel_populate_child_refs( @@ -2564,22 +2898,23 @@ void grpc_client_channel_populate_child_refs( grpc_core::channelz::ChildRefsList* child_subchannels, grpc_core::channelz::ChildRefsList* child_channels) { channel_data* chand = static_cast(elem->channel_data); - if (chand->request_router->lb_policy() != nullptr) { - chand->request_router->lb_policy()->FillChildRefsForChannelz( - child_subchannels, child_channels); + if (chand->resolving_lb_policy != nullptr) { + chand->resolving_lb_policy->FillChildRefsForChannelz(child_subchannels, + child_channels); } } static void try_to_connect_locked(void* arg, grpc_error* error_ignored) { channel_data* chand = static_cast(arg); - chand->request_router->ExitIdleLocked(); + chand->resolving_lb_policy->ExitIdleLocked(); GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "try_to_connect"); } grpc_connectivity_state grpc_client_channel_check_connectivity_state( grpc_channel_element* elem, int try_to_connect) { channel_data* chand = static_cast(elem->channel_data); - grpc_connectivity_state out = chand->request_router->GetConnectivityState(); + grpc_connectivity_state out = + grpc_connectivity_state_check(&chand->state_tracker); if (out == GRPC_CHANNEL_IDLE && try_to_connect) { GRPC_CHANNEL_STACK_REF(chand->owning_stack, "try_to_connect"); GRPC_CLOSURE_SCHED( @@ -2688,15 +3023,15 @@ static void watch_connectivity_state_locked(void* arg, GRPC_CLOSURE_RUN(w->watcher_timer_init, GRPC_ERROR_NONE); GRPC_CLOSURE_INIT(&w->my_closure, on_external_watch_complete_locked, w, grpc_combiner_scheduler(w->chand->combiner)); - w->chand->request_router->NotifyOnConnectivityStateChange(w->state, - &w->my_closure); + grpc_connectivity_state_notify_on_state_change(&w->chand->state_tracker, + w->state, &w->my_closure); } else { GPR_ASSERT(w->watcher_timer_init == nullptr); found = lookup_external_connectivity_watcher(w->chand, w->on_complete); if (found) { GPR_ASSERT(found->on_complete == w->on_complete); - found->chand->request_router->NotifyOnConnectivityStateChange( - nullptr, &found->my_closure); + grpc_connectivity_state_notify_on_state_change( + &found->chand->state_tracker, nullptr, &found->my_closure); } grpc_polling_entity_del_from_pollset_set(&w->pollent, w->chand->interested_parties); diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index d9b3927d1ca..9e3477b9ed5 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -54,35 +54,15 @@ grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( return nullptr; } -LoadBalancingPolicy::LoadBalancingPolicy(Args args) - : InternallyRefCounted(&grpc_trace_lb_policy_refcount), +LoadBalancingPolicy::LoadBalancingPolicy(Args args, intptr_t initial_refcount) + : InternallyRefCounted(&grpc_trace_lb_policy_refcount, initial_refcount), combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), - client_channel_factory_(args.client_channel_factory), - subchannel_pool_(std::move(args.subchannel_pool)), interested_parties_(grpc_pollset_set_create()), - request_reresolution_(nullptr) {} + channel_control_helper_(std::move(args.channel_control_helper)) {} LoadBalancingPolicy::~LoadBalancingPolicy() { grpc_pollset_set_destroy(interested_parties_); GRPC_COMBINER_UNREF(combiner_, "lb_policy"); } -void LoadBalancingPolicy::TryReresolutionLocked( - grpc_core::TraceFlag* grpc_lb_trace, grpc_error* error) { - if (request_reresolution_ != nullptr) { - GRPC_CLOSURE_SCHED(request_reresolution_, error); - request_reresolution_ = nullptr; - if (grpc_lb_trace->enabled()) { - gpr_log(GPR_INFO, - "%s %p: scheduling re-resolution closure with error=%s.", - grpc_lb_trace->name(), this, grpc_error_string(error)); - } - } else { - if (grpc_lb_trace->enabled()) { - gpr_log(GPR_INFO, "%s %p: no available re-resolution closure.", - grpc_lb_trace->name(), this); - } - } -} - } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 56bf1951cfb..aeb8138a12e 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -24,7 +24,6 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -43,8 +42,179 @@ namespace grpc_core { /// /// Any I/O done by the LB policy should be done under the pollset_set /// returned by \a interested_parties(). +// TODO(roth): Once we move to EventManager-based polling, remove the +// interested_parties() hooks from the API. class LoadBalancingPolicy : public InternallyRefCounted { public: + /// State used for an LB pick. + struct PickState { + /// Initial metadata associated with the picking call. + /// This is both an input and output parameter; the LB policy may + /// use metadata here to influence its routing decision, and it may + /// add new metadata here to be sent with the call to the chosen backend. + grpc_metadata_batch* initial_metadata = nullptr; + /// Storage for LB token in \a initial_metadata, or nullptr if not used. + // TODO(roth): Remove this from the API. Maybe have the LB policy + // allocate this on the arena instead? + grpc_linked_mdelem lb_token_mdelem_storage; + /// Callback set by lb policy to be notified of trailing metadata. + /// The callback must be scheduled on grpc_schedule_on_exec_ctx. + grpc_closure* recv_trailing_metadata_ready = nullptr; + /// The address that will be set to point to the original + /// recv_trailing_metadata_ready callback, to be invoked by the LB + /// policy's recv_trailing_metadata_ready callback when complete. + /// Must be non-null if recv_trailing_metadata_ready is non-null. + grpc_closure** original_recv_trailing_metadata_ready = nullptr; + /// If this is not nullptr, then the client channel will point it to the + /// call's trailing metadata before invoking recv_trailing_metadata_ready. + /// If this is nullptr, then the callback will still be called. + /// The lb does not have ownership of the metadata. + grpc_metadata_batch** recv_trailing_metadata = nullptr; + /// Will be set to the selected subchannel, or nullptr on failure or when + /// the LB policy decides to drop the call. + RefCountedPtr connected_subchannel; + /// Will be populated with context to pass to the subchannel call, if + /// needed. + // TODO(roth): Remove this from the API, especially since it's not + // working properly anyway (see https://github.com/grpc/grpc/issues/15927). + grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; + }; + + /// A picker is the object used to actual perform picks. + /// + /// Pickers are intended to encapsulate all of the state and logic + /// needed on the data plane (i.e., to actually process picks for + /// individual RPCs sent on the channel) while excluding all of the + /// state and logic needed on the control plane (i.e., resolver + /// updates, connectivity state notifications, etc); the latter should + /// live in the LB policy object itself. + /// + /// Currently, pickers are always accessed from within the + /// client_channel combiner, so they do not have to be thread-safe. + // TODO(roth): In a subsequent PR, split the data plane work (i.e., + // the interaction with the picker) and the control plane work (i.e., + // the interaction with the LB policy) into two different + // synchronization mechanisms, to avoid lock contention between the two. + class SubchannelPicker { + public: + enum PickResult { + // Pick complete. If connected_subchannel is non-null, client channel + // can immediately proceed with the call on connected_subchannel; + // otherwise, call should be dropped. + PICK_COMPLETE, + // Pick cannot be completed until something changes on the control + // plane. Client channel will queue the pick and try again the + // next time the picker is updated. + PICK_QUEUE, + // LB policy is in transient failure. If the pick is wait_for_ready, + // client channel will wait for the next picker and try again; + // otherwise, the call will be failed immediately (although it may + // be retried if the client channel is configured to do so). + // The Pick() method will set its error parameter if this value is + // returned. + PICK_TRANSIENT_FAILURE, + }; + + SubchannelPicker() = default; + virtual ~SubchannelPicker() = default; + + virtual PickResult Pick(PickState* pick, grpc_error** error) GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + }; + + // A picker that returns PICK_QUEUE for all picks. + // Also calls the parent LB policy's ExitIdleLocked() method when the + // first pick is seen. + class QueuePicker : public SubchannelPicker { + public: + explicit QueuePicker(RefCountedPtr parent) + : parent_(std::move(parent)) {} + + PickResult Pick(PickState* pick, grpc_error** error) override { + // We invoke the parent's ExitIdleLocked() via a closure instead + // of doing it directly here, for two reasons: + // 1. ExitIdleLocked() may cause the policy's state to change and + // a new picker to be delivered to the channel. If that new + // picker is delivered before ExitIdleLocked() returns, then by + // the time this function returns, the pick will already have + // been processed, and we'll be trying to re-process the same + // pick again, leading to a crash. + // 2. In a subsequent PR, we will split the data plane and control + // plane synchronization into separate combiners, at which + // point this will need to hop from the data plane combiner into + // the control plane combiner. + if (!exit_idle_called_) { + exit_idle_called_ = true; + parent_->Ref().release(); // ref held by closure. + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(&CallExitIdle, parent_.get(), + grpc_combiner_scheduler(parent_->combiner())), + GRPC_ERROR_NONE); + } + return PICK_QUEUE; + } + + private: + static void CallExitIdle(void* arg, grpc_error* error) { + LoadBalancingPolicy* parent = static_cast(arg); + parent->ExitIdleLocked(); + parent->Unref(); + } + + RefCountedPtr parent_; + bool exit_idle_called_ = false; + }; + + // A picker that returns PICK_TRANSIENT_FAILURE for all picks. + class TransientFailurePicker : public SubchannelPicker { + public: + explicit TransientFailurePicker(grpc_error* error) : error_(error) {} + ~TransientFailurePicker() { GRPC_ERROR_UNREF(error_); } + + PickResult Pick(PickState* pick, grpc_error** error) override { + *error = GRPC_ERROR_REF(error_); + return PICK_TRANSIENT_FAILURE; + } + + private: + grpc_error* error_; + }; + + /// A proxy object used by the LB policy to communicate with the client + /// channel. + class ChannelControlHelper { + public: + ChannelControlHelper() = default; + virtual ~ChannelControlHelper() = default; + + /// Creates a new subchannel with the specified channel args. + virtual Subchannel* CreateSubchannel(const grpc_channel_args& args) + GRPC_ABSTRACT; + + /// Creates a channel with the specified target, type, and channel args. + virtual grpc_channel* CreateChannel( + const char* target, grpc_client_channel_type type, + const grpc_channel_args& args) GRPC_ABSTRACT; + + /// Sets the connectivity state and returns a new picker to be used + /// by the client channel. + virtual void UpdateState(grpc_connectivity_state state, + grpc_error* state_error, + UniquePtr picker) { + std::move(picker); // Suppress clang-tidy complaint. + // The rest of this is copied from the GRPC_ABSTRACT macro. + gpr_log(GPR_ERROR, "Function marked GRPC_ABSTRACT was not implemented"); + GPR_ASSERT(false); + } + + /// Requests that the resolver re-resolve. + virtual void RequestReresolution() GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + }; + + /// Args used to instantiate an LB policy. struct Args { /// The combiner under which all LB policy calls will be run. /// Policy does NOT take ownership of the reference to the combiner. @@ -52,54 +222,16 @@ class LoadBalancingPolicy : public InternallyRefCounted { // API should change to take a smart pointer that does pass ownership // of a reference. grpc_combiner* combiner = nullptr; - /// Used to create channels and subchannels. - grpc_client_channel_factory* client_channel_factory = nullptr; - /// Subchannel pool. - RefCountedPtr subchannel_pool; + /// Channel control helper. + UniquePtr channel_control_helper; /// Channel args from the resolver. /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. - grpc_channel_args* args = nullptr; + const grpc_channel_args* args = nullptr; /// Load balancing config from the resolver. grpc_json* lb_config = nullptr; }; - /// State used for an LB pick. - struct PickState { - /// Initial metadata associated with the picking call. - grpc_metadata_batch* initial_metadata = nullptr; - /// Pointer to bitmask used for selective cancelling. See - /// \a CancelMatchingPicksLocked() and \a GRPC_INITIAL_METADATA_* in - /// grpc_types.h. - uint32_t* initial_metadata_flags = nullptr; - /// Storage for LB token in \a initial_metadata, or nullptr if not used. - grpc_linked_mdelem lb_token_mdelem_storage; - /// Closure to run when pick is complete, if not completed synchronously. - /// If null, pick will fail if a result is not available synchronously. - grpc_closure* on_complete = nullptr; - // Callback set by lb policy to be notified of trailing metadata. - // The callback must be scheduled on grpc_schedule_on_exec_ctx. - grpc_closure* recv_trailing_metadata_ready = nullptr; - // The address that will be set to point to the original - // recv_trailing_metadata_ready callback, to be invoked by the LB - // policy's recv_trailing_metadata_ready callback when complete. - // Must be non-null if recv_trailing_metadata_ready is non-null. - grpc_closure** original_recv_trailing_metadata_ready = nullptr; - // If this is not nullptr, then the client channel will point it to the - // call's trailing metadata before invoking recv_trailing_metadata_ready. - // If this is nullptr, then the callback will still be called. - // The lb does not have ownership of the metadata. - grpc_metadata_batch** recv_trailing_metadata = nullptr; - /// Will be set to the selected subchannel, or nullptr on failure or when - /// the LB policy decides to drop the call. - RefCountedPtr connected_subchannel; - /// Will be populated with context to pass to the subchannel call, if - /// needed. - grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; - /// Next pointer. For internal use by LB policy. - PickState* next = nullptr; - }; - // Not copyable nor movable. LoadBalancingPolicy(const LoadBalancingPolicy&) = delete; LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete; @@ -113,48 +245,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) GRPC_ABSTRACT; - /// Finds an appropriate subchannel for a call, based on data in \a pick. - /// \a pick must remain alive until the pick is complete. - /// - /// If a result is known immediately, returns true, setting \a *error - /// upon failure. Otherwise, \a pick->on_complete will be invoked once - /// the pick is complete with its error argument set to indicate success - /// or failure. - /// - /// If \a pick->on_complete is null and no result is known immediately, - /// a synchronous failure will be returned (i.e., \a *error will be - /// set and true will be returned). - virtual bool PickLocked(PickState* pick, grpc_error** error) GRPC_ABSTRACT; - - /// Cancels \a pick. - /// The \a on_complete callback of the pending pick will be invoked with - /// \a pick->connected_subchannel set to null. - virtual void CancelPickLocked(PickState* pick, - grpc_error* error) GRPC_ABSTRACT; - - /// Cancels all pending picks for which their \a initial_metadata_flags (as - /// given in the call to \a PickLocked()) matches - /// \a initial_metadata_flags_eq when ANDed with - /// \a initial_metadata_flags_mask. - virtual void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) GRPC_ABSTRACT; - - /// Requests a notification when the connectivity state of the policy - /// changes from \a *state. When that happens, sets \a *state to the - /// new state and schedules \a closure. - virtual void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) GRPC_ABSTRACT; - - /// Returns the policy's current connectivity state. Sets \a error to - /// the associated error, if any. - virtual grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) GRPC_ABSTRACT; - - /// Hands off pending picks to \a new_policy. - virtual void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) - GRPC_ABSTRACT; - /// Tries to enter a READY connectivity state. /// TODO(roth): As part of restructuring how we handle IDLE state, /// consider whether this method is still needed. @@ -183,18 +273,11 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// given the JSON node of a LoadBalancingConfig array. static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array); - /// Sets the re-resolution closure to \a request_reresolution. - void SetReresolutionClosureLocked(grpc_closure* request_reresolution) { - GPR_ASSERT(request_reresolution_ == nullptr); - request_reresolution_ = request_reresolution; - } - grpc_pollset_set* interested_parties() const { return interested_parties_; } - // Callers that need their own reference can call the returned - // object's Ref() method. - SubchannelPoolInterface* subchannel_pool() const { - return subchannel_pool_.get(); + void set_channelz_node( + RefCountedPtr channelz_node) { + channelz_node_ = std::move(channelz_node); } GRPC_ABSTRACT_BASE_CLASS @@ -202,12 +285,18 @@ class LoadBalancingPolicy : public InternallyRefCounted { protected: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - explicit LoadBalancingPolicy(Args args); + explicit LoadBalancingPolicy(Args args, intptr_t initial_refcount = 1); virtual ~LoadBalancingPolicy(); grpc_combiner* combiner() const { return combiner_; } - grpc_client_channel_factory* client_channel_factory() const { - return client_channel_factory_; + + // Note: This will return null after ShutdownLocked() has been called. + ChannelControlHelper* channel_control_helper() const { + return channel_control_helper_.get(); + } + + channelz::ClientChannelNode* channelz_node() const { + return channelz_node_.get(); } /// Shuts down the policy. Any pending picks that have not been @@ -215,27 +304,22 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// failed. virtual void ShutdownLocked() GRPC_ABSTRACT; - /// Tries to request a re-resolution. - void TryReresolutionLocked(grpc_core::TraceFlag* grpc_lb_trace, - grpc_error* error); - private: static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) { LoadBalancingPolicy* policy = static_cast(arg); policy->ShutdownLocked(); + policy->channel_control_helper_.reset(); policy->Unref(); } /// Combiner under which LB policy actions take place. grpc_combiner* combiner_; - /// Client channel factory, used to create channels and subchannels. - grpc_client_channel_factory* client_channel_factory_; - /// Subchannel pool. - RefCountedPtr subchannel_pool_; /// Owned pointer to interested parties in load balancing decisions. grpc_pollset_set* interested_parties_; - /// Callback to force a re-resolution. - grpc_closure* request_reresolution_; + /// Channel control helper. + UniquePtr channel_control_helper_; + /// Channelz node. + RefCountedPtr channelz_node_; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 63e381d64c7..fa1ca6d127a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -74,7 +74,6 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" @@ -131,16 +130,6 @@ class GrpcLb : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( @@ -148,31 +137,6 @@ class GrpcLb : public LoadBalancingPolicy { channelz::ChildRefsList* child_channels) override; private: - /// Linked list of pending pick requests. It stores all information needed to - /// eventually call (Round Robin's) pick() on them. They mainly stay pending - /// waiting for the RR policy to be created. - /// - /// Note that when a pick is sent to the RR policy, we inject our own - /// on_complete callback, so that we can intercept the result before - /// invoking the original on_complete callback. This allows us to set the - /// LB token metadata and add client_stats to the call context. - /// See \a pending_pick_complete() for details. - struct PendingPick { - // The grpclb instance that created the wrapping. This instance is not - // owned; reference counts are untouched. It's used only for logging - // purposes. - GrpcLb* grpclb_policy; - // The original pick. - PickState* pick; - // Our on_complete closure and the original one. - grpc_closure on_complete; - grpc_closure* original_on_complete; - // Stats for client-side load reporting. - RefCountedPtr client_stats; - // Next pending pick. - PendingPick* next = nullptr; - }; - /// Contains a call to the LB server and all the data related to the call. class BalancerCallState : public InternallyRefCounted { public: @@ -248,6 +212,80 @@ class GrpcLb : public LoadBalancingPolicy { grpc_closure client_load_report_closure_; }; + class Serverlist : public RefCounted { + public: + // Takes ownership of serverlist. + explicit Serverlist(grpc_grpclb_serverlist* serverlist) + : serverlist_(serverlist) {} + + ~Serverlist() { grpc_grpclb_destroy_serverlist(serverlist_); } + + bool operator==(const Serverlist& other) const; + + const grpc_grpclb_serverlist* serverlist() const { return serverlist_; } + + // Returns a text representation suitable for logging. + UniquePtr AsText() const; + + // Extracts all non-drop entries into a ServerAddressList. + ServerAddressList GetServerAddressList() const; + + // Returns true if the serverlist contains at least one drop entry and + // no backend address entries. + bool ContainsAllDropEntries() const; + + // Returns the LB token to use for a drop, or null if the call + // should not be dropped. + // Intended to be called from picker, so calls will be externally + // synchronized. + const char* ShouldDrop(); + + private: + grpc_grpclb_serverlist* serverlist_; + size_t drop_index_ = 0; + }; + + class Picker : public SubchannelPicker { + public: + Picker(GrpcLb* parent, RefCountedPtr serverlist, + UniquePtr child_picker, + RefCountedPtr client_stats) + : parent_(parent), + serverlist_(std::move(serverlist)), + child_picker_(std::move(child_picker)), + client_stats_(std::move(client_stats)) {} + + PickResult Pick(PickState* pick, grpc_error** error) override; + + private: + // Storing the address for logging, but not holding a ref. + // DO NOT DEFERENCE! + GrpcLb* parent_; + + // Serverlist to be used for determining drops. + RefCountedPtr serverlist_; + + UniquePtr child_picker_; + RefCountedPtr client_stats_; + }; + + class Helper : public ChannelControlHelper { + public: + explicit Helper(RefCountedPtr parent) + : parent_(std::move(parent)) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + grpc_channel* CreateChannel(const char* target, + grpc_client_channel_type type, + const grpc_channel_args& args) override; + void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + UniquePtr picker) override; + void RequestReresolution() override; + + private: + RefCountedPtr parent_; + }; + ~GrpcLb(); void ShutdownLocked() override; @@ -264,24 +302,10 @@ class GrpcLb : public LoadBalancingPolicy { static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); - // Pending pick methods. - static void PendingPickSetMetadataAndContext(PendingPick* pp); - PendingPick* PendingPickCreate(PickState* pick); - void AddPendingPick(PendingPick* pp); - static void OnPendingPickComplete(void* arg, grpc_error* error); - // Methods for dealing with the RR policy. void CreateOrUpdateRoundRobinPolicyLocked(); grpc_channel_args* CreateRoundRobinPolicyArgsLocked(); void CreateRoundRobinPolicyLocked(Args args); - bool PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error); - void UpdateConnectivityStateFromRoundRobinPolicyLocked( - grpc_error* rr_state_error); - static void OnRoundRobinConnectivityChangedLocked(void* arg, - grpc_error* error); - static void OnRoundRobinRequestReresolutionLocked(void* arg, - grpc_error* error); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -292,7 +316,6 @@ class GrpcLb : public LoadBalancingPolicy { // Internal state. bool started_picking_ = false; bool shutting_down_ = false; - grpc_connectivity_state_tracker state_tracker_; // The channel for communicating with the LB server. grpc_channel* lb_channel_ = nullptr; @@ -321,11 +344,7 @@ class GrpcLb : public LoadBalancingPolicy { // The deserialized response from the balancer. May be nullptr until one // such response has arrived. - grpc_grpclb_serverlist* serverlist_ = nullptr; - // Index into serverlist for next pick. - // If the server at this index is a drop, we return a drop. - // Otherwise, we delegate to the RR policy. - size_t serverlist_index_ = 0; + RefCountedPtr serverlist_; // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. @@ -337,20 +356,65 @@ class GrpcLb : public LoadBalancingPolicy { grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; - // Pending picks that are waiting on the RR policy's connectivity. - PendingPick* pending_picks_ = nullptr; - // The RR policy to use for the backends. OrphanablePtr rr_policy_; - grpc_connectivity_state rr_connectivity_state_; - grpc_closure on_rr_connectivity_changed_; - grpc_closure on_rr_request_reresolution_; }; // -// serverlist parsing code +// GrpcLb::Serverlist // +bool GrpcLb::Serverlist::operator==(const Serverlist& other) const { + return grpc_grpclb_serverlist_equals(serverlist_, other.serverlist_); +} + +void ParseServer(const grpc_grpclb_server* server, + grpc_resolved_address* addr) { + memset(addr, 0, sizeof(*addr)); + if (server->drop) return; + const uint16_t netorder_port = grpc_htons((uint16_t)server->port); + /* the addresses are given in binary format (a in(6)_addr struct) in + * server->ip_address.bytes. */ + const grpc_grpclb_ip_address* ip = &server->ip_address; + if (ip->size == 4) { + addr->len = static_cast(sizeof(grpc_sockaddr_in)); + grpc_sockaddr_in* addr4 = reinterpret_cast(&addr->addr); + addr4->sin_family = GRPC_AF_INET; + memcpy(&addr4->sin_addr, ip->bytes, ip->size); + addr4->sin_port = netorder_port; + } else if (ip->size == 16) { + addr->len = static_cast(sizeof(grpc_sockaddr_in6)); + grpc_sockaddr_in6* addr6 = (grpc_sockaddr_in6*)&addr->addr; + addr6->sin6_family = GRPC_AF_INET6; + memcpy(&addr6->sin6_addr, ip->bytes, ip->size); + addr6->sin6_port = netorder_port; + } +} + +UniquePtr GrpcLb::Serverlist::AsText() const { + gpr_strvec entries; + gpr_strvec_init(&entries); + for (size_t i = 0; i < serverlist_->num_servers; ++i) { + const auto* server = serverlist_->servers[i]; + char* ipport; + if (server->drop) { + ipport = gpr_strdup("(drop)"); + } else { + grpc_resolved_address addr; + ParseServer(server, &addr); + grpc_sockaddr_to_string(&ipport, &addr, false); + } + char* entry; + gpr_asprintf(&entry, " %" PRIuPTR ": %s token=%s\n", i, ipport, + server->load_balance_token); + gpr_free(ipport); + gpr_strvec_add(&entries, entry); + } + UniquePtr result(gpr_strvec_flatten(&entries, nullptr)); + gpr_strvec_destroy(&entries); + return result; +} + // vtable for LB token channel arg. void* lb_token_copy(void* token) { return token == nullptr @@ -393,35 +457,12 @@ bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) { return true; } -void ParseServer(const grpc_grpclb_server* server, - grpc_resolved_address* addr) { - memset(addr, 0, sizeof(*addr)); - if (server->drop) return; - const uint16_t netorder_port = grpc_htons((uint16_t)server->port); - /* the addresses are given in binary format (a in(6)_addr struct) in - * server->ip_address.bytes. */ - const grpc_grpclb_ip_address* ip = &server->ip_address; - if (ip->size == 4) { - addr->len = static_cast(sizeof(grpc_sockaddr_in)); - grpc_sockaddr_in* addr4 = reinterpret_cast(&addr->addr); - addr4->sin_family = GRPC_AF_INET; - memcpy(&addr4->sin_addr, ip->bytes, ip->size); - addr4->sin_port = netorder_port; - } else if (ip->size == 16) { - addr->len = static_cast(sizeof(grpc_sockaddr_in6)); - grpc_sockaddr_in6* addr6 = (grpc_sockaddr_in6*)&addr->addr; - addr6->sin6_family = GRPC_AF_INET6; - memcpy(&addr6->sin6_addr, ip->bytes, ip->size); - addr6->sin6_port = netorder_port; - } -} - -// Returns addresses extracted from \a serverlist. -ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { +// Returns addresses extracted from the serverlist. +ServerAddressList GrpcLb::Serverlist::GetServerAddressList() const { ServerAddressList addresses; - for (size_t i = 0; i < serverlist->num_servers; ++i) { - const grpc_grpclb_server* server = serverlist->servers[i]; - if (!IsServerValid(serverlist->servers[i], i, false)) continue; + for (size_t i = 0; i < serverlist_->num_servers; ++i) { + const grpc_grpclb_server* server = serverlist_->servers[i]; + if (!IsServerValid(serverlist_->servers[i], i, false)) continue; // Address processing. grpc_resolved_address addr; ParseServer(server, &addr); @@ -456,6 +497,176 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) { return addresses; } +bool GrpcLb::Serverlist::ContainsAllDropEntries() const { + if (serverlist_->num_servers == 0) return false; + for (size_t i = 0; i < serverlist_->num_servers; ++i) { + if (!serverlist_->servers[i]->drop) return false; + } + return true; +} + +const char* GrpcLb::Serverlist::ShouldDrop() { + if (serverlist_->num_servers == 0) return nullptr; + grpc_grpclb_server* server = serverlist_->servers[drop_index_]; + drop_index_ = (drop_index_ + 1) % serverlist_->num_servers; + return server->drop ? server->load_balance_token : nullptr; +} + +// +// GrpcLb::Picker +// + +// Adds lb_token of selected subchannel (address) to the call's initial +// metadata. +grpc_error* AddLbTokenToInitialMetadata( + grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage, + grpc_metadata_batch* initial_metadata) { + GPR_ASSERT(lb_token_mdelem_storage != nullptr); + GPR_ASSERT(!GRPC_MDISNULL(lb_token)); + return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage, + lb_token); +} + +// Destroy function used when embedding client stats in call context. +void DestroyClientStats(void* arg) { + static_cast(arg)->Unref(); +} + +GrpcLb::Picker::PickResult GrpcLb::Picker::Pick(PickState* pick, + grpc_error** error) { + // Check if we should drop the call. + const char* drop_token = serverlist_->ShouldDrop(); + if (drop_token != nullptr) { + // Update client load reporting stats to indicate the number of + // dropped calls. Note that we have to do this here instead of in + // the client_load_reporting filter, because we do not create a + // subchannel call (and therefore no client_load_reporting filter) + // for dropped calls. + if (client_stats_ != nullptr) { + client_stats_->AddCallDroppedLocked(drop_token); + } + return PICK_COMPLETE; + } + // Forward pick to child policy. + PickResult result = child_picker_->Pick(pick, error); + // If pick succeeded, add LB token to initial metadata. + if (result == PickResult::PICK_COMPLETE && + pick->connected_subchannel != nullptr) { + const grpc_arg* arg = grpc_channel_args_find( + pick->connected_subchannel->args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); + if (arg == nullptr) { + gpr_log(GPR_ERROR, + "[grpclb %p picker %p] No LB token for connected subchannel " + "pick %p", + parent_, this, pick); + abort(); + } + grpc_mdelem lb_token = {reinterpret_cast(arg->value.pointer.p)}; + AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(lb_token), + &pick->lb_token_mdelem_storage, + pick->initial_metadata); + // Pass on client stats via context. Passes ownership of the reference. + if (client_stats_ != nullptr) { + pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = + client_stats_->Ref().release(); + pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = + DestroyClientStats; + } + } + return result; +} + +// +// GrpcLb::Helper +// + +Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { + if (parent_->shutting_down_) return nullptr; + return parent_->channel_control_helper()->CreateSubchannel(args); +} + +grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, + grpc_client_channel_type type, + const grpc_channel_args& args) { + if (parent_->shutting_down_) return nullptr; + return parent_->channel_control_helper()->CreateChannel(target, type, args); +} + +void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, + grpc_error* state_error, + UniquePtr picker) { + if (parent_->shutting_down_) { + GRPC_ERROR_UNREF(state_error); + return; + } + // There are three cases to consider here: + // 1. We're in fallback mode. In this case, we're always going to use + // RR's result, so we pass its picker through as-is. + // 2. The serverlist contains only drop entries. In this case, we + // want to use our own picker so that we can return the drops. + // 3. Not in fallback mode and serverlist is not all drops (i.e., it + // may be empty or contain at least one backend address). There are + // two sub-cases: + // a. RR is reporting state READY. In this case, we wrap RR's + // picker in our own, so that we can handle drops and LB token + // metadata for each pick. + // b. RR is reporting a state other than READY. In this case, we + // don't want to use our own picker, because we don't want to + // process drops for picks that yield a QUEUE result; this would + // result in dropping too many calls, since we will see the + // queued picks multiple times, and we'd consider each one a + // separate call for the drop calculation. + // + // Cases 1 and 3b: return picker from RR as-is. + if (parent_->serverlist_ == nullptr || + (!parent_->serverlist_->ContainsAllDropEntries() && + state != GRPC_CHANNEL_READY)) { + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, + "[grpclb %p helper %p] state=%s passing RR picker %p as-is", + parent_.get(), this, grpc_connectivity_state_name(state), + picker.get()); + } + parent_->channel_control_helper()->UpdateState(state, state_error, + std::move(picker)); + return; + } + // Cases 2 and 3a: wrap picker from RR in our own picker. + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping RR picker %p", + parent_.get(), this, grpc_connectivity_state_name(state), + picker.get()); + } + RefCountedPtr client_stats; + if (parent_->lb_calld_ != nullptr && + parent_->lb_calld_->client_stats() != nullptr) { + client_stats = parent_->lb_calld_->client_stats()->Ref(); + } + parent_->channel_control_helper()->UpdateState( + state, state_error, + UniquePtr( + New(parent_.get(), parent_->serverlist_, std::move(picker), + std::move(client_stats)))); +} + +void GrpcLb::Helper::RequestReresolution() { + if (parent_->shutting_down_) return; + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, + "[grpclb %p] Re-resolution requested from the internal RR policy " + "(%p).", + parent_.get(), parent_->rr_policy_.get()); + } + // If we are talking to a balancer, we expect to get updated addresses + // from the balancer, so we can ignore the re-resolution request from + // the RR policy. Otherwise, pass the re-resolution request up to the + // channel. + if (parent_->lb_calld_ == nullptr || + !parent_->lb_calld_->seen_initial_response()) { + parent_->channel_control_helper()->RequestReresolution(); + } +} + // // GrpcLb::BalancerCallState // @@ -754,27 +965,20 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( response_slice)) != nullptr) { // Have seen initial response, look for serverlist. GPR_ASSERT(lb_calld->lb_call_ != nullptr); + auto serverlist_wrapper = MakeRefCounted(serverlist); if (grpc_lb_glb_trace.enabled()) { + UniquePtr serverlist_text = serverlist_wrapper->AsText(); gpr_log(GPR_INFO, "[grpclb %p] lb_calld=%p: Serverlist with %" PRIuPTR - " servers received", - grpclb_policy, lb_calld, serverlist->num_servers); - for (size_t i = 0; i < serverlist->num_servers; ++i) { - grpc_resolved_address addr; - ParseServer(serverlist->servers[i], &addr); - char* ipport; - grpc_sockaddr_to_string(&ipport, &addr, false); - gpr_log(GPR_INFO, - "[grpclb %p] lb_calld=%p: Serverlist[%" PRIuPTR "]: %s", - grpclb_policy, lb_calld, i, ipport); - gpr_free(ipport); - } + " servers received:\n%s", + grpclb_policy, lb_calld, serverlist->num_servers, + serverlist_text.get()); } // Start sending client load report only after we start using the // serverlist returned from the current LB call. if (lb_calld->client_stats_report_interval_ > 0 && lb_calld->client_stats_ == nullptr) { - lb_calld->client_stats_.reset(New()); + lb_calld->client_stats_ = MakeRefCounted(); // TODO(roth): We currently track this ref manually. Once the // ClosureRef API is ready, we should pass the RefCountedPtr<> along // with the callback. @@ -783,19 +987,16 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( lb_calld->ScheduleNextClientLoadReportLocked(); } // Check if the serverlist differs from the previous one. - if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_, serverlist)) { + if (grpclb_policy->serverlist_ != nullptr && + *grpclb_policy->serverlist_ == *serverlist_wrapper) { if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, "[grpclb %p] lb_calld=%p: Incoming server list identical to " "current, ignoring.", grpclb_policy, lb_calld); } - grpc_grpclb_destroy_serverlist(serverlist); } else { // New serverlist. - if (grpclb_policy->serverlist_ != nullptr) { - // Dispose of the old serverlist. - grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_); - } else { + if (grpclb_policy->serverlist_ == nullptr) { // Dispose of the fallback. grpclb_policy->fallback_backend_addresses_.reset(); if (grpclb_policy->fallback_timer_callback_pending_) { @@ -805,8 +1006,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( // Update the serverlist in the GrpcLb instance. This serverlist // instance will be destroyed either upon the next update or when the // GrpcLb instance is destroyed. - grpclb_policy->serverlist_ = serverlist; - grpclb_policy->serverlist_index_ = 0; + grpclb_policy->serverlist_ = std::move(serverlist_wrapper); grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); } } else { @@ -853,13 +1053,13 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( lb_calld->lb_call_, grpc_error_string(error)); gpr_free(status_details); } - grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE); // If this lb_calld is still in use, this call ended because of a failure so // we want to retry connecting. Otherwise, we have deliberately ended this // call and no further action is required. if (lb_calld == grpclb_policy->lb_calld_.get()) { grpclb_policy->lb_calld_.reset(); GPR_ASSERT(!grpclb_policy->shutting_down_); + grpclb_policy->channel_control_helper()->RequestReresolution(); if (lb_calld->seen_initial_response_) { // If we lose connection to the LB server, reset the backoff and restart // the LB call immediately. @@ -991,13 +1191,6 @@ GrpcLb::GrpcLb(LoadBalancingPolicy::Args args) GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_rr_connectivity_changed_, - &GrpcLb::OnRoundRobinConnectivityChangedLocked, this, - grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_rr_request_reresolution_, - &GrpcLb::OnRoundRobinRequestReresolutionLocked, this, - grpc_combiner_scheduler(args.combiner)); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "grpclb"); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -1020,20 +1213,18 @@ GrpcLb::GrpcLb(LoadBalancingPolicy::Args args) arg, {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX}); // Process channel args. ProcessChannelArgsLocked(*args.args); + // Initialize channel with a picker that will start us connecting. + channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(Ref()))); } GrpcLb::~GrpcLb() { - GPR_ASSERT(pending_picks_ == nullptr); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); - grpc_connectivity_state_destroy(&state_tracker_); - if (serverlist_ != nullptr) { - grpc_grpclb_destroy_serverlist(serverlist_); - } } void GrpcLb::ShutdownLocked() { - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); shutting_down_ = true; lb_calld_.reset(); if (retry_timer_callback_pending_) { @@ -1043,7 +1234,6 @@ void GrpcLb::ShutdownLocked() { grpc_timer_cancel(&lb_fallback_timer_); } rr_policy_.reset(); - TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_CANCELLED); // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -1053,109 +1243,12 @@ void GrpcLb::ShutdownLocked() { lb_channel_ = nullptr; gpr_atm_no_barrier_store(&lb_channel_uuid_, 0); } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "grpclb_shutdown"); - // Clear pending picks. - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); } // // public methods // -void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->on_complete = pp->original_on_complete; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pp->pick, &error)) { - // Synchronous return; schedule closure. - GRPC_CLOSURE_SCHED(pp->pick->on_complete, error); - } - Delete(pp); - } -} - -// Cancel a specific pending pick. -// -// A grpclb pick progresses as follows: -// - If there's a Round Robin policy (rr_policy_) available, it'll be -// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From -// that point onwards, it'll be RR's responsibility. For cancellations, that -// implies the pick needs also be cancelled by the RR instance. -// - Otherwise, without an RR instance, picks stay pending at this policy's -// level (grpclb), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void GrpcLb::CancelPickLocked(PickState* pick, grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if (pp->pick == pick) { - pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (rr_policy_ != nullptr) { - rr_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - -// Cancel all pending picks. -// -// A grpclb pick progresses as follows: -// - If there's a Round Robin policy (rr_policy_) available, it'll be -// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From -// that point onwards, it'll be RR's responsibility. For cancellations, that -// implies the pick needs also be cancelled by the RR instance. -// - Otherwise, without an RR instance, picks stay pending at this policy's -// level (grpclb), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void GrpcLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if ((*pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (rr_policy_ != nullptr) { - rr_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, - GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - void GrpcLb::ExitIdleLocked() { if (!started_picking_) { StartPickingLocked(); @@ -1171,37 +1264,6 @@ void GrpcLb::ResetBackoffLocked() { } } -bool GrpcLb::PickLocked(PickState* pick, grpc_error** error) { - PendingPick* pp = PendingPickCreate(pick); - bool pick_done = false; - if (rr_policy_ != nullptr) { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] about to PICK from RR %p", this, - rr_policy_.get()); - } - pick_done = - PickFromRoundRobinPolicyLocked(false /* force_async */, pp, error); - } else { // rr_policy_ == NULL - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - pick_done = true; - } else { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] No RR policy. Adding to grpclb's pending picks", - this); - } - AddPendingPick(pp); - if (!started_picking_) { - StartPickingLocked(); - } - pick_done = false; - } - } - return pick_done; -} - void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { @@ -1215,17 +1277,6 @@ void GrpcLb::FillChildRefsForChannelz( } } -grpc_connectivity_state GrpcLb::CheckConnectivityLocked( - grpc_error** connectivity_error) { - return grpc_connectivity_state_get(&state_tracker_, connectivity_error); -} - -void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* notify) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - notify); -} - // Returns the backend addresses extracted from the given addresses. UniquePtr ExtractBackendAddresses( const ServerAddressList& addresses) { @@ -1271,9 +1322,8 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { if (lb_channel_ == nullptr) { char* uri_str; gpr_asprintf(&uri_str, "fake:///%s", server_name_); - lb_channel_ = grpc_client_channel_factory_create_channel( - client_channel_factory(), uri_str, - GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args); + lb_channel_ = channel_control_helper()->CreateChannel( + uri_str, GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, *lb_channel_args); GPR_ASSERT(lb_channel_ != nullptr); grpc_core::channelz::ChannelNode* channel_node = grpc_channel_get_channelz_node(lb_channel_); @@ -1454,143 +1504,10 @@ void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, } } -// -// PendingPick -// - -// Adds lb_token of selected subchannel (address) to the call's initial -// metadata. -grpc_error* AddLbTokenToInitialMetadata( - grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage, - grpc_metadata_batch* initial_metadata) { - GPR_ASSERT(lb_token_mdelem_storage != nullptr); - GPR_ASSERT(!GRPC_MDISNULL(lb_token)); - return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage, - lb_token); -} - -// Destroy function used when embedding client stats in call context. -void DestroyClientStats(void* arg) { - static_cast(arg)->Unref(); -} - -void GrpcLb::PendingPickSetMetadataAndContext(PendingPick* pp) { - // If connected_subchannel is nullptr, no pick has been made by the RR - // policy (e.g., all addresses failed to connect). There won't be any - // LB token available. - if (pp->pick->connected_subchannel != nullptr) { - const grpc_arg* arg = - grpc_channel_args_find(pp->pick->connected_subchannel->args(), - GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN); - if (arg != nullptr) { - grpc_mdelem lb_token = { - reinterpret_cast(arg->value.pointer.p)}; - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(lb_token), - &pp->pick->lb_token_mdelem_storage, - pp->pick->initial_metadata); - } else { - gpr_log(GPR_ERROR, - "[grpclb %p] No LB token for connected subchannel pick %p", - pp->grpclb_policy, pp->pick); - abort(); - } - // Pass on client stats via context. Passes ownership of the reference. - if (pp->client_stats != nullptr) { - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = - pp->client_stats.release(); - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = - DestroyClientStats; - } - } else { - pp->client_stats.reset(); - } -} - -/* The \a on_complete closure passed as part of the pick requires keeping a - * reference to its associated round robin instance. We wrap this closure in - * order to unref the round robin instance upon its invocation */ -void GrpcLb::OnPendingPickComplete(void* arg, grpc_error* error) { - PendingPick* pp = static_cast(arg); - PendingPickSetMetadataAndContext(pp); - GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); - Delete(pp); -} - -GrpcLb::PendingPick* GrpcLb::PendingPickCreate(PickState* pick) { - PendingPick* pp = New(); - pp->grpclb_policy = this; - pp->pick = pick; - GRPC_CLOSURE_INIT(&pp->on_complete, &GrpcLb::OnPendingPickComplete, pp, - grpc_schedule_on_exec_ctx); - pp->original_on_complete = pick->on_complete; - pick->on_complete = &pp->on_complete; - return pp; -} - -void GrpcLb::AddPendingPick(PendingPick* pp) { - pp->next = pending_picks_; - pending_picks_ = pp; -} - // // code for interacting with the RR policy // -// Performs a pick over \a rr_policy_. Given that a pick can return -// immediately (ignoring its completion callback), we need to perform the -// cleanups this callback would otherwise be responsible for. -// If \a force_async is true, then we will manually schedule the -// completion callback even if the pick is available immediately. -bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error) { - // Check for drops if we are not using fallback backend addresses. - if (serverlist_ != nullptr && serverlist_->num_servers > 0) { - // Look at the index into the serverlist to see if we should drop this call. - grpc_grpclb_server* server = serverlist_->servers[serverlist_index_++]; - if (serverlist_index_ == serverlist_->num_servers) { - serverlist_index_ = 0; // Wrap-around. - } - if (server->drop) { - // Update client load reporting stats to indicate the number of - // dropped calls. Note that we have to do this here instead of in - // the client_load_reporting filter, because we do not create a - // subchannel call (and therefore no client_load_reporting filter) - // for dropped calls. - if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { - lb_calld_->client_stats()->AddCallDroppedLocked( - server->load_balance_token); - } - if (force_async) { - GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_NONE); - Delete(pp); - return false; - } - Delete(pp); - return true; - } - } - // Set client_stats. - if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { - pp->client_stats = lb_calld_->client_stats()->Ref(); - } - // Pick via the RR policy. - bool pick_done = rr_policy_->PickLocked(pp->pick, error); - if (pick_done) { - PendingPickSetMetadataAndContext(pp); - if (force_async) { - GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); - *error = GRPC_ERROR_NONE; - pick_done = false; - } - Delete(pp); - } - // else, the pending pick will be registered and taken care of by the - // pending pick list inside the RR policy. Eventually, - // OnPendingPickComplete() will be called, which will (among other - // things) add the LB token to the call's initial metadata. - return pick_done; -} - void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { GPR_ASSERT(rr_policy_ == nullptr); rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( @@ -1604,40 +1521,12 @@ void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, rr_policy_.get()); } - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - auto self = Ref(DEBUG_LOCATION, "on_rr_reresolution_requested"); - self.release(); - rr_policy_->SetReresolutionClosureLocked(&on_rr_request_reresolution_); - grpc_error* rr_state_error = nullptr; - rr_connectivity_state_ = rr_policy_->CheckConnectivityLocked(&rr_state_error); - // Connectivity state is a function of the RR policy updated/created. - UpdateConnectivityStateFromRoundRobinPolicyLocked(rr_state_error); // Add the gRPC LB's interested_parties pollset_set to that of the newly // created RR policy. This will make the RR policy progress upon activity on // gRPC LB, which in turn is tied to the application's call. grpc_pollset_set_add_pollset_set(rr_policy_->interested_parties(), interested_parties()); - // Subscribe to changes to the connectivity of the new RR. - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - self = Ref(DEBUG_LOCATION, "on_rr_connectivity_changed"); - self.release(); - rr_policy_->NotifyOnStateChangeLocked(&rr_connectivity_state_, - &on_rr_connectivity_changed_); rr_policy_->ExitIdleLocked(); - // Send pending picks to RR policy. - PendingPick* pp; - while ((pp = pending_picks_)) { - pending_picks_ = pp->next; - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] Pending pick about to (async) PICK from RR %p", this, - rr_policy_.get()); - } - grpc_error* error = GRPC_ERROR_NONE; - PickFromRoundRobinPolicyLocked(true /* force_async */, pp, &error); - } } grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { @@ -1645,7 +1534,7 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { ServerAddressList* addresses = &tmp_addresses; bool is_backend_from_grpclb_load_balancer = false; if (serverlist_ != nullptr) { - tmp_addresses = ProcessServerlist(serverlist_); + tmp_addresses = serverlist_->GetServerAddressList(); is_backend_from_grpclb_load_balancer = true; } else { // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't @@ -1694,110 +1583,14 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { } else { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); - lb_policy_args.client_channel_factory = client_channel_factory(); lb_policy_args.args = args; - lb_policy_args.subchannel_pool = subchannel_pool()->Ref(); + lb_policy_args.channel_control_helper = + UniquePtr(New(Ref())); CreateRoundRobinPolicyLocked(std::move(lb_policy_args)); } grpc_channel_args_destroy(args); } -void GrpcLb::OnRoundRobinRequestReresolutionLocked(void* arg, - grpc_error* error) { - GrpcLb* grpclb_policy = static_cast(arg); - if (grpclb_policy->shutting_down_ || error != GRPC_ERROR_NONE) { - grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_reresolution_requested"); - return; - } - if (grpc_lb_glb_trace.enabled()) { - gpr_log( - GPR_INFO, - "[grpclb %p] Re-resolution requested from the internal RR policy (%p).", - grpclb_policy, grpclb_policy->rr_policy_.get()); - } - // If we are talking to a balancer, we expect to get updated addresses form - // the balancer, so we can ignore the re-resolution request from the RR - // policy. Otherwise, handle the re-resolution request using the - // grpclb policy's original re-resolution closure. - if (grpclb_policy->lb_calld_ == nullptr || - !grpclb_policy->lb_calld_->seen_initial_response()) { - grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE); - } - // Give back the wrapper closure to the RR policy. - grpclb_policy->rr_policy_->SetReresolutionClosureLocked( - &grpclb_policy->on_rr_request_reresolution_); -} - -void GrpcLb::UpdateConnectivityStateFromRoundRobinPolicyLocked( - grpc_error* rr_state_error) { - const grpc_connectivity_state curr_glb_state = - grpc_connectivity_state_check(&state_tracker_); - /* The new connectivity status is a function of the previous one and the new - * input coming from the status of the RR policy. - * - * current state (grpclb's) - * | - * v || I | C | R | TF | SD | <- new state (RR's) - * ===++====+=====+=====+======+======+ - * I || I | C | R | [I] | [I] | - * ---++----+-----+-----+------+------+ - * C || I | C | R | [C] | [C] | - * ---++----+-----+-----+------+------+ - * R || I | C | R | [R] | [R] | - * ---++----+-----+-----+------+------+ - * TF || I | C | R | [TF] | [TF] | - * ---++----+-----+-----+------+------+ - * SD || NA | NA | NA | NA | NA | (*) - * ---++----+-----+-----+------+------+ - * - * A [STATE] indicates that the old RR policy is kept. In those cases, STATE - * is the current state of grpclb, which is left untouched. - * - * In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to - * the previous RR instance. - * - * Note that the status is never updated to SHUTDOWN as a result of calling - * this function. Only glb_shutdown() has the power to set that state. - * - * (*) This function mustn't be called during shutting down. */ - GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN); - switch (rr_connectivity_state_) { - case GRPC_CHANNEL_TRANSIENT_FAILURE: - case GRPC_CHANNEL_SHUTDOWN: - GPR_ASSERT(rr_state_error != GRPC_ERROR_NONE); - break; - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_READY: - GPR_ASSERT(rr_state_error == GRPC_ERROR_NONE); - } - if (grpc_lb_glb_trace.enabled()) { - gpr_log( - GPR_INFO, - "[grpclb %p] Setting grpclb's state to %s from new RR policy %p state.", - this, grpc_connectivity_state_name(rr_connectivity_state_), - rr_policy_.get()); - } - grpc_connectivity_state_set(&state_tracker_, rr_connectivity_state_, - rr_state_error, - "update_lb_connectivity_status_locked"); -} - -void GrpcLb::OnRoundRobinConnectivityChangedLocked(void* arg, - grpc_error* error) { - GrpcLb* grpclb_policy = static_cast(arg); - if (grpclb_policy->shutting_down_) { - grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_connectivity_changed"); - return; - } - grpclb_policy->UpdateConnectivityStateFromRoundRobinPolicyLocked( - GRPC_ERROR_REF(error)); - // Resubscribe. Reuse the "on_rr_connectivity_changed" ref. - grpclb_policy->rr_policy_->NotifyOnStateChangeLocked( - &grpclb_policy->rr_connectivity_state_, - &grpclb_policy->on_rr_connectivity_changed_); -} - // // factory // diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc index 087cd8f276e..1c7ed871d74 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc @@ -43,7 +43,7 @@ void GrpcLbClientStats::AddCallFinished( } } -void GrpcLbClientStats::AddCallDroppedLocked(char* token) { +void GrpcLbClientStats::AddCallDroppedLocked(const char* token) { // Increment num_calls_started and num_calls_finished. gpr_atm_full_fetch_add(&num_calls_started_, (gpr_atm)1); gpr_atm_full_fetch_add(&num_calls_finished_, (gpr_atm)1); diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h index 18ab2c94529..45ca40942ca 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h @@ -48,7 +48,7 @@ class GrpcLbClientStats : public RefCounted { bool finished_known_received); // This method is not thread-safe; caller must synchronize. - void AddCallDroppedLocked(char* token); + void AddCallDroppedLocked(const char* token); // This method is not thread-safe; caller must synchronize. void GetLocked(int64_t* num_calls_started, int64_t* num_calls_finished, diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index dc716a6adac..bf1c5bd7914 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -52,16 +52,6 @@ class PickFirst : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -99,10 +89,9 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - client_channel_factory, args) { + policy->channel_control_helper(), args) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' // pollset_sets will include the LB policy's pollset_set. @@ -115,6 +104,20 @@ class PickFirst : public LoadBalancingPolicy { } }; + class Picker : public SubchannelPicker { + public: + explicit Picker(RefCountedPtr connected_subchannel) + : connected_subchannel_(std::move(connected_subchannel)) {} + + PickResult Pick(PickState* pick, grpc_error** error) override { + pick->connected_subchannel = connected_subchannel_; + return PICK_COMPLETE; + } + + private: + RefCountedPtr connected_subchannel_; + }; + // Helper class to ensure that any function that modifies the child refs // data structures will update the channelz snapshot data structures before // returning. @@ -142,10 +145,6 @@ class PickFirst : public LoadBalancingPolicy { bool started_picking_ = false; // Are we shut down? bool shutdown_ = false; - // List of picks that are waiting on connectivity. - PickState* pending_picks_ = nullptr; - // Our connectivity state tracker. - grpc_connectivity_state_tracker state_tracker_; /// Lock and data used to capture snapshots of this channels child /// channels and subchannels. This data is consumed by channelz. @@ -155,13 +154,15 @@ class PickFirst : public LoadBalancingPolicy { }; PickFirst::PickFirst(Args args) : LoadBalancingPolicy(std::move(args)) { - GPR_ASSERT(args.client_channel_factory != nullptr); gpr_mu_init(&child_refs_mu_); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, - "pick_first"); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p created.", this); } + // Initialize channel with a picker that will start us connecting upon + // the first pick. + channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(Ref()))); UpdateLocked(*args.args, args.lb_config); } @@ -172,81 +173,16 @@ PickFirst::~PickFirst() { gpr_mu_destroy(&child_refs_mu_); GPR_ASSERT(subchannel_list_ == nullptr); GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); - GPR_ASSERT(pending_picks_ == nullptr); - grpc_connectivity_state_destroy(&state_tracker_); -} - -void PickFirst::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pick, &error)) { - // Synchronous return, schedule closure. - GRPC_CLOSURE_SCHED(pick->on_complete, error); - } - } } void PickFirst::ShutdownLocked() { AutoChildRefsUpdater guard(this); - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p Shutting down", this); } shutdown_ = true; - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error)); - } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "shutdown"); subchannel_list_.reset(); latest_pending_subchannel_list_.reset(); - TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_CANCELLED); - GRPC_ERROR_UNREF(error); -} - -void PickFirst::CancelPickLocked(PickState* pick, grpc_error* error) { - PickState* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PickState* next = pp->next; - if (pp == pick) { - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - GRPC_ERROR_UNREF(error); -} - -void PickFirst::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PickState* pick = pending_picks_; - pending_picks_ = nullptr; - while (pick != nullptr) { - PickState* next = pick->next; - if ((*pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pick->next = pending_picks_; - pending_picks_ = pick; - } - pick = next; - } - GRPC_ERROR_UNREF(error); } void PickFirst::StartPickingLocked() { @@ -270,36 +206,6 @@ void PickFirst::ResetBackoffLocked() { } } -bool PickFirst::PickLocked(PickState* pick, grpc_error** error) { - // If we have a selected subchannel already, return synchronously. - if (selected_ != nullptr) { - pick->connected_subchannel = selected_->connected_subchannel()->Ref(); - return true; - } - // No subchannel selected yet, so handle asynchronously. - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - return true; - } - pick->next = pending_picks_; - pending_picks_ = pick; - if (!started_picking_) { - StartPickingLocked(); - } - return false; -} - -grpc_connectivity_state PickFirst::CheckConnectivityLocked(grpc_error** error) { - return grpc_connectivity_state_get(&state_tracker_, error); -} - -void PickFirst::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* notify) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - notify); -} - void PickFirst::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels_to_fill, channelz::ChildRefsList* ignored) { @@ -341,10 +247,11 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, if (addresses == nullptr) { if (subchannel_list_ == nullptr) { // If we don't have a current subchannel list, go into TRANSIENT FAILURE. - grpc_connectivity_state_set( - &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"), - "pf_update_missing"); + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + UniquePtr(New(error))); } else { // otherwise, keep using the current subchannel list (ignore this update). gpr_log(GPR_ERROR, @@ -364,18 +271,17 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, grpc_channel_args* new_args = grpc_channel_args_copy_and_add(&args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, *addresses, combiner(), - client_channel_factory(), *new_args); + this, &grpc_lb_pick_first_trace, *addresses, combiner(), *new_args); grpc_channel_args_destroy(new_args); if (subchannel_list->num_subchannels() == 0) { // Empty update or no valid subchannels. Unsubscribe from all current // subchannels and put the channel in TRANSIENT_FAILURE. - grpc_connectivity_state_set( - &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), - "pf_update_empty"); subchannel_list_ = std::move(subchannel_list); // Empty list. selected_ = nullptr; + grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + UniquePtr(New(error))); return; } // If one of the subchannels in the new list is already in state @@ -453,7 +359,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( if (p->selected_ == this) { if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, - "Pick First %p connectivity changed for selected subchannel", p); + "Pick First %p selected subchannel connectivity changed to %s", p, + grpc_connectivity_state_name(connectivity_state)); } // If the new state is anything other than READY and there is a // pending update, switch to the pending update. @@ -469,14 +376,12 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->selected_ = nullptr; StopConnectivityWatchLocked(); p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); - grpc_connectivity_state_set( - &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - error != GRPC_ERROR_NONE - ? GRPC_ERROR_REF(error) - : GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "selected subchannel not ready; switching to pending " - "update"), - "selected_not_ready+switch_to_update"); + grpc_error* new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "selected subchannel not ready; switching to pending update", &error, + 1); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), + UniquePtr(New(new_error))); } else { if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { // If the selected subchannel goes bad, request a re-resolution. We also @@ -484,17 +389,28 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // is that if the new state is TRANSIENT_FAILURE due to a GOAWAY // reception we don't want to connect to the re-resolved backends until // we leave the IDLE state. - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_IDLE, - GRPC_ERROR_NONE, - "selected_changed+reresolve"); p->started_picking_ = false; - p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE); + p->channel_control_helper()->RequestReresolution(); // In transient failure. Rely on re-resolution to recover. p->selected_ = nullptr; StopConnectivityWatchLocked(); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(p->Ref()))); } else { - grpc_connectivity_state_set(&p->state_tracker_, connectivity_state, - GRPC_ERROR_REF(error), "selected_changed"); + // This is unlikely but can happen when a subchannel has been asked + // to reconnect by a different channel and this channel has dropped + // some connectivity state notifications. + if (connectivity_state == GRPC_CHANNEL_READY) { + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, GRPC_ERROR_NONE, + UniquePtr( + New(connected_subchannel()->Ref()))); + } else { // CONNECTING + p->channel_control_helper()->UpdateState( + connectivity_state, GRPC_ERROR_REF(error), + UniquePtr(New(p->Ref()))); + } // Renew notification. RenewConnectivityWatchLocked(); } @@ -527,10 +443,14 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // Case 1: Only set state to TRANSIENT_FAILURE if we've tried // all subchannels. if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) { - p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE); - grpc_connectivity_state_set( - &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(error), "exhausted_subchannels"); + p->channel_control_helper()->RequestReresolution(); + grpc_error* new_error = + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "failed to connect to all addresses", &error, 1); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), + UniquePtr( + New(new_error))); } sd->CheckConnectivityStateAndStartWatchingLocked(); break; @@ -539,9 +459,9 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( case GRPC_CHANNEL_IDLE: { // Only update connectivity state in case 1. if (subchannel_list() == p->subchannel_list_.get()) { - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_REF(error), - "connecting_changed"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + UniquePtr(New(p->Ref()))); } // Renew notification. RenewConnectivityWatchLocked(); @@ -578,23 +498,13 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); } // Cases 1 and 2. - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY, - GRPC_ERROR_NONE, "subchannel_ready"); p->selected_ = this; + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, GRPC_ERROR_NONE, + UniquePtr(New(connected_subchannel()->Ref()))); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); } - // Update any calls that were waiting for a pick. - PickState* pick; - while ((pick = p->pending_picks_)) { - p->pending_picks_ = pick->next; - pick->connected_subchannel = p->selected_->connected_subchannel()->Ref(); - if (grpc_lb_pick_first_trace.enabled()) { - gpr_log(GPR_INFO, "Servicing pending pick with selected subchannel %p", - p->selected_->subchannel()); - } - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); - } } void PickFirst::PickFirstSubchannelData:: diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index aab6dd68216..0406efb71d3 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -26,6 +26,7 @@ #include +#include #include #include @@ -62,16 +63,6 @@ class RoundRobin : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -117,14 +108,12 @@ class RoundRobin : public LoadBalancingPolicy { : public SubchannelList { public: - RoundRobinSubchannelList( - RoundRobin* policy, TraceFlag* tracer, - const ServerAddressList& addresses, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, - const grpc_channel_args& args) + RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer, + const ServerAddressList& addresses, + grpc_combiner* combiner, + const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - client_channel_factory, args), - last_ready_index_(num_subchannels() - 1) { + policy->channel_control_helper(), args) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' // pollset_sets will include the LB policy's pollset_set. @@ -157,15 +146,25 @@ class RoundRobin : public LoadBalancingPolicy { // subchannels in each state. void UpdateRoundRobinStateFromSubchannelStateCountsLocked(); - size_t GetNextReadySubchannelIndexLocked(); - void UpdateLastReadySubchannelIndexLocked(size_t last_ready_index); - private: size_t num_ready_ = 0; size_t num_connecting_ = 0; size_t num_transient_failure_ = 0; grpc_error* last_transient_failure_error_ = GRPC_ERROR_NONE; - size_t last_ready_index_; // Index into list of last pick. + }; + + class Picker : public SubchannelPicker { + public: + Picker(RoundRobin* parent, RoundRobinSubchannelList* subchannel_list); + + PickResult Pick(PickState* pick, grpc_error** error) override; + + private: + // Using pointer value only, no ref held -- do not dereference! + RoundRobin* parent_; + + size_t last_picked_index_; + InlinedVector, 10> subchannels_; }; // Helper class to ensure that any function that modifies the child refs @@ -183,8 +182,6 @@ class RoundRobin : public LoadBalancingPolicy { void ShutdownLocked() override; void StartPickingLocked(); - bool DoPickLocked(PickState* pick); - void DrainPendingPicksLocked(); void UpdateChildRefsLocked(); /** list of subchannels */ @@ -199,10 +196,6 @@ class RoundRobin : public LoadBalancingPolicy { bool started_picking_ = false; /** are we shutting down? */ bool shutdown_ = false; - /** List of picks that are waiting on connectivity */ - PickState* pending_picks_ = nullptr; - /** our connectivity state tracker */ - grpc_connectivity_state_tracker state_tracker_; /// Lock and data used to capture snapshots of this channel's child /// channels and subchannels. This data is consumed by channelz. gpr_mu child_refs_mu_; @@ -210,16 +203,62 @@ class RoundRobin : public LoadBalancingPolicy { channelz::ChildRefsList child_channels_; }; -RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) { - GPR_ASSERT(args.client_channel_factory != nullptr); - gpr_mu_init(&child_refs_mu_); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, - "round_robin"); - UpdateLocked(*args.args, args.lb_config); - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, "[RR %p] Created with %" PRIuPTR " subchannels", this, - subchannel_list_->num_subchannels()); +// +// RoundRobin::Picker +// + +RoundRobin::Picker::Picker(RoundRobin* parent, + RoundRobinSubchannelList* subchannel_list) + : parent_(parent) { + for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { + auto* connected_subchannel = + subchannel_list->subchannel(i)->connected_subchannel(); + if (connected_subchannel != nullptr) { + subchannels_.push_back(connected_subchannel->Ref()); + } } + // For discussion on why we generate a random starting index for + // the picker, see https://github.com/grpc/grpc-go/issues/2580. + // TODO(roth): rand(3) is not thread-safe. This should be replaced with + // something better as part of https://github.com/grpc/grpc/issues/17891. + last_picked_index_ = rand() % subchannels_.size(); + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, + "[RR %p picker %p] created picker from subchannel_list=%p " + "with %" PRIuPTR " READY subchannels; last_picked_index_=%" PRIuPTR, + parent_, this, subchannel_list, subchannels_.size(), + last_picked_index_); + } +} + +RoundRobin::Picker::PickResult RoundRobin::Picker::Pick(PickState* pick, + grpc_error** error) { + last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size(); + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, + "[RR %p picker %p] returning index %" PRIuPTR + ", connected_subchannel=%p", + parent_, this, last_picked_index_, + subchannels_[last_picked_index_].get()); + } + pick->connected_subchannel = subchannels_[last_picked_index_]; + return PICK_COMPLETE; +} + +// +// RoundRobin +// + +RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) { + gpr_mu_init(&child_refs_mu_); + if (grpc_lb_round_robin_trace.enabled()) { + gpr_log(GPR_INFO, "[RR %p] Created", this); + } + // Initialize channel with a picker that will start us connecting. + channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(Ref()))); + UpdateLocked(*args.args, args.lb_config); } RoundRobin::~RoundRobin() { @@ -229,82 +268,16 @@ RoundRobin::~RoundRobin() { gpr_mu_destroy(&child_refs_mu_); GPR_ASSERT(subchannel_list_ == nullptr); GPR_ASSERT(latest_pending_subchannel_list_ == nullptr); - GPR_ASSERT(pending_picks_ == nullptr); - grpc_connectivity_state_destroy(&state_tracker_); -} - -void RoundRobin::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pick, &error)) { - // Synchronous return, schedule closure. - GRPC_CLOSURE_SCHED(pick->on_complete, error); - } - } } void RoundRobin::ShutdownLocked() { AutoChildRefsUpdater guard(this); - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] Shutting down", this); } shutdown_ = true; - PickState* pick; - while ((pick = pending_picks_) != nullptr) { - pending_picks_ = pick->next; - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error)); - } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "rr_shutdown"); subchannel_list_.reset(); latest_pending_subchannel_list_.reset(); - TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_CANCELLED); - GRPC_ERROR_UNREF(error); -} - -void RoundRobin::CancelPickLocked(PickState* pick, grpc_error* error) { - PickState* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PickState* next = pp->next; - if (pp == pick) { - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - GRPC_ERROR_UNREF(error); -} - -void RoundRobin::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PickState* pick = pending_picks_; - pending_picks_ = nullptr; - while (pick != nullptr) { - PickState* next = pick->next; - if ((*pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - pick->connected_subchannel.reset(); - GRPC_CLOSURE_SCHED(pick->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pick->next = pending_picks_; - pending_picks_ = pick; - } - pick = next; - } - GRPC_ERROR_UNREF(error); } void RoundRobin::StartPickingLocked() { @@ -325,60 +298,6 @@ void RoundRobin::ResetBackoffLocked() { } } -bool RoundRobin::DoPickLocked(PickState* pick) { - const size_t next_ready_index = - subchannel_list_->GetNextReadySubchannelIndexLocked(); - if (next_ready_index < subchannel_list_->num_subchannels()) { - /* readily available, report right away */ - RoundRobinSubchannelData* sd = - subchannel_list_->subchannel(next_ready_index); - GPR_ASSERT(sd->connected_subchannel() != nullptr); - pick->connected_subchannel = sd->connected_subchannel()->Ref(); - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, - "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, " - "index %" PRIuPTR ")", - this, sd->subchannel(), pick->connected_subchannel.get(), - sd->subchannel_list(), next_ready_index); - } - /* only advance the last picked pointer if the selection was used */ - subchannel_list_->UpdateLastReadySubchannelIndexLocked(next_ready_index); - return true; - } - return false; -} - -void RoundRobin::DrainPendingPicksLocked() { - PickState* pick; - while ((pick = pending_picks_)) { - pending_picks_ = pick->next; - GPR_ASSERT(DoPickLocked(pick)); - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); - } -} - -bool RoundRobin::PickLocked(PickState* pick, grpc_error** error) { - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, "[RR %p] Trying to pick (shutdown: %d)", this, shutdown_); - } - GPR_ASSERT(!shutdown_); - if (subchannel_list_ != nullptr) { - if (DoPickLocked(pick)) return true; - } - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - return true; - } - /* no pick currently available. Save for later in list of pending picks */ - pick->next = pending_picks_; - pending_picks_ = pick; - if (!started_picking_) { - StartPickingLocked(); - } - return false; -} - void RoundRobin::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels_to_fill, channelz::ChildRefsList* ignored) { @@ -462,8 +381,8 @@ void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked( last_transient_failure_error_ = transient_failure_error; } -// Sets the RR policy's connectivity state based on the current -// subchannel list. +// Sets the RR policy's connectivity state and generates a new picker based +// on the current subchannel list. void RoundRobin::RoundRobinSubchannelList:: MaybeUpdateRoundRobinConnectivityStateLocked() { RoundRobin* p = static_cast(policy()); @@ -485,18 +404,21 @@ void RoundRobin::RoundRobinSubchannelList:: */ if (num_ready_ > 0) { /* 1) READY */ - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY, - GRPC_ERROR_NONE, "rr_ready"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_READY, GRPC_ERROR_NONE, + UniquePtr(New(p, this))); } else if (num_connecting_ > 0) { /* 2) CONNECTING */ - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_NONE, "rr_connecting"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + UniquePtr(New(p->Ref()))); } else if (num_transient_failure_ == num_subchannels()) { /* 3) TRANSIENT_FAILURE */ - grpc_connectivity_state_set(&p->state_tracker_, - GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(last_transient_failure_error_), - "rr_exhausted_subchannels"); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_REF(last_transient_failure_error_), + UniquePtr(New( + GRPC_ERROR_REF(last_transient_failure_error_)))); } } @@ -525,8 +447,6 @@ void RoundRobin::RoundRobinSubchannelList:: } p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); } - // Drain pending picks. - p->DrainPendingPicksLocked(); } // Update the RR policy's connectivity state if needed. MaybeUpdateRoundRobinConnectivityStateLocked(); @@ -566,7 +486,7 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( "Requesting re-resolution", p, subchannel()); } - p->TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_NONE); + p->channel_control_helper()->RequestReresolution(); } // Update state counters. UpdateConnectivityStateLocked(connectivity_state, error); @@ -575,73 +495,6 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( RenewConnectivityWatchLocked(); } -/** Returns the index into p->subchannel_list->subchannels of the next - * subchannel in READY state, or p->subchannel_list->num_subchannels if no - * subchannel is READY. - * - * Note that this function does *not* update p->last_ready_subchannel_index. - * The caller must do that if it returns a pick. */ -size_t -RoundRobin::RoundRobinSubchannelList::GetNextReadySubchannelIndexLocked() { - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, - "[RR %p] getting next ready subchannel (out of %" PRIuPTR - "), last_ready_index=%" PRIuPTR, - policy(), num_subchannels(), last_ready_index_); - } - for (size_t i = 0; i < num_subchannels(); ++i) { - const size_t index = (i + last_ready_index_ + 1) % num_subchannels(); - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log( - GPR_INFO, - "[RR %p] checking subchannel %p, subchannel_list %p, index %" PRIuPTR - ": state=%s", - policy(), subchannel(index)->subchannel(), this, index, - grpc_connectivity_state_name( - subchannel(index)->connectivity_state())); - } - if (subchannel(index)->connectivity_state() == GRPC_CHANNEL_READY) { - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, - "[RR %p] found next ready subchannel (%p) at index %" PRIuPTR - " of subchannel_list %p", - policy(), subchannel(index)->subchannel(), index, this); - } - return index; - } - } - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, "[RR %p] no subchannels in ready state", this); - } - return num_subchannels(); -} - -// Sets last_ready_index_ to last_ready_index. -void RoundRobin::RoundRobinSubchannelList::UpdateLastReadySubchannelIndexLocked( - size_t last_ready_index) { - GPR_ASSERT(last_ready_index < num_subchannels()); - last_ready_index_ = last_ready_index; - if (grpc_lb_round_robin_trace.enabled()) { - gpr_log(GPR_INFO, - "[RR %p] setting last_ready_subchannel_index=%" PRIuPTR - " (SC %p, CSC %p)", - policy(), last_ready_index, - subchannel(last_ready_index)->subchannel(), - subchannel(last_ready_index)->connected_subchannel()); - } -} - -grpc_connectivity_state RoundRobin::CheckConnectivityLocked( - grpc_error** error) { - return grpc_connectivity_state_get(&state_tracker_, error); -} - -void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* notify) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - notify); -} - void RoundRobin::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { AutoChildRefsUpdater guard(this); @@ -651,10 +504,11 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, // If we don't have a current subchannel list, go into TRANSIENT_FAILURE. // Otherwise, keep using the current subchannel list (ignore this update). if (subchannel_list_ == nullptr) { - grpc_connectivity_state_set( - &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"), - "rr_update_missing"); + grpc_error* error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + UniquePtr(New(error))); } return; } @@ -671,17 +525,16 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, *addresses, combiner(), - client_channel_factory(), args); + this, &grpc_lb_round_robin_trace, *addresses, combiner(), args); // If we haven't started picking yet or the new list is empty, // immediately promote the new list to the current list. if (!started_picking_ || latest_pending_subchannel_list_->num_subchannels() == 0) { if (latest_pending_subchannel_list_->num_subchannels() == 0) { - grpc_connectivity_state_set( - &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"), - "rr_update_empty"); + grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + UniquePtr(New(error))); } subchannel_list_ = std::move(latest_pending_subchannel_list_); } else { diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 0174a98a73d..c262dfe60f5 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -232,7 +232,7 @@ class SubchannelList : public InternallyRefCounted { protected: SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, + LoadBalancingPolicy::ChannelControlHelper* helper, const grpc_channel_args& args); virtual ~SubchannelList(); @@ -486,7 +486,7 @@ template SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, + LoadBalancingPolicy::ChannelControlHelper* helper, const grpc_channel_args& args) : InternallyRefCounted(tracer), policy_(policy), @@ -509,12 +509,8 @@ SubchannelList::SubchannelList( GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. for (size_t i = 0; i < addresses.size(); i++) { - // If there were any balancer addresses, we would have chosen grpclb - // policy, which does not use a SubchannelList. GPR_ASSERT(!addresses[i].IsBalancer()); - InlinedVector args_to_add; - args_to_add.emplace_back( - SubchannelPoolInterface::CreateChannelArg(policy_->subchannel_pool())); + InlinedVector args_to_add; const size_t subchannel_address_arg_index = args_to_add.size(); args_to_add.emplace_back( Subchannel::CreateSubchannelAddressArg(&addresses[i].address())); @@ -527,8 +523,7 @@ SubchannelList::SubchannelList( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); gpr_free(args_to_add[subchannel_address_arg_index].value.string); - Subchannel* subchannel = grpc_client_channel_factory_create_subchannel( - client_channel_factory, new_args); + Subchannel* subchannel = helper->CreateSubchannel(*new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) { // Subchannel could not be created. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 678b4d75eb9..4b3f2882424 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -70,7 +70,6 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" @@ -125,16 +124,6 @@ class XdsLb : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; - bool PickLocked(PickState* pick, grpc_error** error) override; - void CancelPickLocked(PickState* pick, grpc_error* error) override; - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override; - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override; - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override; - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( @@ -142,31 +131,6 @@ class XdsLb : public LoadBalancingPolicy { channelz::ChildRefsList* child_channels) override; private: - /// Linked list of pending pick requests. It stores all information needed to - /// eventually call pick() on them. They mainly stay pending waiting for the - /// child policy to be created. - /// - /// Note that when a pick is sent to the child policy, we inject our own - /// on_complete callback, so that we can intercept the result before - /// invoking the original on_complete callback. This allows us to set the - /// LB token metadata and add client_stats to the call context. - /// See \a pending_pick_complete() for details. - struct PendingPick { - // The xds lb instance that created the wrapping. This instance is not - // owned; reference counts are untouched. It's used only for logging - // purposes. - XdsLb* xdslb_policy; - // The original pick. - PickState* pick; - // Our on_complete closure and the original one. - grpc_closure on_complete; - grpc_closure* original_on_complete; - // Stats for client-side load reporting. - RefCountedPtr client_stats; - // Next pending pick. - PendingPick* next = nullptr; - }; - /// Contains a call to the LB server and all the data related to the call. class BalancerCallState : public InternallyRefCounted { public: @@ -241,6 +205,36 @@ class XdsLb : public LoadBalancingPolicy { grpc_closure client_load_report_closure_; }; + class Picker : public SubchannelPicker { + public: + Picker(UniquePtr child_picker, + RefCountedPtr client_stats) + : child_picker_(std::move(child_picker)), + client_stats_(std::move(client_stats)) {} + + PickResult Pick(PickState* pick, grpc_error** error) override; + + private: + UniquePtr child_picker_; + RefCountedPtr client_stats_; + }; + + class Helper : public ChannelControlHelper { + public: + explicit Helper(RefCountedPtr parent) : parent_(std::move(parent)) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + grpc_channel* CreateChannel(const char* target, + grpc_client_channel_type type, + const grpc_channel_args& args) override; + void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + UniquePtr picker) override; + void RequestReresolution() override; + + private: + RefCountedPtr parent_; + }; + ~XdsLb(); void ShutdownLocked() override; @@ -263,24 +257,10 @@ class XdsLb : public LoadBalancingPolicy { static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); - // Pending pick methods. - static void PendingPickCleanup(PendingPick* pp); - PendingPick* PendingPickCreate(PickState* pick); - void AddPendingPick(PendingPick* pp); - static void OnPendingPickComplete(void* arg, grpc_error* error); - // Methods for dealing with the child policy. void CreateOrUpdateChildPolicyLocked(); grpc_channel_args* CreateChildPolicyArgsLocked(); void CreateChildPolicyLocked(const char* name, Args args); - bool PickFromChildPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error); - void UpdateConnectivityStateFromChildPolicyLocked( - grpc_error* child_state_error); - static void OnChildPolicyConnectivityChangedLocked(void* arg, - grpc_error* error); - static void OnChildPolicyRequestReresolutionLocked(void* arg, - grpc_error* error); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -294,7 +274,6 @@ class XdsLb : public LoadBalancingPolicy { // Internal state. bool started_picking_ = false; bool shutting_down_ = false; - grpc_connectivity_state_tracker state_tracker_; // The channel for communicating with the LB server. grpc_channel* lb_channel_ = nullptr; @@ -337,17 +316,91 @@ class XdsLb : public LoadBalancingPolicy { grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; - // Pending picks that are waiting on the xDS policy's connectivity. - PendingPick* pending_picks_ = nullptr; - // The policy to use for the backends. OrphanablePtr child_policy_; UniquePtr child_policy_json_string_; - grpc_connectivity_state child_connectivity_state_; - grpc_closure on_child_connectivity_changed_; - grpc_closure on_child_request_reresolution_; }; +// +// XdsLb::Picker +// + +// Destroy function used when embedding client stats in call context. +void DestroyClientStats(void* arg) { + static_cast(arg)->Unref(); +} + +XdsLb::Picker::PickResult XdsLb::Picker::Pick(PickState* pick, + grpc_error** error) { + // TODO(roth): Add support for drop handling. + // Forward pick to child policy. + PickResult result = child_picker_->Pick(pick, error); + // If pick succeeded, add client stats. + if (result == PickResult::PICK_COMPLETE && + pick->connected_subchannel != nullptr && client_stats_ != nullptr) { + pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = + client_stats_->Ref().release(); + pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = + DestroyClientStats; + } + return result; +} + +// +// XdsLb::Helper +// + +Subchannel* XdsLb::Helper::CreateSubchannel(const grpc_channel_args& args) { + if (parent_->shutting_down_) return nullptr; + return parent_->channel_control_helper()->CreateSubchannel(args); +} + +grpc_channel* XdsLb::Helper::CreateChannel(const char* target, + grpc_client_channel_type type, + const grpc_channel_args& args) { + if (parent_->shutting_down_) return nullptr; + return parent_->channel_control_helper()->CreateChannel(target, type, args); +} + +void XdsLb::Helper::UpdateState(grpc_connectivity_state state, + grpc_error* state_error, + UniquePtr picker) { + if (parent_->shutting_down_) { + GRPC_ERROR_UNREF(state_error); + return; + } + // TODO(juanlishen): When in fallback mode, pass the child picker + // through without wrapping it. (Or maybe use a different helper for + // the fallback policy?) + RefCountedPtr client_stats; + if (parent_->lb_calld_ != nullptr && + parent_->lb_calld_->client_stats() != nullptr) { + client_stats = parent_->lb_calld_->client_stats()->Ref(); + } + parent_->channel_control_helper()->UpdateState( + state, state_error, + UniquePtr( + New(std::move(picker), std::move(client_stats)))); +} + +void XdsLb::Helper::RequestReresolution() { + if (parent_->shutting_down_) return; + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] Re-resolution requested from the internal RR policy " + "(%p).", + parent_.get(), parent_->child_policy_.get()); + } + // If we are talking to a balancer, we expect to get updated addresses + // from the balancer, so we can ignore the re-resolution request from + // the RR policy. Otherwise, pass the re-resolution request up to the + // channel. + if (parent_->lb_calld_ == nullptr || + !parent_->lb_calld_->seen_initial_response()) { + parent_->channel_control_helper()->RequestReresolution(); + } +} + // // serverlist parsing code // @@ -709,7 +762,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( // serverlist returned from the current LB call. if (lb_calld->client_stats_report_interval_ > 0 && lb_calld->client_stats_ == nullptr) { - lb_calld->client_stats_.reset(New()); + lb_calld->client_stats_ = MakeRefCounted(); // TODO(roth): We currently track this ref manually. Once the // ClosureRef API is ready, we should pass the RefCountedPtr<> along // with the callback. @@ -792,13 +845,13 @@ void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked( lb_calld->lb_call_, grpc_error_string(error)); gpr_free(status_details); } - xdslb_policy->TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_NONE); // If this lb_calld is still in use, this call ended because of a failure so // we want to retry connecting. Otherwise, we have deliberately ended this // call and no further action is required. if (lb_calld == xdslb_policy->lb_calld_.get()) { xdslb_policy->lb_calld_.reset(); GPR_ASSERT(!xdslb_policy->shutting_down_); + xdslb_policy->channel_control_helper()->RequestReresolution(); if (lb_calld->seen_initial_response_) { // If we lose connection to the LB server, reset the backoff and restart // the LB call immediately. @@ -919,13 +972,6 @@ XdsLb::XdsLb(LoadBalancingPolicy::Args args) GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &XdsLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_child_connectivity_changed_, - &XdsLb::OnChildPolicyConnectivityChangedLocked, this, - grpc_combiner_scheduler(args.combiner)); - GRPC_CLOSURE_INIT(&on_child_request_reresolution_, - &XdsLb::OnChildPolicyRequestReresolutionLocked, this, - grpc_combiner_scheduler(args.combiner)); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "xds"); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -950,21 +996,22 @@ XdsLb::XdsLb(LoadBalancingPolicy::Args args) ParseLbConfig(args.lb_config); // Process channel args. ProcessChannelArgsLocked(*args.args); + // Initialize channel with a picker that will start us connecting. + channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(Ref()))); } XdsLb::~XdsLb() { - GPR_ASSERT(pending_picks_ == nullptr); gpr_mu_destroy(&lb_channel_mu_); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); - grpc_connectivity_state_destroy(&state_tracker_); if (serverlist_ != nullptr) { xds_grpclb_destroy_serverlist(serverlist_); } } void XdsLb::ShutdownLocked() { - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown"); shutting_down_ = true; lb_calld_.reset(); if (retry_timer_callback_pending_) { @@ -974,7 +1021,6 @@ void XdsLb::ShutdownLocked() { grpc_timer_cancel(&lb_fallback_timer_); } child_policy_.reset(); - TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_CANCELLED); // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -985,109 +1031,12 @@ void XdsLb::ShutdownLocked() { lb_channel_ = nullptr; gpr_mu_unlock(&lb_channel_mu_); } - grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_REF(error), "xds_shutdown"); - // Clear pending picks. - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); } // // public methods // -void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) { - PendingPick* pp; - while ((pp = pending_picks_) != nullptr) { - pending_picks_ = pp->next; - pp->pick->on_complete = pp->original_on_complete; - grpc_error* error = GRPC_ERROR_NONE; - if (new_policy->PickLocked(pp->pick, &error)) { - // Synchronous return; schedule closure. - GRPC_CLOSURE_SCHED(pp->pick->on_complete, error); - } - Delete(pp); - } -} - -// Cancel a specific pending pick. -// -// A pick progresses as follows: -// - If there's a child policy available, it'll be handed over to child policy -// (in CreateChildPolicyLocked()). From that point onwards, it'll be the -// child policy's responsibility. For cancellations, that implies the pick -// needs to be also cancelled by the child policy instance. -// - Otherwise, without a child policy instance, picks stay pending at this -// policy's level (xds), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void XdsLb::CancelPickLocked(PickState* pick, grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if (pp->pick == pick) { - pick->connected_subchannel.reset(); - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (child_policy_ != nullptr) { - child_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - -// Cancel all pending picks. -// -// A pick progresses as follows: -// - If there's a child policy available, it'll be handed over to child policy -// (in CreateChildPolicyLocked()). From that point onwards, it'll be the -// child policy's responsibility. For cancellations, that implies the pick -// needs to be also cancelled by the child policy instance. -// - Otherwise, without a child policy instance, picks stay pending at this -// policy's level (xds), inside the pending_picks_ list. To cancel these, -// we invoke the completion closure and set the pick's connected -// subchannel to nullptr right here. -void XdsLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) { - PendingPick* pp = pending_picks_; - pending_picks_ = nullptr; - while (pp != nullptr) { - PendingPick* next = pp->next; - if ((*pp->pick->initial_metadata_flags & initial_metadata_flags_mask) == - initial_metadata_flags_eq) { - // Note: pp is deleted in this callback. - GRPC_CLOSURE_SCHED(&pp->on_complete, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick Cancelled", &error, 1)); - } else { - pp->next = pending_picks_; - pending_picks_ = pp; - } - pp = next; - } - if (child_policy_ != nullptr) { - child_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, - GRPC_ERROR_REF(error)); - } - GRPC_ERROR_UNREF(error); -} - void XdsLb::ExitIdleLocked() { if (!started_picking_) { StartPickingLocked(); @@ -1103,36 +1052,6 @@ void XdsLb::ResetBackoffLocked() { } } -bool XdsLb::PickLocked(PickState* pick, grpc_error** error) { - PendingPick* pp = PendingPickCreate(pick); - bool pick_done = false; - if (child_policy_ != nullptr) { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] about to PICK from policy %p", this, - child_policy_.get()); - } - pick_done = PickFromChildPolicyLocked(false /* force_async */, pp, error); - } else { // child_policy_ == NULL - if (pick->on_complete == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "No pick result available but synchronous result required."); - pick_done = true; - } else { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] No child policy. Adding to xds's pending picks", - this); - } - AddPendingPick(pp); - if (!started_picking_) { - StartPickingLocked(); - } - pick_done = false; - } - } - return pick_done; -} - void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { // delegate to the child_policy_ to fill the children subchannels. @@ -1147,17 +1066,6 @@ void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, } } -grpc_connectivity_state XdsLb::CheckConnectivityLocked( - grpc_error** connectivity_error) { - return grpc_connectivity_state_get(&state_tracker_, connectivity_error); -} - -void XdsLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current, - grpc_closure* closure) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, current, - closure); -} - void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); if (addresses == nullptr) { @@ -1185,9 +1093,8 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { char* uri_str; gpr_asprintf(&uri_str, "fake:///%s", server_name_); gpr_mu_lock(&lb_channel_mu_); - lb_channel_ = grpc_client_channel_factory_create_channel( - client_channel_factory(), uri_str, - GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args); + lb_channel_ = channel_control_helper()->CreateChannel( + uri_str, GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, *lb_channel_args); gpr_mu_unlock(&lb_channel_mu_); GPR_ASSERT(lb_channel_ != nullptr); gpr_free(uri_str); @@ -1402,90 +1309,10 @@ void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg, } } -// -// PendingPick -// - -// Destroy function used when embedding client stats in call context. -void DestroyClientStats(void* arg) { - static_cast(arg)->Unref(); -} - -void XdsLb::PendingPickCleanup(PendingPick* pp) { - // If connected_subchannel is nullptr, no pick has been made by the - // child policy (e.g., all addresses failed to connect). - if (pp->pick->connected_subchannel != nullptr) { - // Pass on client stats via context. Passes ownership of the reference. - if (pp->client_stats != nullptr) { - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = - pp->client_stats.release(); - pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = - DestroyClientStats; - } - } else { - pp->client_stats.reset(); - } -} - -/* The \a on_complete closure passed as part of the pick requires keeping a - * reference to its associated child policy instance. We wrap this closure in - * order to unref the child policy instance upon its invocation */ -void XdsLb::OnPendingPickComplete(void* arg, grpc_error* error) { - PendingPick* pp = static_cast(arg); - PendingPickCleanup(pp); - GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error)); - Delete(pp); -} - -XdsLb::PendingPick* XdsLb::PendingPickCreate(PickState* pick) { - PendingPick* pp = New(); - pp->xdslb_policy = this; - pp->pick = pick; - GRPC_CLOSURE_INIT(&pp->on_complete, &XdsLb::OnPendingPickComplete, pp, - grpc_schedule_on_exec_ctx); - pp->original_on_complete = pick->on_complete; - pick->on_complete = &pp->on_complete; - return pp; -} - -void XdsLb::AddPendingPick(PendingPick* pp) { - pp->next = pending_picks_; - pending_picks_ = pp; -} - // // code for interacting with the child policy // -// Performs a pick over \a child_policy_. Given that a pick can return -// immediately (ignoring its completion callback), we need to perform the -// cleanups this callback would otherwise be responsible for. -// If \a force_async is true, then we will manually schedule the -// completion callback even if the pick is available immediately. -bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp, - grpc_error** error) { - // Set client_stats. - if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) { - pp->client_stats = lb_calld_->client_stats()->Ref(); - } - // Pick via the child policy. - bool pick_done = child_policy_->PickLocked(pp->pick, error); - if (pick_done) { - PendingPickCleanup(pp); - if (force_async) { - GRPC_CLOSURE_SCHED(pp->original_on_complete, *error); - *error = GRPC_ERROR_NONE; - pick_done = false; - } - Delete(pp); - } - // else, the pending pick will be registered and taken care of by the - // pending pick list inside the child policy. Eventually, - // OnPendingPickComplete() will be called, which will (among other - // things) add the LB token to the call's initial metadata. - return pick_done; -} - void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { GPR_ASSERT(child_policy_ == nullptr); child_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( @@ -1494,42 +1321,12 @@ void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { gpr_log(GPR_ERROR, "[xdslb %p] Failure creating a child policy", this); return; } - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - auto self = Ref(DEBUG_LOCATION, "on_child_reresolution_requested"); - self.release(); - child_policy_->SetReresolutionClosureLocked(&on_child_request_reresolution_); - grpc_error* child_state_error = nullptr; - child_connectivity_state_ = - child_policy_->CheckConnectivityLocked(&child_state_error); - // Connectivity state is a function of the child policy updated/created. - UpdateConnectivityStateFromChildPolicyLocked(child_state_error); // Add the xDS's interested_parties pollset_set to that of the newly created // child policy. This will make the child policy progress upon activity on // xDS LB, which in turn is tied to the application's call. grpc_pollset_set_add_pollset_set(child_policy_->interested_parties(), interested_parties()); - // Subscribe to changes to the connectivity of the new child policy. - // TODO(roth): We currently track this ref manually. Once the new - // ClosureRef API is done, pass the RefCountedPtr<> along with the closure. - self = Ref(DEBUG_LOCATION, "on_child_connectivity_changed"); - self.release(); - child_policy_->NotifyOnStateChangeLocked(&child_connectivity_state_, - &on_child_connectivity_changed_); child_policy_->ExitIdleLocked(); - // Send pending picks to child policy. - PendingPick* pp; - while ((pp = pending_picks_)) { - pending_picks_ = pp->next; - if (grpc_lb_xds_trace.enabled()) { - gpr_log( - GPR_INFO, - "[xdslb %p] Pending pick about to (async) PICK from child policy %p", - this, child_policy_.get()); - } - grpc_error* error = GRPC_ERROR_NONE; - PickFromChildPolicyLocked(true /* force_async */, pp, &error); - } } grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { @@ -1587,9 +1384,9 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { } else { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); - lb_policy_args.client_channel_factory = client_channel_factory(); - lb_policy_args.subchannel_pool = subchannel_pool()->Ref(); lb_policy_args.args = args; + lb_policy_args.channel_control_helper = + UniquePtr(New(Ref())); lb_policy_args.lb_config = child_policy_config; CreateChildPolicyLocked(child_policy_name, std::move(lb_policy_args)); if (grpc_lb_xds_trace.enabled()) { @@ -1601,102 +1398,6 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { grpc_json_destroy(child_policy_json); } -void XdsLb::OnChildPolicyRequestReresolutionLocked(void* arg, - grpc_error* error) { - XdsLb* xdslb_policy = static_cast(arg); - if (xdslb_policy->shutting_down_ || error != GRPC_ERROR_NONE) { - xdslb_policy->Unref(DEBUG_LOCATION, "on_child_reresolution_requested"); - return; - } - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Re-resolution requested from child policy " - "(%p).", - xdslb_policy, xdslb_policy->child_policy_.get()); - } - // If we are talking to a balancer, we expect to get updated addresses form - // the balancer, so we can ignore the re-resolution request from the child - // policy. - // Otherwise, handle the re-resolution request using the xds policy's - // original re-resolution closure. - if (xdslb_policy->lb_calld_ == nullptr || - !xdslb_policy->lb_calld_->seen_initial_response()) { - xdslb_policy->TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_NONE); - } - // Give back the wrapper closure to the child policy. - xdslb_policy->child_policy_->SetReresolutionClosureLocked( - &xdslb_policy->on_child_request_reresolution_); -} - -void XdsLb::UpdateConnectivityStateFromChildPolicyLocked( - grpc_error* child_state_error) { - const grpc_connectivity_state curr_glb_state = - grpc_connectivity_state_check(&state_tracker_); - /* The new connectivity status is a function of the previous one and the new - * input coming from the status of the child policy. - * - * current state (xds's) - * | - * v || I | C | R | TF | SD | <- new state (child policy's) - * ===++====+=====+=====+======+======+ - * I || I | C | R | [I] | [I] | - * ---++----+-----+-----+------+------+ - * C || I | C | R | [C] | [C] | - * ---++----+-----+-----+------+------+ - * R || I | C | R | [R] | [R] | - * ---++----+-----+-----+------+------+ - * TF || I | C | R | [TF] | [TF] | - * ---++----+-----+-----+------+------+ - * SD || NA | NA | NA | NA | NA | (*) - * ---++----+-----+-----+------+------+ - * - * A [STATE] indicates that the old child policy is kept. In those cases, - * STATE is the current state of xds, which is left untouched. - * - * In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to - * the previous child policy instance. - * - * Note that the status is never updated to SHUTDOWN as a result of calling - * this function. Only glb_shutdown() has the power to set that state. - * - * (*) This function mustn't be called during shutting down. */ - GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN); - switch (child_connectivity_state_) { - case GRPC_CHANNEL_TRANSIENT_FAILURE: - case GRPC_CHANNEL_SHUTDOWN: - GPR_ASSERT(child_state_error != GRPC_ERROR_NONE); - break; - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_READY: - GPR_ASSERT(child_state_error == GRPC_ERROR_NONE); - } - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Setting xds's state to %s from child policy %p state.", - this, grpc_connectivity_state_name(child_connectivity_state_), - child_policy_.get()); - } - grpc_connectivity_state_set(&state_tracker_, child_connectivity_state_, - child_state_error, - "update_lb_connectivity_status_locked"); -} - -void XdsLb::OnChildPolicyConnectivityChangedLocked(void* arg, - grpc_error* error) { - XdsLb* xdslb_policy = static_cast(arg); - if (xdslb_policy->shutting_down_) { - xdslb_policy->Unref(DEBUG_LOCATION, "on_child_connectivity_changed"); - return; - } - xdslb_policy->UpdateConnectivityStateFromChildPolicyLocked( - GRPC_ERROR_REF(error)); - // Resubscribe. Reuse the "on_child_connectivity_changed" ref. - xdslb_policy->child_policy_->NotifyOnStateChangeLocked( - &xdslb_policy->child_connectivity_state_, - &xdslb_policy->on_child_connectivity_changed_); -} - // // factory // diff --git a/src/core/ext/filters/client_channel/request_routing.cc b/src/core/ext/filters/client_channel/request_routing.cc deleted file mode 100644 index d6ff34c99b5..00000000000 --- a/src/core/ext/filters/client_channel/request_routing.cc +++ /dev/null @@ -1,946 +0,0 @@ -/* - * - * Copyright 2015 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/ext/filters/client_channel/request_routing.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" -#include "src/core/ext/filters/client_channel/http_connect_handshaker.h" -#include "src/core/ext/filters/client_channel/lb_policy_registry.h" -#include "src/core/ext/filters/client_channel/local_subchannel_pool.h" -#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" -#include "src/core/ext/filters/client_channel/resolver_registry.h" -#include "src/core/ext/filters/client_channel/retry_throttle.h" -#include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/ext/filters/deadline/deadline_filter.h" -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/channel/status_util.h" -#include "src/core/lib/gpr/string.h" -#include "src/core/lib/gprpp/inlined_vector.h" -#include "src/core/lib/gprpp/manual_constructor.h" -#include "src/core/lib/iomgr/combiner.h" -#include "src/core/lib/iomgr/iomgr.h" -#include "src/core/lib/iomgr/polling_entity.h" -#include "src/core/lib/profiling/timers.h" -#include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/surface/channel.h" -#include "src/core/lib/transport/connectivity_state.h" -#include "src/core/lib/transport/error_utils.h" -#include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/metadata_batch.h" -#include "src/core/lib/transport/service_config.h" -#include "src/core/lib/transport/static_metadata.h" -#include "src/core/lib/transport/status_metadata.h" - -namespace grpc_core { - -// -// RequestRouter::Request::ResolverResultWaiter -// - -// Handles waiting for a resolver result. -// Used only for the first call on an idle channel. -class RequestRouter::Request::ResolverResultWaiter { - public: - explicit ResolverResultWaiter(Request* request) - : request_router_(request->request_router_), - request_(request), - tracer_enabled_(request_router_->tracer_->enabled()) { - if (tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: deferring pick pending resolver " - "result", - request_router_, request); - } - // Add closure to be run when a resolver result is available. - GRPC_CLOSURE_INIT(&done_closure_, &DoneLocked, this, - grpc_combiner_scheduler(request_router_->combiner_)); - AddToWaitingList(); - // Set cancellation closure, so that we abort if the call is cancelled. - GRPC_CLOSURE_INIT(&cancel_closure_, &CancelLocked, this, - grpc_combiner_scheduler(request_router_->combiner_)); - grpc_call_combiner_set_notify_on_cancel(request->call_combiner_, - &cancel_closure_); - } - - private: - // Adds done_closure_ to - // request_router_->waiting_for_resolver_result_closures_. - void AddToWaitingList() { - grpc_closure_list_append( - &request_router_->waiting_for_resolver_result_closures_, &done_closure_, - GRPC_ERROR_NONE); - } - - // Invoked when a resolver result is available. - static void DoneLocked(void* arg, grpc_error* error) { - ResolverResultWaiter* self = static_cast(arg); - RequestRouter* request_router = self->request_router_; - // If CancelLocked() has already run, delete ourselves without doing - // anything. Note that the call stack may have already been destroyed, - // so it's not safe to access anything in state_. - if (GPR_UNLIKELY(self->finished_)) { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p: call cancelled before resolver result", - request_router); - } - Delete(self); - return; - } - // Otherwise, process the resolver result. - Request* request = self->request_; - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: resolver failed to return data", - request_router, request); - } - GRPC_CLOSURE_RUN(request->on_route_done_, GRPC_ERROR_REF(error)); - } else if (GPR_UNLIKELY(request_router->resolver_ == nullptr)) { - // Shutting down. - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, "request_router=%p request=%p: resolver disconnected", - request_router, request); - } - GRPC_CLOSURE_RUN(request->on_route_done_, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); - } else if (GPR_UNLIKELY(request_router->lb_policy_ == nullptr)) { - // Transient resolver failure. - // If call has wait_for_ready=true, try again; otherwise, fail. - if (*request->pick_.initial_metadata_flags & - GRPC_INITIAL_METADATA_WAIT_FOR_READY) { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: resolver returned but no LB " - "policy; wait_for_ready=true; trying again", - request_router, request); - } - // Re-add ourselves to the waiting list. - self->AddToWaitingList(); - // Return early so that we don't set finished_ to true below. - return; - } else { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: resolver returned but no LB " - "policy; wait_for_ready=false; failing", - request_router, request); - } - GRPC_CLOSURE_RUN( - request->on_route_done_, - grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Name resolution failure"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); - } - } else { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: resolver returned, doing LB " - "pick", - request_router, request); - } - request->ProcessServiceConfigAndStartLbPickLocked(); - } - self->finished_ = true; - } - - // Invoked when the call is cancelled. - // Note: This runs under the client_channel combiner, but will NOT be - // holding the call combiner. - static void CancelLocked(void* arg, grpc_error* error) { - ResolverResultWaiter* self = static_cast(arg); - RequestRouter* request_router = self->request_router_; - // If DoneLocked() has already run, delete ourselves without doing anything. - if (self->finished_) { - Delete(self); - return; - } - Request* request = self->request_; - // If we are being cancelled, immediately invoke on_route_done_ - // to propagate the error back to the caller. - if (error != GRPC_ERROR_NONE) { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: cancelling call waiting for " - "name resolution", - request_router, request); - } - // Note: Although we are not in the call combiner here, we are - // basically stealing the call combiner from the pending pick, so - // it's safe to run on_route_done_ here -- we are essentially - // calling it here instead of calling it in DoneLocked(). - GRPC_CLOSURE_RUN(request->on_route_done_, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Pick cancelled", &error, 1)); - } - self->finished_ = true; - } - - RequestRouter* request_router_; - Request* request_; - const bool tracer_enabled_; - grpc_closure done_closure_; - grpc_closure cancel_closure_; - bool finished_ = false; -}; - -// -// RequestRouter::Request::AsyncPickCanceller -// - -// Handles the call combiner cancellation callback for an async LB pick. -class RequestRouter::Request::AsyncPickCanceller { - public: - explicit AsyncPickCanceller(Request* request) - : request_router_(request->request_router_), - request_(request), - tracer_enabled_(request_router_->tracer_->enabled()) { - GRPC_CALL_STACK_REF(request->owning_call_, "pick_callback_cancel"); - // Set cancellation closure, so that we abort if the call is cancelled. - GRPC_CLOSURE_INIT(&cancel_closure_, &CancelLocked, this, - grpc_combiner_scheduler(request_router_->combiner_)); - grpc_call_combiner_set_notify_on_cancel(request->call_combiner_, - &cancel_closure_); - } - - void MarkFinishedLocked() { - finished_ = true; - GRPC_CALL_STACK_UNREF(request_->owning_call_, "pick_callback_cancel"); - } - - private: - // Invoked when the call is cancelled. - // Note: This runs under the client_channel combiner, but will NOT be - // holding the call combiner. - static void CancelLocked(void* arg, grpc_error* error) { - AsyncPickCanceller* self = static_cast(arg); - Request* request = self->request_; - RequestRouter* request_router = self->request_router_; - if (!self->finished_) { - // Note: request_router->lb_policy_ may have changed since we started our - // pick, in which case we will be cancelling the pick on a policy other - // than the one we started it on. However, this will just be a no-op. - if (error != GRPC_ERROR_NONE && request_router->lb_policy_ != nullptr) { - if (self->tracer_enabled_) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: cancelling pick from LB " - "policy %p", - request_router, request, request_router->lb_policy_.get()); - } - request_router->lb_policy_->CancelPickLocked(&request->pick_, - GRPC_ERROR_REF(error)); - } - request->pick_canceller_ = nullptr; - GRPC_CALL_STACK_UNREF(request->owning_call_, "pick_callback_cancel"); - } - Delete(self); - } - - RequestRouter* request_router_; - Request* request_; - const bool tracer_enabled_; - grpc_closure cancel_closure_; - bool finished_ = false; -}; - -// -// RequestRouter::Request -// - -RequestRouter::Request::Request(grpc_call_stack* owning_call, - grpc_call_combiner* call_combiner, - grpc_polling_entity* pollent, - grpc_metadata_batch* send_initial_metadata, - uint32_t* send_initial_metadata_flags, - ApplyServiceConfigCallback apply_service_config, - void* apply_service_config_user_data, - grpc_closure* on_route_done) - : owning_call_(owning_call), - call_combiner_(call_combiner), - pollent_(pollent), - apply_service_config_(apply_service_config), - apply_service_config_user_data_(apply_service_config_user_data), - on_route_done_(on_route_done) { - pick_.initial_metadata = send_initial_metadata; - pick_.initial_metadata_flags = send_initial_metadata_flags; -} - -RequestRouter::Request::~Request() { - if (pick_.connected_subchannel != nullptr) { - pick_.connected_subchannel.reset(); - } - for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) { - if (pick_.subchannel_call_context[i].destroy != nullptr) { - pick_.subchannel_call_context[i].destroy( - pick_.subchannel_call_context[i].value); - } - } -} - -// Invoked once resolver results are available. -void RequestRouter::Request::ProcessServiceConfigAndStartLbPickLocked() { - // Get service config data if needed. - if (!apply_service_config_(apply_service_config_user_data_)) return; - // Start LB pick. - StartLbPickLocked(); -} - -void RequestRouter::Request::MaybeAddCallToInterestedPartiesLocked() { - if (!pollent_added_to_interested_parties_) { - pollent_added_to_interested_parties_ = true; - grpc_polling_entity_add_to_pollset_set( - pollent_, request_router_->interested_parties_); - } -} - -void RequestRouter::Request::MaybeRemoveCallFromInterestedPartiesLocked() { - if (pollent_added_to_interested_parties_) { - pollent_added_to_interested_parties_ = false; - grpc_polling_entity_del_from_pollset_set( - pollent_, request_router_->interested_parties_); - } -} - -// Starts a pick on the LB policy. -void RequestRouter::Request::StartLbPickLocked() { - if (request_router_->tracer_->enabled()) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: starting pick on lb_policy=%p", - request_router_, this, request_router_->lb_policy_.get()); - } - GRPC_CLOSURE_INIT(&on_pick_done_, &LbPickDoneLocked, this, - grpc_combiner_scheduler(request_router_->combiner_)); - pick_.on_complete = &on_pick_done_; - GRPC_CALL_STACK_REF(owning_call_, "pick_callback"); - grpc_error* error = GRPC_ERROR_NONE; - const bool pick_done = - request_router_->lb_policy_->PickLocked(&pick_, &error); - if (pick_done) { - // Pick completed synchronously. - if (request_router_->tracer_->enabled()) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: pick completed synchronously", - request_router_, this); - } - GRPC_CLOSURE_RUN(on_route_done_, error); - GRPC_CALL_STACK_UNREF(owning_call_, "pick_callback"); - } else { - // Pick will be returned asynchronously. - // Add the request's polling entity to the request_router's - // interested_parties, so that the I/O of the LB policy can be done - // under it. It will be removed in LbPickDoneLocked(). - MaybeAddCallToInterestedPartiesLocked(); - // Request notification on call cancellation. - // We allocate a separate object to track cancellation, since the - // cancellation closure might still be pending when we need to reuse - // the memory in which this Request object is stored for a subsequent - // retry attempt. - pick_canceller_ = New(this); - } -} - -// Callback invoked by LoadBalancingPolicy::PickLocked() for async picks. -// Unrefs the LB policy and invokes on_route_done_. -void RequestRouter::Request::LbPickDoneLocked(void* arg, grpc_error* error) { - Request* self = static_cast(arg); - RequestRouter* request_router = self->request_router_; - if (request_router->tracer_->enabled()) { - gpr_log(GPR_INFO, - "request_router=%p request=%p: pick completed asynchronously", - request_router, self); - } - self->MaybeRemoveCallFromInterestedPartiesLocked(); - if (self->pick_canceller_ != nullptr) { - self->pick_canceller_->MarkFinishedLocked(); - } - GRPC_CLOSURE_RUN(self->on_route_done_, GRPC_ERROR_REF(error)); - GRPC_CALL_STACK_UNREF(self->owning_call_, "pick_callback"); -} - -// -// RequestRouter::LbConnectivityWatcher -// - -class RequestRouter::LbConnectivityWatcher { - public: - LbConnectivityWatcher(RequestRouter* request_router, - grpc_connectivity_state state, - LoadBalancingPolicy* lb_policy, - grpc_channel_stack* owning_stack, - grpc_combiner* combiner) - : request_router_(request_router), - state_(state), - lb_policy_(lb_policy), - owning_stack_(owning_stack) { - GRPC_CHANNEL_STACK_REF(owning_stack_, "LbConnectivityWatcher"); - GRPC_CLOSURE_INIT(&on_changed_, &OnLbPolicyStateChangedLocked, this, - grpc_combiner_scheduler(combiner)); - lb_policy_->NotifyOnStateChangeLocked(&state_, &on_changed_); - } - - ~LbConnectivityWatcher() { - GRPC_CHANNEL_STACK_UNREF(owning_stack_, "LbConnectivityWatcher"); - } - - private: - static void OnLbPolicyStateChangedLocked(void* arg, grpc_error* error) { - LbConnectivityWatcher* self = static_cast(arg); - // If the notification is not for the current policy, we're stale, - // so delete ourselves. - if (self->lb_policy_ != self->request_router_->lb_policy_.get()) { - Delete(self); - return; - } - // Otherwise, process notification. - if (self->request_router_->tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: lb_policy=%p state changed to %s", - self->request_router_, self->lb_policy_, - grpc_connectivity_state_name(self->state_)); - } - self->request_router_->SetConnectivityStateLocked( - self->state_, GRPC_ERROR_REF(error), "lb_changed"); - // If shutting down, terminate watch. - if (self->state_ == GRPC_CHANNEL_SHUTDOWN) { - Delete(self); - return; - } - // Renew watch. - self->lb_policy_->NotifyOnStateChangeLocked(&self->state_, - &self->on_changed_); - } - - RequestRouter* request_router_; - grpc_connectivity_state state_; - // LB policy address. No ref held, so not safe to dereference unless - // it happens to match request_router->lb_policy_. - LoadBalancingPolicy* lb_policy_; - grpc_channel_stack* owning_stack_; - grpc_closure on_changed_; -}; - -// -// RequestRounter::ReresolutionRequestHandler -// - -class RequestRouter::ReresolutionRequestHandler { - public: - ReresolutionRequestHandler(RequestRouter* request_router, - LoadBalancingPolicy* lb_policy, - grpc_channel_stack* owning_stack, - grpc_combiner* combiner) - : request_router_(request_router), - lb_policy_(lb_policy), - owning_stack_(owning_stack) { - GRPC_CHANNEL_STACK_REF(owning_stack_, "ReresolutionRequestHandler"); - GRPC_CLOSURE_INIT(&closure_, &OnRequestReresolutionLocked, this, - grpc_combiner_scheduler(combiner)); - lb_policy_->SetReresolutionClosureLocked(&closure_); - } - - private: - static void OnRequestReresolutionLocked(void* arg, grpc_error* error) { - ReresolutionRequestHandler* self = - static_cast(arg); - RequestRouter* request_router = self->request_router_; - // If this invocation is for a stale LB policy, treat it as an LB shutdown - // signal. - if (self->lb_policy_ != request_router->lb_policy_.get() || - error != GRPC_ERROR_NONE || request_router->resolver_ == nullptr) { - GRPC_CHANNEL_STACK_UNREF(request_router->owning_stack_, - "ReresolutionRequestHandler"); - Delete(self); - return; - } - if (request_router->tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: started name re-resolving", - request_router); - } - request_router->resolver_->RequestReresolutionLocked(); - // Give back the closure to the LB policy. - self->lb_policy_->SetReresolutionClosureLocked(&self->closure_); - } - - RequestRouter* request_router_; - // LB policy address. No ref held, so not safe to dereference unless - // it happens to match request_router->lb_policy_. - LoadBalancingPolicy* lb_policy_; - grpc_channel_stack* owning_stack_; - grpc_closure closure_; -}; - -// -// RequestRouter -// - -RequestRouter::RequestRouter( - grpc_channel_stack* owning_stack, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, - grpc_pollset_set* interested_parties, TraceFlag* tracer, - ProcessResolverResultCallback process_resolver_result, - void* process_resolver_result_user_data, const char* target_uri, - const grpc_channel_args* args, grpc_error** error) - : owning_stack_(owning_stack), - combiner_(combiner), - client_channel_factory_(client_channel_factory), - interested_parties_(interested_parties), - tracer_(tracer), - process_resolver_result_(process_resolver_result), - process_resolver_result_user_data_(process_resolver_result_user_data) { - // Get subchannel pool. - const grpc_arg* arg = - grpc_channel_args_find(args, GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL); - if (grpc_channel_arg_get_bool(arg, false)) { - subchannel_pool_ = MakeRefCounted(); - } else { - subchannel_pool_ = GlobalSubchannelPool::instance(); - } - GRPC_CLOSURE_INIT(&on_resolver_result_changed_, - &RequestRouter::OnResolverResultChangedLocked, this, - grpc_combiner_scheduler(combiner)); - grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, - "request_router"); - grpc_channel_args* new_args = nullptr; - if (process_resolver_result == nullptr) { - grpc_arg arg = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), 0); - new_args = grpc_channel_args_copy_and_add(args, &arg, 1); - } - resolver_ = ResolverRegistry::CreateResolver( - target_uri, (new_args == nullptr ? args : new_args), interested_parties_, - combiner_); - grpc_channel_args_destroy(new_args); - if (resolver_ == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); - } -} - -RequestRouter::~RequestRouter() { - if (resolver_ != nullptr) { - // The only way we can get here is if we never started resolving, - // because we take a ref to the channel stack when we start - // resolving and do not release it until the resolver callback is - // invoked after the resolver shuts down. - resolver_.reset(); - } - if (lb_policy_ != nullptr) { - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties_); - lb_policy_.reset(); - } - if (client_channel_factory_ != nullptr) { - grpc_client_channel_factory_unref(client_channel_factory_); - } - grpc_connectivity_state_destroy(&state_tracker_); -} - -namespace { - -const char* GetChannelConnectivityStateChangeString( - grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "Channel state change to IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "Channel state change to CONNECTING"; - case GRPC_CHANNEL_READY: - return "Channel state change to READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "Channel state change to TRANSIENT_FAILURE"; - case GRPC_CHANNEL_SHUTDOWN: - return "Channel state change to SHUTDOWN"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -} // namespace - -void RequestRouter::SetConnectivityStateLocked(grpc_connectivity_state state, - grpc_error* error, - const char* reason) { - if (lb_policy_ != nullptr) { - if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - // Cancel picks with wait_for_ready=false. - lb_policy_->CancelMatchingPicksLocked( - /* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY, - /* check= */ 0, GRPC_ERROR_REF(error)); - } else if (state == GRPC_CHANNEL_SHUTDOWN) { - // Cancel all picks. - lb_policy_->CancelMatchingPicksLocked(/* mask= */ 0, /* check= */ 0, - GRPC_ERROR_REF(error)); - } - } - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: setting connectivity state to %s", - this, grpc_connectivity_state_name(state)); - } - if (channelz_node_ != nullptr) { - channelz_node_->AddTraceEvent( - channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - GetChannelConnectivityStateChangeString(state))); - } - grpc_connectivity_state_set(&state_tracker_, state, error, reason); -} - -void RequestRouter::StartResolvingLocked() { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: starting name resolution", this); - } - GPR_ASSERT(!started_resolving_); - started_resolving_ = true; - GRPC_CHANNEL_STACK_REF(owning_stack_, "resolver"); - resolver_->NextLocked(&resolver_result_, &on_resolver_result_changed_); -} - -// Invoked from the resolver NextLocked() callback when the resolver -// is shutting down. -void RequestRouter::OnResolverShutdownLocked(grpc_error* error) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: shutting down", this); - } - if (lb_policy_ != nullptr) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: shutting down lb_policy=%p", this, - lb_policy_.get()); - } - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties_); - lb_policy_.reset(); - } - if (resolver_ != nullptr) { - // This should never happen; it can only be triggered by a resolver - // implementation spotaneously deciding to report shutdown without - // being orphaned. This code is included just to be defensive. - if (tracer_->enabled()) { - gpr_log(GPR_INFO, - "request_router=%p: spontaneous shutdown from resolver %p", this, - resolver_.get()); - } - resolver_.reset(); - SetConnectivityStateLocked(GRPC_CHANNEL_SHUTDOWN, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Resolver spontaneous shutdown", &error, 1), - "resolver_spontaneous_shutdown"); - } - grpc_closure_list_fail_all(&waiting_for_resolver_result_closures_, - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Channel disconnected", &error, 1)); - GRPC_CLOSURE_LIST_SCHED(&waiting_for_resolver_result_closures_); - GRPC_CHANNEL_STACK_UNREF(owning_stack_, "resolver"); - grpc_channel_args_destroy(resolver_result_); - resolver_result_ = nullptr; - GRPC_ERROR_UNREF(error); -} - -// Creates a new LB policy, replacing any previous one. -// If the new policy is created successfully, sets *connectivity_state and -// *connectivity_error to its initial connectivity state; otherwise, -// leaves them unchanged. -void RequestRouter::CreateNewLbPolicyLocked( - const char* lb_policy_name, grpc_json* lb_config, - grpc_connectivity_state* connectivity_state, - grpc_error** connectivity_error, TraceStringVector* trace_strings) { - LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = combiner_; - lb_policy_args.client_channel_factory = client_channel_factory_; - lb_policy_args.subchannel_pool = subchannel_pool_; - lb_policy_args.args = resolver_result_; - lb_policy_args.lb_config = lb_config; - OrphanablePtr new_lb_policy = - LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(lb_policy_name, - lb_policy_args); - if (GPR_UNLIKELY(new_lb_policy == nullptr)) { - gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); - if (channelz_node_ != nullptr) { - char* str; - gpr_asprintf(&str, "Could not create LB policy \'%s\'", lb_policy_name); - trace_strings->push_back(str); - } - } else { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: created new LB policy \"%s\" (%p)", - this, lb_policy_name, new_lb_policy.get()); - } - if (channelz_node_ != nullptr) { - char* str; - gpr_asprintf(&str, "Created new LB policy \'%s\'", lb_policy_name); - trace_strings->push_back(str); - } - // Swap out the LB policy and update the fds in interested_parties_. - if (lb_policy_ != nullptr) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: shutting down lb_policy=%p", this, - lb_policy_.get()); - } - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties_); - lb_policy_->HandOffPendingPicksLocked(new_lb_policy.get()); - } - lb_policy_ = std::move(new_lb_policy); - grpc_pollset_set_add_pollset_set(lb_policy_->interested_parties(), - interested_parties_); - // Create re-resolution request handler for the new LB policy. It - // will delete itself when no longer needed. - New(this, lb_policy_.get(), owning_stack_, - combiner_); - // Get the new LB policy's initial connectivity state and start a - // connectivity watch. - GRPC_ERROR_UNREF(*connectivity_error); - *connectivity_state = - lb_policy_->CheckConnectivityLocked(connectivity_error); - if (exit_idle_when_lb_policy_arrives_) { - lb_policy_->ExitIdleLocked(); - exit_idle_when_lb_policy_arrives_ = false; - } - // Create new watcher. It will delete itself when done. - New(this, *connectivity_state, lb_policy_.get(), - owning_stack_, combiner_); - } -} - -void RequestRouter::MaybeAddTraceMessagesForAddressChangesLocked( - TraceStringVector* trace_strings) { - const ServerAddressList* addresses = - FindServerAddressListChannelArg(resolver_result_); - const bool resolution_contains_addresses = - addresses != nullptr && addresses->size() > 0; - if (!resolution_contains_addresses && - previous_resolution_contained_addresses_) { - trace_strings->push_back(gpr_strdup("Address list became empty")); - } else if (resolution_contains_addresses && - !previous_resolution_contained_addresses_) { - trace_strings->push_back(gpr_strdup("Address list became non-empty")); - } - previous_resolution_contained_addresses_ = resolution_contains_addresses; -} - -void RequestRouter::ConcatenateAndAddChannelTraceLocked( - TraceStringVector* trace_strings) const { - if (!trace_strings->empty()) { - gpr_strvec v; - gpr_strvec_init(&v); - gpr_strvec_add(&v, gpr_strdup("Resolution event: ")); - bool is_first = 1; - for (size_t i = 0; i < trace_strings->size(); ++i) { - if (!is_first) gpr_strvec_add(&v, gpr_strdup(", ")); - is_first = false; - gpr_strvec_add(&v, (*trace_strings)[i]); - } - char* flat; - size_t flat_len = 0; - flat = gpr_strvec_flatten(&v, &flat_len); - channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info, - grpc_slice_new(flat, flat_len, gpr_free)); - gpr_strvec_destroy(&v); - } -} - -// Callback invoked when a resolver result is available. -void RequestRouter::OnResolverResultChangedLocked(void* arg, - grpc_error* error) { - RequestRouter* self = static_cast(arg); - if (self->tracer_->enabled()) { - const char* disposition = - self->resolver_result_ != nullptr - ? "" - : (error == GRPC_ERROR_NONE ? " (transient error)" - : " (resolver shutdown)"); - gpr_log(GPR_INFO, - "request_router=%p: got resolver result: resolver_result=%p " - "error=%s%s", - self, self->resolver_result_, grpc_error_string(error), - disposition); - } - // Handle shutdown. - if (error != GRPC_ERROR_NONE || self->resolver_ == nullptr) { - self->OnResolverShutdownLocked(GRPC_ERROR_REF(error)); - return; - } - // Data used to set the channel's connectivity state. - bool set_connectivity_state = true; - // We only want to trace the address resolution in the follow cases: - // (a) Address resolution resulted in service config change. - // (b) Address resolution that causes number of backends to go from - // zero to non-zero. - // (c) Address resolution that causes number of backends to go from - // non-zero to zero. - // (d) Address resolution that causes a new LB policy to be created. - // - // we track a list of strings to eventually be concatenated and traced. - TraceStringVector trace_strings; - grpc_connectivity_state connectivity_state = GRPC_CHANNEL_TRANSIENT_FAILURE; - grpc_error* connectivity_error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy"); - // resolver_result_ will be null in the case of a transient - // resolution error. In that case, we don't have any new result to - // process, which means that we keep using the previous result (if any). - if (self->resolver_result_ == nullptr) { - if (self->tracer_->enabled()) { - gpr_log(GPR_INFO, "request_router=%p: resolver transient failure", self); - } - // Don't override connectivity state if we already have an LB policy. - if (self->lb_policy_ != nullptr) set_connectivity_state = false; - } else { - // Parse the resolver result. - const char* lb_policy_name = nullptr; - grpc_json* lb_policy_config = nullptr; - const bool service_config_changed = self->process_resolver_result_( - self->process_resolver_result_user_data_, *self->resolver_result_, - &lb_policy_name, &lb_policy_config); - GPR_ASSERT(lb_policy_name != nullptr); - // Check to see if we're already using the right LB policy. - const bool lb_policy_name_changed = - self->lb_policy_ == nullptr || - strcmp(self->lb_policy_->name(), lb_policy_name) != 0; - if (self->lb_policy_ != nullptr && !lb_policy_name_changed) { - // Continue using the same LB policy. Update with new addresses. - if (self->tracer_->enabled()) { - gpr_log(GPR_INFO, - "request_router=%p: updating existing LB policy \"%s\" (%p)", - self, lb_policy_name, self->lb_policy_.get()); - } - self->lb_policy_->UpdateLocked(*self->resolver_result_, lb_policy_config); - // No need to set the channel's connectivity state; the existing - // watch on the LB policy will take care of that. - set_connectivity_state = false; - } else { - // Instantiate new LB policy. - self->CreateNewLbPolicyLocked(lb_policy_name, lb_policy_config, - &connectivity_state, &connectivity_error, - &trace_strings); - } - // Add channel trace event. - if (self->channelz_node_ != nullptr) { - if (service_config_changed) { - // TODO(ncteisen): might be worth somehow including a snippet of the - // config in the trace, at the risk of bloating the trace logs. - trace_strings.push_back(gpr_strdup("Service config changed")); - } - self->MaybeAddTraceMessagesForAddressChangesLocked(&trace_strings); - self->ConcatenateAndAddChannelTraceLocked(&trace_strings); - } - // Clean up. - grpc_channel_args_destroy(self->resolver_result_); - self->resolver_result_ = nullptr; - } - // Set the channel's connectivity state if needed. - if (set_connectivity_state) { - self->SetConnectivityStateLocked(connectivity_state, connectivity_error, - "resolver_result"); - } else { - GRPC_ERROR_UNREF(connectivity_error); - } - // Invoke closures that were waiting for results and renew the watch. - GRPC_CLOSURE_LIST_SCHED(&self->waiting_for_resolver_result_closures_); - self->resolver_->NextLocked(&self->resolver_result_, - &self->on_resolver_result_changed_); -} - -void RequestRouter::RouteCallLocked(Request* request) { - GPR_ASSERT(request->pick_.connected_subchannel == nullptr); - request->request_router_ = this; - if (lb_policy_ != nullptr) { - // We already have resolver results, so process the service config - // and start an LB pick. - request->ProcessServiceConfigAndStartLbPickLocked(); - } else if (resolver_ == nullptr) { - GRPC_CLOSURE_RUN(request->on_route_done_, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected")); - } else { - // We do not yet have an LB policy, so wait for a resolver result. - if (!started_resolving_) { - StartResolvingLocked(); - } - // Create a new waiter, which will delete itself when done. - New(request); - // Add the request's polling entity to the request_router's - // interested_parties, so that the I/O of the resolver can be done - // under it. It will be removed in LbPickDoneLocked(). - request->MaybeAddCallToInterestedPartiesLocked(); - } -} - -void RequestRouter::ShutdownLocked(grpc_error* error) { - if (resolver_ != nullptr) { - SetConnectivityStateLocked(GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), - "disconnect"); - resolver_.reset(); - if (!started_resolving_) { - grpc_closure_list_fail_all(&waiting_for_resolver_result_closures_, - GRPC_ERROR_REF(error)); - GRPC_CLOSURE_LIST_SCHED(&waiting_for_resolver_result_closures_); - } - if (lb_policy_ != nullptr) { - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties_); - lb_policy_.reset(); - } - } - GRPC_ERROR_UNREF(error); -} - -grpc_connectivity_state RequestRouter::GetConnectivityState() { - return grpc_connectivity_state_check(&state_tracker_); -} - -void RequestRouter::NotifyOnConnectivityStateChange( - grpc_connectivity_state* state, grpc_closure* closure) { - grpc_connectivity_state_notify_on_state_change(&state_tracker_, state, - closure); -} - -void RequestRouter::ExitIdleLocked() { - if (lb_policy_ != nullptr) { - lb_policy_->ExitIdleLocked(); - } else { - exit_idle_when_lb_policy_arrives_ = true; - if (!started_resolving_ && resolver_ != nullptr) { - StartResolvingLocked(); - } - } -} - -void RequestRouter::ResetConnectionBackoffLocked() { - if (resolver_ != nullptr) { - resolver_->ResetBackoffLocked(); - resolver_->RequestReresolutionLocked(); - } - if (lb_policy_ != nullptr) { - lb_policy_->ResetBackoffLocked(); - } -} - -} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/request_routing.h b/src/core/ext/filters/client_channel/request_routing.h deleted file mode 100644 index 0027163869e..00000000000 --- a/src/core/ext/filters/client_channel/request_routing.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H - -#include - -#include "src/core/ext/filters/client_channel/client_channel_channelz.h" -#include "src/core/ext/filters/client_channel/client_channel_factory.h" -#include "src/core/ext/filters/client_channel/lb_policy.h" -#include "src/core/ext/filters/client_channel/resolver.h" -#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/channel_stack.h" -#include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/inlined_vector.h" -#include "src/core/lib/gprpp/orphanable.h" -#include "src/core/lib/iomgr/call_combiner.h" -#include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/polling_entity.h" -#include "src/core/lib/iomgr/pollset_set.h" -#include "src/core/lib/transport/connectivity_state.h" -#include "src/core/lib/transport/metadata_batch.h" - -namespace grpc_core { - -class RequestRouter { - public: - class Request { - public: - // Synchronous callback that applies the service config to a call. - // Returns false if the call should be failed. - typedef bool (*ApplyServiceConfigCallback)(void* user_data); - - Request(grpc_call_stack* owning_call, grpc_call_combiner* call_combiner, - grpc_polling_entity* pollent, - grpc_metadata_batch* send_initial_metadata, - uint32_t* send_initial_metadata_flags, - ApplyServiceConfigCallback apply_service_config, - void* apply_service_config_user_data, grpc_closure* on_route_done); - - ~Request(); - - // TODO(roth): It seems a bit ugly to expose this member in a - // non-const way. Find a better API to avoid this. - LoadBalancingPolicy::PickState* pick() { return &pick_; } - - private: - friend class RequestRouter; - - class ResolverResultWaiter; - class AsyncPickCanceller; - - void ProcessServiceConfigAndStartLbPickLocked(); - void StartLbPickLocked(); - static void LbPickDoneLocked(void* arg, grpc_error* error); - - void MaybeAddCallToInterestedPartiesLocked(); - void MaybeRemoveCallFromInterestedPartiesLocked(); - - // Populated by caller. - grpc_call_stack* owning_call_; - grpc_call_combiner* call_combiner_; - grpc_polling_entity* pollent_; - ApplyServiceConfigCallback apply_service_config_; - void* apply_service_config_user_data_; - grpc_closure* on_route_done_; - LoadBalancingPolicy::PickState pick_; - - // Internal state. - RequestRouter* request_router_ = nullptr; - bool pollent_added_to_interested_parties_ = false; - grpc_closure on_pick_done_; - AsyncPickCanceller* pick_canceller_ = nullptr; - }; - - // Synchronous callback that takes the service config JSON string and - // LB policy name. - // Returns true if the service config has changed since the last result. - typedef bool (*ProcessResolverResultCallback)(void* user_data, - const grpc_channel_args& args, - const char** lb_policy_name, - grpc_json** lb_policy_config); - - RequestRouter(grpc_channel_stack* owning_stack, grpc_combiner* combiner, - grpc_client_channel_factory* client_channel_factory, - grpc_pollset_set* interested_parties, TraceFlag* tracer, - ProcessResolverResultCallback process_resolver_result, - void* process_resolver_result_user_data, const char* target_uri, - const grpc_channel_args* args, grpc_error** error); - - ~RequestRouter(); - - void set_channelz_node(channelz::ClientChannelNode* channelz_node) { - channelz_node_ = channelz_node; - } - - void RouteCallLocked(Request* request); - - // TODO(roth): Add methods to cancel picks. - - void ShutdownLocked(grpc_error* error); - - void ExitIdleLocked(); - void ResetConnectionBackoffLocked(); - - grpc_connectivity_state GetConnectivityState(); - void NotifyOnConnectivityStateChange(grpc_connectivity_state* state, - grpc_closure* closure); - - LoadBalancingPolicy* lb_policy() const { return lb_policy_.get(); } - - private: - using TraceStringVector = InlinedVector; - - class ReresolutionRequestHandler; - class LbConnectivityWatcher; - - void StartResolvingLocked(); - void OnResolverShutdownLocked(grpc_error* error); - void CreateNewLbPolicyLocked(const char* lb_policy_name, grpc_json* lb_config, - grpc_connectivity_state* connectivity_state, - grpc_error** connectivity_error, - TraceStringVector* trace_strings); - void MaybeAddTraceMessagesForAddressChangesLocked( - TraceStringVector* trace_strings); - void ConcatenateAndAddChannelTraceLocked( - TraceStringVector* trace_strings) const; - static void OnResolverResultChangedLocked(void* arg, grpc_error* error); - - void SetConnectivityStateLocked(grpc_connectivity_state state, - grpc_error* error, const char* reason); - - // Passed in from caller at construction time. - grpc_channel_stack* owning_stack_; - grpc_combiner* combiner_; - grpc_client_channel_factory* client_channel_factory_; - grpc_pollset_set* interested_parties_; - TraceFlag* tracer_; - - channelz::ClientChannelNode* channelz_node_ = nullptr; - - // Resolver and associated state. - OrphanablePtr resolver_; - ProcessResolverResultCallback process_resolver_result_; - void* process_resolver_result_user_data_; - bool started_resolving_ = false; - grpc_channel_args* resolver_result_ = nullptr; - bool previous_resolution_contained_addresses_ = false; - grpc_closure_list waiting_for_resolver_result_closures_; - grpc_closure on_resolver_result_changed_; - - // LB policy and associated state. - OrphanablePtr lb_policy_; - bool exit_idle_when_lb_policy_arrives_ = false; - - // Subchannel pool to pass to LB policy. - RefCountedPtr subchannel_pool_; - - grpc_connectivity_state_tracker state_tracker_; -}; - -} // namespace grpc_core - -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_REQUEST_ROUTING_H */ diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc new file mode 100644 index 00000000000..ad9720fdda9 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -0,0 +1,460 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/ext/filters/client_channel/resolving_lb_policy.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/http_connect_handshaker.h" +#include "src/core/ext/filters/client_channel/lb_policy_registry.h" +#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" +#include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/retry_throttle.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/ext/filters/deadline/deadline_filter.h" +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/status_util.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/iomgr/combiner.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/profiling/timers.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/error_utils.h" +#include "src/core/lib/transport/metadata.h" +#include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/transport/service_config.h" +#include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/status_metadata.h" + +namespace grpc_core { + +// +// ResolvingLoadBalancingPolicy::ResolvingControlHelper +// + +class ResolvingLoadBalancingPolicy::ResolvingControlHelper + : public LoadBalancingPolicy::ChannelControlHelper { + public: + explicit ResolvingControlHelper( + RefCountedPtr parent) + : parent_(std::move(parent)) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. + return parent_->channel_control_helper()->CreateSubchannel(args); + } + + grpc_channel* CreateChannel(const char* target, grpc_client_channel_type type, + const grpc_channel_args& args) override { + if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. + return parent_->channel_control_helper()->CreateChannel(target, type, args); + } + + void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + UniquePtr picker) override { + if (parent_->resolver_ == nullptr) { + // shutting down. + GRPC_ERROR_UNREF(state_error); + return; + } + parent_->channel_control_helper()->UpdateState(state, state_error, + std::move(picker)); + } + + void RequestReresolution() override { + if (parent_->tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: started name re-resolving", + parent_.get()); + } + if (parent_->resolver_ != nullptr) { + parent_->resolver_->RequestReresolutionLocked(); + } + } + + private: + RefCountedPtr parent_; +}; + +// +// ResolvingLoadBalancingPolicy +// + +ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( + Args args, TraceFlag* tracer, UniquePtr target_uri, + UniquePtr child_policy_name, grpc_json* child_lb_config, + grpc_error** error) + : LoadBalancingPolicy(std::move(args)), + tracer_(tracer), + target_uri_(std::move(target_uri)), + child_policy_name_(std::move(child_policy_name)), + child_lb_config_str_(grpc_json_dump_to_string(child_lb_config, 0)), + child_lb_config_(grpc_json_parse_string(child_lb_config_str_.get())) { + GPR_ASSERT(child_policy_name_ != nullptr); + // Don't fetch service config, since this ctor is for use in nested LB + // policies, not at the top level, and we only fetch the service + // config at the top level. + grpc_arg arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), 0); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(args.args, &arg, 1); + *error = Init(*new_args); + grpc_channel_args_destroy(new_args); +} + +ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( + Args args, TraceFlag* tracer, UniquePtr target_uri, + ProcessResolverResultCallback process_resolver_result, + void* process_resolver_result_user_data, grpc_error** error) + : LoadBalancingPolicy(std::move(args)), + tracer_(tracer), + target_uri_(std::move(target_uri)), + process_resolver_result_(process_resolver_result), + process_resolver_result_user_data_(process_resolver_result_user_data) { + GPR_ASSERT(process_resolver_result != nullptr); + *error = Init(*args.args); +} + +grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) { + GRPC_CLOSURE_INIT( + &on_resolver_result_changed_, + &ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked, this, + grpc_combiner_scheduler(combiner())); + resolver_ = ResolverRegistry::CreateResolver( + target_uri_.get(), &args, interested_parties(), combiner()); + if (resolver_ == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); + } + // Return our picker to the channel. + channel_control_helper()->UpdateState( + GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, + UniquePtr(New(Ref()))); + return GRPC_ERROR_NONE; +} + +ResolvingLoadBalancingPolicy::~ResolvingLoadBalancingPolicy() { + GPR_ASSERT(resolver_ == nullptr); + GPR_ASSERT(lb_policy_ == nullptr); + grpc_json_destroy(child_lb_config_); +} + +void ResolvingLoadBalancingPolicy::ShutdownLocked() { + if (resolver_ != nullptr) { + resolver_.reset(); + if (lb_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties()); + lb_policy_.reset(); + } + } +} + +void ResolvingLoadBalancingPolicy::ExitIdleLocked() { + if (lb_policy_ != nullptr) { + lb_policy_->ExitIdleLocked(); + } else { + if (!started_resolving_ && resolver_ != nullptr) { + StartResolvingLocked(); + } + } +} + +void ResolvingLoadBalancingPolicy::ResetBackoffLocked() { + if (resolver_ != nullptr) { + resolver_->ResetBackoffLocked(); + resolver_->RequestReresolutionLocked(); + } + if (lb_policy_ != nullptr) { + lb_policy_->ResetBackoffLocked(); + } +} + +void ResolvingLoadBalancingPolicy::FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) { + if (lb_policy_ != nullptr) { + lb_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + } +} + +void ResolvingLoadBalancingPolicy::StartResolvingLocked() { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: starting name resolution", this); + } + GPR_ASSERT(!started_resolving_); + started_resolving_ = true; + Ref().release(); + resolver_->NextLocked(&resolver_result_, &on_resolver_result_changed_); +} + +// Invoked from the resolver NextLocked() callback when the resolver +// is shutting down. +void ResolvingLoadBalancingPolicy::OnResolverShutdownLocked(grpc_error* error) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down", this); + } + if (lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, + lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties()); + lb_policy_.reset(); + } + if (resolver_ != nullptr) { + // This should never happen; it can only be triggered by a resolver + // implementation spotaneously deciding to report shutdown without + // being orphaned. This code is included just to be defensive. + if (tracer_->enabled()) { + gpr_log(GPR_INFO, + "resolving_lb=%p: spontaneous shutdown from resolver %p", this, + resolver_.get()); + } + resolver_.reset(); + grpc_error* error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Resolver spontaneous shutdown", &error, 1); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), + UniquePtr(New(error))); + } + grpc_channel_args_destroy(resolver_result_); + resolver_result_ = nullptr; + GRPC_ERROR_UNREF(error); + Unref(); +} + +// Creates a new LB policy, replacing any previous one. +// Updates trace_strings to indicate what was done. +void ResolvingLoadBalancingPolicy::CreateNewLbPolicyLocked( + const char* lb_policy_name, grpc_json* lb_config, + TraceStringVector* trace_strings) { + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = combiner(); + lb_policy_args.channel_control_helper = + UniquePtr(New(Ref())); + lb_policy_args.args = resolver_result_; + lb_policy_args.lb_config = lb_config; + OrphanablePtr new_lb_policy = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + lb_policy_name, std::move(lb_policy_args)); + if (GPR_UNLIKELY(new_lb_policy == nullptr)) { + gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); + if (channelz_node() != nullptr) { + char* str; + gpr_asprintf(&str, "Could not create LB policy \"%s\"", lb_policy_name); + trace_strings->push_back(str); + } + } else { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: created new LB policy \"%s\" (%p)", + this, lb_policy_name, new_lb_policy.get()); + } + if (channelz_node() != nullptr) { + char* str; + gpr_asprintf(&str, "Created new LB policy \"%s\"", lb_policy_name); + trace_strings->push_back(str); + } + // Propagate channelz node. + auto* channelz = channelz_node(); + if (channelz != nullptr) { + new_lb_policy->set_channelz_node(channelz->Ref()); + } + // Swap out the LB policy and update the fds in interested_parties_. + if (lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, + lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties()); + } + lb_policy_ = std::move(new_lb_policy); + grpc_pollset_set_add_pollset_set(lb_policy_->interested_parties(), + interested_parties()); + lb_policy_->ExitIdleLocked(); + } +} + +void ResolvingLoadBalancingPolicy::MaybeAddTraceMessagesForAddressChangesLocked( + TraceStringVector* trace_strings) { + const ServerAddressList* addresses = + FindServerAddressListChannelArg(resolver_result_); + const bool resolution_contains_addresses = + addresses != nullptr && addresses->size() > 0; + if (!resolution_contains_addresses && + previous_resolution_contained_addresses_) { + trace_strings->push_back(gpr_strdup("Address list became empty")); + } else if (resolution_contains_addresses && + !previous_resolution_contained_addresses_) { + trace_strings->push_back(gpr_strdup("Address list became non-empty")); + } + previous_resolution_contained_addresses_ = resolution_contains_addresses; +} + +void ResolvingLoadBalancingPolicy::ConcatenateAndAddChannelTraceLocked( + TraceStringVector* trace_strings) const { + if (!trace_strings->empty()) { + gpr_strvec v; + gpr_strvec_init(&v); + gpr_strvec_add(&v, gpr_strdup("Resolution event: ")); + bool is_first = 1; + for (size_t i = 0; i < trace_strings->size(); ++i) { + if (!is_first) gpr_strvec_add(&v, gpr_strdup(", ")); + is_first = false; + gpr_strvec_add(&v, (*trace_strings)[i]); + } + char* flat; + size_t flat_len = 0; + flat = gpr_strvec_flatten(&v, &flat_len); + channelz_node()->AddTraceEvent(channelz::ChannelTrace::Severity::Info, + grpc_slice_new(flat, flat_len, gpr_free)); + gpr_strvec_destroy(&v); + } +} + +// Callback invoked when a resolver result is available. +void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( + void* arg, grpc_error* error) { + auto* self = static_cast(arg); + if (self->tracer_->enabled()) { + const char* disposition = + self->resolver_result_ != nullptr + ? "" + : (error == GRPC_ERROR_NONE ? " (transient error)" + : " (resolver shutdown)"); + gpr_log(GPR_INFO, + "resolving_lb=%p: got resolver result: resolver_result=%p " + "error=%s%s", + self, self->resolver_result_, grpc_error_string(error), + disposition); + } + // Handle shutdown. + if (error != GRPC_ERROR_NONE || self->resolver_ == nullptr) { + self->OnResolverShutdownLocked(GRPC_ERROR_REF(error)); + return; + } + // We only want to trace the address resolution in the follow cases: + // (a) Address resolution resulted in service config change. + // (b) Address resolution that causes number of backends to go from + // zero to non-zero. + // (c) Address resolution that causes number of backends to go from + // non-zero to zero. + // (d) Address resolution that causes a new LB policy to be created. + // + // we track a list of strings to eventually be concatenated and traced. + TraceStringVector trace_strings; + // resolver_result_ will be null in the case of a transient + // resolution error. In that case, we don't have any new result to + // process, which means that we keep using the previous result (if any). + if (self->resolver_result_ == nullptr) { + if (self->tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: resolver transient failure", self); + } + // If we already have an LB policy from a previous resolution + // result, then we continue to let it set the connectivity state. + // Otherwise, we go into TRANSIENT_FAILURE. + if (self->lb_policy_ == nullptr) { + // TODO(roth): When we change the resolver API to be able to + // return transient errors in a cleaner way, we should make it the + // resolver's responsibility to attach a status to the error, + // rather than doing it centrally here. + grpc_error* state_error = grpc_error_set_int( + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Resolver transient failure", &error, 1), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + self->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(state_error), + UniquePtr( + New(state_error))); + } + } else { + // Parse the resolver result. + const char* lb_policy_name = nullptr; + grpc_json* lb_policy_config = nullptr; + bool service_config_changed = false; + if (self->process_resolver_result_ != nullptr) { + service_config_changed = self->process_resolver_result_( + self->process_resolver_result_user_data_, *self->resolver_result_, + &lb_policy_name, &lb_policy_config); + } else { + lb_policy_name = self->child_policy_name_.get(); + lb_policy_config = self->child_lb_config_; + } + GPR_ASSERT(lb_policy_name != nullptr); + // Check to see if we're already using the right LB policy. + const bool lb_policy_name_changed = + self->lb_policy_ == nullptr || + strcmp(self->lb_policy_->name(), lb_policy_name) != 0; + if (self->lb_policy_ != nullptr && !lb_policy_name_changed) { + // Continue using the same LB policy. Update with new addresses. + if (self->tracer_->enabled()) { + gpr_log(GPR_INFO, + "resolving_lb=%p: updating existing LB policy \"%s\" (%p)", + self, lb_policy_name, self->lb_policy_.get()); + } + self->lb_policy_->UpdateLocked(*self->resolver_result_, lb_policy_config); + } else { + // Instantiate new LB policy. + if (self->tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: creating new LB policy \"%s\"", + self, lb_policy_name); + } + self->CreateNewLbPolicyLocked(lb_policy_name, lb_policy_config, + &trace_strings); + } + // Add channel trace event. + if (self->channelz_node() != nullptr) { + if (service_config_changed) { + // TODO(ncteisen): might be worth somehow including a snippet of the + // config in the trace, at the risk of bloating the trace logs. + trace_strings.push_back(gpr_strdup("Service config changed")); + } + self->MaybeAddTraceMessagesForAddressChangesLocked(&trace_strings); + self->ConcatenateAndAddChannelTraceLocked(&trace_strings); + } + // Clean up. + grpc_channel_args_destroy(self->resolver_result_); + self->resolver_result_ = nullptr; + } + // Renew resolver callback. + self->resolver_->NextLocked(&self->resolver_result_, + &self->on_resolver_result_changed_); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h new file mode 100644 index 00000000000..c302ae5d975 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -0,0 +1,137 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H + +#include + +#include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/resolver.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/iomgr/call_combiner.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/metadata_batch.h" + +namespace grpc_core { + +// An LB policy that wraps a resolver and a child LB policy to make use +// of the addresses returned by the resolver. +// +// When used in the client_channel code, the resolver will attempt to +// fetch the service config, and the child LB policy name and config +// will be determined based on the service config. +// +// When used in an LB policy implementation that needs to do another +// round of resolution before creating a child policy, the resolver does +// not fetch the service config, and the caller must pre-determine the +// child LB policy and config to use. +class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { + public: + // If error is set when this returns, then construction failed, and + // the caller may not use the new object. + ResolvingLoadBalancingPolicy(Args args, TraceFlag* tracer, + UniquePtr target_uri, + UniquePtr child_policy_name, + grpc_json* child_lb_config, grpc_error** error); + + // Private ctor, to be used by client_channel only! + // + // Synchronous callback that takes the resolver result and sets + // lb_policy_name and lb_policy_config to point to the right data. + // Returns true if the service config has changed since the last result. + typedef bool (*ProcessResolverResultCallback)(void* user_data, + const grpc_channel_args& args, + const char** lb_policy_name, + grpc_json** lb_policy_config); + // If error is set when this returns, then construction failed, and + // the caller may not use the new object. + ResolvingLoadBalancingPolicy( + Args args, TraceFlag* tracer, UniquePtr target_uri, + ProcessResolverResultCallback process_resolver_result, + void* process_resolver_result_user_data, grpc_error** error); + + virtual const char* name() const override { return "resolving_lb"; } + + // No-op -- should never get updates from the channel. + // TODO(roth): Need to support updating child LB policy's config. + // For xds policy, will also need to support updating config + // independently of args from resolver, since they will be coming from + // different places. Maybe change LB policy API to support that? + void UpdateLocked(const grpc_channel_args& args, + grpc_json* lb_config) override {} + + void ExitIdleLocked() override; + + void ResetBackoffLocked() override; + + void FillChildRefsForChannelz( + channelz::ChildRefsList* child_subchannels, + channelz::ChildRefsList* child_channels) override; + + private: + using TraceStringVector = InlinedVector; + + class ResolvingControlHelper; + + ~ResolvingLoadBalancingPolicy(); + + grpc_error* Init(const grpc_channel_args& args); + void ShutdownLocked() override; + + void StartResolvingLocked(); + void OnResolverShutdownLocked(grpc_error* error); + void CreateNewLbPolicyLocked(const char* lb_policy_name, grpc_json* lb_config, + TraceStringVector* trace_strings); + void MaybeAddTraceMessagesForAddressChangesLocked( + TraceStringVector* trace_strings); + void ConcatenateAndAddChannelTraceLocked( + TraceStringVector* trace_strings) const; + static void OnResolverResultChangedLocked(void* arg, grpc_error* error); + + // Passed in from caller at construction time. + TraceFlag* tracer_; + UniquePtr target_uri_; + ProcessResolverResultCallback process_resolver_result_ = nullptr; + void* process_resolver_result_user_data_ = nullptr; + UniquePtr child_policy_name_; + UniquePtr child_lb_config_str_; + grpc_json* child_lb_config_ = nullptr; + + // Resolver and associated state. + OrphanablePtr resolver_; + bool started_resolving_ = false; + grpc_channel_args* resolver_result_ = nullptr; + bool previous_resolution_contained_addresses_ = false; + grpc_closure on_resolver_result_changed_; + + // Child LB policy and associated state. + OrphanablePtr lb_policy_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H */ diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 1a07edad09c..e2e19a32fd6 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -956,22 +956,17 @@ void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) { } else if (c->disconnected_) { GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } else { - c->SetConnectivityStateLocked( - GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Connect Failed", &error, 1), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), - "connect_failed"); - grpc_connectivity_state_set( - &c->state_and_health_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, - grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Connect Failed", &error, 1), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), - "connect_failed"); - const char* errmsg = grpc_error_string(error); gpr_log(GPR_INFO, "Connect failed: %s", errmsg); - + error = + grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Connect Failed", &error, 1), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_REF(error), "connect_failed"); + grpc_connectivity_state_set(&c->state_and_health_tracker_, + GRPC_CHANNEL_TRANSIENT_FAILURE, error, + "connect_failed"); c->MaybeStartConnectingLocked(); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); } diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h index 9053c60111f..dda5026cbca 100644 --- a/src/core/lib/gprpp/orphanable.h +++ b/src/core/lib/gprpp/orphanable.h @@ -94,8 +94,9 @@ class InternallyRefCounted : public Orphanable { // Note: RefCount tracing is only enabled on debug builds, even when a // TraceFlag is used. template - explicit InternallyRefCounted(TraceFlagT* trace_flag = nullptr) - : refs_(1, trace_flag) {} + explicit InternallyRefCounted(TraceFlagT* trace_flag = nullptr, + intptr_t initial_refcount = 1) + : refs_(initial_refcount, trace_flag) {} virtual ~InternallyRefCounted() = default; RefCountedPtr Ref() GRPC_MUST_USE_RESULT { diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index fa97ffcfed2..761b77baf58 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -221,8 +221,9 @@ class RefCounted : public Impl { // Note: RefCount tracing is only enabled on debug builds, even when a // TraceFlag is used. template - explicit RefCounted(TraceFlagT* trace_flag = nullptr) - : refs_(1, trace_flag) {} + explicit RefCounted(TraceFlagT* trace_flag = nullptr, + intptr_t initial_refcount = 1) + : refs_(initial_refcount, trace_flag) {} // Note: Depending on the Impl used, this dtor can be implicitly virtual. ~RefCounted() = default; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 71de0c4abe0..a9d045281ec 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -329,10 +329,10 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/parse_address.cc', 'src/core/ext/filters/client_channel/proxy_mapper.cc', 'src/core/ext/filters/client_channel/proxy_mapper_registry.cc', - 'src/core/ext/filters/client_channel/request_routing.cc', 'src/core/ext/filters/client_channel/resolver.cc', 'src/core/ext/filters/client_channel/resolver_registry.cc', 'src/core/ext/filters/client_channel/resolver_result_parsing.cc', + 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/subchannel.cc', diff --git a/test/core/channel/channel_stack_builder_test.cc b/test/core/channel/channel_stack_builder_test.cc index b5598e63f9f..efe616ab7fd 100644 --- a/test/core/channel/channel_stack_builder_test.cc +++ b/test/core/channel/channel_stack_builder_test.cc @@ -45,16 +45,6 @@ static void call_destroy_func(grpc_call_element* elem, const grpc_call_final_info* final_info, grpc_closure* ignored) {} -static void call_func(grpc_call_element* elem, - grpc_transport_stream_op_batch* op) {} - -static void channel_func(grpc_channel_element* elem, grpc_transport_op* op) { - if (op->disconnect_with_error != GRPC_ERROR_NONE) { - GRPC_ERROR_UNREF(op->disconnect_with_error); - } - GRPC_CLOSURE_SCHED(op->on_consumed, GRPC_ERROR_NONE); -} - bool g_replacement_fn_called = false; bool g_original_fn_called = false; void set_arg_once_fn(grpc_channel_stack* channel_stack, @@ -77,8 +67,8 @@ static void test_channel_stack_builder_filter_replace(void) { } const grpc_channel_filter replacement_filter = { - call_func, - channel_func, + grpc_call_next_op, + grpc_channel_next_op, 0, call_init_func, grpc_call_stack_ignore_set_pollset_or_pollset_set, @@ -90,8 +80,8 @@ const grpc_channel_filter replacement_filter = { "filter_name"}; const grpc_channel_filter original_filter = { - call_func, - channel_func, + grpc_call_next_op, + grpc_channel_next_op, 0, call_init_func, grpc_call_stack_ignore_set_pollset_or_pollset_set, diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index d6d072101ac..77b354740e5 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -48,25 +48,19 @@ namespace { // A minimal forwarding class to avoid implementing a standalone test LB. class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { public: - ForwardingLoadBalancingPolicy(Args args, - const std::string& delegate_policy_name) - : LoadBalancingPolicy(std::move(args)) { + ForwardingLoadBalancingPolicy( + UniquePtr delegating_helper, Args args, + const std::string& delegate_policy_name, intptr_t initial_refcount = 1) + : LoadBalancingPolicy(std::move(args), initial_refcount) { Args delegate_args; delegate_args.combiner = combiner(); - delegate_args.client_channel_factory = client_channel_factory(); - delegate_args.subchannel_pool = subchannel_pool()->Ref(); + delegate_args.channel_control_helper = std::move(delegating_helper); delegate_args.args = args.args; delegate_args.lb_config = args.lb_config; delegate_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( delegate_policy_name.c_str(), std::move(delegate_args)); grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), interested_parties()); - // Give re-resolution closure to delegate. - GRPC_CLOSURE_INIT(&on_delegate_request_reresolution_, - OnDelegateRequestReresolutionLocked, this, - grpc_combiner_scheduler(combiner())); - Ref().release(); // held by callback. - delegate_->SetReresolutionClosureLocked(&on_delegate_request_reresolution_); } ~ForwardingLoadBalancingPolicy() override = default; @@ -76,35 +70,6 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { delegate_->UpdateLocked(args, lb_config); } - bool PickLocked(PickState* pick, grpc_error** error) override { - return delegate_->PickLocked(pick, error); - } - - void CancelPickLocked(PickState* pick, grpc_error* error) override { - delegate_->CancelPickLocked(pick, error); - } - - void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, - uint32_t initial_metadata_flags_eq, - grpc_error* error) override { - delegate_->CancelMatchingPicksLocked(initial_metadata_flags_mask, - initial_metadata_flags_eq, error); - } - - void NotifyOnStateChangeLocked(grpc_connectivity_state* state, - grpc_closure* closure) override { - delegate_->NotifyOnStateChangeLocked(state, closure); - } - - grpc_connectivity_state CheckConnectivityLocked( - grpc_error** connectivity_error) override { - return delegate_->CheckConnectivityLocked(connectivity_error); - } - - void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override { - delegate_->HandOffPendingPicksLocked(new_policy); - } - void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } void ResetBackoffLocked() override { delegate_->ResetBackoffLocked(); } @@ -116,26 +81,9 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { } private: - void ShutdownLocked() override { - delegate_.reset(); - TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_CANCELLED); - } - - static void OnDelegateRequestReresolutionLocked(void* arg, - grpc_error* error) { - ForwardingLoadBalancingPolicy* self = - static_cast(arg); - if (error != GRPC_ERROR_NONE || self->delegate_ == nullptr) { - self->Unref(); - return; - } - self->TryReresolutionLocked(&grpc_trace_forwarding_lb, GRPC_ERROR_NONE); - self->delegate_->SetReresolutionClosureLocked( - &self->on_delegate_request_reresolution_); - } + void ShutdownLocked() override { delegate_.reset(); } OrphanablePtr delegate_; - grpc_closure on_delegate_request_reresolution_; }; // @@ -150,10 +98,13 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy public: InterceptRecvTrailingMetadataLoadBalancingPolicy( Args args, InterceptRecvTrailingMetadataCallback cb, void* user_data) - : ForwardingLoadBalancingPolicy(std::move(args), - /*delegate_lb_policy_name=*/"pick_first"), - cb_(cb), - user_data_(user_data) {} + : ForwardingLoadBalancingPolicy( + UniquePtr(New( + RefCountedPtr( + this), + cb, user_data)), + std::move(args), /*delegate_lb_policy_name=*/"pick_first", + /*initial_refcount=*/2) {} ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; @@ -161,17 +112,65 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy return kInterceptRecvTrailingMetadataLbPolicyName; } - bool PickLocked(PickState* pick, grpc_error** error) override { - bool ret = ForwardingLoadBalancingPolicy::PickLocked(pick, error); - // Note: This assumes that the delegate policy does not - // intercepting recv_trailing_metadata. If we ever need to use - // this with a delegate policy that does, then we'll need to - // handle async pick returns separately. - New(pick, cb_, user_data_); // deletes itself - return ret; - } - private: + class Picker : public SubchannelPicker { + public: + explicit Picker(UniquePtr delegate_picker, + InterceptRecvTrailingMetadataCallback cb, void* user_data) + : delegate_picker_(std::move(delegate_picker)), + cb_(cb), + user_data_(user_data) {} + + PickResult Pick(PickState* pick, grpc_error** error) override { + PickResult result = delegate_picker_->Pick(pick, error); + if (result == PICK_COMPLETE && pick->connected_subchannel != nullptr) { + New(pick, cb_, user_data_); // deletes itself + } + return result; + } + + private: + UniquePtr delegate_picker_; + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; + }; + + class Helper : public ChannelControlHelper { + public: + Helper( + RefCountedPtr parent, + InterceptRecvTrailingMetadataCallback cb, void* user_data) + : parent_(std::move(parent)), cb_(cb), user_data_(user_data) {} + + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + return parent_->channel_control_helper()->CreateSubchannel(args); + } + + grpc_channel* CreateChannel(const char* target, + grpc_client_channel_type type, + const grpc_channel_args& args) override { + return parent_->channel_control_helper()->CreateChannel(target, type, + args); + } + + void UpdateState(grpc_connectivity_state state, grpc_error* state_error, + UniquePtr picker) override { + parent_->channel_control_helper()->UpdateState( + state, state_error, + UniquePtr( + New(std::move(picker), cb_, user_data_))); + } + + void RequestReresolution() override { + parent_->channel_control_helper()->RequestReresolution(); + } + + private: + RefCountedPtr parent_; + InterceptRecvTrailingMetadataCallback cb_; + void* user_data_; + }; + class TrailingMetadataHandler { public: TrailingMetadataHandler(PickState* pick, @@ -204,9 +203,6 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy grpc_closure* original_recv_trailing_metadata_ready_ = nullptr; grpc_metadata_batch* recv_trailing_metadata_ = nullptr; }; - - InterceptRecvTrailingMetadataCallback cb_; - void* user_data_; }; class InterceptTrailingFactory : public LoadBalancingPolicyFactory { diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 973f47beaf7..e57650fe5b7 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -570,6 +570,7 @@ static void BM_IsolatedFilter(benchmark::State& state) { } gpr_arena_destroy(call_args.arena); grpc_channel_stack_destroy(channel_stack); + grpc_core::ExecCtx::Get()->Flush(); gpr_free(channel_stack); gpr_free(call_stack); diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index d1a2debd7e3..3533c7c00c5 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -936,8 +936,6 @@ src/core/ext/filters/client_channel/proxy_mapper.cc \ src/core/ext/filters/client_channel/proxy_mapper.h \ src/core/ext/filters/client_channel/proxy_mapper_registry.cc \ src/core/ext/filters/client_channel/proxy_mapper_registry.h \ -src/core/ext/filters/client_channel/request_routing.cc \ -src/core/ext/filters/client_channel/request_routing.h \ src/core/ext/filters/client_channel/resolver.cc \ src/core/ext/filters/client_channel/resolver.h \ src/core/ext/filters/client_channel/resolver/README.md \ @@ -962,6 +960,8 @@ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_registry.h \ src/core/ext/filters/client_channel/resolver_result_parsing.cc \ src/core/ext/filters/client_channel/resolver_result_parsing.h \ +src/core/ext/filters/client_channel/resolving_lb_policy.cc \ +src/core/ext/filters/client_channel/resolving_lb_policy.h \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/retry_throttle.h \ src/core/ext/filters/client_channel/server_address.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 84d5c45095f..823e17dd45a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9968,11 +9968,11 @@ "src/core/ext/filters/client_channel/parse_address.h", "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", - "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/subchannel.h", @@ -10015,8 +10015,6 @@ "src/core/ext/filters/client_channel/proxy_mapper.h", "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", "src/core/ext/filters/client_channel/proxy_mapper_registry.h", - "src/core/ext/filters/client_channel/request_routing.cc", - "src/core/ext/filters/client_channel/request_routing.h", "src/core/ext/filters/client_channel/resolver.cc", "src/core/ext/filters/client_channel/resolver.h", "src/core/ext/filters/client_channel/resolver_factory.h", @@ -10024,6 +10022,8 @@ "src/core/ext/filters/client_channel/resolver_registry.h", "src/core/ext/filters/client_channel/resolver_result_parsing.cc", "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/resolving_lb_policy.cc", + "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.cc", From 9345eac21198270d59a46f8d776d9faa86eb746f Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 19 Feb 2019 13:08:26 -0800 Subject: [PATCH 427/814] non-blocking server streaming for health service --- src/python/grpcio/grpc/_server.py | 113 +++-- .../grpc_health/v1/health.py | 59 ++- .../health_check/_health_servicer_test.py | 317 +++++++------ .../grpcio_tests/tests/unit/_rpc_test.py | 439 ++++++++++++------ 4 files changed, 587 insertions(+), 341 deletions(-) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 6caaece82c4..b58201b79d0 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -111,7 +111,7 @@ def _raise_rpc_error(state): def _possibly_finish_call(state, token): state.due.remove(token) - if (state.client is _CANCELLED or state.statused) and not state.due: + if not _is_rpc_state_active(state) and not state.due: callbacks = state.callbacks state.callbacks = None return state, callbacks @@ -218,7 +218,7 @@ class _Context(grpc.ServicerContext): def is_active(self): with self._state.condition: - return self._state.client is not _CANCELLED and not self._state.statused + return _is_rpc_state_active(self._state) def time_remaining(self): return max(self._rpc_event.call_details.deadline - time.time(), 0) @@ -313,7 +313,7 @@ class _RequestIterator(object): def _raise_or_start_receive_message(self): if self._state.client is _CANCELLED: _raise_rpc_error(self._state) - elif self._state.client is _CLOSED or self._state.statused: + elif not _is_rpc_state_active(self._state): raise StopIteration() else: self._call.start_server_batch( @@ -358,7 +358,7 @@ def _unary_request(rpc_event, state, request_deserializer): def unary_request(): with state.condition: - if state.client is _CANCELLED or state.statused: + if not _is_rpc_state_active(state): return None else: rpc_event.call.start_server_batch( @@ -386,10 +386,18 @@ def _unary_request(rpc_event, state, request_deserializer): return unary_request -def _call_behavior(rpc_event, state, behavior, argument, request_deserializer): +def _call_behavior(rpc_event, + state, + behavior, + argument, + request_deserializer, + stream_observer=None): context = _Context(rpc_event, state, request_deserializer) try: - return behavior(argument, context), True + if stream_observer is not None: + return behavior(argument, context, stream_observer), True + else: + return behavior(argument, context), True except Exception as exception: # pylint: disable=broad-except with state.condition: if state.aborted: @@ -434,7 +442,7 @@ def _serialize_response(rpc_event, state, response, response_serializer): def _send_response(rpc_event, state, serialized_response): with state.condition: - if state.client is _CANCELLED or state.statused: + if not _is_rpc_state_active(state): return False else: if state.initial_metadata_allowed: @@ -455,7 +463,7 @@ def _send_response(rpc_event, state, serialized_response): while True: state.condition.wait() if token not in state.due: - return state.client is not _CANCELLED and not state.statused + return _is_rpc_state_active(state) def _status(rpc_event, state, serialized_response): @@ -501,65 +509,102 @@ def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): cygrpc.install_context_from_call(rpc_event.call) + + def on_next(response): + if response is None: + _status(rpc_event, state, None) + else: + serialized_response = _serialize_response( + rpc_event, state, response, response_serializer) + if serialized_response is not None: + _send_response(rpc_event, state, serialized_response) + try: argument = argument_thunk() if argument is not None: - response_iterator, proceed = _call_behavior( - rpc_event, state, behavior, argument, request_deserializer) - if proceed: - while True: - response, proceed = _take_response_from_response_iterator( - rpc_event, state, response_iterator) - if proceed: - if response is None: - _status(rpc_event, state, None) - break - else: - serialized_response = _serialize_response( - rpc_event, state, response, response_serializer) - if serialized_response is not None: - proceed = _send_response( - rpc_event, state, serialized_response) - if not proceed: - break - else: - break - else: - break + if hasattr(behavior, 'experimental_non_blocking' + ) and behavior.experimental_non_blocking: + _call_behavior( + rpc_event, + state, + behavior, + argument, + request_deserializer, + stream_observer=on_next) + else: + response_iterator, proceed = _call_behavior( + rpc_event, state, behavior, argument, request_deserializer) + if proceed: + _stream_response_iterator_adapter(rpc_event, state, on_next, + response_iterator) finally: cygrpc.uninstall_context() -def _handle_unary_unary(rpc_event, state, method_handler, thread_pool): +def _is_rpc_state_active(state): + return state.client is not _CANCELLED and not state.statused + + +def _stream_response_iterator_adapter(rpc_event, state, stream_observer, + response_iterator): + while True: + response, proceed = _take_response_from_response_iterator( + rpc_event, state, response_iterator) + if proceed: + stream_observer(response) + if not _is_rpc_state_active(state): + break + else: + break + + +def _select_thread_pool_for_behavior(behavior, default_thread_pool): + if hasattr(behavior, 'experimental_thread_pool' + ) and behavior.experimental_thread_pool is not None: + return behavior.experimental_thread_pool + else: + return default_thread_pool + + +def _handle_unary_unary(rpc_event, state, method_handler, default_thread_pool): unary_request = _unary_request(rpc_event, state, method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.unary_unary, + default_thread_pool) return thread_pool.submit(_unary_response_in_pool, rpc_event, state, method_handler.unary_unary, unary_request, method_handler.request_deserializer, method_handler.response_serializer) -def _handle_unary_stream(rpc_event, state, method_handler, thread_pool): +def _handle_unary_stream(rpc_event, state, method_handler, default_thread_pool): unary_request = _unary_request(rpc_event, state, method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.unary_stream, + default_thread_pool) return thread_pool.submit(_stream_response_in_pool, rpc_event, state, method_handler.unary_stream, unary_request, method_handler.request_deserializer, method_handler.response_serializer) -def _handle_stream_unary(rpc_event, state, method_handler, thread_pool): +def _handle_stream_unary(rpc_event, state, method_handler, default_thread_pool): request_iterator = _RequestIterator(state, rpc_event.call, method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.stream_unary, + default_thread_pool) return thread_pool.submit( _unary_response_in_pool, rpc_event, state, method_handler.stream_unary, lambda: request_iterator, method_handler.request_deserializer, method_handler.response_serializer) -def _handle_stream_stream(rpc_event, state, method_handler, thread_pool): +def _handle_stream_stream(rpc_event, state, method_handler, + default_thread_pool): request_iterator = _RequestIterator(state, rpc_event.call, method_handler.request_deserializer) + thread_pool = _select_thread_pool_for_behavior(method_handler.stream_stream, + default_thread_pool) return thread_pool.submit( _stream_response_in_pool, rpc_event, state, method_handler.stream_stream, lambda: request_iterator, diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py index 0a5bbb5504c..f135ffbb645 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -13,6 +13,7 @@ # limitations under the License. """Reference implementation for health checking in gRPC Python.""" +import collections import threading import grpc @@ -27,7 +28,7 @@ class _Watcher(): def __init__(self): self._condition = threading.Condition() - self._responses = list() + self._responses = collections.deque() self._open = True def __iter__(self): @@ -38,7 +39,7 @@ class _Watcher(): while not self._responses and self._open: self._condition.wait() if self._responses: - return self._responses.pop(0) + return self._responses.popleft() else: raise StopIteration() @@ -59,20 +60,35 @@ class _Watcher(): self._condition.notify() +def _watcher_to_on_next_adapter(watcher): + + def on_next(response): + if response is None: + watcher.close() + else: + watcher.add(response) + + return on_next + + class HealthServicer(_health_pb2_grpc.HealthServicer): """Servicer handling RPCs for service statuses.""" - def __init__(self): + def __init__(self, + experimental_non_blocking=True, + experimental_thread_pool=None): self._lock = threading.RLock() self._server_status = {} - self._watchers = {} + self._on_next_callbacks = {} + self.Watch.__func__.experimental_non_blocking = experimental_non_blocking + self.Watch.__func__.experimental_thread_pool = experimental_thread_pool - def _on_close_callback(self, watcher, service): + def _on_close_callback(self, on_next, service): def callback(): with self._lock: - self._watchers[service].remove(watcher) - watcher.close() + self._on_next_callbacks[service].remove(on_next) + on_next(None) return callback @@ -85,19 +101,26 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): else: return _health_pb2.HealthCheckResponse(status=status) - def Watch(self, request, context): + # pylint: disable=arguments-differ + def Watch(self, request, context, on_next=None): + blocking_watcher = None + if on_next is None: + # The server does not support the experimental_non_blocking + # parameter. For backwards compatibility, return a blocking response + # generator. + blocking_watcher = _Watcher() + on_next = _watcher_to_on_next_adapter(blocking_watcher) service = request.service with self._lock: status = self._server_status.get(service) if status is None: status = _health_pb2.HealthCheckResponse.SERVICE_UNKNOWN # pylint: disable=no-member - watcher = _Watcher() - watcher.add(_health_pb2.HealthCheckResponse(status=status)) - if service not in self._watchers: - self._watchers[service] = set() - self._watchers[service].add(watcher) - context.add_callback(self._on_close_callback(watcher, service)) - return watcher + on_next(_health_pb2.HealthCheckResponse(status=status)) + if service not in self._on_next_callbacks: + self._on_next_callbacks[service] = set() + self._on_next_callbacks[service].add(on_next) + context.add_callback(self._on_close_callback(on_next, service)) + return blocking_watcher def set(self, service, status): """Sets the status of a service. @@ -109,6 +132,6 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): """ with self._lock: self._server_status[service] = status - if service in self._watchers: - for watcher in self._watchers[service]: - watcher.add(_health_pb2.HealthCheckResponse(status=status)) + if service in self._on_next_callbacks: + for on_next in self._on_next_callbacks[service]: + on_next(_health_pb2.HealthCheckResponse(status=status)) diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index 35794987bc8..3b8ee883bbe 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -38,29 +38,170 @@ def _consume_responses(response_iterator, response_queue): response_queue.put(response) -class HealthServicerTest(unittest.TestCase): +class BaseWatchTests(object): + + class WatchTests(unittest.TestCase): + + def start_server(self, servicer): + self._servicer = servicer + self._servicer.set('', health_pb2.HealthCheckResponse.SERVING) + self._servicer.set(_SERVING_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + self._servicer.set(_UNKNOWN_SERVICE, + health_pb2.HealthCheckResponse.UNKNOWN) + self._servicer.set(_NOT_SERVING_SERVICE, + health_pb2.HealthCheckResponse.NOT_SERVING) + self._server = test_common.test_server() + port = self._server.add_insecure_port('[::]:0') + health_pb2_grpc.add_HealthServicer_to_server( + self._servicer, self._server) + self._server.start() + + self._channel = grpc.insecure_channel('localhost:%d' % port) + self._stub = health_pb2_grpc.HealthStub(self._channel) + + def tearDown(self): + self._server.stop(None) + self._channel.close() + + def test_watch_empty_service(self): + request = health_pb2.HealthCheckRequest(service='') + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response.status) + + rendezvous.cancel() + thread.join() + self.assertTrue(response_queue.empty()) + + def test_watch_new_service(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response.status) + + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.NOT_SERVING) + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, + response.status) + + rendezvous.cancel() + thread.join() + self.assertTrue(response_queue.empty()) + + def test_watch_service_isolation(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + self._servicer.set('some-other-service', + health_pb2.HealthCheckResponse.SERVING) + with self.assertRaises(queue.Empty): + response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + + rendezvous.cancel() + thread.join() + self.assertTrue(response_queue.empty()) + + def test_two_watchers(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue1 = queue.Queue() + response_queue2 = queue.Queue() + rendezvous1 = self._stub.Watch(request) + rendezvous2 = self._stub.Watch(request) + thread1 = threading.Thread( + target=_consume_responses, args=(rendezvous1, response_queue1)) + thread2 = threading.Thread( + target=_consume_responses, args=(rendezvous2, response_queue2)) + thread1.start() + thread2.start() + + response1 = response_queue1.get( + timeout=test_constants.SHORT_TIMEOUT) + response2 = response_queue2.get( + timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response1.status) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response2.status) + + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + response1 = response_queue1.get( + timeout=test_constants.SHORT_TIMEOUT) + response2 = response_queue2.get( + timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response1.status) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response2.status) + + rendezvous1.cancel() + rendezvous2.cancel() + thread1.join() + thread2.join() + self.assertTrue(response_queue1.empty()) + self.assertTrue(response_queue2.empty()) + + def test_cancelled_watch_removed_from_watch_list(self): + request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, + response.status) + + rendezvous.cancel() + self._servicer.set(_WATCH_SERVICE, + health_pb2.HealthCheckResponse.SERVING) + thread.join() + + # Wait, if necessary, for serving thread to process client cancellation + timeout = time.time() + test_constants.SHORT_TIMEOUT + while time.time( + ) < timeout and self._servicer._on_next_callbacks[_WATCH_SERVICE]: + time.sleep(1) + self.assertFalse(self._servicer._on_next_callbacks[_WATCH_SERVICE], + 'watch set should be empty') + self.assertTrue(response_queue.empty()) + + +class HealthServicerTest(BaseWatchTests.WatchTests): def setUp(self): - self._servicer = health.HealthServicer() - self._servicer.set('', health_pb2.HealthCheckResponse.SERVING) - self._servicer.set(_SERVING_SERVICE, - health_pb2.HealthCheckResponse.SERVING) - self._servicer.set(_UNKNOWN_SERVICE, - health_pb2.HealthCheckResponse.UNKNOWN) - self._servicer.set(_NOT_SERVING_SERVICE, - health_pb2.HealthCheckResponse.NOT_SERVING) - self._server = test_common.test_server() - port = self._server.add_insecure_port('[::]:0') - health_pb2_grpc.add_HealthServicer_to_server(self._servicer, - self._server) - self._server.start() - - self._channel = grpc.insecure_channel('localhost:%d' % port) - self._stub = health_pb2_grpc.HealthStub(self._channel) - - def tearDown(self): - self._server.stop(None) - self._channel.close() + super(HealthServicerTest, self).start_server( + health.HealthServicer( + experimental_non_blocking=False, experimental_thread_pool=None)) def test_check_empty_service(self): request = health_pb2.HealthCheckRequest() @@ -90,135 +231,17 @@ class HealthServicerTest(unittest.TestCase): self.assertEqual(grpc.StatusCode.NOT_FOUND, context.exception.code()) - def test_watch_empty_service(self): - request = health_pb2.HealthCheckRequest(service='') - response_queue = queue.Queue() - rendezvous = self._stub.Watch(request) - thread = threading.Thread( - target=_consume_responses, args=(rendezvous, response_queue)) - thread.start() - - response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) - self.assertEqual(health_pb2.HealthCheckResponse.SERVING, - response.status) - - rendezvous.cancel() - thread.join() - self.assertTrue(response_queue.empty()) - - def test_watch_new_service(self): - request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) - response_queue = queue.Queue() - rendezvous = self._stub.Watch(request) - thread = threading.Thread( - target=_consume_responses, args=(rendezvous, response_queue)) - thread.start() - - response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) - self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, - response.status) - - self._servicer.set(_WATCH_SERVICE, - health_pb2.HealthCheckResponse.SERVING) - response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) - self.assertEqual(health_pb2.HealthCheckResponse.SERVING, - response.status) - - self._servicer.set(_WATCH_SERVICE, - health_pb2.HealthCheckResponse.NOT_SERVING) - response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) - self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, - response.status) - - rendezvous.cancel() - thread.join() - self.assertTrue(response_queue.empty()) - - def test_watch_service_isolation(self): - request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) - response_queue = queue.Queue() - rendezvous = self._stub.Watch(request) - thread = threading.Thread( - target=_consume_responses, args=(rendezvous, response_queue)) - thread.start() - - response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) - self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, - response.status) - - self._servicer.set('some-other-service', - health_pb2.HealthCheckResponse.SERVING) - with self.assertRaises(queue.Empty): - response_queue.get(timeout=test_constants.SHORT_TIMEOUT) - - rendezvous.cancel() - thread.join() - self.assertTrue(response_queue.empty()) - - def test_two_watchers(self): - request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) - response_queue1 = queue.Queue() - response_queue2 = queue.Queue() - rendezvous1 = self._stub.Watch(request) - rendezvous2 = self._stub.Watch(request) - thread1 = threading.Thread( - target=_consume_responses, args=(rendezvous1, response_queue1)) - thread2 = threading.Thread( - target=_consume_responses, args=(rendezvous2, response_queue2)) - thread1.start() - thread2.start() - - response1 = response_queue1.get(timeout=test_constants.SHORT_TIMEOUT) - response2 = response_queue2.get(timeout=test_constants.SHORT_TIMEOUT) - self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, - response1.status) - self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, - response2.status) - - self._servicer.set(_WATCH_SERVICE, - health_pb2.HealthCheckResponse.SERVING) - response1 = response_queue1.get(timeout=test_constants.SHORT_TIMEOUT) - response2 = response_queue2.get(timeout=test_constants.SHORT_TIMEOUT) - self.assertEqual(health_pb2.HealthCheckResponse.SERVING, - response1.status) - self.assertEqual(health_pb2.HealthCheckResponse.SERVING, - response2.status) - - rendezvous1.cancel() - rendezvous2.cancel() - thread1.join() - thread2.join() - self.assertTrue(response_queue1.empty()) - self.assertTrue(response_queue2.empty()) - - def test_cancelled_watch_removed_from_watch_list(self): - request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) - response_queue = queue.Queue() - rendezvous = self._stub.Watch(request) - thread = threading.Thread( - target=_consume_responses, args=(rendezvous, response_queue)) - thread.start() - - response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) - self.assertEqual(health_pb2.HealthCheckResponse.SERVICE_UNKNOWN, - response.status) - - rendezvous.cancel() - self._servicer.set(_WATCH_SERVICE, - health_pb2.HealthCheckResponse.SERVING) - thread.join() - - # Wait, if necessary, for serving thread to process client cancellation - timeout = time.time() + test_constants.SHORT_TIMEOUT - while time.time() < timeout and self._servicer._watchers[_WATCH_SERVICE]: - time.sleep(1) - self.assertFalse(self._servicer._watchers[_WATCH_SERVICE], - 'watch set should be empty') - self.assertTrue(response_queue.empty()) - def test_health_service_name(self): self.assertEqual(health.SERVICE_NAME, 'grpc.health.v1.Health') +class HealthServicerBackwardsCompatibleWatchTest(BaseWatchTests.WatchTests): + + def setUp(self): + super(HealthServicerBackwardsCompatibleWatchTest, self).start_server( + health.HealthServicer( + experimental_non_blocking=False, experimental_thread_pool=None)) + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/unit/_rpc_test.py b/src/python/grpcio_tests/tests/unit/_rpc_test.py index a99121cee57..20ef66671a0 100644 --- a/src/python/grpcio_tests/tests/unit/_rpc_test.py +++ b/src/python/grpcio_tests/tests/unit/_rpc_test.py @@ -23,6 +23,7 @@ import grpc from grpc.framework.foundation import logging_pool from tests.unit import test_common +from tests.unit import _thread_pool from tests.unit.framework.common import test_constants from tests.unit.framework.common import test_control @@ -33,8 +34,10 @@ _DESERIALIZE_RESPONSE = lambda bytestring: bytestring[:len(bytestring) // 3] _UNARY_UNARY = '/test/UnaryUnary' _UNARY_STREAM = '/test/UnaryStream' +_UNARY_STREAM_NON_BLOCKING = '/test/UnaryStreamNonBlocking' _STREAM_UNARY = '/test/StreamUnary' _STREAM_STREAM = '/test/StreamStream' +_STREAM_STREAM_NON_BLOCKING = '/test/StreamStreamNonBlocking' class _Callback(object): @@ -59,8 +62,14 @@ class _Callback(object): class _Handler(object): - def __init__(self, control): + def __init__(self, control, thread_pool): self._control = control + self._thread_pool = thread_pool + non_blocking_functions = (self.handle_unary_stream_non_blocking, + self.handle_stream_stream_non_blocking) + for non_blocking_function in non_blocking_functions: + non_blocking_function.__func__.experimental_non_blocking = True + non_blocking_function.__func__.experimental_thread_pool = self._thread_pool def handle_unary_unary(self, request, servicer_context): self._control.control() @@ -87,6 +96,20 @@ class _Handler(object): 'testvalue', ),)) + def handle_unary_stream_non_blocking(self, request, servicer_context, + on_next): + for _ in range(test_constants.STREAM_LENGTH): + self._control.control() + on_next(request) + # yield request + self._control.control() + if servicer_context is not None: + servicer_context.set_trailing_metadata((( + 'testkey', + 'testvalue', + ),)) + on_next(None) + def handle_stream_unary(self, request_iterator, servicer_context): if servicer_context is not None: servicer_context.invocation_metadata() @@ -115,6 +138,20 @@ class _Handler(object): yield request self._control.control() + def handle_stream_stream_non_blocking(self, request_iterator, + servicer_context, on_next): + self._control.control() + if servicer_context is not None: + servicer_context.set_trailing_metadata((( + 'testkey', + 'testvalue', + ),)) + for request in request_iterator: + self._control.control() + on_next(request) + self._control.control() + on_next(None) + class _MethodHandler(grpc.RpcMethodHandler): @@ -145,6 +182,10 @@ class _GenericHandler(grpc.GenericRpcHandler): return _MethodHandler(False, True, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None, self._handler.handle_unary_stream, None, None) + elif handler_call_details.method == _UNARY_STREAM_NON_BLOCKING: + return _MethodHandler( + False, True, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None, + self._handler.handle_unary_stream_non_blocking, None, None) elif handler_call_details.method == _STREAM_UNARY: return _MethodHandler(True, False, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None, None, @@ -152,6 +193,10 @@ class _GenericHandler(grpc.GenericRpcHandler): elif handler_call_details.method == _STREAM_STREAM: return _MethodHandler(True, True, None, None, None, None, None, self._handler.handle_stream_stream) + elif handler_call_details.method == _STREAM_STREAM_NON_BLOCKING: + return _MethodHandler( + True, True, None, None, None, None, None, + self._handler.handle_stream_stream_non_blocking) else: return None @@ -167,6 +212,13 @@ def _unary_stream_multi_callable(channel): response_deserializer=_DESERIALIZE_RESPONSE) +def _unary_stream_non_blocking_multi_callable(channel): + return channel.unary_stream( + _UNARY_STREAM_NON_BLOCKING, + request_serializer=_SERIALIZE_REQUEST, + response_deserializer=_DESERIALIZE_RESPONSE) + + def _stream_unary_multi_callable(channel): return channel.stream_unary( _STREAM_UNARY, @@ -178,11 +230,16 @@ def _stream_stream_multi_callable(channel): return channel.stream_stream(_STREAM_STREAM) +def _stream_stream_non_blocking_multi_callable(channel): + return channel.stream_stream(_STREAM_STREAM_NON_BLOCKING) + + class RPCTest(unittest.TestCase): def setUp(self): self._control = test_control.PauseFailControl() - self._handler = _Handler(self._control) + self._thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + self._handler = _Handler(self._control, self._thread_pool) self._server = test_common.test_server() port = self._server.add_insecure_port('[::]:0') @@ -195,6 +252,16 @@ class RPCTest(unittest.TestCase): self._server.stop(None) self._channel.close() + def testDefaultThreadPoolIsUsed(self): + self._consume_one_stream_response_unary_request( + _unary_stream_multi_callable(self._channel)) + self.assertFalse(self._thread_pool.was_used()) + + def testExperimentalThreadPoolIsUsed(self): + self._consume_one_stream_response_unary_request( + _unary_stream_non_blocking_multi_callable(self._channel)) + self.assertTrue(self._thread_pool.was_used()) + def testUnrecognizedMethod(self): request = b'abc' @@ -227,7 +294,7 @@ class RPCTest(unittest.TestCase): self.assertEqual(expected_response, response) self.assertIs(grpc.StatusCode.OK, call.code()) - self.assertEqual("", call.debug_error_string()) + self.assertEqual('', call.debug_error_string()) def testSuccessfulUnaryRequestFutureUnaryResponse(self): request = b'\x07\x08' @@ -310,6 +377,7 @@ class RPCTest(unittest.TestCase): def testSuccessfulStreamRequestStreamResponse(self): requests = tuple( b'\x77\x58' for _ in range(test_constants.STREAM_LENGTH)) + expected_responses = tuple( self._handler.handle_stream_stream(iter(requests), None)) request_iterator = iter(requests) @@ -425,58 +493,36 @@ class RPCTest(unittest.TestCase): test_is_running_cell[0] = False def testConsumingOneStreamResponseUnaryRequest(self): - request = b'\x57\x38' + self._consume_one_stream_response_unary_request( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - response_iterator = multi_callable( - request, - metadata=(('test', 'ConsumingOneStreamResponseUnaryRequest'),)) - next(response_iterator) + def testConsumingOneStreamResponseUnaryRequestNonBlocking(self): + self._consume_one_stream_response_unary_request( + _unary_stream_non_blocking_multi_callable(self._channel)) def testConsumingSomeButNotAllStreamResponsesUnaryRequest(self): - request = b'\x57\x38' + self._consume_some_but_not_all_stream_responses_unary_request( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - response_iterator = multi_callable( - request, - metadata=(('test', - 'ConsumingSomeButNotAllStreamResponsesUnaryRequest'),)) - for _ in range(test_constants.STREAM_LENGTH // 2): - next(response_iterator) + def testConsumingSomeButNotAllStreamResponsesUnaryRequestNonBlocking(self): + self._consume_some_but_not_all_stream_responses_unary_request( + _unary_stream_non_blocking_multi_callable(self._channel)) def testConsumingSomeButNotAllStreamResponsesStreamRequest(self): - requests = tuple( - b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) - request_iterator = iter(requests) + self._consume_some_but_not_all_stream_responses_stream_request( + _stream_stream_multi_callable(self._channel)) - multi_callable = _stream_stream_multi_callable(self._channel) - response_iterator = multi_callable( - request_iterator, - metadata=(('test', - 'ConsumingSomeButNotAllStreamResponsesStreamRequest'),)) - for _ in range(test_constants.STREAM_LENGTH // 2): - next(response_iterator) + def testConsumingSomeButNotAllStreamResponsesStreamRequestNonBlocking(self): + self._consume_some_but_not_all_stream_responses_stream_request( + _stream_stream_non_blocking_multi_callable(self._channel)) def testConsumingTooManyStreamResponsesStreamRequest(self): - requests = tuple( - b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) - request_iterator = iter(requests) + self._consume_too_many_stream_responses_stream_request( + _stream_stream_multi_callable(self._channel)) - multi_callable = _stream_stream_multi_callable(self._channel) - response_iterator = multi_callable( - request_iterator, - metadata=(('test', - 'ConsumingTooManyStreamResponsesStreamRequest'),)) - for _ in range(test_constants.STREAM_LENGTH): - next(response_iterator) - for _ in range(test_constants.STREAM_LENGTH): - with self.assertRaises(StopIteration): - next(response_iterator) - - self.assertIsNotNone(response_iterator.initial_metadata()) - self.assertIs(grpc.StatusCode.OK, response_iterator.code()) - self.assertIsNotNone(response_iterator.details()) - self.assertIsNotNone(response_iterator.trailing_metadata()) + def testConsumingTooManyStreamResponsesStreamRequestNonBlocking(self): + self._consume_too_many_stream_responses_stream_request( + _stream_stream_non_blocking_multi_callable(self._channel)) def testCancelledUnaryRequestUnaryResponse(self): request = b'\x07\x17' @@ -498,24 +544,12 @@ class RPCTest(unittest.TestCase): self.assertIs(grpc.StatusCode.CANCELLED, response_future.code()) def testCancelledUnaryRequestStreamResponse(self): - request = b'\x07\x19' + self._cancelled_unary_request_stream_response( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - with self._control.pause(): - response_iterator = multi_callable( - request, - metadata=(('test', 'CancelledUnaryRequestStreamResponse'),)) - self._control.block_until_paused() - response_iterator.cancel() - - with self.assertRaises(grpc.RpcError) as exception_context: - next(response_iterator) - self.assertIs(grpc.StatusCode.CANCELLED, - exception_context.exception.code()) - self.assertIsNotNone(response_iterator.initial_metadata()) - self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code()) - self.assertIsNotNone(response_iterator.details()) - self.assertIsNotNone(response_iterator.trailing_metadata()) + def testCancelledUnaryRequestStreamResponseNonBlocking(self): + self._cancelled_unary_request_stream_response( + _unary_stream_non_blocking_multi_callable(self._channel)) def testCancelledStreamRequestUnaryResponse(self): requests = tuple( @@ -543,23 +577,12 @@ class RPCTest(unittest.TestCase): self.assertIsNotNone(response_future.trailing_metadata()) def testCancelledStreamRequestStreamResponse(self): - requests = tuple( - b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)) - request_iterator = iter(requests) + self._cancelled_stream_request_stream_response( + _stream_stream_multi_callable(self._channel)) - multi_callable = _stream_stream_multi_callable(self._channel) - with self._control.pause(): - response_iterator = multi_callable( - request_iterator, - metadata=(('test', 'CancelledStreamRequestStreamResponse'),)) - response_iterator.cancel() - - with self.assertRaises(grpc.RpcError): - next(response_iterator) - self.assertIsNotNone(response_iterator.initial_metadata()) - self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code()) - self.assertIsNotNone(response_iterator.details()) - self.assertIsNotNone(response_iterator.trailing_metadata()) + def testCancelledStreamRequestStreamResponseNonBlocking(self): + self._cancelled_stream_request_stream_response( + _stream_stream_non_blocking_multi_callable(self._channel)) def testExpiredUnaryRequestBlockingUnaryResponse(self): request = b'\x07\x17' @@ -608,21 +631,12 @@ class RPCTest(unittest.TestCase): response_future.exception().code()) def testExpiredUnaryRequestStreamResponse(self): - request = b'\x07\x19' + self._expired_unary_request_stream_response( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - with self._control.pause(): - with self.assertRaises(grpc.RpcError) as exception_context: - response_iterator = multi_callable( - request, - timeout=test_constants.SHORT_TIMEOUT, - metadata=(('test', 'ExpiredUnaryRequestStreamResponse'),)) - next(response_iterator) - - self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, - exception_context.exception.code()) - self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, - response_iterator.code()) + def testExpiredUnaryRequestStreamResponseNonBlocking(self): + self._expired_unary_request_stream_response( + _unary_stream_non_blocking_multi_callable(self._channel)) def testExpiredStreamRequestBlockingUnaryResponse(self): requests = tuple( @@ -678,23 +692,12 @@ class RPCTest(unittest.TestCase): self.assertIsNotNone(response_future.trailing_metadata()) def testExpiredStreamRequestStreamResponse(self): - requests = tuple( - b'\x67\x18' for _ in range(test_constants.STREAM_LENGTH)) - request_iterator = iter(requests) + self._expired_stream_request_stream_response( + _stream_stream_multi_callable(self._channel)) - multi_callable = _stream_stream_multi_callable(self._channel) - with self._control.pause(): - with self.assertRaises(grpc.RpcError) as exception_context: - response_iterator = multi_callable( - request_iterator, - timeout=test_constants.SHORT_TIMEOUT, - metadata=(('test', 'ExpiredStreamRequestStreamResponse'),)) - next(response_iterator) - - self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, - exception_context.exception.code()) - self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, - response_iterator.code()) + def testExpiredStreamRequestStreamResponseNonBlocking(self): + self._expired_stream_request_stream_response( + _stream_stream_non_blocking_multi_callable(self._channel)) def testFailedUnaryRequestBlockingUnaryResponse(self): request = b'\x37\x17' @@ -712,10 +715,10 @@ class RPCTest(unittest.TestCase): # sanity checks on to make sure returned string contains default members # of the error debug_error_string = exception_context.exception.debug_error_string() - self.assertIn("created", debug_error_string) - self.assertIn("description", debug_error_string) - self.assertIn("file", debug_error_string) - self.assertIn("file_line", debug_error_string) + self.assertIn('created', debug_error_string) + self.assertIn('description', debug_error_string) + self.assertIn('file', debug_error_string) + self.assertIn('file_line', debug_error_string) def testFailedUnaryRequestFutureUnaryResponse(self): request = b'\x37\x17' @@ -742,18 +745,12 @@ class RPCTest(unittest.TestCase): self.assertIs(response_future, value_passed_to_callback) def testFailedUnaryRequestStreamResponse(self): - request = b'\x37\x17' + self._failed_unary_request_stream_response( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - with self.assertRaises(grpc.RpcError) as exception_context: - with self._control.fail(): - response_iterator = multi_callable( - request, - metadata=(('test', 'FailedUnaryRequestStreamResponse'),)) - next(response_iterator) - - self.assertIs(grpc.StatusCode.UNKNOWN, - exception_context.exception.code()) + def testFailedUnaryRequestStreamResponseNonBlocking(self): + self._failed_unary_request_stream_response( + _unary_stream_non_blocking_multi_callable(self._channel)) def testFailedStreamRequestBlockingUnaryResponse(self): requests = tuple( @@ -795,21 +792,12 @@ class RPCTest(unittest.TestCase): self.assertIs(response_future, value_passed_to_callback) def testFailedStreamRequestStreamResponse(self): - requests = tuple( - b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) - request_iterator = iter(requests) + self._failed_stream_request_stream_response( + _stream_stream_multi_callable(self._channel)) - multi_callable = _stream_stream_multi_callable(self._channel) - with self._control.fail(): - with self.assertRaises(grpc.RpcError) as exception_context: - response_iterator = multi_callable( - request_iterator, - metadata=(('test', 'FailedStreamRequestStreamResponse'),)) - tuple(response_iterator) - - self.assertIs(grpc.StatusCode.UNKNOWN, - exception_context.exception.code()) - self.assertIs(grpc.StatusCode.UNKNOWN, response_iterator.code()) + def testFailedStreamRequestStreamResponseNonBlocking(self): + self._failed_stream_request_stream_response( + _stream_stream_non_blocking_multi_callable(self._channel)) def testIgnoredUnaryRequestFutureUnaryResponse(self): request = b'\x37\x17' @@ -820,11 +808,12 @@ class RPCTest(unittest.TestCase): metadata=(('test', 'IgnoredUnaryRequestFutureUnaryResponse'),)) def testIgnoredUnaryRequestStreamResponse(self): - request = b'\x37\x17' + self._ignored_unary_stream_request_future_unary_response( + _unary_stream_multi_callable(self._channel)) - multi_callable = _unary_stream_multi_callable(self._channel) - multi_callable( - request, metadata=(('test', 'IgnoredUnaryRequestStreamResponse'),)) + def testIgnoredUnaryRequestStreamResponseNonBlocking(self): + self._ignored_unary_stream_request_future_unary_response( + _unary_stream_non_blocking_multi_callable(self._channel)) def testIgnoredStreamRequestFutureUnaryResponse(self): requests = tuple( @@ -837,11 +826,177 @@ class RPCTest(unittest.TestCase): metadata=(('test', 'IgnoredStreamRequestFutureUnaryResponse'),)) def testIgnoredStreamRequestStreamResponse(self): + self._ignored_stream_request_stream_response( + _stream_stream_multi_callable(self._channel)) + + def testIgnoredStreamRequestStreamResponseNonBlocking(self): + self._ignored_stream_request_stream_response( + _stream_stream_non_blocking_multi_callable(self._channel)) + + def _consume_one_stream_response_unary_request(self, multi_callable): + request = b'\x57\x38' + + response_iterator = multi_callable( + request, + metadata=(('test', 'ConsumingOneStreamResponseUnaryRequest'),)) + next(response_iterator) + + def _consume_some_but_not_all_stream_responses_unary_request( + self, multi_callable): + request = b'\x57\x38' + + response_iterator = multi_callable( + request, + metadata=(('test', + 'ConsumingSomeButNotAllStreamResponsesUnaryRequest'),)) + for _ in range(test_constants.STREAM_LENGTH // 2): + next(response_iterator) + + def _consume_some_but_not_all_stream_responses_stream_request( + self, multi_callable): + requests = tuple( + b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + response_iterator = multi_callable( + request_iterator, + metadata=(('test', + 'ConsumingSomeButNotAllStreamResponsesStreamRequest'),)) + for _ in range(test_constants.STREAM_LENGTH // 2): + next(response_iterator) + + def _consume_too_many_stream_responses_stream_request(self, multi_callable): + requests = tuple( + b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + response_iterator = multi_callable( + request_iterator, + metadata=(('test', + 'ConsumingTooManyStreamResponsesStreamRequest'),)) + for _ in range(test_constants.STREAM_LENGTH): + next(response_iterator) + for _ in range(test_constants.STREAM_LENGTH): + with self.assertRaises(StopIteration): + next(response_iterator) + + self.assertIsNotNone(response_iterator.initial_metadata()) + self.assertIs(grpc.StatusCode.OK, response_iterator.code()) + self.assertIsNotNone(response_iterator.details()) + self.assertIsNotNone(response_iterator.trailing_metadata()) + + def _cancelled_unary_request_stream_response(self, multi_callable): + request = b'\x07\x19' + + with self._control.pause(): + response_iterator = multi_callable( + request, + metadata=(('test', 'CancelledUnaryRequestStreamResponse'),)) + self._control.block_until_paused() + response_iterator.cancel() + + with self.assertRaises(grpc.RpcError) as exception_context: + next(response_iterator) + self.assertIs(grpc.StatusCode.CANCELLED, + exception_context.exception.code()) + self.assertIsNotNone(response_iterator.initial_metadata()) + self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code()) + self.assertIsNotNone(response_iterator.details()) + self.assertIsNotNone(response_iterator.trailing_metadata()) + + def _cancelled_stream_request_stream_response(self, multi_callable): + requests = tuple( + b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + with self._control.pause(): + response_iterator = multi_callable( + request_iterator, + metadata=(('test', 'CancelledStreamRequestStreamResponse'),)) + response_iterator.cancel() + + with self.assertRaises(grpc.RpcError): + next(response_iterator) + self.assertIsNotNone(response_iterator.initial_metadata()) + self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code()) + self.assertIsNotNone(response_iterator.details()) + self.assertIsNotNone(response_iterator.trailing_metadata()) + + def _expired_unary_request_stream_response(self, multi_callable): + request = b'\x07\x19' + + with self._control.pause(): + with self.assertRaises(grpc.RpcError) as exception_context: + response_iterator = multi_callable( + request, + timeout=test_constants.SHORT_TIMEOUT, + metadata=(('test', 'ExpiredUnaryRequestStreamResponse'),)) + next(response_iterator) + + self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, + exception_context.exception.code()) + self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, + response_iterator.code()) + + def _expired_stream_request_stream_response(self, multi_callable): + requests = tuple( + b'\x67\x18' for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + with self._control.pause(): + with self.assertRaises(grpc.RpcError) as exception_context: + response_iterator = multi_callable( + request_iterator, + timeout=test_constants.SHORT_TIMEOUT, + metadata=(('test', 'ExpiredStreamRequestStreamResponse'),)) + next(response_iterator) + + self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, + exception_context.exception.code()) + self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, + response_iterator.code()) + + def _failed_unary_request_stream_response(self, multi_callable): + request = b'\x37\x17' + + with self.assertRaises(grpc.RpcError) as exception_context: + with self._control.fail(): + response_iterator = multi_callable( + request, + metadata=(('test', 'FailedUnaryRequestStreamResponse'),)) + next(response_iterator) + + self.assertIs(grpc.StatusCode.UNKNOWN, + exception_context.exception.code()) + + def _failed_stream_request_stream_response(self, multi_callable): + requests = tuple( + b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) + request_iterator = iter(requests) + + with self._control.fail(): + with self.assertRaises(grpc.RpcError) as exception_context: + response_iterator = multi_callable( + request_iterator, + metadata=(('test', 'FailedStreamRequestStreamResponse'),)) + tuple(response_iterator) + + self.assertIs(grpc.StatusCode.UNKNOWN, + exception_context.exception.code()) + self.assertIs(grpc.StatusCode.UNKNOWN, response_iterator.code()) + + def _ignored_unary_stream_request_future_unary_response( + self, multi_callable): + request = b'\x37\x17' + + multi_callable( + request, metadata=(('test', 'IgnoredUnaryRequestStreamResponse'),)) + + def _ignored_stream_request_stream_response(self, multi_callable): requests = tuple( b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH)) request_iterator = iter(requests) - multi_callable = _stream_stream_multi_callable(self._channel) multi_callable( request_iterator, metadata=(('test', 'IgnoredStreamRequestStreamResponse'),)) From 00f85c28c9e794f99319d8fdaef2d6f8c50d6476 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 19 Feb 2019 13:46:47 -0800 Subject: [PATCH 428/814] update tests.json --- src/python/grpcio_tests/tests/tests.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index 00b55b02e89..c33c0c17d26 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -3,6 +3,7 @@ "channelz._channelz_servicer_test.ChannelzServicerTest", "fork._fork_interop_test.ForkInteropTest", "health_check._health_servicer_test.HealthServicerTest", + "health_check._health_servicer_test.HealthServicerBackwardsCompatibleWatchTest", "interop._insecure_intraop_test.InsecureIntraopTest", "interop._secure_intraop_test.SecureIntraopTest", "protoc_plugin._python_plugin_test.PythonPluginTest", From 72035e7265037676a8cd63abd2556d20df64e377 Mon Sep 17 00:00:00 2001 From: Yuwei Huang Date: Tue, 19 Feb 2019 13:58:26 -0800 Subject: [PATCH 429/814] Move thread body logic into a private static method Clang doesn't support adapting calling convention when converting a non-capturing lambda into a function pointer, and it doesn't support tagging a lambda with calling convention AFAICT. In thd_windows.cc, we create the thread body lambda and pass it to CreateThread(), which fails to build on clang because it cannot convert the lambda into stdcall function. Note that this bug only happens when building for x32 architecture. x64 is not affected because there is only one standard x64 calling convention. This change fixes this by moving the thread body logic into a private static method and tagging it with WINAPI (which expands to __stdcall). --- src/core/lib/gprpp/thd_windows.cc | 33 ++++++++++++++----------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index 71584fd358e..2512002a96c 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -33,10 +33,8 @@ #if defined(_MSC_VER) #define thread_local __declspec(thread) -#define WIN_LAMBDA #elif defined(__GNUC__) #define thread_local __thread -#define WIN_LAMBDA WINAPI #else #error "Unknown compiler - please file a bug report" #endif @@ -71,22 +69,7 @@ class ThreadInternalsWindows gpr_free(info_); *success = false; } else { - handle = CreateThread( - nullptr, 64 * 1024, - [](void* v) WIN_LAMBDA -> DWORD { - g_thd_info = static_cast(v); - gpr_mu_lock(&g_thd_info->thread->mu_); - while (!g_thd_info->thread->started_) { - gpr_cv_wait(&g_thd_info->thread->ready_, &g_thd_info->thread->mu_, - gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - gpr_mu_unlock(&g_thd_info->thread->mu_); - g_thd_info->body(g_thd_info->arg); - BOOL ret = SetEvent(g_thd_info->join_event); - GPR_ASSERT(ret); - return 0; - }, - info_, 0, nullptr); + handle = CreateThread(nullptr, 64 * 1024, thread_body, info_, 0, nullptr); if (handle == nullptr) { destroy_thread(); *success = false; @@ -116,6 +99,20 @@ class ThreadInternalsWindows } private: + static DWORD WINAPI thread_body(void* v) { + g_thd_info = static_cast(v); + gpr_mu_lock(&g_thd_info->thread->mu_); + while (!g_thd_info->thread->started_) { + gpr_cv_wait(&g_thd_info->thread->ready_, &g_thd_info->thread->mu_, + gpr_inf_future(GPR_CLOCK_MONOTONIC)); + } + gpr_mu_unlock(&g_thd_info->thread->mu_); + g_thd_info->body(g_thd_info->arg); + BOOL ret = SetEvent(g_thd_info->join_event); + GPR_ASSERT(ret); + return 0; + } + void destroy_thread() { CloseHandle(info_->join_event); gpr_free(info_); From 830d7d1e6108c1ee95373718788732145e107442 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 19 Feb 2019 14:02:29 -0800 Subject: [PATCH 430/814] order --- src/python/grpcio_tests/tests/tests.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index c33c0c17d26..7729ca01d53 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -2,8 +2,8 @@ "_sanity._sanity_test.SanityTest", "channelz._channelz_servicer_test.ChannelzServicerTest", "fork._fork_interop_test.ForkInteropTest", - "health_check._health_servicer_test.HealthServicerTest", "health_check._health_servicer_test.HealthServicerBackwardsCompatibleWatchTest", + "health_check._health_servicer_test.HealthServicerTest", "interop._insecure_intraop_test.InsecureIntraopTest", "interop._secure_intraop_test.SecureIntraopTest", "protoc_plugin._python_plugin_test.PythonPluginTest", From 0346ec2f45647741cf55109075cf9fe9a70f097e Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 19 Feb 2019 14:18:00 -0800 Subject: [PATCH 431/814] stream_observer->on_next_callback --- src/python/grpcio/grpc/_server.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index b58201b79d0..b1b6027ed5a 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -391,11 +391,11 @@ def _call_behavior(rpc_event, behavior, argument, request_deserializer, - stream_observer=None): + on_next_callback=None): context = _Context(rpc_event, state, request_deserializer) try: - if stream_observer is not None: - return behavior(argument, context, stream_observer), True + if on_next_callback is not None: + return behavior(argument, context, on_next_callback), True else: return behavior(argument, context), True except Exception as exception: # pylint: disable=broad-except @@ -530,7 +530,7 @@ def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, behavior, argument, request_deserializer, - stream_observer=on_next) + on_next_callback=on_next) else: response_iterator, proceed = _call_behavior( rpc_event, state, behavior, argument, request_deserializer) @@ -545,13 +545,13 @@ def _is_rpc_state_active(state): return state.client is not _CANCELLED and not state.statused -def _stream_response_iterator_adapter(rpc_event, state, stream_observer, +def _stream_response_iterator_adapter(rpc_event, state, on_next_callback, response_iterator): while True: response, proceed = _take_response_from_response_iterator( rpc_event, state, response_iterator) if proceed: - stream_observer(response) + on_next_callback(response) if not _is_rpc_state_active(state): break else: From a5c96cf7652bc6d3435c310259706056dc0ccedc Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 19 Feb 2019 14:38:11 -0800 Subject: [PATCH 432/814] fix test --- .../grpc_health/v1/health.py | 31 ++++++++++--------- .../health_check/_health_servicer_test.py | 18 +++++++---- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py index f135ffbb645..c1bb998df90 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -60,15 +60,15 @@ class _Watcher(): self._condition.notify() -def _watcher_to_on_next_adapter(watcher): +def _watcher_to_on_next_callback_adapter(watcher): - def on_next(response): + def on_next_callback(response): if response is None: watcher.close() else: watcher.add(response) - return on_next + return on_next_callback class HealthServicer(_health_pb2_grpc.HealthServicer): @@ -83,12 +83,12 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): self.Watch.__func__.experimental_non_blocking = experimental_non_blocking self.Watch.__func__.experimental_thread_pool = experimental_thread_pool - def _on_close_callback(self, on_next, service): + def _on_close_callback(self, on_next_callback, service): def callback(): with self._lock: - self._on_next_callbacks[service].remove(on_next) - on_next(None) + self._on_next_callbacks[service].remove(on_next_callback) + on_next_callback(None) return callback @@ -102,24 +102,26 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): return _health_pb2.HealthCheckResponse(status=status) # pylint: disable=arguments-differ - def Watch(self, request, context, on_next=None): + def Watch(self, request, context, on_next_callback=None): blocking_watcher = None - if on_next is None: + if on_next_callback is None: # The server does not support the experimental_non_blocking # parameter. For backwards compatibility, return a blocking response # generator. blocking_watcher = _Watcher() - on_next = _watcher_to_on_next_adapter(blocking_watcher) + on_next_callback = _watcher_to_on_next_callback_adapter( + blocking_watcher) service = request.service with self._lock: status = self._server_status.get(service) if status is None: status = _health_pb2.HealthCheckResponse.SERVICE_UNKNOWN # pylint: disable=no-member - on_next(_health_pb2.HealthCheckResponse(status=status)) + on_next_callback(_health_pb2.HealthCheckResponse(status=status)) if service not in self._on_next_callbacks: self._on_next_callbacks[service] = set() - self._on_next_callbacks[service].add(on_next) - context.add_callback(self._on_close_callback(on_next, service)) + self._on_next_callbacks[service].add(on_next_callback) + context.add_callback( + self._on_close_callback(on_next_callback, service)) return blocking_watcher def set(self, service, status): @@ -133,5 +135,6 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): with self._lock: self._server_status[service] = status if service in self._on_next_callbacks: - for on_next in self._on_next_callbacks[service]: - on_next(_health_pb2.HealthCheckResponse(status=status)) + for on_next_callback in self._on_next_callbacks[service]: + on_next_callback( + _health_pb2.HealthCheckResponse(status=status)) diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index 3b8ee883bbe..2b1d17adfb0 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -23,6 +23,7 @@ from grpc_health.v1 import health_pb2 from grpc_health.v1 import health_pb2_grpc from tests.unit import test_common +from tests.unit import _thread_pool from tests.unit.framework.common import test_constants from six.moves import queue @@ -42,8 +43,11 @@ class BaseWatchTests(object): class WatchTests(unittest.TestCase): - def start_server(self, servicer): - self._servicer = servicer + def start_server(self, non_blocking=False, thread_pool=None): + self._thread_pool = thread_pool + self._servicer = health.HealthServicer( + experimental_non_blocking=non_blocking, + experimental_thread_pool=thread_pool) self._servicer.set('', health_pb2.HealthCheckResponse.SERVING) self._servicer.set(_SERVING_SERVICE, health_pb2.HealthCheckResponse.SERVING) @@ -80,6 +84,9 @@ class BaseWatchTests(object): thread.join() self.assertTrue(response_queue.empty()) + if self._thread_pool is not None: + self.assertTrue(self._thread_pool.was_used()) + def test_watch_new_service(self): request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) response_queue = queue.Queue() @@ -199,9 +206,9 @@ class BaseWatchTests(object): class HealthServicerTest(BaseWatchTests.WatchTests): def setUp(self): + self._thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) super(HealthServicerTest, self).start_server( - health.HealthServicer( - experimental_non_blocking=False, experimental_thread_pool=None)) + non_blocking=True, thread_pool=self._thread_pool) def test_check_empty_service(self): request = health_pb2.HealthCheckRequest() @@ -239,8 +246,7 @@ class HealthServicerBackwardsCompatibleWatchTest(BaseWatchTests.WatchTests): def setUp(self): super(HealthServicerBackwardsCompatibleWatchTest, self).start_server( - health.HealthServicer( - experimental_non_blocking=False, experimental_thread_pool=None)) + non_blocking=False, thread_pool=None) if __name__ == '__main__': From 77f325a9af10656a34b5602759a896a67436f54f Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 19 Feb 2019 14:54:02 -0800 Subject: [PATCH 433/814] bazel target --- .../tests/health_check/_health_servicer_test.py | 2 +- src/python/grpcio_tests/tests/unit/BUILD.bazel | 12 ++++++------ .../tests/unit/_channel_connectivity_test.py | 2 +- .../tests/unit/_channel_ready_future_test.py | 2 +- .../tests/unit/{_thread_pool.py => thread_pool.py} | 0 5 files changed, 9 insertions(+), 9 deletions(-) rename src/python/grpcio_tests/tests/unit/{_thread_pool.py => thread_pool.py} (100%) diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index 2b1d17adfb0..a7fad6d9c05 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -23,7 +23,7 @@ from grpc_health.v1 import health_pb2 from grpc_health.v1 import health_pb2_grpc from tests.unit import test_common -from tests.unit import _thread_pool +from tests.unit import thread_pool from tests.unit.framework.common import test_constants from six.moves import queue diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel index a9bcd9f304b..54b3c9b6f6a 100644 --- a/src/python/grpcio_tests/tests/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel @@ -46,6 +46,11 @@ py_library( srcs = ["test_common.py"], ) +py_library( + name = "thread_pool", + srcs = ["thread_pool.py"], +) + py_library( name = "_exit_scenarios", srcs = ["_exit_scenarios.py"], @@ -56,11 +61,6 @@ py_library( srcs = ["_server_shutdown_scenarios.py"], ) -py_library( - name = "_thread_pool", - srcs = ["_thread_pool.py"], -) - py_library( name = "_from_grpc_import_star", srcs = ["_from_grpc_import_star.py"], @@ -76,9 +76,9 @@ py_library( "//src/python/grpcio/grpc:grpcio", ":resources", ":test_common", + ":thread_pool", ":_exit_scenarios", ":_server_shutdown_scenarios", - ":_thread_pool", ":_from_grpc_import_star", "//src/python/grpcio_tests/tests/unit/framework/common", "//src/python/grpcio_tests/tests/testing", diff --git a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py index 565bd39b3aa..630b23d7f70 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py @@ -20,7 +20,7 @@ import unittest import grpc from tests.unit.framework.common import test_constants -from tests.unit import _thread_pool +from tests.unit import thread_pool def _ready_in_connectivities(connectivities): diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py index 46a4eb9bb60..c9b59dba698 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py @@ -19,7 +19,7 @@ import logging import grpc from tests.unit.framework.common import test_constants -from tests.unit import _thread_pool +from tests.unit import thread_pool class _Callback(object): diff --git a/src/python/grpcio_tests/tests/unit/_thread_pool.py b/src/python/grpcio_tests/tests/unit/thread_pool.py similarity index 100% rename from src/python/grpcio_tests/tests/unit/_thread_pool.py rename to src/python/grpcio_tests/tests/unit/thread_pool.py From 003212648f6b213d84a438c4b370e948013b8ed2 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 19 Feb 2019 15:08:42 -0800 Subject: [PATCH 434/814] fixup --- .../tests/health_check/_health_servicer_test.py | 2 +- .../tests/unit/_channel_connectivity_test.py | 16 ++++++++++------ .../tests/unit/_channel_ready_future_test.py | 8 +++++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index a7fad6d9c05..42a61b29f7c 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -206,7 +206,7 @@ class BaseWatchTests(object): class HealthServicerTest(BaseWatchTests.WatchTests): def setUp(self): - self._thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + self._thread_pool = thread_pool.RecordingThreadPool(max_workers=None) super(HealthServicerTest, self).start_server( non_blocking=True, thread_pool=self._thread_pool) diff --git a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py index 630b23d7f70..78cd09712bc 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py @@ -85,8 +85,10 @@ class ChannelConnectivityTest(unittest.TestCase): self.assertNotIn(grpc.ChannelConnectivity.READY, fifth_connectivities) def test_immediately_connectable_channel_connectivity(self): - thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) - server = grpc.server(thread_pool, options=(('grpc.so_reuseport', 0),)) + recording_thread_pool = thread_pool.RecordingThreadPool( + max_workers=None) + server = grpc.server( + recording_thread_pool, options=(('grpc.so_reuseport', 0),)) port = server.add_insecure_port('[::]:0') server.start() first_callback = _Callback() @@ -125,11 +127,13 @@ class ChannelConnectivityTest(unittest.TestCase): fourth_connectivities) self.assertNotIn(grpc.ChannelConnectivity.SHUTDOWN, fourth_connectivities) - self.assertFalse(thread_pool.was_used()) + self.assertFalse(recording_thread_pool.was_used()) def test_reachable_then_unreachable_channel_connectivity(self): - thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) - server = grpc.server(thread_pool, options=(('grpc.so_reuseport', 0),)) + recording_thread_pool = thread_pool.RecordingThreadPool( + max_workers=None) + server = grpc.server( + recording_thread_pool, options=(('grpc.so_reuseport', 0),)) port = server.add_insecure_port('[::]:0') server.start() callback = _Callback() @@ -143,7 +147,7 @@ class ChannelConnectivityTest(unittest.TestCase): _last_connectivity_is_not_ready) channel.unsubscribe(callback.update) channel.close() - self.assertFalse(thread_pool.was_used()) + self.assertFalse(recording_thread_pool.was_used()) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py index c9b59dba698..cda157d5c56 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py @@ -63,8 +63,10 @@ class ChannelReadyFutureTest(unittest.TestCase): channel.close() def test_immediately_connectable_channel_connectivity(self): - thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) - server = grpc.server(thread_pool, options=(('grpc.so_reuseport', 0),)) + recording_thread_pool = thread_pool.RecordingThreadPool( + max_workers=None) + server = grpc.server( + recording_thread_pool, options=(('grpc.so_reuseport', 0),)) port = server.add_insecure_port('[::]:0') server.start() channel = grpc.insecure_channel('localhost:{}'.format(port)) @@ -84,7 +86,7 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertFalse(ready_future.cancelled()) self.assertTrue(ready_future.done()) self.assertFalse(ready_future.running()) - self.assertFalse(thread_pool.was_used()) + self.assertFalse(recording_thread_pool.was_used()) channel.close() server.stop(None) From da1f8d7c66b83184f043b370dcb41407cf3d8454 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Tue, 19 Feb 2019 15:46:49 -0800 Subject: [PATCH 435/814] rpc test fix --- src/python/grpcio_tests/tests/unit/_rpc_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio_tests/tests/unit/_rpc_test.py b/src/python/grpcio_tests/tests/unit/_rpc_test.py index 20ef66671a0..4862d0fb185 100644 --- a/src/python/grpcio_tests/tests/unit/_rpc_test.py +++ b/src/python/grpcio_tests/tests/unit/_rpc_test.py @@ -23,7 +23,7 @@ import grpc from grpc.framework.foundation import logging_pool from tests.unit import test_common -from tests.unit import _thread_pool +from tests.unit import thread_pool from tests.unit.framework.common import test_constants from tests.unit.framework.common import test_control @@ -238,7 +238,7 @@ class RPCTest(unittest.TestCase): def setUp(self): self._control = test_control.PauseFailControl() - self._thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + self._thread_pool = thread_pool.RecordingThreadPool(max_workers=None) self._handler = _Handler(self._control, self._thread_pool) self._server = test_common.test_server() From b31f402b469ceeec2a9f7d70c596a1c03351d795 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Tue, 19 Feb 2019 10:46:05 -0800 Subject: [PATCH 436/814] Add flaky_network_test after fixing internal build failures. Re-add flaky_network_test along with a couple of new testcases. --- test/cpp/end2end/BUILD | 19 + test/cpp/end2end/flaky_network_test.cc | 492 ++++++++++++++++++ .../linux/grpc_bazel_privileged_docker.sh | 26 + .../internal_ci/linux/grpc_flaky_network.cfg | 2 +- .../linux/grpc_flaky_network_in_docker.sh | 8 +- 5 files changed, 542 insertions(+), 5 deletions(-) create mode 100644 test/cpp/end2end/flaky_network_test.cc create mode 100755 tools/internal_ci/linux/grpc_bazel_privileged_docker.sh diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index cbf09354a03..64b3eae60da 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -553,6 +553,25 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "flaky_network_test", + srcs = ["flaky_network_test.cc"], + external_deps = [ + "gtest", + ], + tags = ["manual"], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + grpc_cc_test( name = "shutdown_test", srcs = ["shutdown_test.cc"], diff --git a/test/cpp/end2end/flaky_network_test.cc b/test/cpp/end2end/flaky_network_test.cc new file mode 100644 index 00000000000..20c8fb59fa2 --- /dev/null +++ b/test/cpp/end2end/flaky_network_test.cc @@ -0,0 +1,492 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/gpr/env.h" + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#include + +#ifdef GPR_LINUX +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; + +namespace grpc { +namespace testing { +namespace { + +class FlakyNetworkTest : public ::testing::Test { + protected: + FlakyNetworkTest() + : server_host_("grpctest"), + interface_("lo:1"), + ipv4_address_("10.0.0.1"), + netmask_("/32"), + kRequestMessage_("🖖") {} + + void InterfaceUp() { + std::ostringstream cmd; + // create interface_ with address ipv4_address_ + cmd << "ip addr add " << ipv4_address_ << netmask_ << " dev " << interface_; + std::system(cmd.str().c_str()); + } + + void InterfaceDown() { + std::ostringstream cmd; + // remove interface_ + cmd << "ip addr del " << ipv4_address_ << netmask_ << " dev " << interface_; + std::system(cmd.str().c_str()); + } + + void DNSUp() { + std::ostringstream cmd; + // Add DNS entry for server_host_ in /etc/hosts + cmd << "echo '" << ipv4_address_ << " " << server_host_ + << "' >> /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DNSDown() { + std::ostringstream cmd; + // Remove DNS entry for server_host_ from /etc/hosts + // NOTE: we can't do this in one step with sed -i because when we are + // running under docker, the file is mounted by docker so we can't change + // its inode from within the container (sed -i creates a new file and + // replaces the old file, which changes the inode) + cmd << "sed '/" << server_host_ << "/d' /etc/hosts > /etc/hosts.orig"; + std::system(cmd.str().c_str()); + + // clear the stream + cmd.str(""); + + cmd << "cat /etc/hosts.orig > /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DropPackets() { + std::ostringstream cmd; + // drop packets with src IP = ipv4_address_ + cmd << "iptables -A INPUT -s " << ipv4_address_ << " -j DROP"; + + std::system(cmd.str().c_str()); + // clear the stream + cmd.str(""); + + // drop packets with dst IP = ipv4_address_ + cmd << "iptables -A INPUT -d " << ipv4_address_ << " -j DROP"; + } + + void RestoreNetwork() { + std::ostringstream cmd; + // remove iptables rule to drop packets with src IP = ipv4_address_ + cmd << "iptables -D INPUT -s " << ipv4_address_ << " -j DROP"; + std::system(cmd.str().c_str()); + // clear the stream + cmd.str(""); + // remove iptables rule to drop packets with dest IP = ipv4_address_ + cmd << "iptables -D INPUT -d " << ipv4_address_ << " -j DROP"; + } + + void FlakeNetwork() { + std::ostringstream cmd; + // Emulate a flaky network connection over interface_. Add a delay of 100ms + // +/- 590ms, 3% packet loss, 1% duplicates and 0.1% corrupt packets. + cmd << "tc qdisc replace dev " << interface_ + << " root netem delay 100ms 50ms distribution normal loss 3% duplicate " + "1% corrupt 0.1% "; + std::system(cmd.str().c_str()); + } + + void UnflakeNetwork() { + // Remove simulated network flake on interface_ + std::ostringstream cmd; + cmd << "tc qdisc del dev " << interface_ << " root netem"; + std::system(cmd.str().c_str()); + } + + void NetworkUp() { + InterfaceUp(); + DNSUp(); + } + + void NetworkDown() { + InterfaceDown(); + DNSDown(); + } + + void SetUp() override { + NetworkUp(); + grpc_init(); + StartServer(); + } + + void TearDown() override { + NetworkDown(); + StopServer(); + grpc_shutdown(); + } + + void StartServer() { + // TODO (pjaikumar): Ideally, we should allocate the port dynamically using + // grpc_pick_unused_port_or_die(). That doesn't work inside some docker + // containers because port_server listens on localhost which maps to + // ip6-looopback, but ipv6 support is not enabled by default in docker. + port_ = SERVER_PORT; + + server_.reset(new ServerData(port_)); + server_->Start(server_host_); + } + void StopServer() { server_->Shutdown(); } + + std::unique_ptr BuildStub( + const std::shared_ptr& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr BuildChannel( + const grpc::string& lb_policy_name, + ChannelArguments args = ChannelArguments()) { + if (lb_policy_name.size() > 0) { + args.SetLoadBalancingPolicyName(lb_policy_name); + } // else, default to pick first + std::ostringstream server_address; + server_address << server_host_ << ":" << port_; + return CreateCustomChannel(server_address.str(), + InsecureChannelCredentials(), args); + } + + bool SendRpc( + const std::unique_ptr& stub, + int timeout_ms = 0, bool wait_for_ready = false) { + auto response = std::unique_ptr(new EchoResponse()); + EchoRequest request; + request.set_message(kRequestMessage_); + ClientContext context; + if (timeout_ms > 0) { + context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); + } + // See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md for + // details of wait-for-ready semantics + if (wait_for_ready) { + context.set_wait_for_ready(true); + } + Status status = stub->Echo(&context, request, response.get()); + auto ok = status.ok(); + if (ok) { + gpr_log(GPR_DEBUG, "RPC returned %s\n", response->message().c_str()); + } else { + gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); + } + return ok; + } + + struct ServerData { + int port_; + std::unique_ptr server_; + TestServiceImpl service_; + std::unique_ptr thread_; + bool server_ready_ = false; + + explicit ServerData(int port) { port_ = port; } + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting server on port %d", port_); + std::mutex mu; + std::unique_lock lock(mu); + std::condition_variable cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.wait(lock, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + + void Serve(const grpc::string& server_host, std::mutex* mu, + std::condition_variable* cond) { + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + builder.AddListeningPort(server_address.str(), + InsecureServerCredentials()); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + std::lock_guard lock(*mu); + server_ready_ = true; + cond->notify_one(); + } + + void Shutdown() { + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + thread_->join(); + } + }; + + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + private: + const grpc::string server_host_; + const grpc::string interface_; + const grpc::string ipv4_address_; + const grpc::string netmask_; + std::unique_ptr stub_; + std::unique_ptr server_; + const int SERVER_PORT = 32750; + int port_; + const grpc::string kRequestMessage_; +}; + +// Network interface connected to server flaps +TEST_F(FlakyNetworkTest, NetworkTransition) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // bring down network + NetworkDown(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + // bring network interface back up + InterfaceUp(); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + // Restore DNS entry for server + DNSUp(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); +} + +// Traffic to server server is blackholed temporarily with keepalives enabled +TEST_F(FlakyNetworkTest, ServerUnreachableWithKeepalive) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // break network connectivity + DropPackets(); + std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + // bring network interface back up + RestoreNetwork(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); +} + +// +// Traffic to server server is blackholed temporarily with keepalives disabled +TEST_F(FlakyNetworkTest, ServerUnreachableNoKeepalive) { + auto channel = BuildChannel("pick_first", ChannelArguments()); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // break network connectivity + DropPackets(); + + std::thread sender = std::thread([this, &stub]() { + // RPC with deadline should timeout + EXPECT_FALSE(SendRpc(stub, /*timeout_ms=*/500, /*wait_for_ready=*/true)); + // RPC without deadline forever until call finishes + EXPECT_TRUE(SendRpc(stub, /*timeout_ms=*/0, /*wait_for_ready=*/true)); + }); + + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + // bring network interface back up + RestoreNetwork(); + + // wait for RPC to finish + sender.join(); +} + +// Send RPCs over a flaky network connection +TEST_F(FlakyNetworkTest, FlakyNetwork) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + const int kMessageCount = 100; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // simulate flaky network (packet loss, corruption and delays) + FlakeNetwork(); + for (int i = 0; i < kMessageCount; ++i) { + EXPECT_TRUE(SendRpc(stub)); + } + // remove network flakiness + UnflakeNetwork(); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); +} + +// Server is shutdown gracefully and restarted. Client keepalives are enabled +TEST_F(FlakyNetworkTest, ServerRestartKeepaliveEnabled) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // server goes down, client should detect server going down and calls should + // fail + StopServer(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + EXPECT_FALSE(SendRpc(stub)); + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + // server restarts, calls succeed + StartServer(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + // EXPECT_TRUE(SendRpc(stub)); +} + +// Server is shutdown gracefully and restarted. Client keepalives are enabled +TEST_F(FlakyNetworkTest, ServerRestartKeepaliveDisabled) { + auto channel = BuildChannel("pick_first", ChannelArguments()); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // server sends GOAWAY when it's shutdown, so client attempts to reconnect + StopServer(); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + // server restarts, calls succeed + StartServer(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); +} + +} // namespace +} // namespace testing +} // namespace grpc +#endif // GPR_LINUX + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_test_init(argc, argv); + auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh b/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh new file mode 100755 index 00000000000..ae1056d7c3d --- /dev/null +++ b/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -ex + +# change to grpc repo root +cd $(dirname $0)/../../.. + +source tools/internal_ci/helper_scripts/prepare_build_linux_rc + +export DOCKERFILE_DIR=tools/dockerfile/test/bazel +export DOCKER_RUN_SCRIPT=$BAZEL_SCRIPT +# NET_ADMIN capability allows tests to manipulate network interfaces +exec tools/run_tests/dockerize/build_and_run_docker.sh --cap-add NET_ADMIN diff --git a/tools/internal_ci/linux/grpc_flaky_network.cfg b/tools/internal_ci/linux/grpc_flaky_network.cfg index de7a3b9cd8f..07bedd79f94 100644 --- a/tools/internal_ci/linux/grpc_flaky_network.cfg +++ b/tools/internal_ci/linux/grpc_flaky_network.cfg @@ -15,7 +15,7 @@ # Config file for the internal CI (in protobuf text format) # Location of the continuous shell script in repository. -build_file: "grpc/tools/internal_ci/linux/grpc_bazel.sh" +build_file: "grpc/tools/internal_ci/linux/grpc_bazel_privileged_docker.sh" timeout_mins: 240 env_vars { key: "BAZEL_SCRIPT" diff --git a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh index 42b6d44c1cb..60bb49b639a 100755 --- a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh +++ b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh @@ -23,9 +23,9 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc (cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \ && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') -cd /var/local/git/grpc +cd /var/local/git/grpc/test/cpp/end2end -# TODO(jtattermusch): install prerequsites if needed +# iptables is used to drop traffic between client and server +apt-get install -y iptables -# TODO(jtattermusch): run the flaky network test instead -bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/... +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all :flaky_network_test From 0203bf74f5384213758675c87296b78d04f62b47 Mon Sep 17 00:00:00 2001 From: Kim Bao Long Date: Wed, 20 Feb 2019 16:17:47 +0700 Subject: [PATCH 437/814] Remove the redundant words in comments Although it is spelling mistakes, it might make an affects while reading docs. Co-Authored-By: Nguyen Phuong An Signed-off-by: Kim Bao Long --- src/compiler/cpp_generator_helpers.h | 2 +- src/compiler/csharp_generator_helpers.h | 2 +- src/compiler/node_generator_helpers.h | 2 +- src/compiler/php_generator_helpers.h | 2 +- src/compiler/ruby_generator_helpers-inl.h | 2 +- src/core/lib/surface/completion_queue.cc | 2 +- .../tests/protoc_plugin/beta_python_plugin_test.py | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/compiler/cpp_generator_helpers.h b/src/compiler/cpp_generator_helpers.h index b8efcbdb843..f9a69373bd1 100644 --- a/src/compiler/cpp_generator_helpers.h +++ b/src/compiler/cpp_generator_helpers.h @@ -52,7 +52,7 @@ inline grpc::string ClassName(const grpc::protobuf::Descriptor* descriptor, } // Get leading or trailing comments in a string. Comment lines start with "// ". -// Leading detached comments are put in in front of leading comments. +// Leading detached comments are put in front of leading comments. template inline grpc::string GetCppComments(const DescriptorType* desc, bool leading) { return grpc_generator::GetPrefixedComments(desc, leading, "//"); diff --git a/src/compiler/csharp_generator_helpers.h b/src/compiler/csharp_generator_helpers.h index 8c89925551c..0d9ae6360dd 100644 --- a/src/compiler/csharp_generator_helpers.h +++ b/src/compiler/csharp_generator_helpers.h @@ -32,7 +32,7 @@ inline bool ServicesFilename(const grpc::protobuf::FileDescriptor* file, } // Get leading or trailing comments in a string. Comment lines start with "// ". -// Leading detached comments are put in in front of leading comments. +// Leading detached comments are put in front of leading comments. template inline grpc::string GetCsharpComments(const DescriptorType* desc, bool leading) { diff --git a/src/compiler/node_generator_helpers.h b/src/compiler/node_generator_helpers.h index 82d2d845441..110749f77f1 100644 --- a/src/compiler/node_generator_helpers.h +++ b/src/compiler/node_generator_helpers.h @@ -31,7 +31,7 @@ inline grpc::string GetJSServiceFilename(const grpc::string& filename) { } // Get leading or trailing comments in a string. Comment lines start with "// ". -// Leading detached comments are put in in front of leading comments. +// Leading detached comments are put in front of leading comments. template inline grpc::string GetNodeComments(const DescriptorType* desc, bool leading) { return grpc_generator::GetPrefixedComments(desc, leading, "//"); diff --git a/src/compiler/php_generator_helpers.h b/src/compiler/php_generator_helpers.h index 3ad19977641..abe273d47bb 100644 --- a/src/compiler/php_generator_helpers.h +++ b/src/compiler/php_generator_helpers.h @@ -63,7 +63,7 @@ inline grpc::string GetPHPServiceFilename( } // Get leading or trailing comments in a string. Comment lines start with "// ". -// Leading detached comments are put in in front of leading comments. +// Leading detached comments are put in front of leading comments. template inline grpc::string GetPHPComments(const DescriptorType* desc, grpc::string prefix) { diff --git a/src/compiler/ruby_generator_helpers-inl.h b/src/compiler/ruby_generator_helpers-inl.h index 2323770425a..67a899be93d 100644 --- a/src/compiler/ruby_generator_helpers-inl.h +++ b/src/compiler/ruby_generator_helpers-inl.h @@ -47,7 +47,7 @@ inline grpc::string MessagesRequireName( } // Get leading or trailing comments in a string. Comment lines start with "# ". -// Leading detached comments are put in in front of leading comments. +// Leading detached comments are put in front of leading comments. template inline grpc::string GetRubyComments(const DescriptorType* desc, bool leading) { return grpc_generator::GetPrefixedComments(desc, leading, "#"); diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index f473b23788e..bfd8445f70e 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -1097,7 +1097,7 @@ static void cq_shutdown_next(grpc_completion_queue* cq) { } cqd->shutdown_called = true; /* Doing a full_fetch_add (i.e acq/release) here to match with - * cq_begin_op_for_next and and cq_end_op_for_next functions which read/write + * cq_begin_op_for_next and cq_end_op_for_next functions which read/write * on this counter without necessarily holding a lock on cq */ if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { cq_finish_shutdown_next(cq); diff --git a/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py b/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py index 43c90af6a70..56f6871e5c2 100644 --- a/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py +++ b/src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py @@ -195,7 +195,7 @@ def _CreateService(payload_pb2, responses_pb2, service_pb2): Yields: A (servicer_methods, stub) pair where servicer_methods is the back-end of - the service bound to the stub and and stub is the stub on which to invoke + the service bound to the stub and stub is the stub on which to invoke RPCs. """ servicer_methods = _ServicerMethods(payload_pb2, responses_pb2) @@ -237,7 +237,7 @@ def _CreateIncompleteService(service_pb2): service_pb2: The service_pb2 module generated by this test. Yields: A (servicer_methods, stub) pair where servicer_methods is the back-end of - the service bound to the stub and and stub is the stub on which to invoke + the service bound to the stub and stub is the stub on which to invoke RPCs. """ From 5c52622fa6488a7ceeea8ee2454d157a10da0a40 Mon Sep 17 00:00:00 2001 From: Nguyen Hai Truong Date: Wed, 20 Feb 2019 02:13:27 -0800 Subject: [PATCH 438/814] Trivial fix many typos Signed-off-by: Nguyen Hai Truong --- doc/core/epoll-polling-engine.md | 6 +++--- doc/core/transport_explainer.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/core/epoll-polling-engine.md b/doc/core/epoll-polling-engine.md index 1f5d855743a..e660a709384 100644 --- a/doc/core/epoll-polling-engine.md +++ b/doc/core/epoll-polling-engine.md @@ -85,16 +85,16 @@ There are two cases to check here: * This is straightforward and nothing really needs to be done here * **Case 2:** The `fd `and `pollset` point to different `polling_islands`: In this case we _merge_ both the polling islands i.e: * Add all the `fds` from the smaller `polling_island `to the larger `polling_island` and update the `merged_to` pointer on the smaller island to point to the larger island. - * Wake up all the threads waiting on the smaller `polling_island`'s `epoll_fd` (by signalling the `event_fd` on that island) and make them now wait on the larger `polling_island`'s `epoll_fd` + * Wake up all the threads waiting on the smaller `polling_island`'s `epoll_fd` (by signaling the `event_fd` on that island) and make them now wait on the larger `polling_island`'s `epoll_fd` * Update `fd` and `pollset` to now point to the larger `polling_island` ### 4.3 Directed wakeups: The new implementation, just like the current implementation, does not provide us any guarantees that the thread that is woken up is the thread that is actually interested in the event. So the thread that woke up executes the callbacks and finally has to 'kick' the appropriate polling thread interested in the event. -In the current implementation, every polling thread also had a `event_fd` on which it was listening to and hence waking it up was as simple as signalling that `event_fd`. However, using an `event_fd` also meant that every thread has to use a `poll()` (on `event_fd` and `epoll_fd`) instead of doing an `epoll_wait()` and this resulted in the thundering herd problems described above. +In the current implementation, every polling thread also had a `event_fd` on which it was listening to and hence waking it up was as simple as signaling that `event_fd`. However, using an `event_fd` also meant that every thread has to use a `poll()` (on `event_fd` and `epoll_fd`) instead of doing an `epoll_wait()` and this resulted in the thundering herd problems described above. -The proposal here is to use signals and kicking a thread would just be sending a signal to that thread. Unfortunately there are only a few signals available on posix systems and most of them have pre-determined behavior leaving only a few signals `SIGUSR1`, `SIGUSR2` and `SIGRTx (SIGRTMIN to SIGRTMAX)` for custom use. +The proposal here is to use signals and kicking a thread would just be sending a signal to that thread. Unfortunately there are only a few signals available on POSIX systems and most of them have pre-determined behavior leaving only a few signals `SIGUSR1`, `SIGUSR2` and `SIGRTx (SIGRTMIN to SIGRTMAX)` for custom use. The calling application might have registered other signal handlers for these signals. `We will provide a new API where the applications can "give a signal number" to gRPC library to use for this purpose. diff --git a/doc/core/transport_explainer.md b/doc/core/transport_explainer.md index a100128e538..cc4cab1eae9 100644 --- a/doc/core/transport_explainer.md +++ b/doc/core/transport_explainer.md @@ -28,7 +28,7 @@ synonymously since all RPCs are actually streams internally.) The ops in a batch can include: * send\_initial\_metadata - - Client: initate an RPC + - Client: initiate an RPC - Server: supply response headers * recv\_initial\_metadata - Client: get response headers From 453c6331b6ca6e0127a75c428d45876cf904279f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 19 Feb 2019 22:19:16 -0800 Subject: [PATCH 439/814] Fix counters in streaming QPS benchmarks --- test/cpp/qps/client_callback.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index 4a06325f2b7..0d637c07fef 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -221,11 +221,11 @@ class CallbackStreamingClient : public CallbackClient { } ~CallbackStreamingClient() {} - void AddHistogramEntry(double start_, bool ok, Thread* thread_ptr) { + void AddHistogramEntry(double start, bool ok, Thread* thread_ptr) { // Update Histogram with data from the callback run HistogramEntry entry; if (ok) { - entry.set_value((UsageTimer::Now() - start_) * 1e9); + entry.set_value((UsageTimer::Now() - start) * 1e9); } thread_ptr->UpdateHistogram(&entry); } @@ -254,8 +254,8 @@ class CallbackStreamingPingPongReactor final void StartNewRpc() { if (client_->ThreadCompleted()) return; - start_ = UsageTimer::Now(); ctx_->stub_->experimental_async()->StreamingCall(&(ctx_->context_), this); + write_time_ = UsageTimer::Now(); StartWrite(client_->request()); StartCall(); } @@ -270,7 +270,7 @@ class CallbackStreamingPingPongReactor final } void OnReadDone(bool ok) override { - client_->AddHistogramEntry(start_, ok, thread_ptr_); + client_->AddHistogramEntry(write_time_, ok, thread_ptr_); if (client_->ThreadCompleted() || !ok || (client_->messages_per_stream() != 0 && @@ -281,6 +281,7 @@ class CallbackStreamingPingPongReactor final StartWritesDone(); return; } + write_time_ = UsageTimer::Now(); StartWrite(client_->request()); } @@ -312,7 +313,7 @@ class CallbackStreamingPingPongReactor final CallbackStreamingPingPongClient* client_; std::unique_ptr ctx_; Client::Thread* thread_ptr_; // Needed to update histogram entries - double start_; // Track message start time + double write_time_; // Track ping-pong round start time int messages_issued_; // Messages issued by this stream }; From 9cf00ed80b2e11f0e96ddb5a454aecd2b2781d4a Mon Sep 17 00:00:00 2001 From: Nguyen Hai Truong Date: Wed, 20 Feb 2019 23:19:33 +0700 Subject: [PATCH 440/814] Reformat some link and fix typos Signed-off-by: Nguyen Hai Truong --- .github/ISSUE_TEMPLATE.md | 6 +++--- doc/interop-test-descriptions.md | 2 +- src/cpp/README.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) mode change 100644 => 100755 .github/ISSUE_TEMPLATE.md mode change 100644 => 100755 doc/interop-test-descriptions.md mode change 100644 => 100755 src/cpp/README.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md old mode 100644 new mode 100755 index d31aea6c736..acfcdc14845 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -3,7 +3,7 @@ This form is for bug reports and feature requests ONLY! For general questions and troubleshooting, please ask/look for answers here: - grpc.io mailing list: https://groups.google.com/forum/#!forum/grpc-io -- StackOverflow, with "grpc" tag: http://stackoverflow.com/questions/tagged/grpc +- StackOverflow, with "grpc" tag: https://stackoverflow.com/questions/tagged/grpc Issues specific to *grpc-java*, *grpc-go*, *grpc-node*, *grpc-dart*, *grpc-web* should be created in the repository they belong to (e.g. https://github.com/grpc/grpc-LANGUAGE/issues/new) --> @@ -11,7 +11,7 @@ Issues specific to *grpc-java*, *grpc-go*, *grpc-node*, *grpc-dart*, *grpc-web* ### What version of gRPC and what language are you using? -### What operating system (Linux, Windows, …) and version? +### What operating system (Linux, Windows,...) and version? ### What runtime / compiler are you using (e.g. python version or version of gcc) @@ -27,7 +27,7 @@ If possible, provide a recipe for reproducing the error. Try being specific and Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs). -See https://github.com/grpc/grpc/blob/master/TROUBLESHOOTING.md for how to diagnose problems better. +See [TROUBLESHOOTING.md](https://github.com/grpc/grpc/blob/master/TROUBLESHOOTING.md) for how to diagnose problems better. ### Anything else we should know about your project / environment? diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md old mode 100644 new mode 100755 index 9f6961f5199..208af424298 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -652,7 +652,7 @@ The test downloaded from https://console.developers.google.com. Alternately, if using a usable auth implementation, it may specify the file location in the environment variable GOOGLE_APPLICATION_CREDENTIALS -- optionally uses the flag `--oauth_scope` for the oauth scope if implementator +- optionally uses the flag `--oauth_scope` for the oauth scope if implementer wishes to use service account credential instead of JWT credential. For testing against grpc-test.sandbox.googleapis.com, oauth scope "https://www.googleapis.com/auth/xapi.zoo" should be used. diff --git a/src/cpp/README.md b/src/cpp/README.md old mode 100644 new mode 100755 index 4ec9133c598..da5c5e69453 --- a/src/cpp/README.md +++ b/src/cpp/README.md @@ -52,7 +52,7 @@ support for crosscompiling and can be used for targeting Android platform. If your project is using cmake, there are several ways to add gRPC dependency. - install gRPC via cmake first and then locate it with `find_package(gRPC CONFIG)`. [Example](../../examples/cpp/helloworld/CMakeLists.txt) - via cmake's `ExternalProject_Add` using a technique called "superbuild". [Example](../../examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt) -- add gRPC source tree to your project (preferrably as a git submodule) and add it to your cmake project with `add_subdirectory`. [Example](../../examples/cpp/helloworld/CMakeLists.txt) +- add gRPC source tree to your project (preferably as a git submodule) and add it to your cmake project with `add_subdirectory`. [Example](../../examples/cpp/helloworld/CMakeLists.txt) ## Packaging systems From 1ccdb0ee265a02cda9751d43f74ee7285ecdae60 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 20 Feb 2019 11:28:16 -0500 Subject: [PATCH 441/814] Alias std::memory_order as grpc_core::MemoryOrder. --- src/core/lib/gprpp/atomic.h | 60 +++++++++++++++++++---------- src/core/lib/gprpp/ref_counted.h | 12 +++--- src/core/lib/surface/lame_client.cc | 4 +- 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/core/lib/gprpp/atomic.h b/src/core/lib/gprpp/atomic.h index 9ba4f85db89..e7c10f68763 100644 --- a/src/core/lib/gprpp/atomic.h +++ b/src/core/lib/gprpp/atomic.h @@ -28,53 +28,73 @@ namespace grpc_core { template using Atomic = std::atomic; +enum class MemoryOrder { + RELAXED = std::memory_order_relaxed, + CONSUME = std::memory_order_consume, + ACQUIRE = std::memory_order_acquire, + RELEASE = std::memory_order_release, + ACQ_REL = std::memory_order_acq_rel, + SEQ_CST = std::memory_order_seq_cst +}; + // Prefer the helper methods below over the same functions provided by // std::atomic, because they maintain stats over atomic opertions which are // useful for comparing benchmarks. template -bool AtomicCompareExchangeWeak(std::atomic* storage, T* expected, T desired, - std::memory_order success, - std::memory_order failure) { +T AtomicLoad(const Atomic* storage, MemoryOrder order) { + return storage->load(static_cast(order)); +} + +template +T AtomicStore(Atomic* storage, T val, MemoryOrder order) { + return storage->store(val, static_cast(order)); +} +template +bool AtomicCompareExchangeWeak(Atomic* storage, T* expected, T desired, + MemoryOrder success, MemoryOrder failure) { return GPR_ATM_INC_CAS_THEN( storage->compare_exchange_weak(*expected, desired, success, failure)); } template -bool AtomicCompareExchangeStrong(std::atomic* storage, T* expected, - T desired, std::memory_order success, - std::memory_order failure) { - return GPR_ATM_INC_CAS_THEN( - storage->compare_exchange_weak(*expected, desired, success, failure)); +bool AtomicCompareExchangeStrong(Atomic* storage, T* expected, T desired, + MemoryOrder success, MemoryOrder failure) { + return GPR_ATM_INC_CAS_THEN(storage->compare_exchange_weak( + *expected, desired, static_cast(success), + static_cast(failure))); } template -T AtomicFetchAdd(std::atomic* storage, Arg arg, - std::memory_order order = std::memory_order_seq_cst) { - return GPR_ATM_INC_ADD_THEN(storage->fetch_add(static_cast(arg), order)); +T AtomicFetchAdd(Atomic* storage, Arg arg, + MemoryOrder order = MemoryOrder::SEQ_CST) { + return GPR_ATM_INC_ADD_THEN(storage->fetch_add( + static_cast(arg), static_cast(order))); } template -T AtomicFetchSub(std::atomic* storage, Arg arg, - std::memory_order order = std::memory_order_seq_cst) { - return GPR_ATM_INC_ADD_THEN(storage->fetch_sub(static_cast(arg), order)); +T AtomicFetchSub(Atomic* storage, Arg arg, + MemoryOrder order = MemoryOrder::SEQ_CST) { + return GPR_ATM_INC_ADD_THEN(storage->fetch_sub( + static_cast(arg), static_cast(order))); } // Atomically increment a counter only if the counter value is not zero. // Returns true if increment took place; false if counter is zero. template -bool AtomicIncrementIfNonzero( - std::atomic* counter, - std::memory_order load_order = std::memory_order_acquire) { - T count = counter->load(load_order); +bool AtomicIncrementIfNonzero(Atomic* counter, + MemoryOrder load_order = MemoryOrder::ACQ_REL) { + T count = counter->load(static_cast(load_order)); do { // If zero, we are done (without an increment). If not, we must do a CAS to // maintain the contract: do not increment the counter if it is already zero if (count == 0) { return false; } - } while (!AtomicCompareExchangeWeak(counter, &count, count + 1, - std::memory_order_acq_rel, load_order)); + } while (!AtomicCompareExchangeWeak( + counter, &count, count + 1, + static_cast(MemoryOrder::ACQ_REL), + static_cast(load_order))); return true; } diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index b0430b6b809..8148cfd35d2 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -89,9 +89,7 @@ class RefCount { } // Increases the ref-count by `n`. - void Ref(Value n = 1) { - AtomicFetchAdd(&value_, n, std::memory_order_relaxed); - } + void Ref(Value n = 1) { AtomicFetchAdd(&value_, n, MemoryOrder::RELAXED); } void Ref(const DebugLocation& location, const char* reason, Value n = 1) { #ifndef NDEBUG if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { @@ -107,7 +105,7 @@ class RefCount { // Similar to Ref() with an assert on the ref-count being non-zero. void RefNonZero() { #ifndef NDEBUG - const Value prior = AtomicFetchAdd(&value_, 1, std::memory_order_relaxed); + const Value prior = AtomicFetchAdd(&value_, 1, MemoryOrder::RELAXED); assert(prior > 0); #else Ref(); @@ -127,7 +125,7 @@ class RefCount { // Decrements the ref-count and returns true if the ref-count reaches 0. bool Unref() { - const Value prior = AtomicFetchSub(&value_, 1, std::memory_order_acq_rel); + const Value prior = AtomicFetchSub(&value_, 1, MemoryOrder::ACQ_REL); GPR_DEBUG_ASSERT(prior > 0); return prior == 1; } @@ -144,12 +142,12 @@ class RefCount { } private: - Value get() const { return value_.load(std::memory_order_relaxed); } + Value get() const { return AtomicLoad(&value_, MemoryOrder::RELAXED); } #ifndef NDEBUG TraceFlag* trace_flag_; #endif - std::atomic value_; + Atomic value_; }; // A base class for reference-counted objects. diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc index 0ff512f07e2..c2ee9d985e9 100644 --- a/src/core/lib/surface/lame_client.cc +++ b/src/core/lib/surface/lame_client.cc @@ -54,8 +54,8 @@ static void fill_metadata(grpc_call_element* elem, grpc_metadata_batch* mdb) { CallData* calld = static_cast(elem->call_data); bool expected = false; if (!AtomicCompareExchangeStrong(&calld->filled_metadata, &expected, true, - std::memory_order_relaxed, - std::memory_order_relaxed)) { + MemoryOrder::RELAXED, + MemoryOrder::RELAXED)) { return; } ChannelData* chand = static_cast(elem->channel_data); From cedc76bf3833db276732e6ef0a0c5074d655f9ac Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 20 Feb 2019 08:45:31 -0800 Subject: [PATCH 442/814] Resolve comments --- src/core/lib/iomgr/fork_posix.cc | 1 - test/core/json/fuzzer.cc | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index 86bfb01a4ef..7f8fb7e828b 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -35,7 +35,6 @@ #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/timer_manager.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" -#include "src/core/lib/surface/init.h" /* * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK diff --git a/test/core/json/fuzzer.cc b/test/core/json/fuzzer.cc index 77a10a17678..8b3e9792d15 100644 --- a/test/core/json/fuzzer.cc +++ b/test/core/json/fuzzer.cc @@ -31,7 +31,7 @@ bool leak_check = true; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { char* s; - grpc_core::testing::LeakDetector leak_detector(leak_check); + grpc_core::testing::LeakDetector leak_detector(true); s = static_cast(gpr_malloc(size)); memcpy(s, data, size); grpc_json* x; From 4f299d84ed2218749ed25944a352a6b0fecff6d4 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 20 Feb 2019 09:44:41 -0800 Subject: [PATCH 443/814] Add private _finalize_state method to ServicerContext --- src/python/grpcio/grpc/__init__.py | 9 ++++++++ src/python/grpcio/grpc/_server.py | 35 ++++++++++++++++++------------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 8613bc501f1..68e5361bb99 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -14,6 +14,7 @@ """gRPC's Python API.""" import abc +import contextlib import enum import logging import sys @@ -1779,6 +1780,14 @@ def server(thread_pool, maximum_concurrent_rpcs) +@contextlib.contextmanager +def _create_servicer_context(rpc_event, state, request_deserializer): + from grpc import _server # pylint: disable=cyclic-import + context = _server._Context(rpc_event, state, request_deserializer) + yield context + context._finalize_state() # pylint: disable=protected-access + + ################################### __all__ ################################# __all__ = ( diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 6caaece82c4..31f31b0f208 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -302,6 +302,9 @@ class _Context(grpc.ServicerContext): with self._state.condition: self._state.details = _common.encode(details) + def _finalize_state(self): + pass + class _RequestIterator(object): @@ -387,20 +390,24 @@ def _unary_request(rpc_event, state, request_deserializer): def _call_behavior(rpc_event, state, behavior, argument, request_deserializer): - context = _Context(rpc_event, state, request_deserializer) - try: - return behavior(argument, context), True - except Exception as exception: # pylint: disable=broad-except - with state.condition: - if state.aborted: - _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, - b'RPC Aborted') - elif exception not in state.rpc_errors: - details = 'Exception calling application: {}'.format(exception) - _LOGGER.exception(details) - _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, - _common.encode(details)) - return None, False + from grpc import _create_servicer_context + with _create_servicer_context(rpc_event, state, + request_deserializer) as context: + try: + response = behavior(argument, context) + return response, True + except Exception as exception: # pylint: disable=broad-except + with state.condition: + if state.aborted: + _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, + b'RPC Aborted') + elif exception not in state.rpc_errors: + details = 'Exception calling application: {}'.format( + exception) + _LOGGER.exception(details) + _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, + _common.encode(details)) + return None, False def _take_response_from_response_iterator(rpc_event, state, response_iterator): From 0800ce597634dcfddc08b327aff1c61adde71787 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 20 Feb 2019 12:53:59 -0500 Subject: [PATCH 444/814] Move all helper functions to a class called Atomic. --- .../server_load_reporting_filter.cc | 4 +- src/core/lib/gprpp/atomic.h | 109 +++++++++--------- src/core/lib/gprpp/ref_counted.h | 8 +- src/core/lib/surface/lame_client.cc | 5 +- 4 files changed, 60 insertions(+), 66 deletions(-) diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc index b0420a28b5f..d7fd73fd6b2 100644 --- a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc +++ b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc @@ -343,7 +343,7 @@ bool MaybeAddServerLoadReportingFilter(const grpc_channel_args& args) { struct ServerLoadReportingFilterStaticRegistrar { ServerLoadReportingFilterStaticRegistrar() { static grpc_core::Atomic registered{false}; - if (registered) return; + if (registered.Load(grpc_core::MemoryOrder::ACQUIRE)) return; RegisterChannelFilter( "server_load_reporting", GRPC_SERVER_CHANNEL, INT_MAX, @@ -356,7 +356,7 @@ struct ServerLoadReportingFilterStaticRegistrar { ::grpc::load_reporter::MeasureEndBytesReceived(); ::grpc::load_reporter::MeasureEndLatencyMs(); ::grpc::load_reporter::MeasureOtherCallMetric(); - registered = true; + registered.Store(true, grpc_core::MemoryOrder::RELEASE); } } server_load_reporting_filter_static_registrar; diff --git a/src/core/lib/gprpp/atomic.h b/src/core/lib/gprpp/atomic.h index e7c10f68763..622df1b7889 100644 --- a/src/core/lib/gprpp/atomic.h +++ b/src/core/lib/gprpp/atomic.h @@ -25,9 +25,6 @@ namespace grpc_core { -template -using Atomic = std::atomic; - enum class MemoryOrder { RELAXED = std::memory_order_relaxed, CONSUME = std::memory_order_consume, @@ -37,66 +34,64 @@ enum class MemoryOrder { SEQ_CST = std::memory_order_seq_cst }; -// Prefer the helper methods below over the same functions provided by -// std::atomic, because they maintain stats over atomic opertions which are -// useful for comparing benchmarks. - template -T AtomicLoad(const Atomic* storage, MemoryOrder order) { - return storage->load(static_cast(order)); -} +class Atomic { + public: + explicit Atomic(T val = T()) : storage_(val) {} -template -T AtomicStore(Atomic* storage, T val, MemoryOrder order) { - return storage->store(val, static_cast(order)); -} -template -bool AtomicCompareExchangeWeak(Atomic* storage, T* expected, T desired, - MemoryOrder success, MemoryOrder failure) { - return GPR_ATM_INC_CAS_THEN( - storage->compare_exchange_weak(*expected, desired, success, failure)); -} + T Load(MemoryOrder order) const { + return storage_.load(static_cast(order)); + } -template -bool AtomicCompareExchangeStrong(Atomic* storage, T* expected, T desired, - MemoryOrder success, MemoryOrder failure) { - return GPR_ATM_INC_CAS_THEN(storage->compare_exchange_weak( - *expected, desired, static_cast(success), - static_cast(failure))); -} + void Store(T val, MemoryOrder order) { + storage_.store(val, static_cast(order)); + } -template -T AtomicFetchAdd(Atomic* storage, Arg arg, - MemoryOrder order = MemoryOrder::SEQ_CST) { - return GPR_ATM_INC_ADD_THEN(storage->fetch_add( - static_cast(arg), static_cast(order))); -} + bool CompareExchangeWeak(T* expected, T desired, MemoryOrder success, + MemoryOrder failure) { + return GPR_ATM_INC_CAS_THEN( + storage_.compare_exchange_weak(*expected, desired, success, failure)); + } -template -T AtomicFetchSub(Atomic* storage, Arg arg, - MemoryOrder order = MemoryOrder::SEQ_CST) { - return GPR_ATM_INC_ADD_THEN(storage->fetch_sub( - static_cast(arg), static_cast(order))); -} + bool CompareExchangeStrong(T* expected, T desired, MemoryOrder success, + MemoryOrder failure) { + return GPR_ATM_INC_CAS_THEN(storage_.compare_exchange_weak( + *expected, desired, static_cast(success), + static_cast(failure))); + } -// Atomically increment a counter only if the counter value is not zero. -// Returns true if increment took place; false if counter is zero. -template -bool AtomicIncrementIfNonzero(Atomic* counter, - MemoryOrder load_order = MemoryOrder::ACQ_REL) { - T count = counter->load(static_cast(load_order)); - do { - // If zero, we are done (without an increment). If not, we must do a CAS to - // maintain the contract: do not increment the counter if it is already zero - if (count == 0) { - return false; - } - } while (!AtomicCompareExchangeWeak( - counter, &count, count + 1, - static_cast(MemoryOrder::ACQ_REL), - static_cast(load_order))); - return true; -} + template + T FetchAdd(Arg arg, MemoryOrder order = MemoryOrder::SEQ_CST) { + return GPR_ATM_INC_ADD_THEN(storage_.fetch_add( + static_cast(arg), static_cast(order))); + } + + template + T FetchSub(Arg arg, MemoryOrder order = MemoryOrder::SEQ_CST) { + return GPR_ATM_INC_ADD_THEN(storage_.fetch_sub( + static_cast(arg), static_cast(order))); + } + + // Atomically increment a counter only if the counter value is not zero. + // Returns true if increment took place; false if counter is zero. + bool IncrementIfNonzero(MemoryOrder load_order = MemoryOrder::ACQ_REL) { + T count = storage_.load(static_cast(load_order)); + do { + // If zero, we are done (without an increment). If not, we must do a CAS + // to maintain the contract: do not increment the counter if it is already + // zero + if (count == 0) { + return false; + } + } while (!storage_.AtomicCompareExchangeWeak( + &count, count + 1, static_cast(MemoryOrder::ACQ_REL), + static_cast(load_order))); + return true; + } + + private: + std::atomic storage_; +}; } // namespace grpc_core diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index 8148cfd35d2..98a7edebf86 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -89,7 +89,7 @@ class RefCount { } // Increases the ref-count by `n`. - void Ref(Value n = 1) { AtomicFetchAdd(&value_, n, MemoryOrder::RELAXED); } + void Ref(Value n = 1) { value_.FetchAdd(n, MemoryOrder::RELAXED); } void Ref(const DebugLocation& location, const char* reason, Value n = 1) { #ifndef NDEBUG if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) { @@ -105,7 +105,7 @@ class RefCount { // Similar to Ref() with an assert on the ref-count being non-zero. void RefNonZero() { #ifndef NDEBUG - const Value prior = AtomicFetchAdd(&value_, 1, MemoryOrder::RELAXED); + const Value prior = value_.FetchAdd(1, MemoryOrder::RELAXED); assert(prior > 0); #else Ref(); @@ -125,7 +125,7 @@ class RefCount { // Decrements the ref-count and returns true if the ref-count reaches 0. bool Unref() { - const Value prior = AtomicFetchSub(&value_, 1, MemoryOrder::ACQ_REL); + const Value prior = value_.FetchSub(1, MemoryOrder::ACQ_REL); GPR_DEBUG_ASSERT(prior > 0); return prior == 1; } @@ -142,7 +142,7 @@ class RefCount { } private: - Value get() const { return AtomicLoad(&value_, MemoryOrder::RELAXED); } + Value get() const { return value_.Load(MemoryOrder::RELAXED); } #ifndef NDEBUG TraceFlag* trace_flag_; diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc index c2ee9d985e9..5f5f10d2ebf 100644 --- a/src/core/lib/surface/lame_client.cc +++ b/src/core/lib/surface/lame_client.cc @@ -53,9 +53,8 @@ struct ChannelData { static void fill_metadata(grpc_call_element* elem, grpc_metadata_batch* mdb) { CallData* calld = static_cast(elem->call_data); bool expected = false; - if (!AtomicCompareExchangeStrong(&calld->filled_metadata, &expected, true, - MemoryOrder::RELAXED, - MemoryOrder::RELAXED)) { + if (!calld->filled_metadata.CompareExchangeStrong( + &expected, true, MemoryOrder::RELAXED, MemoryOrder::RELAXED)) { return; } ChannelData* chand = static_cast(elem->channel_data); From 2ba9a5aaa8db02c7780e7f25ea73f93ed491f0bc Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 20 Feb 2019 10:33:02 -0800 Subject: [PATCH 445/814] bazel dep --- src/python/grpcio_tests/tests/health_check/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python/grpcio_tests/tests/health_check/BUILD.bazel b/src/python/grpcio_tests/tests/health_check/BUILD.bazel index 77bc61aa30e..49f076be9a1 100644 --- a/src/python/grpcio_tests/tests/health_check/BUILD.bazel +++ b/src/python/grpcio_tests/tests/health_check/BUILD.bazel @@ -9,6 +9,7 @@ py_test( "//src/python/grpcio/grpc:grpcio", "//src/python/grpcio_health_checking/grpc_health/v1:grpc_health", "//src/python/grpcio_tests/tests/unit:test_common", + "//src/python/grpcio_tests/tests/unit:thread_pool", "//src/python/grpcio_tests/tests/unit/framework/common:common", ], imports = ["../../",], From bf7107b9dc92ff96c9d00a6ee95fc21afeecc848 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 20 Feb 2019 11:00:04 -0800 Subject: [PATCH 446/814] comments --- src/python/grpcio/grpc/_server.py | 20 +++++----- .../grpc_health/v1/health.py | 39 ++++++++++--------- .../health_check/_health_servicer_test.py | 7 ++-- .../grpcio_tests/tests/unit/_rpc_test.py | 1 - 4 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index b1b6027ed5a..0af35e7fc25 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -391,11 +391,11 @@ def _call_behavior(rpc_event, behavior, argument, request_deserializer, - on_next_callback=None): + send_response_callback=None): context = _Context(rpc_event, state, request_deserializer) try: - if on_next_callback is not None: - return behavior(argument, context, on_next_callback), True + if send_response_callback is not None: + return behavior(argument, context, send_response_callback), True else: return behavior(argument, context), True except Exception as exception: # pylint: disable=broad-except @@ -510,7 +510,7 @@ def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): cygrpc.install_context_from_call(rpc_event.call) - def on_next(response): + def send_response(response): if response is None: _status(rpc_event, state, None) else: @@ -530,13 +530,13 @@ def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, behavior, argument, request_deserializer, - on_next_callback=on_next) + send_response_callback=send_response) else: response_iterator, proceed = _call_behavior( rpc_event, state, behavior, argument, request_deserializer) if proceed: - _stream_response_iterator_adapter(rpc_event, state, on_next, - response_iterator) + _send_message_callback_to_blocking_iterator_adapter( + rpc_event, state, send_response, response_iterator) finally: cygrpc.uninstall_context() @@ -545,13 +545,13 @@ def _is_rpc_state_active(state): return state.client is not _CANCELLED and not state.statused -def _stream_response_iterator_adapter(rpc_event, state, on_next_callback, - response_iterator): +def _send_message_callback_to_blocking_iterator_adapter( + rpc_event, state, send_response_callback, response_iterator): while True: response, proceed = _take_response_from_response_iterator( rpc_event, state, response_iterator) if proceed: - on_next_callback(response) + send_response_callback(response) if not _is_rpc_state_active(state): break else: diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py index c1bb998df90..b08297a5d71 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -60,15 +60,15 @@ class _Watcher(): self._condition.notify() -def _watcher_to_on_next_callback_adapter(watcher): +def _watcher_to_send_response_callback_adapter(watcher): - def on_next_callback(response): + def send_response_callback(response): if response is None: watcher.close() else: watcher.add(response) - return on_next_callback + return send_response_callback class HealthServicer(_health_pb2_grpc.HealthServicer): @@ -79,16 +79,17 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): experimental_thread_pool=None): self._lock = threading.RLock() self._server_status = {} - self._on_next_callbacks = {} + self._send_response_callbacks = {} self.Watch.__func__.experimental_non_blocking = experimental_non_blocking self.Watch.__func__.experimental_thread_pool = experimental_thread_pool - def _on_close_callback(self, on_next_callback, service): + def _on_close_callback(self, send_response_callback, service): def callback(): with self._lock: - self._on_next_callbacks[service].remove(on_next_callback) - on_next_callback(None) + self._send_response_callbacks[service].remove( + send_response_callback) + send_response_callback(None) return callback @@ -102,26 +103,27 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): return _health_pb2.HealthCheckResponse(status=status) # pylint: disable=arguments-differ - def Watch(self, request, context, on_next_callback=None): + def Watch(self, request, context, send_response_callback=None): blocking_watcher = None - if on_next_callback is None: + if send_response_callback is None: # The server does not support the experimental_non_blocking # parameter. For backwards compatibility, return a blocking response # generator. blocking_watcher = _Watcher() - on_next_callback = _watcher_to_on_next_callback_adapter( + send_response_callback = _watcher_to_send_response_callback_adapter( blocking_watcher) service = request.service with self._lock: status = self._server_status.get(service) if status is None: status = _health_pb2.HealthCheckResponse.SERVICE_UNKNOWN # pylint: disable=no-member - on_next_callback(_health_pb2.HealthCheckResponse(status=status)) - if service not in self._on_next_callbacks: - self._on_next_callbacks[service] = set() - self._on_next_callbacks[service].add(on_next_callback) + send_response_callback( + _health_pb2.HealthCheckResponse(status=status)) + if service not in self._send_response_callbacks: + self._send_response_callbacks[service] = set() + self._send_response_callbacks[service].add(send_response_callback) context.add_callback( - self._on_close_callback(on_next_callback, service)) + self._on_close_callback(send_response_callback, service)) return blocking_watcher def set(self, service, status): @@ -134,7 +136,8 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): """ with self._lock: self._server_status[service] = status - if service in self._on_next_callbacks: - for on_next_callback in self._on_next_callbacks[service]: - on_next_callback( + if service in self._send_response_callbacks: + for send_response_callback in self._send_response_callbacks[ + service]: + send_response_callback( _health_pb2.HealthCheckResponse(status=status)) diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index 42a61b29f7c..f92596f5c9b 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -196,10 +196,11 @@ class BaseWatchTests(object): # Wait, if necessary, for serving thread to process client cancellation timeout = time.time() + test_constants.SHORT_TIMEOUT while time.time( - ) < timeout and self._servicer._on_next_callbacks[_WATCH_SERVICE]: + ) < timeout and self._servicer._send_response_callbacks[_WATCH_SERVICE]: time.sleep(1) - self.assertFalse(self._servicer._on_next_callbacks[_WATCH_SERVICE], - 'watch set should be empty') + self.assertFalse( + self._servicer._send_response_callbacks[_WATCH_SERVICE], + 'watch set should be empty') self.assertTrue(response_queue.empty()) diff --git a/src/python/grpcio_tests/tests/unit/_rpc_test.py b/src/python/grpcio_tests/tests/unit/_rpc_test.py index 4862d0fb185..3f3f87adf9c 100644 --- a/src/python/grpcio_tests/tests/unit/_rpc_test.py +++ b/src/python/grpcio_tests/tests/unit/_rpc_test.py @@ -101,7 +101,6 @@ class _Handler(object): for _ in range(test_constants.STREAM_LENGTH): self._control.control() on_next(request) - # yield request self._control.control() if servicer_context is not None: servicer_context.set_trailing_metadata((( From 227cce9ad376ad3fdfcf7502df3322e0bda695e8 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 20 Feb 2019 11:27:59 -0800 Subject: [PATCH 447/814] Use malloc/free in leak checker --- src/core/lib/gpr/sync_posix.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 3c49d78f9c1..a30e36c11ac 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -76,7 +76,7 @@ gpr_atm gpr_counter_atm_add = 0; void gpr_mu_init(gpr_mu* mu) { #ifdef GRPC_ASAN_ENABLED GPR_ASSERT(pthread_mutex_init(&mu->mutex, nullptr) == 0); - mu->leak_checker = static_cast(gpr_malloc(sizeof(*mu->leak_checker))); + mu->leak_checker = static_cast(malloc(sizeof(*mu->leak_checker))); GPR_ASSERT(mu->leak_checker != nullptr); #else GPR_ASSERT(pthread_mutex_init(mu, nullptr) == 0); @@ -86,7 +86,7 @@ void gpr_mu_init(gpr_mu* mu) { void gpr_mu_destroy(gpr_mu* mu) { #ifdef GRPC_ASAN_ENABLED GPR_ASSERT(pthread_mutex_destroy(&mu->mutex) == 0); - gpr_free(mu->leak_checker); + free(mu->leak_checker); #else GPR_ASSERT(pthread_mutex_destroy(mu) == 0); #endif @@ -136,7 +136,7 @@ void gpr_cv_init(gpr_cv* cv) { #ifdef GRPC_ASAN_ENABLED GPR_ASSERT(pthread_cond_init(&cv->cond_var, &attr) == 0); - cv->leak_checker = static_cast(gpr_malloc(sizeof(*cv->leak_checker))); + cv->leak_checker = static_cast(malloc(sizeof(*cv->leak_checker))); GPR_ASSERT(cv->leak_checker != nullptr); #else GPR_ASSERT(pthread_cond_init(cv, &attr) == 0); @@ -146,7 +146,7 @@ void gpr_cv_init(gpr_cv* cv) { void gpr_cv_destroy(gpr_cv* cv) { #ifdef GRPC_ASAN_ENABLED GPR_ASSERT(pthread_cond_destroy(&cv->cond_var) == 0); - gpr_free(cv->leak_checker); + free(cv->leak_checker); #else GPR_ASSERT(pthread_cond_destroy(cv) == 0); #endif From 42c512c43ea7c6c010d926cd1d24c24f4f9a46ad Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 20 Feb 2019 10:37:08 -0800 Subject: [PATCH 448/814] Use atm operations on gpr_atm variables --- src/core/lib/channel/channelz.cc | 51 ++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 8a596ad4605..0eed9a59fef 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -385,52 +385,65 @@ grpc_json* SocketNode::RenderJson() { json = data; json_iterator = nullptr; gpr_timespec ts; - if (streams_started_ != 0) { + gpr_atm streams_started = gpr_atm_no_barrier_load(&streams_started_); + if (streams_started != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "streamsStarted", streams_started_); - if (last_local_stream_created_millis_ != 0) { - ts = grpc_millis_to_timespec(last_local_stream_created_millis_, + json, json_iterator, "streamsStarted", streams_started); + gpr_atm last_local_stream_created_millis = + gpr_atm_no_barrier_load(&last_local_stream_created_millis_); + if (last_local_stream_created_millis != 0) { + ts = grpc_millis_to_timespec(last_local_stream_created_millis, GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child( json_iterator, json, "lastLocalStreamCreatedTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); } - if (last_remote_stream_created_millis_ != 0) { - ts = grpc_millis_to_timespec(last_remote_stream_created_millis_, + gpr_atm last_remote_stream_created_millis = + gpr_atm_no_barrier_load(&last_remote_stream_created_millis_); + if (last_remote_stream_created_millis != 0) { + ts = grpc_millis_to_timespec(last_remote_stream_created_millis, GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child( json_iterator, json, "lastRemoteStreamCreatedTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); } } - if (streams_succeeded_ != 0) { + gpr_atm streams_succeeded = gpr_atm_no_barrier_load(&streams_succeeded_); + if (streams_succeeded != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "streamsSucceeded", streams_succeeded_); + json, json_iterator, "streamsSucceeded", streams_succeeded); } - if (streams_failed_) { + gpr_atm streams_failed = gpr_atm_no_barrier_load(&streams_failed_); + if (streams_failed) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "streamsFailed", streams_failed_); + json, json_iterator, "streamsFailed", streams_failed); } - if (messages_sent_ != 0) { + gpr_atm messages_sent = gpr_atm_no_barrier_load(&messages_sent_); + if (messages_sent != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "messagesSent", messages_sent_); - ts = grpc_millis_to_timespec(last_message_sent_millis_, GPR_CLOCK_REALTIME); + json, json_iterator, "messagesSent", messages_sent); + ts = grpc_millis_to_timespec( + gpr_atm_no_barrier_load(&last_message_sent_millis_), + GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child(json_iterator, json, "lastMessageSentTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); } - if (messages_received_ != 0) { + gpr_atm messages_received = gpr_atm_no_barrier_load(&messages_received_); + if (messages_received != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "messagesReceived", messages_received_); - ts = grpc_millis_to_timespec(last_message_received_millis_, - GPR_CLOCK_REALTIME); + json, json_iterator, "messagesReceived", messages_received); + ts = grpc_millis_to_timespec( + gpr_atm_no_barrier_load(&last_message_received_millis_), + GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child( json_iterator, json, "lastMessageReceivedTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); } - if (keepalives_sent_ != 0) { + gpr_atm keepalives_sent = gpr_atm_no_barrier_load(&keepalives_sent_); + if (keepalives_sent != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "keepAlivesSent", keepalives_sent_); + json, json_iterator, "keepAlivesSent", keepalives_sent); } return top_level_json; } From d209deb14b5a3612a274639aa6ae3d07bf9cc138 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 30 Jan 2019 10:28:34 -0800 Subject: [PATCH 449/814] Revert "Revert "Merge pull request #17644 from lidizheng/bzl-py3"" This reverts commit 7da0aacef2886d5556a043fc3b6400db9daa5424. --- BUILD | 5 +++ src/python/grpcio/grpc/BUILD.bazel | 6 ++-- .../grpcio/grpc/framework/common/BUILD.bazel | 14 ++++---- .../grpc/framework/foundation/BUILD.bazel | 13 +++++--- .../framework/interfaces/base/BUILD.bazel | 13 +++++--- .../framework/interfaces/face/BUILD.bazel | 6 ++-- .../grpcio_status/grpc_status/rpc_status.py | 5 --- src/python/grpcio_tests/tests/BUILD.bazel | 8 +++++ .../tests/bazel_namespace_package_hack.py | 32 +++++++++++++++++++ .../grpcio_tests/tests/interop/BUILD.bazel | 7 ++-- .../grpcio_tests/tests/interop/methods.py | 3 ++ .../reflection/_reflection_servicer_test.py | 20 +++++++++--- .../grpcio_tests/tests/status/BUILD.bazel | 1 + .../tests/status/_grpc_status_test.py | 3 ++ third_party/py/python_configure.bzl | 11 ++++--- tools/bazel.rc | 4 +++ .../linux/grpc_python_bazel_test_in_docker.sh | 2 ++ 17 files changed, 117 insertions(+), 36 deletions(-) create mode 100644 src/python/grpcio_tests/tests/BUILD.bazel create mode 100644 src/python/grpcio_tests/tests/bazel_namespace_package_hack.py diff --git a/BUILD b/BUILD index a566057e926..6895916ac67 100644 --- a/BUILD +++ b/BUILD @@ -63,6 +63,11 @@ config_setting( values = {"cpu": "x64_windows_msvc"}, ) +config_setting( + name = "python3", + values = {"python_path": "python3"}, +) + # This should be updated along with build.yaml g_stands_for = "godric" diff --git a/src/python/grpcio/grpc/BUILD.bazel b/src/python/grpcio/grpc/BUILD.bazel index 6958ccdfb66..27d5d2e4bb2 100644 --- a/src/python/grpcio/grpc/BUILD.bazel +++ b/src/python/grpcio/grpc/BUILD.bazel @@ -15,9 +15,11 @@ py_library( "//src/python/grpcio/grpc/_cython:cygrpc", "//src/python/grpcio/grpc/experimental", "//src/python/grpcio/grpc/framework", - requirement('enum34'), requirement('six'), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), data = [ "//:grpc", ], diff --git a/src/python/grpcio/grpc/framework/common/BUILD.bazel b/src/python/grpcio/grpc/framework/common/BUILD.bazel index 9d9ef682c90..52fbb2b516c 100644 --- a/src/python/grpcio/grpc/framework/common/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/common/BUILD.bazel @@ -13,15 +13,17 @@ py_library( py_library( name = "cardinality", srcs = ["cardinality.py"], - deps = [ - requirement("enum34"), - ], + deps = select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( name = "style", srcs = ["style.py"], - deps = [ - requirement("enum34"), - ], + deps = select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) diff --git a/src/python/grpcio/grpc/framework/foundation/BUILD.bazel b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel index 1287fdd44ed..a447ecded49 100644 --- a/src/python/grpcio/grpc/framework/foundation/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel @@ -23,9 +23,11 @@ py_library( name = "callable_util", srcs = ["callable_util.py"], deps = [ - requirement("enum34"), requirement("six"), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( @@ -39,9 +41,10 @@ py_library( py_library( name = "logging_pool", srcs = ["logging_pool.py"], - deps = [ - requirement("futures"), - ], + deps = select({ + "//conditions:default": [requirement('futures'),], + "//:python3": [], + }), ) py_library( diff --git a/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel b/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel index 408a66a6310..35cfe877f34 100644 --- a/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel @@ -15,15 +15,18 @@ py_library( srcs = ["base.py"], deps = [ "//src/python/grpcio/grpc/framework/foundation:abandonment", - requirement("enum34"), requirement("six"), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( name = "utilities", srcs = ["utilities.py"], - deps = [ - requirement("enum34"), - ], + deps = select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) diff --git a/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel b/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel index e683e7cc426..83fadb6372e 100644 --- a/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel +++ b/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel @@ -16,9 +16,11 @@ py_library( deps = [ "//src/python/grpcio/grpc/framework/foundation", "//src/python/grpcio/grpc/framework/common", - requirement("enum34"), requirement("six"), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), ) py_library( diff --git a/src/python/grpcio_status/grpc_status/rpc_status.py b/src/python/grpcio_status/grpc_status/rpc_status.py index 87618fa5412..76891e2422e 100644 --- a/src/python/grpcio_status/grpc_status/rpc_status.py +++ b/src/python/grpcio_status/grpc_status/rpc_status.py @@ -17,11 +17,6 @@ import collections import grpc -# TODO(https://github.com/bazelbuild/bazel/issues/6844) -# Due to Bazel issue, the namespace packages won't resolve correctly. -# Adding this unused-import as a workaround to avoid module-not-found error -# under Bazel builds. -import google.protobuf # pylint: disable=unused-import from google.rpc import status_pb2 _CODE_TO_GRPC_CODE_MAPPING = {x.value[0]: x for x in grpc.StatusCode} diff --git a/src/python/grpcio_tests/tests/BUILD.bazel b/src/python/grpcio_tests/tests/BUILD.bazel new file mode 100644 index 00000000000..b908ab85173 --- /dev/null +++ b/src/python/grpcio_tests/tests/BUILD.bazel @@ -0,0 +1,8 @@ +py_library( + name = "bazel_namespace_package_hack", + srcs = ["bazel_namespace_package_hack.py"], + visibility = [ + "//src/python/grpcio_tests/tests/status:__subpackages__", + "//src/python/grpcio_tests/tests/interop:__subpackages__", + ], +) diff --git a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py new file mode 100644 index 00000000000..c6b72c327b1 --- /dev/null +++ b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py @@ -0,0 +1,32 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import site +import sys + + +# TODO(https://github.com/bazelbuild/bazel/issues/6844) Bazel failed to +# interpret namespace packages correctly. This monkey patch will force the +# Python process to parse the .pth file in the sys.path to resolve namespace +# package in the right place. +# Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 +def sys_path_to_site_dir_hack(): + """Add valid sys.path item to site directory to parse the .pth files.""" + for item in sys.path: + if os.path.exists(item): + # The only difference between sys.path and site-directory is + # whether the .pth file will be parsed or not. A site-directory + # will always exist in sys.path, but not another way around. + site.addsitedir(item) diff --git a/src/python/grpcio_tests/tests/interop/BUILD.bazel b/src/python/grpcio_tests/tests/interop/BUILD.bazel index aebdbf67ebf..770b1f78a70 100644 --- a/src/python/grpcio_tests/tests/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests/interop/BUILD.bazel @@ -29,17 +29,20 @@ py_library( srcs = ["methods.py"], deps = [ "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing:py_messages_proto", "//src/proto/grpc/testing:py_test_proto", requirement('google-auth'), requirement('requests'), - requirement('enum34'), requirement('urllib3'), requirement('chardet'), requirement('certifi'), requirement('idna'), - ], + ] + select({ + "//conditions:default": [requirement('enum34'),], + "//:python3": [], + }), imports=["../../",], ) diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index c11f6c8fad7..e16966e3918 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -13,6 +13,9 @@ # limitations under the License. """Implementations of interoperability test methods.""" +from tests import bazel_namespace_package_hack +bazel_namespace_package_hack.sys_path_to_site_dir_hack() + import enum import json import os diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py index 560f6d3ddb3..37a66ad52bb 100644 --- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py +++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py @@ -50,6 +50,16 @@ def _file_descriptor_to_proto(descriptor): class ReflectionServicerTest(unittest.TestCase): + # TODO(https://github.com/grpc/grpc/issues/17844) + # Bazel + Python 3 will result in creating two different instance of + # DESCRIPTOR for each message. So, the equal comparison between protobuf + # returned by stub and manually crafted protobuf will always fail. + def _assert_sequence_of_proto_equal(self, x, y): + self.assertSequenceEqual( + list(map(lambda x: x.SerializeToString(), x)), + list(map(lambda x: x.SerializeToString(), y)), + ) + def setUp(self): self._server = test_common.test_server() reflection.enable_server_reflection(_SERVICE_NAMES, self._server) @@ -84,7 +94,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testFileBySymbol(self): requests = ( @@ -108,7 +118,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testFileContainingExtension(self): requests = ( @@ -137,7 +147,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testExtensionNumbersOfType(self): requests = ( @@ -162,7 +172,7 @@ class ReflectionServicerTest(unittest.TestCase): error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), )), ) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testListServices(self): requests = (reflection_pb2.ServerReflectionRequest(list_services='',),) @@ -173,7 +183,7 @@ class ReflectionServicerTest(unittest.TestCase): service=tuple( reflection_pb2.ServiceResponse(name=name) for name in _SERVICE_NAMES))),) - self.assertSequenceEqual(expected_responses, responses) + self._assert_sequence_of_proto_equal(expected_responses, responses) def testReflectionServiceName(self): self.assertEqual(reflection.SERVICE_NAME, diff --git a/src/python/grpcio_tests/tests/status/BUILD.bazel b/src/python/grpcio_tests/tests/status/BUILD.bazel index 937e50498e0..b163fe3975e 100644 --- a/src/python/grpcio_tests/tests/status/BUILD.bazel +++ b/src/python/grpcio_tests/tests/status/BUILD.bazel @@ -10,6 +10,7 @@ py_test( deps = [ "//src/python/grpcio/grpc:grpcio", "//src/python/grpcio_status/grpc_status:grpc_status", + "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", "//src/python/grpcio_tests/tests/unit:test_common", "//src/python/grpcio_tests/tests/unit/framework/common:common", requirement('protobuf'), diff --git a/src/python/grpcio_tests/tests/status/_grpc_status_test.py b/src/python/grpcio_tests/tests/status/_grpc_status_test.py index 519c372a960..77f5fb283d1 100644 --- a/src/python/grpcio_tests/tests/status/_grpc_status_test.py +++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py @@ -13,6 +13,9 @@ # limitations under the License. """Tests of grpc_status.""" +from tests import bazel_namespace_package_hack +bazel_namespace_package_hack.sys_path_to_site_dir_hack() + import unittest import logging diff --git a/third_party/py/python_configure.bzl b/third_party/py/python_configure.bzl index 2ba1e07049c..9036a95909b 100644 --- a/third_party/py/python_configure.bzl +++ b/third_party/py/python_configure.bzl @@ -138,10 +138,13 @@ def _symlink_genrule_for_dir(repository_ctx, def _get_python_bin(repository_ctx): """Gets the python bin path.""" - python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH) - if python_bin != None: - return python_bin - python_bin_path = repository_ctx.which("python") + python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH, 'python') + if not '/' in python_bin and not '\\' in python_bin: + # It's a command, use 'which' to find its path. + python_bin_path = repository_ctx.which(python_bin) + else: + # It's a path, use it as it is. + python_bin_path = python_bin if python_bin_path != None: return str(python_bin_path) _fail("Cannot find python in PATH, please make sure " + diff --git a/tools/bazel.rc b/tools/bazel.rc index 59e597b4723..99347495361 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -57,3 +57,7 @@ build:basicprof --copt=-DNDEBUG build:basicprof --copt=-O2 build:basicprof --copt=-DGRPC_BASIC_PROFILER build:basicprof --copt=-DGRPC_TIMERS_RDTSC + +build:python3 --python_path=python3 +build:python3 --force_python=PY3 +build:python3 --action_env=PYTHON_BIN_PATH=python3 diff --git a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh index 156d65955ad..14989648a2a 100755 --- a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh +++ b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh @@ -25,3 +25,5 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc ${name}') cd /var/local/git/grpc/test bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +bazel clean --expunge +bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... From 48ccc2477cf76e3eeeb2eb1f7ce187aa9553d0df Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 30 Jan 2019 10:34:56 -0800 Subject: [PATCH 450/814] Prevent the Bazel hack from affecting environment other than Bazel --- src/python/grpcio_tests/tests/bazel_namespace_package_hack.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py index c6b72c327b1..168aa163fe2 100644 --- a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py +++ b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py @@ -24,6 +24,9 @@ import sys # Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 def sys_path_to_site_dir_hack(): """Add valid sys.path item to site directory to parse the .pth files.""" + # If not running under Bazel, return. + if 'RUN_UNDER_RUNFILES' not in os.environ: + return for item in sys.path: if os.path.exists(item): # The only difference between sys.path and site-directory is From e9c67f23f35a5f90b12db259cd3efc4fb5cee6c7 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 31 Jan 2019 16:18:13 -0800 Subject: [PATCH 451/814] Add a new environment variable GRPC_BAZEL_BUILD --- src/python/grpcio_tests/tests/bazel_namespace_package_hack.py | 4 ++-- tools/bazel.rc | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py index 168aa163fe2..b533ca3074c 100644 --- a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py +++ b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py @@ -24,8 +24,8 @@ import sys # Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 def sys_path_to_site_dir_hack(): """Add valid sys.path item to site directory to parse the .pth files.""" - # If not running under Bazel, return. - if 'RUN_UNDER_RUNFILES' not in os.environ: + # GRPC_BAZEL_BUILD is explicitly set by tools/bazel.rc. + if 'GRPC_BAZEL_BUILD' not in os.environ: return for item in sys.path: if os.path.exists(item): diff --git a/tools/bazel.rc b/tools/bazel.rc index 99347495361..2d04bf7c9e8 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -5,6 +5,7 @@ build --client_env=CC=clang build --copt=-DGRPC_BAZEL_BUILD +build --action_env=GRPC_BAZEL_BUILD=1 build:opt --compilation_mode=opt build:opt --copt=-Wframe-larger-than=16384 From 61bea3891beaa9c3f4d6be047c26df91aff3c31b Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 19 Feb 2019 11:39:37 -0800 Subject: [PATCH 452/814] Another attempt to fix this problem cleanly --- .../grpcio_tests/tests/bazel_namespace_package_hack.py | 3 --- src/python/grpcio_tests/tests/interop/methods.py | 9 +++++++-- .../grpcio_tests/tests/status/_grpc_status_test.py | 9 +++++++-- tools/bazel.rc | 1 - 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py index b533ca3074c..c6b72c327b1 100644 --- a/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py +++ b/src/python/grpcio_tests/tests/bazel_namespace_package_hack.py @@ -24,9 +24,6 @@ import sys # Analysis in depth: https://github.com/bazelbuild/rules_python/issues/55 def sys_path_to_site_dir_hack(): """Add valid sys.path item to site directory to parse the .pth files.""" - # GRPC_BAZEL_BUILD is explicitly set by tools/bazel.rc. - if 'GRPC_BAZEL_BUILD' not in os.environ: - return for item in sys.path: if os.path.exists(item): # The only difference between sys.path and site-directory is diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index e16966e3918..40341ca091b 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -13,8 +13,13 @@ # limitations under the License. """Implementations of interoperability test methods.""" -from tests import bazel_namespace_package_hack -bazel_namespace_package_hack.sys_path_to_site_dir_hack() +# NOTE(lidiz) This module only exists in Bazel BUILD file, for more details +# please refer to comments in the "bazel_namespace_package_hack" module. +try: + from tests import bazel_namespace_package_hack + bazel_namespace_package_hack.sys_path_to_site_dir_hack() +except ImportError: + pass import enum import json diff --git a/src/python/grpcio_tests/tests/status/_grpc_status_test.py b/src/python/grpcio_tests/tests/status/_grpc_status_test.py index 77f5fb283d1..d1e9773b495 100644 --- a/src/python/grpcio_tests/tests/status/_grpc_status_test.py +++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py @@ -13,8 +13,13 @@ # limitations under the License. """Tests of grpc_status.""" -from tests import bazel_namespace_package_hack -bazel_namespace_package_hack.sys_path_to_site_dir_hack() +# NOTE(lidiz) This module only exists in Bazel BUILD file, for more details +# please refer to comments in the "bazel_namespace_package_hack" module. +try: + from tests import bazel_namespace_package_hack + bazel_namespace_package_hack.sys_path_to_site_dir_hack() +except ImportError: + pass import unittest diff --git a/tools/bazel.rc b/tools/bazel.rc index 2d04bf7c9e8..99347495361 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -5,7 +5,6 @@ build --client_env=CC=clang build --copt=-DGRPC_BAZEL_BUILD -build --action_env=GRPC_BAZEL_BUILD=1 build:opt --compilation_mode=opt build:opt --copt=-Wframe-larger-than=16384 From cb3966b881d968fd2faec099c585ef2a67001c3b Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 20 Feb 2019 13:42:09 -0800 Subject: [PATCH 453/814] Use `tuple` instead of `list`/`map` combination --- .../tests/reflection/_reflection_servicer_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py index 37a66ad52bb..29bb292c913 100644 --- a/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py +++ b/src/python/grpcio_tests/tests/reflection/_reflection_servicer_test.py @@ -56,8 +56,8 @@ class ReflectionServicerTest(unittest.TestCase): # returned by stub and manually crafted protobuf will always fail. def _assert_sequence_of_proto_equal(self, x, y): self.assertSequenceEqual( - list(map(lambda x: x.SerializeToString(), x)), - list(map(lambda x: x.SerializeToString(), y)), + tuple(proto.SerializeToString() for proto in x), + tuple(proto.SerializeToString() for proto in y), ) def setUp(self): From eaeda3618dd94e378e6eb0167a8121f066b0ea6b Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 20 Feb 2019 14:17:33 -0800 Subject: [PATCH 454/814] Check file existence correctly --- third_party/py/python_configure.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/py/python_configure.bzl b/third_party/py/python_configure.bzl index 9036a95909b..e6fa5ed10e9 100644 --- a/third_party/py/python_configure.bzl +++ b/third_party/py/python_configure.bzl @@ -139,7 +139,7 @@ def _symlink_genrule_for_dir(repository_ctx, def _get_python_bin(repository_ctx): """Gets the python bin path.""" python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH, 'python') - if not '/' in python_bin and not '\\' in python_bin: + if not repository_ctx.path(python_bin).exists: # It's a command, use 'which' to find its path. python_bin_path = repository_ctx.which(python_bin) else: From a2495502df6133bdd939be6ef83ce417249e7ec3 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 20 Feb 2019 15:54:11 -0800 Subject: [PATCH 455/814] add enter_graceful_shutdown() to health service --- .../grpc_health/v1/health.py | 17 +++++++++++++ .../health_check/_health_servicer_test.py | 24 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py index b08297a5d71..04ea3b4ecfb 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -82,6 +82,7 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): self._send_response_callbacks = {} self.Watch.__func__.experimental_non_blocking = experimental_non_blocking self.Watch.__func__.experimental_thread_pool = experimental_thread_pool + self._gracefully_shutting_down = False def _on_close_callback(self, send_response_callback, service): @@ -135,9 +136,25 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): the service """ with self._lock: + if self._gracefully_shutting_down: + return self._server_status[service] = status if service in self._send_response_callbacks: for send_response_callback in self._send_response_callbacks[ service]: send_response_callback( _health_pb2.HealthCheckResponse(status=status)) + + def enter_graceful_shutdown(self): + """Permanently sets the status of all services to NOT_SERVING. + + This should be invoked when the server is entering a graceful shutdown + period. After this method is invoked, future attempts to set the status + of a service will be ignored. + """ + with self._lock: + if self._gracefully_shutting_down: + return + for service in self._server_status: + self.set(service, _health_pb2.HealthCheckResponse.NOT_SERVING) # pylint: disable=no-member + self._gracefully_shutting_down = True diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index f92596f5c9b..62eef8e2291 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -203,6 +203,30 @@ class BaseWatchTests(object): 'watch set should be empty') self.assertTrue(response_queue.empty()) + def test_graceful_shutdown(self): + request = health_pb2.HealthCheckRequest(service='') + response_queue = queue.Queue() + rendezvous = self._stub.Watch(request) + thread = threading.Thread( + target=_consume_responses, args=(rendezvous, response_queue)) + thread.start() + + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, + response.status) + + self._servicer.enter_graceful_shutdown() + response = response_queue.get(timeout=test_constants.SHORT_TIMEOUT) + self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, + response.status) + + # This should be a no-op. + self._servicer.set('', health_pb2.HealthCheckResponse.SERVING) + + rendezvous.cancel() + thread.join() + self.assertTrue(response_queue.empty()) + class HealthServicerTest(BaseWatchTests.WatchTests): From fbc4ea7d8efa1081613fb79ac3d66331c8381670 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 20 Feb 2019 16:00:11 -0800 Subject: [PATCH 456/814] mark as experimental --- src/python/grpcio_health_checking/grpc_health/v1/health.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py index 04ea3b4ecfb..3d8c16ee1b6 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -151,6 +151,8 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): This should be invoked when the server is entering a graceful shutdown period. After this method is invoked, future attempts to set the status of a service will be ignored. + + This is an EXPERIMENTAL API. """ with self._lock: if self._gracefully_shutting_down: From ab5b28538f16daed9ccd857b87714df49c2a4712 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 20 Feb 2019 16:20:32 -0800 Subject: [PATCH 457/814] use else: --- .../grpc_health/v1/health.py | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py index 3d8c16ee1b6..dc889cdc774 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -118,13 +118,15 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): status = self._server_status.get(service) if status is None: status = _health_pb2.HealthCheckResponse.SERVICE_UNKNOWN # pylint: disable=no-member - send_response_callback( - _health_pb2.HealthCheckResponse(status=status)) - if service not in self._send_response_callbacks: - self._send_response_callbacks[service] = set() - self._send_response_callbacks[service].add(send_response_callback) - context.add_callback( - self._on_close_callback(send_response_callback, service)) + else: + send_response_callback( + _health_pb2.HealthCheckResponse(status=status)) + if service not in self._send_response_callbacks: + self._send_response_callbacks[service] = set() + self._send_response_callbacks[service].add( + send_response_callback) + context.add_callback( + self._on_close_callback(send_response_callback, service)) return blocking_watcher def set(self, service, status): @@ -157,6 +159,8 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): with self._lock: if self._gracefully_shutting_down: return - for service in self._server_status: - self.set(service, _health_pb2.HealthCheckResponse.NOT_SERVING) # pylint: disable=no-member - self._gracefully_shutting_down = True + else: + for service in self._server_status: + self.set(service, + _health_pb2.HealthCheckResponse.NOT_SERVING) # pylint: disable=no-member + self._gracefully_shutting_down = True From cdab1c260fe7585939d27e6d3f9102263e8b29a2 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 20 Feb 2019 16:32:34 -0800 Subject: [PATCH 458/814] Fix termination condition of streaming callback QPS tests --- test/cpp/qps/client_callback.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/test/cpp/qps/client_callback.cc b/test/cpp/qps/client_callback.cc index 0d637c07fef..815780e40ff 100644 --- a/test/cpp/qps/client_callback.cc +++ b/test/cpp/qps/client_callback.cc @@ -253,18 +253,20 @@ class CallbackStreamingPingPongReactor final : client_(client), ctx_(std::move(ctx)), messages_issued_(0) {} void StartNewRpc() { - if (client_->ThreadCompleted()) return; ctx_->stub_->experimental_async()->StreamingCall(&(ctx_->context_), this); write_time_ = UsageTimer::Now(); StartWrite(client_->request()); + writes_done_started_.clear(); StartCall(); } void OnWriteDone(bool ok) override { - if (!ok || client_->ThreadCompleted()) { - if (!ok) gpr_log(GPR_ERROR, "Error writing RPC"); + if (!ok) { + gpr_log(GPR_ERROR, "Error writing RPC"); + } + if ((!ok || client_->ThreadCompleted()) && + !writes_done_started_.test_and_set()) { StartWritesDone(); - return; } StartRead(&ctx_->response_); } @@ -278,7 +280,9 @@ class CallbackStreamingPingPongReactor final if (!ok) { gpr_log(GPR_ERROR, "Error reading RPC"); } - StartWritesDone(); + if (!writes_done_started_.test_and_set()) { + StartWritesDone(); + } return; } write_time_ = UsageTimer::Now(); @@ -295,8 +299,6 @@ class CallbackStreamingPingPongReactor final } void ScheduleRpc() { - if (client_->ThreadCompleted()) return; - if (!client_->IsClosedLoop()) { gpr_timespec next_issue_time = client_->NextRPCIssueTime(); // Start an alarm callback to run the internal callback after @@ -312,6 +314,7 @@ class CallbackStreamingPingPongReactor final CallbackStreamingPingPongClient* client_; std::unique_ptr ctx_; + std::atomic_flag writes_done_started_; Client::Thread* thread_ptr_; // Needed to update histogram entries double write_time_; // Track ping-pong round start time int messages_issued_; // Messages issued by this stream From 93ef0db86b4eee95ae105f1436951e3b2f349886 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 20 Feb 2019 17:11:42 -0800 Subject: [PATCH 459/814] use else in right spot --- .../grpc_health/v1/health.py | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py index dc889cdc774..15494fafdbc 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -118,15 +118,13 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): status = self._server_status.get(service) if status is None: status = _health_pb2.HealthCheckResponse.SERVICE_UNKNOWN # pylint: disable=no-member - else: - send_response_callback( - _health_pb2.HealthCheckResponse(status=status)) - if service not in self._send_response_callbacks: - self._send_response_callbacks[service] = set() - self._send_response_callbacks[service].add( - send_response_callback) - context.add_callback( - self._on_close_callback(send_response_callback, service)) + send_response_callback( + _health_pb2.HealthCheckResponse(status=status)) + if service not in self._send_response_callbacks: + self._send_response_callbacks[service] = set() + self._send_response_callbacks[service].add(send_response_callback) + context.add_callback( + self._on_close_callback(send_response_callback, service)) return blocking_watcher def set(self, service, status): @@ -140,12 +138,13 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): with self._lock: if self._gracefully_shutting_down: return - self._server_status[service] = status - if service in self._send_response_callbacks: - for send_response_callback in self._send_response_callbacks[ - service]: - send_response_callback( - _health_pb2.HealthCheckResponse(status=status)) + else: + self._server_status[service] = status + if service in self._send_response_callbacks: + for send_response_callback in self._send_response_callbacks[ + service]: + send_response_callback( + _health_pb2.HealthCheckResponse(status=status)) def enter_graceful_shutdown(self): """Permanently sets the status of all services to NOT_SERVING. From 3cbf4f50eaf08f53987ae39a5df60f14373175e2 Mon Sep 17 00:00:00 2001 From: Yuwei Huang Date: Wed, 20 Feb 2019 17:31:19 -0800 Subject: [PATCH 460/814] Remove extra semicolons after function definitions We are planning to enable -Wextra-semi flag in our project but some header files in gRPC have extra semicolons that violates the check and blocks us from enabling the flag. This change removes unnecessary semicolons in the code. Note that having semicolon after the GRPC_ABSTRACT macro technically also violates the check, but it's fine for us since they are not used in public headers, and it will be confusing to have lines ending only with GRPC_ABSTRACT, so I keep them as-is. --- include/grpcpp/impl/codegen/client_interceptor.h | 2 +- include/grpcpp/impl/codegen/interceptor.h | 2 +- include/grpcpp/impl/codegen/server_callback.h | 4 ++-- include/grpcpp/impl/codegen/server_interceptor.h | 2 +- include/grpcpp/security/credentials.h | 2 +- include/grpcpp/server.h | 4 ++-- src/compiler/protobuf_plugin.h | 6 +++--- .../ext/filters/client_channel/lb_policy/grpclb/grpclb.cc | 2 +- src/core/lib/gprpp/thd.h | 2 +- src/core/lib/iomgr/buffer_list.h | 2 +- src/cpp/common/core_codegen.cc | 2 +- src/cpp/server/server_cc.cc | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 7dfe2290a3f..e36a9da79d2 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -76,7 +76,7 @@ class ClientRpcInfo { UNKNOWN // UNKNOWN is not API and will be removed later }; - ~ClientRpcInfo(){}; + ~ClientRpcInfo() {} // Delete copy constructor but allow default move constructor ClientRpcInfo(const ClientRpcInfo&) = delete; diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 3af783a61b6..b0f57f71196 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -90,7 +90,7 @@ enum class InterceptionHookPoints { /// 5. Set some fields of an RPC at each interception point, when possible class InterceptorBatchMethods { public: - virtual ~InterceptorBatchMethods(){}; + virtual ~InterceptorBatchMethods() {} /// Determine whether the current batch has an interception hook point /// of type \a type virtual bool QueryInterceptionHookPoint(InterceptionHookPoints type) = 0; diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index a0e59215dd6..60c308b22e7 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -102,7 +102,7 @@ class ServerCallbackWriter { // Default implementation that can/should be overridden Write(msg, std::move(options)); Finish(std::move(s)); - }; + } protected: template @@ -125,7 +125,7 @@ class ServerCallbackReaderWriter { // Default implementation that can/should be overridden Write(msg, std::move(options)); Finish(std::move(s)); - }; + } protected: void BindReactor(ServerBidiReactor* reactor) { diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h index 3e71b3fc55e..8875a28bf32 100644 --- a/include/grpcpp/impl/codegen/server_interceptor.h +++ b/include/grpcpp/impl/codegen/server_interceptor.h @@ -60,7 +60,7 @@ class ServerRpcInfo { /// Type categorizes RPCs by unary or streaming type enum class Type { UNARY, CLIENT_STREAMING, SERVER_STREAMING, BIDI_STREAMING }; - ~ServerRpcInfo(){}; + ~ServerRpcInfo() {} // Delete all copy and move constructors and assignments ServerRpcInfo(const ServerRpcInfo&) = delete; diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index d8c9e04d778..dfea3900048 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -95,7 +95,7 @@ class ChannelCredentials : private GrpcLibraryCodegen { std::unique_ptr> interceptor_creators) { return nullptr; - }; + } }; /// A call credentials object encapsulates the state needed by a client to diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 885bd8de8d7..248f20452a5 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -189,7 +189,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { /// \param num_cqs How many completion queues does \a cqs hold. void Start(ServerCompletionQueue** cqs, size_t num_cqs) override; - grpc_server* server() override { return server_; }; + grpc_server* server() override { return server_; } private: std::vector>* @@ -223,7 +223,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { int max_receive_message_size() const override { return max_receive_message_size_; - }; + } CompletionQueue* CallbackCQ() override; diff --git a/src/compiler/protobuf_plugin.h b/src/compiler/protobuf_plugin.h index b971af13109..a3e448aa89d 100644 --- a/src/compiler/protobuf_plugin.h +++ b/src/compiler/protobuf_plugin.h @@ -108,11 +108,11 @@ class ProtoBufService : public grpc_generator::Service { grpc::string name() const { return service_->name(); } - int method_count() const { return service_->method_count(); }; + int method_count() const { return service_->method_count(); } std::unique_ptr method(int i) const { return std::unique_ptr( new ProtoBufMethod(service_->method(i))); - }; + } grpc::string GetLeadingComments(const grpc::string prefix) const { return GetCommentsHelper(service_, true, prefix); @@ -166,7 +166,7 @@ class ProtoBufFile : public grpc_generator::File { grpc::string additional_headers() const { return ""; } - int service_count() const { return file_->service_count(); }; + int service_count() const { return file_->service_count(); } std::unique_ptr service(int i) const { return std::unique_ptr( new ProtoBufService(file_->service(i))); diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 63e381d64c7..fb7b530d044 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -596,7 +596,7 @@ void GrpcLb::BalancerCallState::StartQuery() { call_error = grpc_call_start_batch_and_execute( lb_call_, ops, (size_t)(op - ops), &lb_on_balancer_status_received_); GPR_ASSERT(GRPC_CALL_OK == call_error); -}; +} void GrpcLb::BalancerCallState::ScheduleNextClientLoadReportLocked() { const grpc_millis next_client_load_report_time = diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index fca9afed1d7..0d94f2ec0c5 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -140,7 +140,7 @@ class Thread { } else { GPR_ASSERT(state_ == FAILED); } - }; + } private: Thread(const Thread&) = delete; diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 3dba15312d6..8bb271867c2 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -160,6 +160,6 @@ void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, grpc_core::Timestamps*, grpc_error* error)); -}; /* namespace grpc_core */ +} /* namespace grpc_core */ #endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */ diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc index 9430dcc9881..ab5f601fdd4 100644 --- a/src/cpp/common/core_codegen.cc +++ b/src/cpp/common/core_codegen.cc @@ -81,7 +81,7 @@ void CoreCodegen::gpr_free(void* p) { return ::gpr_free(p); } void CoreCodegen::grpc_init() { ::grpc_init(); } void CoreCodegen::grpc_shutdown() { ::grpc_shutdown(); } -void CoreCodegen::gpr_mu_init(gpr_mu* mu) { ::gpr_mu_init(mu); }; +void CoreCodegen::gpr_mu_init(gpr_mu* mu) { ::gpr_mu_init(mu); } void CoreCodegen::gpr_mu_destroy(gpr_mu* mu) { ::gpr_mu_destroy(mu); } void CoreCodegen::gpr_mu_lock(gpr_mu* mu) { ::gpr_mu_lock(mu); } void CoreCodegen::gpr_mu_unlock(gpr_mu* mu) { ::gpr_mu_unlock(mu); } diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 05f78dbe6fe..7eb0f2372b6 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -1251,6 +1251,6 @@ CompletionQueue* Server::CallbackCQ() { shutdown_callback->TakeCQ(callback_cq_); } return callback_cq_; -}; +} } // namespace grpc From af3d32214c06a77f64db1661ed56fa8c9f86340d Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 20 Feb 2019 19:44:13 -0800 Subject: [PATCH 461/814] increase timeout --- .../grpcio_tests/tests/health_check/_health_servicer_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index 62eef8e2291..b8da700fada 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -194,7 +194,7 @@ class BaseWatchTests(object): thread.join() # Wait, if necessary, for serving thread to process client cancellation - timeout = time.time() + test_constants.SHORT_TIMEOUT + timeout = time.time() + test_constants.TIME_ALLOWANCE while time.time( ) < timeout and self._servicer._send_response_callbacks[_WATCH_SERVICE]: time.sleep(1) From 147c61b2a4e35ec53a9df5c66d0711835eaa4e51 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 19 Feb 2019 16:54:57 -0800 Subject: [PATCH 462/814] Exclude StartCall from starting callback counter value --- include/grpcpp/impl/codegen/client_callback.h | 50 ++++++++----------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 52bcea99706..0b2631014a2 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -268,9 +268,8 @@ class ClientCallbackReaderWriterImpl // This call initiates two batches, plus any backlog, each with a callback // 1. Send initial metadata (unless corked) + recv initial metadata // 2. Any read backlog - // 3. Recv trailing metadata, on_completion callback - // 4. Any write backlog - // 5. See if the call can finish (if other callbacks were triggered already) + // 3. Any write backlog + // 4. Recv trailing metadata, on_completion callback started_ = true; start_tag_.Set(call_.call(), @@ -308,12 +307,6 @@ class ClientCallbackReaderWriterImpl call_.PerformOps(&read_ops_); } - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_ops_); - finish_ops_.ClientRecvStatus(context_, &finish_status_); - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - if (write_ops_at_start_) { call_.PerformOps(&write_ops_); } @@ -321,7 +314,12 @@ class ClientCallbackReaderWriterImpl if (writes_done_ops_at_start_) { call_.PerformOps(&writes_done_ops_); } - MaybeFinish(); + + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); } void Read(Response* msg) override { @@ -414,8 +412,8 @@ class ClientCallbackReaderWriterImpl CallbackWithSuccessTag read_tag_; bool read_ops_at_start_{false}; - // Minimum of 3 callbacks to pre-register for StartCall, start, and finish - std::atomic_int callbacks_outstanding_{3}; + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic_int callbacks_outstanding_{2}; bool started_{false}; }; @@ -468,7 +466,6 @@ class ClientCallbackReaderImpl // 1. Send initial metadata (unless corked) + recv initial metadata // 2. Any backlog // 3. Recv trailing metadata, on_completion callback - // 4. See if the call can finish (if other callbacks were triggered already) started_ = true; start_tag_.Set(call_.call(), @@ -500,8 +497,6 @@ class ClientCallbackReaderImpl finish_ops_.ClientRecvStatus(context_, &finish_status_); finish_ops_.set_core_cq_tag(&finish_tag_); call_.PerformOps(&finish_ops_); - - MaybeFinish(); } void Read(Response* msg) override { @@ -545,8 +540,8 @@ class ClientCallbackReaderImpl CallbackWithSuccessTag read_tag_; bool read_ops_at_start_{false}; - // Minimum of 3 callbacks to pre-register for StartCall, start, and finish - std::atomic_int callbacks_outstanding_{3}; + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic_int callbacks_outstanding_{2}; bool started_{false}; }; @@ -597,9 +592,8 @@ class ClientCallbackWriterImpl void StartCall() override { // This call initiates two batches, plus any backlog, each with a callback // 1. Send initial metadata (unless corked) + recv initial metadata - // 2. Recv trailing metadata, on_completion callback - // 3. Any backlog - // 4. See if the call can finish (if other callbacks were triggered already) + // 2. Any backlog + // 3. Recv trailing metadata, on_completion callback started_ = true; start_tag_.Set(call_.call(), @@ -626,12 +620,6 @@ class ClientCallbackWriterImpl &write_ops_); write_ops_.set_core_cq_tag(&write_tag_); - finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, - &finish_ops_); - finish_ops_.ClientRecvStatus(context_, &finish_status_); - finish_ops_.set_core_cq_tag(&finish_tag_); - call_.PerformOps(&finish_ops_); - if (write_ops_at_start_) { call_.PerformOps(&write_ops_); } @@ -640,7 +628,11 @@ class ClientCallbackWriterImpl call_.PerformOps(&writes_done_ops_); } - MaybeFinish(); + finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); }, + &finish_ops_); + finish_ops_.ClientRecvStatus(context_, &finish_status_); + finish_ops_.set_core_cq_tag(&finish_tag_); + call_.PerformOps(&finish_ops_); } void Write(const Request* msg, WriteOptions options) override { @@ -722,8 +714,8 @@ class ClientCallbackWriterImpl CallbackWithSuccessTag writes_done_tag_; bool writes_done_ops_at_start_{false}; - // Minimum of 3 callbacks to pre-register for StartCall, start, and finish - std::atomic_int callbacks_outstanding_{3}; + // Minimum of 2 callbacks to pre-register for start and finish + std::atomic_int callbacks_outstanding_{2}; bool started_{false}; }; From 301ed88a43726ca3df8cbd05ac44558dc4b9c353 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 20 Feb 2019 21:39:02 -0800 Subject: [PATCH 463/814] Avoid unused result warning --- src/cpp/server/load_reporter/get_cpu_stats_linux.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cpp/server/load_reporter/get_cpu_stats_linux.cc b/src/cpp/server/load_reporter/get_cpu_stats_linux.cc index 9c1fd0cd0b8..561d4f50482 100644 --- a/src/cpp/server/load_reporter/get_cpu_stats_linux.cc +++ b/src/cpp/server/load_reporter/get_cpu_stats_linux.cc @@ -32,7 +32,10 @@ std::pair GetCpuStatsImpl() { FILE* fp; fp = fopen("/proc/stat", "r"); uint64_t user, nice, system, idle; - fscanf(fp, "cpu %lu %lu %lu %lu", &user, &nice, &system, &idle); + if (fscanf(fp, "cpu %lu %lu %lu %lu", &user, &nice, &system, &idle) != 4) { + // Something bad happened with the information, so assume it's all invalid + user = nice = system = idle = 0; + } fclose(fp); busy = user + nice + system; total = busy + idle; From 98e0ff582ab6b4e00dcf575c0c8d5c2da1058d59 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Wed, 20 Feb 2019 22:06:51 -0800 Subject: [PATCH 464/814] Fix C++ bulid on Mac OS --- BUILD | 1 + test/cpp/end2end/BUILD | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD b/BUILD index 13f507aa374..de3b85375cb 100644 --- a/BUILD +++ b/BUILD @@ -355,6 +355,7 @@ grpc_cc_library( "gpr", "grpc", "grpc++_base", + "grpc_cfstream", "grpc++_codegen_base", "grpc++_codegen_base_src", "grpc++_codegen_proto", diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 1970f3693cb..a9db19dfe8e 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -638,7 +638,6 @@ grpc_cc_test( "//:gpr", "//:grpc", "//:grpc++", - "//:grpc_cfstream", "//src/proto/grpc/testing:echo_messages_proto", "//src/proto/grpc/testing:echo_proto", "//src/proto/grpc/testing:simple_messages_proto", From d770e265ee932bbf9f4c387af2c4e0fc1163140f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 20 Feb 2019 22:57:16 -0800 Subject: [PATCH 465/814] Fix-forward to avoid TSAN race on detached thread deletion --- src/core/lib/gprpp/thd.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index 0d94f2ec0c5..5631c5f1f0e 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -112,19 +112,22 @@ class Thread { } /// The destructor is strictly optional; either the thread never came to life - /// and the constructor itself killed it or it has already been joined and - /// the Join function kills it. The destructor shouldn't have to do anything. - ~Thread() { GPR_ASSERT(impl_ == nullptr); } + /// and the constructor itself killed it, or it has already been joined and + /// the Join function kills it, or it was detached (non-joinable) and it has + /// run to completion and is now killing itself. The destructor shouldn't have + /// to do anything. + ~Thread() { GPR_ASSERT(!options_.joinable() || impl_ == nullptr); } void Start() { if (impl_ != nullptr) { GPR_ASSERT(state_ == ALIVE); state_ = STARTED; impl_->Start(); - if (!options_.joinable()) { - state_ = DONE; - impl_ = nullptr; - } + // If the Thread is not joinable, then the impl_ will cause the deletion + // of this Thread object when the thread function completes. Since no + // other operation is allowed to a detached thread after Start, there is + // no need to change the value of the impl_ or state_ . The next operation + // on this object will be the deletion, which will trigger the destructor. } else { GPR_ASSERT(state_ == FAILED); } From 0f7450b728980dae8e3ddb6c0a51be993d70859d Mon Sep 17 00:00:00 2001 From: Nguyen Phuong An Date: Wed, 13 Feb 2019 12:09:19 +0700 Subject: [PATCH 466/814] Add copyright headers --- tools/http2_interop/doc.go | 14 ++++++++++++++ tools/http2_interop/frame.go | 14 ++++++++++++++ tools/http2_interop/frameheader.go | 14 ++++++++++++++ tools/http2_interop/goaway.go | 14 ++++++++++++++ tools/http2_interop/http1frame.go | 14 ++++++++++++++ tools/http2_interop/http2interop.go | 14 ++++++++++++++ tools/http2_interop/http2interop_test.go | 14 ++++++++++++++ tools/http2_interop/ping.go | 14 ++++++++++++++ tools/http2_interop/s6.5.go | 14 ++++++++++++++ tools/http2_interop/s6.5_test.go | 14 ++++++++++++++ tools/http2_interop/settings.go | 14 ++++++++++++++ tools/http2_interop/testsuite.go | 14 ++++++++++++++ tools/http2_interop/unknownframe.go | 14 ++++++++++++++ 13 files changed, 182 insertions(+) diff --git a/tools/http2_interop/doc.go b/tools/http2_interop/doc.go index 6c6b5cb1938..9ae736a7566 100644 --- a/tools/http2_interop/doc.go +++ b/tools/http2_interop/doc.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + // http2interop project doc.go /* diff --git a/tools/http2_interop/frame.go b/tools/http2_interop/frame.go index 12689e9b33d..a2df52ff4ae 100644 --- a/tools/http2_interop/frame.go +++ b/tools/http2_interop/frame.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( diff --git a/tools/http2_interop/frameheader.go b/tools/http2_interop/frameheader.go index 84f6fa5c558..148268b2371 100644 --- a/tools/http2_interop/frameheader.go +++ b/tools/http2_interop/frameheader.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( diff --git a/tools/http2_interop/goaway.go b/tools/http2_interop/goaway.go index 289442d615b..2321709fdc4 100644 --- a/tools/http2_interop/goaway.go +++ b/tools/http2_interop/goaway.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( diff --git a/tools/http2_interop/http1frame.go b/tools/http2_interop/http1frame.go index 68ab197b652..e79d2fde5a8 100644 --- a/tools/http2_interop/http1frame.go +++ b/tools/http2_interop/http1frame.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( diff --git a/tools/http2_interop/http2interop.go b/tools/http2_interop/http2interop.go index fa113961f2a..3af5134f9d8 100644 --- a/tools/http2_interop/http2interop.go +++ b/tools/http2_interop/http2interop.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( diff --git a/tools/http2_interop/http2interop_test.go b/tools/http2_interop/http2interop_test.go index fb314da1964..989b60590c3 100644 --- a/tools/http2_interop/http2interop_test.go +++ b/tools/http2_interop/http2interop_test.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( diff --git a/tools/http2_interop/ping.go b/tools/http2_interop/ping.go index 6011eed4511..4c6868bb414 100644 --- a/tools/http2_interop/ping.go +++ b/tools/http2_interop/ping.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( diff --git a/tools/http2_interop/s6.5.go b/tools/http2_interop/s6.5.go index 4295c46f73a..89ca57f221a 100644 --- a/tools/http2_interop/s6.5.go +++ b/tools/http2_interop/s6.5.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( diff --git a/tools/http2_interop/s6.5_test.go b/tools/http2_interop/s6.5_test.go index 063fd5664c8..61e8a4080e1 100644 --- a/tools/http2_interop/s6.5_test.go +++ b/tools/http2_interop/s6.5_test.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( diff --git a/tools/http2_interop/settings.go b/tools/http2_interop/settings.go index 544cec01ee7..6db7c273daf 100644 --- a/tools/http2_interop/settings.go +++ b/tools/http2_interop/settings.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( diff --git a/tools/http2_interop/testsuite.go b/tools/http2_interop/testsuite.go index 51d36e217ed..c361eec9cb0 100644 --- a/tools/http2_interop/testsuite.go +++ b/tools/http2_interop/testsuite.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( diff --git a/tools/http2_interop/unknownframe.go b/tools/http2_interop/unknownframe.go index 0450e7e976c..dacb249b74f 100644 --- a/tools/http2_interop/unknownframe.go +++ b/tools/http2_interop/unknownframe.go @@ -1,3 +1,17 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package http2interop import ( From d0c42dec85b7255eeb76f94e25c1ad74390fe6f3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 21 Feb 2019 09:15:22 +0100 Subject: [PATCH 467/814] hotfix: download unreleased preview3 --- .../grpc_interop_aspnetcore/Dockerfile.template | 7 +++++++ .../interoptest/grpc_interop_aspnetcore/Dockerfile | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template index e1b6da89a74..a341592a2ab 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template @@ -16,5 +16,12 @@ FROM microsoft/dotnet:3.0.100-preview2-sdk-stretch + RUN rm /usr/bin/dotnet # remove symlink + RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.azureedge.net/dotnet/Sdk/3.0.100-preview3-010313/dotnet-sdk-3.0.100-preview3-010313-linux-x64.tar.gz ${'\\'} + && mkdir -p /usr/share/dotnet ${'\\'} + && tar -zxf dotnet.tar.gz -C /usr/share/dotnet ${'\\'} + && rm dotnet.tar.gz ${'\\'} + && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet + # Define the default command. CMD ["bash"] diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile index 2caa093ccc1..75a8a200ab4 100644 --- a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile @@ -14,5 +14,12 @@ FROM microsoft/dotnet:3.0.100-preview2-sdk-stretch +RUN rm /usr/bin/dotnet # remove symlink +RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.azureedge.net/dotnet/Sdk/3.0.100-preview3-010313/dotnet-sdk-3.0.100-preview3-010313-linux-x64.tar.gz \ + && mkdir -p /usr/share/dotnet \ + && tar -zxf dotnet.tar.gz -C /usr/share/dotnet \ + && rm dotnet.tar.gz \ + && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet + # Define the default command. CMD ["bash"] From 64dbadace89a179850f018b58a52ee130549fde3 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Thu, 21 Feb 2019 00:43:48 -0800 Subject: [PATCH 468/814] Debug flaky_network_test Run the test with some tracing enabled to debug test flakes. --- tools/internal_ci/linux/grpc_flaky_network_in_docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh index 60bb49b639a..eb6216c62c3 100755 --- a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh +++ b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh @@ -28,4 +28,4 @@ cd /var/local/git/grpc/test/cpp/end2end # iptables is used to drop traffic between client and server apt-get install -y iptables -bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all :flaky_network_test +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all :flaky_network_test --test_env=GRPC_VERBOSITY=debug --test_env=GRPC_TRACE=channel,client_channel,call_error,connectivity_state From 330e0f3ba8770ffceb1b7e7d34d7cd7b6896c913 Mon Sep 17 00:00:00 2001 From: Tony Allevato Date: Thu, 21 Feb 2019 09:52:17 -0800 Subject: [PATCH 469/814] Support "darwin_x86_64" CPU in cares.BUILD. Bazel recognizes both "darwin" and "darwin_x86_64" as CPU values, and the Apple Bazel rules currently recommend the latter for building macOS targets. Until this is cleaned up, this change allows grpc to build correctly when that configuration is used. Fixes #17649. --- third_party/cares/cares.BUILD | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/third_party/cares/cares.BUILD b/third_party/cares/cares.BUILD index fd14007e804..54b8c57b1d6 100644 --- a/third_party/cares/cares.BUILD +++ b/third_party/cares/cares.BUILD @@ -3,6 +3,11 @@ config_setting( values = {"cpu": "darwin"}, ) +config_setting( + name = "darwin_x86_64", + values = {"cpu": "darwin_x86_64"}, +) + config_setting( name = "windows", values = {"cpu": "x64_windows"}, @@ -54,6 +59,7 @@ genrule( ":ios_armv7s": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], ":ios_arm64": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], ":darwin": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], + ":darwin_x86_64": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], ":windows": ["@com_github_grpc_grpc//third_party/cares:config_windows/ares_config.h"], ":android": ["@com_github_grpc_grpc//third_party/cares:config_android/ares_config.h"], "//conditions:default": ["@com_github_grpc_grpc//third_party/cares:config_linux/ares_config.h"], From deb1081536e59c22f6ec5cedd5d8ea429ce4f498 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 21 Feb 2019 12:09:36 -0800 Subject: [PATCH 470/814] Disable flaky health service test --- .../grpcio_tests/tests/health_check/_health_servicer_test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index b8da700fada..1098d38c83e 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -176,6 +176,7 @@ class BaseWatchTests(object): self.assertTrue(response_queue1.empty()) self.assertTrue(response_queue2.empty()) + @unittest.skip("https://github.com/grpc/grpc/issues/18127") def test_cancelled_watch_removed_from_watch_list(self): request = health_pb2.HealthCheckRequest(service=_WATCH_SERVICE) response_queue = queue.Queue() From 624fb64f61334d0e0e7e21540142b5197c51e57a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 20 Feb 2019 16:43:18 -0800 Subject: [PATCH 471/814] LB policy ctors no longer perform updates; UpdateLocked() must be called after construction. --- .../ext/filters/client_channel/lb_policy.cc | 22 +-- .../ext/filters/client_channel/lb_policy.h | 20 +-- .../client_channel/lb_policy/grpclb/grpclb.cc | 138 +++++++----------- .../lb_policy/pick_first/pick_first.cc | 48 +++--- .../lb_policy/round_robin/round_robin.cc | 45 ++---- .../client_channel/lb_policy/xds/xds.cc | 102 +++++-------- .../client_channel/resolving_lb_policy.cc | 32 ++-- .../client_channel/resolving_lb_policy.h | 8 +- test/core/util/test_lb_policies.cc | 1 - 9 files changed, 166 insertions(+), 250 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 9e3477b9ed5..527b241eb6b 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -28,6 +28,17 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount( namespace grpc_core { +LoadBalancingPolicy::LoadBalancingPolicy(Args args, intptr_t initial_refcount) + : InternallyRefCounted(&grpc_trace_lb_policy_refcount, initial_refcount), + combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), + interested_parties_(grpc_pollset_set_create()), + channel_control_helper_(std::move(args.channel_control_helper)) {} + +LoadBalancingPolicy::~LoadBalancingPolicy() { + grpc_pollset_set_destroy(interested_parties_); + GRPC_COMBINER_UNREF(combiner_, "lb_policy"); +} + grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( const grpc_json* lb_config_array) { if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { @@ -54,15 +65,4 @@ grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( return nullptr; } -LoadBalancingPolicy::LoadBalancingPolicy(Args args, intptr_t initial_refcount) - : InternallyRefCounted(&grpc_trace_lb_policy_refcount, initial_refcount), - combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), - interested_parties_(grpc_pollset_set_create()), - channel_control_helper_(std::move(args.channel_control_helper)) {} - -LoadBalancingPolicy::~LoadBalancingPolicy() { - grpc_pollset_set_destroy(interested_parties_); - GRPC_COMBINER_UNREF(combiner_, "lb_policy"); -} - } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index aeb8138a12e..20a94ed9ab9 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -223,13 +223,11 @@ class LoadBalancingPolicy : public InternallyRefCounted { // of a reference. grpc_combiner* combiner = nullptr; /// Channel control helper. + /// Note: LB policies MUST NOT call any method on the helper from + /// their constructor. UniquePtr channel_control_helper; - /// Channel args from the resolver. - /// Note that the LB policy gets the set of addresses from the - /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. + /// Channel args. const grpc_channel_args* args = nullptr; - /// Load balancing config from the resolver. - grpc_json* lb_config = nullptr; }; // Not copyable nor movable. @@ -240,15 +238,17 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual const char* name() const GRPC_ABSTRACT; /// Updates the policy with a new set of \a args and a new \a lb_config from - /// the resolver. Note that the LB policy gets the set of addresses from the + /// the resolver. Will be invoked immediately after LB policy is constructed, + /// and then again whenever the resolver returns a new result. + /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. virtual void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) GRPC_ABSTRACT; /// Tries to enter a READY connectivity state. - /// TODO(roth): As part of restructuring how we handle IDLE state, - /// consider whether this method is still needed. - virtual void ExitIdleLocked() GRPC_ABSTRACT; + /// This is a no-op by default, since most LB policies never go into + /// IDLE state. + virtual void ExitIdleLocked() {} /// Resets connection backoff. virtual void ResetBackoffLocked() GRPC_ABSTRACT; @@ -290,6 +290,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_combiner* combiner() const { return combiner_; } + // Note: LB policies MUST NOT call any method on the helper from + // their constructor. // Note: This will return null after ShutdownLocked() has been called. ChannelControlHelper* channel_control_helper() const { return channel_control_helper_.get(); diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index fa1ca6d127a..12daea46dd1 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -26,15 +26,13 @@ /// channel that uses pick_first to select from the list of balancer /// addresses. /// -/// The first time the policy gets a request for a pick, a ping, or to exit -/// the idle state, \a StartPickingLocked() is called. This method is -/// responsible for instantiating the internal *streaming* call to the LB -/// server (whichever address pick_first chose). The call will be complete -/// when either the balancer sends status or when we cancel the call (e.g., -/// because we are shutting down). In needed, we retry the call. If we -/// received at least one valid message from the server, a new call attempt -/// will be made immediately; otherwise, we apply back-off delays between -/// attempts. +/// When we get our initial update, we instantiate the internal *streaming* +/// call to the LB server (whichever address pick_first chose). The call +/// will be complete when either the balancer sends status or when we cancel +/// the call (e.g., because we are shutting down). In needed, we retry the +/// call. If we received at least one valid message from the server, a new +/// call attempt will be made immediately; otherwise, we apply back-off +/// delays between attempts. /// /// We maintain an internal round_robin policy instance for distributing /// requests across backends. Whenever we receive a new serverlist from @@ -130,7 +128,6 @@ class GrpcLb : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; - void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, @@ -290,11 +287,10 @@ class GrpcLb : public LoadBalancingPolicy { void ShutdownLocked() override; - // Helper function used in ctor and UpdateLocked(). + // Helper function used in UpdateLocked(). void ProcessChannelArgsLocked(const grpc_channel_args& args); // Methods for dealing with the balancer channel and call. - void StartPickingLocked(); void StartBalancerCallLocked(); static void OnFallbackTimerLocked(void* arg, grpc_error* error); void StartBalancerCallRetryTimerLocked(); @@ -303,9 +299,9 @@ class GrpcLb : public LoadBalancingPolicy { grpc_error* error); // Methods for dealing with the RR policy. - void CreateOrUpdateRoundRobinPolicyLocked(); grpc_channel_args* CreateRoundRobinPolicyArgsLocked(); void CreateRoundRobinPolicyLocked(Args args); + void CreateOrUpdateRoundRobinPolicyLocked(); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -314,7 +310,6 @@ class GrpcLb : public LoadBalancingPolicy { grpc_channel_args* args_ = nullptr; // Internal state. - bool started_picking_ = false; bool shutting_down_ = false; // The channel for communicating with the LB server. @@ -1211,12 +1206,6 @@ GrpcLb::GrpcLb(LoadBalancingPolicy::Args args) arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS); lb_fallback_timeout_ms_ = grpc_channel_arg_get_integer( arg, {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX}); - // Process channel args. - ProcessChannelArgsLocked(*args.args); - // Initialize channel with a picker that will start us connecting. - channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, - UniquePtr(New(Ref()))); } GrpcLb::~GrpcLb() { @@ -1249,12 +1238,6 @@ void GrpcLb::ShutdownLocked() { // public methods // -void GrpcLb::ExitIdleLocked() { - if (!started_picking_) { - StartPickingLocked(); - } -} - void GrpcLb::ResetBackoffLocked() { if (lb_channel_ != nullptr) { grpc_channel_reset_connect_backoff(lb_channel_); @@ -1339,12 +1322,26 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { } void GrpcLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { + const bool is_initial_update = lb_channel_ == nullptr; ProcessChannelArgsLocked(args); // Update the existing RR policy. if (rr_policy_ != nullptr) CreateOrUpdateRoundRobinPolicyLocked(); - // Start watching the LB channel connectivity for connection, if not - // already doing so. - if (!watching_lb_channel_) { + // If this is the initial update, start the fallback timer. + if (is_initial_update) { + if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && + !fallback_timer_callback_pending_) { + grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; + Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Ref for callback + GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, + grpc_combiner_scheduler(combiner())); + fallback_timer_callback_pending_ = true; + grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); + } + StartBalancerCallLocked(); + } else if (!watching_lb_channel_) { + // If this is not the initial update and we're not already watching + // the LB channel's connectivity state, start a watch now. This + // ensures that we'll know when to switch to a new balancer call. lb_channel_connectivity_ = grpc_channel_check_connectivity_state( lb_channel_, true /* try to connect */); grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( @@ -1368,25 +1365,6 @@ void GrpcLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { // code for balancer channel and call // -void GrpcLb::StartPickingLocked() { - // Start a timer to fall back. - if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && - !fallback_timer_callback_pending_) { - grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = Ref(DEBUG_LOCATION, "on_fallback_timer"); - self.release(); - GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, - grpc_combiner_scheduler(combiner())); - fallback_timer_callback_pending_ = true; - grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); - } - started_picking_ = true; - StartBalancerCallLocked(); -} - void GrpcLb::StartBalancerCallLocked() { GPR_ASSERT(lb_channel_ != nullptr); if (shutting_down_) return; @@ -1488,13 +1466,11 @@ void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, case GRPC_CHANNEL_IDLE: case GRPC_CHANNEL_READY: grpclb_policy->lb_calld_.reset(); - if (grpclb_policy->started_picking_) { - if (grpclb_policy->retry_timer_callback_pending_) { - grpc_timer_cancel(&grpclb_policy->lb_call_retry_timer_); - } - grpclb_policy->lb_call_backoff_.Reset(); - grpclb_policy->StartBalancerCallLocked(); + if (grpclb_policy->retry_timer_callback_pending_) { + grpc_timer_cancel(&grpclb_policy->lb_call_retry_timer_); } + grpclb_policy->lb_call_backoff_.Reset(); + grpclb_policy->StartBalancerCallLocked(); // fallthrough case GRPC_CHANNEL_SHUTDOWN: done: @@ -1508,27 +1484,6 @@ void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, // code for interacting with the RR policy // -void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { - GPR_ASSERT(rr_policy_ == nullptr); - rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - "round_robin", std::move(args)); - if (GPR_UNLIKELY(rr_policy_ == nullptr)) { - gpr_log(GPR_ERROR, "[grpclb %p] Failure creating a RoundRobin policy", - this); - return; - } - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, - rr_policy_.get()); - } - // Add the gRPC LB's interested_parties pollset_set to that of the newly - // created RR policy. This will make the RR policy progress upon activity on - // gRPC LB, which in turn is tied to the application's call. - grpc_pollset_set_add_pollset_set(rr_policy_->interested_parties(), - interested_parties()); - rr_policy_->ExitIdleLocked(); -} - grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { ServerAddressList tmp_addresses; ServerAddressList* addresses = &tmp_addresses; @@ -1570,17 +1525,31 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { return args; } +void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { + GPR_ASSERT(rr_policy_ == nullptr); + rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + "round_robin", std::move(args)); + if (GPR_UNLIKELY(rr_policy_ == nullptr)) { + gpr_log(GPR_ERROR, "[grpclb %p] Failure creating a RoundRobin policy", + this); + return; + } + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, + rr_policy_.get()); + } + // Add the gRPC LB's interested_parties pollset_set to that of the newly + // created RR policy. This will make the RR policy progress upon activity on + // gRPC LB, which in turn is tied to the application's call. + grpc_pollset_set_add_pollset_set(rr_policy_->interested_parties(), + interested_parties()); +} + void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { if (shutting_down_) return; grpc_channel_args* args = CreateRoundRobinPolicyArgsLocked(); GPR_ASSERT(args != nullptr); - if (rr_policy_ != nullptr) { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Updating RR policy %p", this, - rr_policy_.get()); - } - rr_policy_->UpdateLocked(*args, nullptr); - } else { + if (rr_policy_ == nullptr) { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); lb_policy_args.args = args; @@ -1588,6 +1557,11 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { UniquePtr(New(Ref())); CreateRoundRobinPolicyLocked(std::move(lb_policy_args)); } + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, "[grpclb %p] Updating RR policy %p", this, + rr_policy_.get()); + } + rr_policy_->UpdateLocked(*args, nullptr); grpc_channel_args_destroy(args); } diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index bf1c5bd7914..58bf3d89f21 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -132,7 +132,6 @@ class PickFirst : public LoadBalancingPolicy { void ShutdownLocked() override; - void StartPickingLocked(); void UpdateChildRefsLocked(); // All our subchannels. @@ -141,8 +140,8 @@ class PickFirst : public LoadBalancingPolicy { OrphanablePtr latest_pending_subchannel_list_; // Selected subchannel in \a subchannel_list_. PickFirstSubchannelData* selected_ = nullptr; - // Have we started picking? - bool started_picking_ = false; + // Are we in IDLE state? + bool idle_ = false; // Are we shut down? bool shutdown_ = false; @@ -158,12 +157,6 @@ PickFirst::PickFirst(Args args) : LoadBalancingPolicy(std::move(args)) { if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p created.", this); } - // Initialize channel with a picker that will start us connecting upon - // the first pick. - channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, - UniquePtr(New(Ref()))); - UpdateLocked(*args.args, args.lb_config); } PickFirst::~PickFirst() { @@ -185,17 +178,14 @@ void PickFirst::ShutdownLocked() { latest_pending_subchannel_list_.reset(); } -void PickFirst::StartPickingLocked() { - started_picking_ = true; - if (subchannel_list_ != nullptr && subchannel_list_->num_subchannels() > 0) { - subchannel_list_->subchannel(0) - ->CheckConnectivityStateAndStartWatchingLocked(); - } -} - void PickFirst::ExitIdleLocked() { - if (!started_picking_) { - StartPickingLocked(); + if (idle_) { + idle_ = false; + if (subchannel_list_ != nullptr && + subchannel_list_->num_subchannels() > 0) { + subchannel_list_->subchannel(0) + ->CheckConnectivityStateAndStartWatchingLocked(); + } } } @@ -289,6 +279,8 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, // currently selected subchannel is also present in the update. It // can also happen if one of the subchannels in the update is already // in the subchannel index because it's in use by another channel. + // TODO(roth): If we're in IDLE state, we should probably defer this + // check and instead do it in ExitIdleLocked(). for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { PickFirstSubchannelData* sd = subchannel_list->subchannel(i); grpc_error* error = GRPC_ERROR_NONE; @@ -305,7 +297,7 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, // Make sure that subsequent calls to ExitIdleLocked() don't cause // us to start watching a subchannel other than the one we've // selected. - started_picking_ = true; + idle_ = false; return; } } @@ -313,17 +305,17 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, // We don't yet have a selected subchannel, so replace the current // subchannel list immediately. subchannel_list_ = std::move(subchannel_list); - // If we've started picking, start trying to connect to the first + // If we're not in IDLE state, start trying to connect to the first // subchannel in the new list. - if (started_picking_) { + if (!idle_) { // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() // here, since we've already checked the initial connectivity // state of all subchannels above. subchannel_list_->subchannel(0)->StartConnectivityWatchLocked(); } } else { - // We do have a selected subchannel, so keep using it until one of - // the subchannels in the new list reports READY. + // We do have a selected subchannel (which means it's READY), so keep + // using it until one of the subchannels in the new list reports READY. if (latest_pending_subchannel_list_ != nullptr) { if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, @@ -334,9 +326,9 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, } } latest_pending_subchannel_list_ = std::move(subchannel_list); - // If we've started picking, start trying to connect to the first + // If we're not in IDLE state, start trying to connect to the first // subchannel in the new list. - if (started_picking_) { + if (!idle_) { // Note: No need to use CheckConnectivityStateAndStartWatchingLocked() // here, since we've already checked the initial connectivity // state of all subchannels above. @@ -385,11 +377,11 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( } else { if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { // If the selected subchannel goes bad, request a re-resolution. We also - // set the channel state to IDLE and reset started_picking_. The reason + // set the channel state to IDLE and reset idle_. The reason // is that if the new state is TRANSIENT_FAILURE due to a GOAWAY // reception we don't want to connect to the re-resolved backends until // we leave the IDLE state. - p->started_picking_ = false; + p->idle_ = true; p->channel_control_helper()->RequestReresolution(); // In transient failure. Rely on re-resolution to recover. p->selected_ = nullptr; diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 0406efb71d3..f92c2d4ba59 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -63,7 +63,6 @@ class RoundRobin : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; - void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* ignored) override; @@ -181,7 +180,6 @@ class RoundRobin : public LoadBalancingPolicy { void ShutdownLocked() override; - void StartPickingLocked(); void UpdateChildRefsLocked(); /** list of subchannels */ @@ -192,8 +190,6 @@ class RoundRobin : public LoadBalancingPolicy { * racing callbacks that reference outdated subchannel lists won't perform any * update. */ OrphanablePtr latest_pending_subchannel_list_; - /** have we started picking? */ - bool started_picking_ = false; /** are we shutting down? */ bool shutdown_ = false; /// Lock and data used to capture snapshots of this channel's child @@ -254,11 +250,6 @@ RoundRobin::RoundRobin(Args args) : LoadBalancingPolicy(std::move(args)) { if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] Created", this); } - // Initialize channel with a picker that will start us connecting. - channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, - UniquePtr(New(Ref()))); - UpdateLocked(*args.args, args.lb_config); } RoundRobin::~RoundRobin() { @@ -280,17 +271,6 @@ void RoundRobin::ShutdownLocked() { latest_pending_subchannel_list_.reset(); } -void RoundRobin::StartPickingLocked() { - started_picking_ = true; - subchannel_list_->StartWatchingLocked(); -} - -void RoundRobin::ExitIdleLocked() { - if (!started_picking_) { - StartPickingLocked(); - } -} - void RoundRobin::ResetBackoffLocked() { subchannel_list_->ResetBackoffLocked(); if (latest_pending_subchannel_list_ != nullptr) { @@ -526,19 +506,22 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } latest_pending_subchannel_list_ = MakeOrphanable( this, &grpc_lb_round_robin_trace, *addresses, combiner(), args); - // If we haven't started picking yet or the new list is empty, - // immediately promote the new list to the current list. - if (!started_picking_ || - latest_pending_subchannel_list_->num_subchannels() == 0) { - if (latest_pending_subchannel_list_->num_subchannels() == 0) { - grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - UniquePtr(New(error))); - } + if (latest_pending_subchannel_list_->num_subchannels() == 0) { + // If the new list is empty, immediately promote the new list to the + // current list and transition to TRANSIENT_FAILURE. + grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + UniquePtr(New(error))); subchannel_list_ = std::move(latest_pending_subchannel_list_); + } else if (subchannel_list_ == nullptr) { + // If there is no current list, immediately promote the new list to + // the current list and start watching it. + subchannel_list_ = std::move(latest_pending_subchannel_list_); + subchannel_list_->StartWatchingLocked(); } else { - // If we've started picking, start watching the new list. + // Start watching the pending list. It will get swapped into the + // current list when it reports READY. latest_pending_subchannel_list_->StartWatchingLocked(); } } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 4b3f2882424..a1d2002079d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -26,14 +26,13 @@ /// channel that uses pick_first to select from the list of balancer /// addresses. /// -/// The first time the xDS policy gets a request for a pick or to exit the idle -/// state, \a StartPickingLocked() is called. This method is responsible for -/// instantiating the internal *streaming* call to the LB server (whichever -/// address pick_first chose). The call will be complete when either the -/// balancer sends status or when we cancel the call (e.g., because we are -/// shutting down). In needed, we retry the call. If we received at least one -/// valid message from the server, a new call attempt will be made immediately; -/// otherwise, we apply back-off delays between attempts. +/// When we get our initial update, we instantiate the internal *streaming* +/// call to the LB server (whichever address pick_first chose). The call +/// will be complete when either the balancer sends status or when we cancel +/// the call (e.g., because we are shutting down). In needed, we retry the +/// call. If we received at least one valid message from the server, a new +/// call attempt will be made immediately; otherwise, we apply back-off +/// delays between attempts. /// /// We maintain an internal child policy (round_robin) instance for distributing /// requests across backends. Whenever we receive a new serverlist from @@ -124,7 +123,6 @@ class XdsLb : public LoadBalancingPolicy { void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override; - void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, @@ -239,7 +237,7 @@ class XdsLb : public LoadBalancingPolicy { void ShutdownLocked() override; - // Helper function used in ctor and UpdateLocked(). + // Helper function used in UpdateLocked(). void ProcessChannelArgsLocked(const grpc_channel_args& args); // Parses the xds config given the JSON node of the first child of XdsConfig. @@ -249,7 +247,6 @@ class XdsLb : public LoadBalancingPolicy { void ParseLbConfig(grpc_json* xds_config_json); // Methods for dealing with the balancer channel and call. - void StartPickingLocked(); void StartBalancerCallLocked(); static void OnFallbackTimerLocked(void* arg, grpc_error* error); void StartBalancerCallRetryTimerLocked(); @@ -272,7 +269,6 @@ class XdsLb : public LoadBalancingPolicy { grpc_channel_args* args_ = nullptr; // Internal state. - bool started_picking_ = false; bool shutting_down_ = false; // The channel for communicating with the LB server. @@ -992,14 +988,6 @@ XdsLb::XdsLb(LoadBalancingPolicy::Args args) arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS); lb_fallback_timeout_ms_ = grpc_channel_arg_get_integer( arg, {GRPC_XDS_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX}); - // Parse the LB config. - ParseLbConfig(args.lb_config); - // Process channel args. - ProcessChannelArgsLocked(*args.args); - // Initialize channel with a picker that will start us connecting. - channel_control_helper()->UpdateState( - GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, - UniquePtr(New(Ref()))); } XdsLb::~XdsLb() { @@ -1037,12 +1025,6 @@ void XdsLb::ShutdownLocked() { // public methods // -void XdsLb::ExitIdleLocked() { - if (!started_picking_) { - StartPickingLocked(); - } -} - void XdsLb::ResetBackoffLocked() { if (lb_channel_ != nullptr) { grpc_channel_reset_connect_backoff(lb_channel_); @@ -1137,6 +1119,7 @@ void XdsLb::ParseLbConfig(grpc_json* xds_config_json) { } void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { + const bool is_initial_update = lb_channel_ == nullptr; ParseLbConfig(lb_config); // TODO(juanlishen): Pass fallback policy config update after fallback policy // is added. @@ -1150,9 +1133,26 @@ void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { // TODO(vpowar): Handle the fallback_address changes when we add support for // fallback in xDS. if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); - // Start watching the LB channel connectivity for connection, if not - // already doing so. - if (!watching_lb_channel_) { + // If this is the initial update, start the fallback timer. + if (is_initial_update) { + if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && + !fallback_timer_callback_pending_) { + grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; + // TODO(roth): We currently track this ref manually. Once the + // ClosureRef API is ready, we should pass the RefCountedPtr<> along + // with the callback. + auto self = Ref(DEBUG_LOCATION, "on_fallback_timer"); + self.release(); + GRPC_CLOSURE_INIT(&lb_on_fallback_, &XdsLb::OnFallbackTimerLocked, this, + grpc_combiner_scheduler(combiner())); + fallback_timer_callback_pending_ = true; + grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); + } + StartBalancerCallLocked(); + } else if (!watching_lb_channel_) { + // If this is not the initial update and we're not already watching + // the LB channel's connectivity state, start a watch now. This + // ensures that we'll know when to switch to a new balancer call. lb_channel_connectivity_ = grpc_channel_check_connectivity_state( lb_channel_, true /* try to connect */); grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( @@ -1176,25 +1176,6 @@ void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { // code for balancer channel and call // -void XdsLb::StartPickingLocked() { - // Start a timer to fall back. - if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && - !fallback_timer_callback_pending_) { - grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = Ref(DEBUG_LOCATION, "on_fallback_timer"); - self.release(); - GRPC_CLOSURE_INIT(&lb_on_fallback_, &XdsLb::OnFallbackTimerLocked, this, - grpc_combiner_scheduler(combiner())); - fallback_timer_callback_pending_ = true; - grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); - } - started_picking_ = true; - StartBalancerCallLocked(); -} - void XdsLb::StartBalancerCallLocked() { GPR_ASSERT(lb_channel_ != nullptr); if (shutting_down_) return; @@ -1293,13 +1274,11 @@ void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg, case GRPC_CHANNEL_IDLE: case GRPC_CHANNEL_READY: xdslb_policy->lb_calld_.reset(); - if (xdslb_policy->started_picking_) { - if (xdslb_policy->retry_timer_callback_pending_) { - grpc_timer_cancel(&xdslb_policy->lb_call_retry_timer_); - } - xdslb_policy->lb_call_backoff_.Reset(); - xdslb_policy->StartBalancerCallLocked(); + if (xdslb_policy->retry_timer_callback_pending_) { + grpc_timer_cancel(&xdslb_policy->lb_call_retry_timer_); } + xdslb_policy->lb_call_backoff_.Reset(); + xdslb_policy->StartBalancerCallLocked(); // Fall through. case GRPC_CHANNEL_SHUTDOWN: done: @@ -1326,7 +1305,6 @@ void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { // xDS LB, which in turn is tied to the application's call. grpc_pollset_set_add_pollset_set(child_policy_->interested_parties(), interested_parties()); - child_policy_->ExitIdleLocked(); } grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { @@ -1375,25 +1353,23 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { child_policy_name = "round_robin"; } // TODO(juanlishen): Switch policy according to child_policy_config->key. - if (child_policy_ != nullptr) { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Updating the child policy %p", this, - child_policy_.get()); - } - child_policy_->UpdateLocked(*args, child_policy_config); - } else { + if (child_policy_ == nullptr) { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); lb_policy_args.args = args; lb_policy_args.channel_control_helper = UniquePtr(New(Ref())); - lb_policy_args.lb_config = child_policy_config; CreateChildPolicyLocked(child_policy_name, std::move(lb_policy_args)); if (grpc_lb_xds_trace.enabled()) { gpr_log(GPR_INFO, "[xdslb %p] Created a new child policy %p", this, child_policy_.get()); } } + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, "[xdslb %p] Updating child policy %p", this, + child_policy_.get()); + } + child_policy_->UpdateLocked(*args, child_policy_config); grpc_channel_args_destroy(args); grpc_json_destroy(child_policy_json); } diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index ad9720fdda9..22050cba59e 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -262,14 +262,12 @@ void ResolvingLoadBalancingPolicy::OnResolverShutdownLocked(grpc_error* error) { // Creates a new LB policy, replacing any previous one. // Updates trace_strings to indicate what was done. void ResolvingLoadBalancingPolicy::CreateNewLbPolicyLocked( - const char* lb_policy_name, grpc_json* lb_config, - TraceStringVector* trace_strings) { + const char* lb_policy_name, TraceStringVector* trace_strings) { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); lb_policy_args.channel_control_helper = UniquePtr(New(Ref())); lb_policy_args.args = resolver_result_; - lb_policy_args.lb_config = lb_config; OrphanablePtr new_lb_policy = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( lb_policy_name, std::move(lb_policy_args)); @@ -307,7 +305,6 @@ void ResolvingLoadBalancingPolicy::CreateNewLbPolicyLocked( lb_policy_ = std::move(new_lb_policy); grpc_pollset_set_add_pollset_set(lb_policy_->interested_parties(), interested_parties()); - lb_policy_->ExitIdleLocked(); } } @@ -417,27 +414,22 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( lb_policy_config = self->child_lb_config_; } GPR_ASSERT(lb_policy_name != nullptr); - // Check to see if we're already using the right LB policy. - const bool lb_policy_name_changed = - self->lb_policy_ == nullptr || - strcmp(self->lb_policy_->name(), lb_policy_name) != 0; - if (self->lb_policy_ != nullptr && !lb_policy_name_changed) { - // Continue using the same LB policy. Update with new addresses. - if (self->tracer_->enabled()) { - gpr_log(GPR_INFO, - "resolving_lb=%p: updating existing LB policy \"%s\" (%p)", - self, lb_policy_name, self->lb_policy_.get()); - } - self->lb_policy_->UpdateLocked(*self->resolver_result_, lb_policy_config); - } else { - // Instantiate new LB policy. + // If we're not already using the right LB policy name, instantiate + // a new one. + if (self->lb_policy_ == nullptr || + strcmp(self->lb_policy_->name(), lb_policy_name) != 0) { if (self->tracer_->enabled()) { gpr_log(GPR_INFO, "resolving_lb=%p: creating new LB policy \"%s\"", self, lb_policy_name); } - self->CreateNewLbPolicyLocked(lb_policy_name, lb_policy_config, - &trace_strings); + self->CreateNewLbPolicyLocked(lb_policy_name, &trace_strings); } + // Update the LB policy with the new addresses and config. + if (self->tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: updating LB policy \"%s\" (%p)", self, + lb_policy_name, self->lb_policy_.get()); + } + self->lb_policy_->UpdateLocked(*self->resolver_result_, lb_policy_config); // Add channel trace event. if (self->channelz_node() != nullptr) { if (service_config_changed) { diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index c302ae5d975..19ca62fc556 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -77,10 +77,8 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { virtual const char* name() const override { return "resolving_lb"; } // No-op -- should never get updates from the channel. - // TODO(roth): Need to support updating child LB policy's config. - // For xds policy, will also need to support updating config - // independently of args from resolver, since they will be coming from - // different places. Maybe change LB policy API to support that? + // TODO(roth): Need to support updating child LB policy's config for xds + // use case. void UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) override {} @@ -104,7 +102,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void StartResolvingLocked(); void OnResolverShutdownLocked(grpc_error* error); - void CreateNewLbPolicyLocked(const char* lb_policy_name, grpc_json* lb_config, + void CreateNewLbPolicyLocked(const char* lb_policy_name, TraceStringVector* trace_strings); void MaybeAddTraceMessagesForAddressChangesLocked( TraceStringVector* trace_strings); diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 77b354740e5..bfdd7441563 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -56,7 +56,6 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { delegate_args.combiner = combiner(); delegate_args.channel_control_helper = std::move(delegating_helper); delegate_args.args = args.args; - delegate_args.lb_config = args.lb_config; delegate_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( delegate_policy_name.c_str(), std::move(delegate_args)); grpc_pollset_set_add_pollset_set(delegate_->interested_parties(), From 523e537368079c3f74bc5776d9fba5c6ec1f7f91 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 21 Feb 2019 12:11:00 -0800 Subject: [PATCH 472/814] Start connectivity watches before updating connectivity state. --- .../lb_policy/pick_first/pick_first.cc | 20 ++++++++++--------- .../lb_policy/round_robin/round_robin.cc | 7 ++++--- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 58bf3d89f21..c222b7ba292 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -288,8 +288,8 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, GRPC_ERROR_UNREF(error); if (state == GRPC_CHANNEL_READY) { subchannel_list_ = std::move(subchannel_list); - sd->ProcessUnselectedReadyLocked(); sd->StartConnectivityWatchLocked(); + sd->ProcessUnselectedReadyLocked(); // If there was a previously pending update (which may or may // not have contained the currently selected subchannel), drop // it, so that it doesn't override what we've done here. @@ -421,9 +421,9 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // select in place of the current one. switch (connectivity_state) { case GRPC_CHANNEL_READY: { - ProcessUnselectedReadyLocked(); // Renew notification. RenewConnectivityWatchLocked(); + ProcessUnselectedReadyLocked(); break; } case GRPC_CHANNEL_TRANSIENT_FAILURE: { @@ -502,16 +502,18 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { void PickFirst::PickFirstSubchannelData:: CheckConnectivityStateAndStartWatchingLocked() { PickFirst* p = static_cast(subchannel_list()->policy()); + // Check current state. grpc_error* error = GRPC_ERROR_NONE; - if (p->selected_ != this && - CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) { - // We must process the READY subchannel before we start watching it. - // Otherwise, we won't know it's READY because we will be waiting for its - // connectivity state to change from READY. + grpc_connectivity_state current_state = CheckConnectivityStateLocked(&error); + GRPC_ERROR_UNREF(error); + // Start watch. + StartConnectivityWatchLocked(); + // If current state is READY, select the subchannel now, since we started + // watching from this state and will not get a notification of it + // transitioning into this state. + if (p->selected_ != this && current_state == GRPC_CHANNEL_READY) { ProcessUnselectedReadyLocked(); } - GRPC_ERROR_UNREF(error); - StartConnectivityWatchLocked(); } // diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index f92c2d4ba59..b9250f92033 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -325,14 +325,14 @@ void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() { subchannel(i)->UpdateConnectivityStateLocked(state, error); } } - // Now set the LB policy's state based on the subchannels' states. - UpdateRoundRobinStateFromSubchannelStateCountsLocked(); // Start connectivity watch for each subchannel. for (size_t i = 0; i < num_subchannels(); i++) { if (subchannel(i)->subchannel() != nullptr) { subchannel(i)->StartConnectivityWatchLocked(); } } + // Now set the LB policy's state based on the subchannels' states. + UpdateRoundRobinStateFromSubchannelStateCountsLocked(); } void RoundRobin::RoundRobinSubchannelList::UpdateStateCountersLocked( @@ -468,11 +468,12 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( } p->channel_control_helper()->RequestReresolution(); } + // Renew connectivity watch. + RenewConnectivityWatchLocked(); // Update state counters. UpdateConnectivityStateLocked(connectivity_state, error); // Update overall state and renew notification. subchannel_list()->UpdateRoundRobinStateFromSubchannelStateCountsLocked(); - RenewConnectivityWatchLocked(); } void RoundRobin::UpdateLocked(const grpc_channel_args& args, From 8ba4d3a801216d9d794877921554601db1862ebf Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 21 Feb 2019 13:48:40 -0800 Subject: [PATCH 473/814] Disable test_abort_does_not_leak_local_vars This test relies on gc timing and has been flaky (https://github.com/grpc/grpc/issues/17927). --- src/python/grpcio_tests/tests/unit/_abort_test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python/grpcio_tests/tests/unit/_abort_test.py b/src/python/grpcio_tests/tests/unit/_abort_test.py index 64952c899e4..2c83e0dab38 100644 --- a/src/python/grpcio_tests/tests/unit/_abort_test.py +++ b/src/python/grpcio_tests/tests/unit/_abort_test.py @@ -115,6 +115,7 @@ class AbortTest(unittest.TestCase): # on Python 3 (via the `__traceback__` attribute) holds a reference to # all local vars. Storing the raised exception can prevent GC and stop the # grpc_call from being unref'ed, even after server shutdown. + @unittest.skip("https://github.com/grpc/grpc/issues/17927") def test_abort_does_not_leak_local_vars(self): global do_not_leak_me # pylint: disable=global-statement weak_ref = weakref.ref(do_not_leak_me) From e8efe06a42bd2804c1ce8b1f296268e1dbaa37c5 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 15 Feb 2019 14:43:15 -0800 Subject: [PATCH 474/814] Re-add cfstream_test 2nd attempt at adding cfstream_test after fixing internal build failures caused by first attempt. --- BUILD | 7 + bazel/grpc_build_system.bzl | 23 +- test/cpp/end2end/BUILD | 21 ++ test/cpp/end2end/cfstream_test.cc | 278 ++++++++++++++++++ tools/internal_ci/macos/grpc_cfstream.cfg | 19 ++ .../internal_ci/macos/grpc_run_bazel_tests.sh | 29 ++ 6 files changed, 371 insertions(+), 6 deletions(-) create mode 100644 test/cpp/end2end/cfstream_test.cc create mode 100644 tools/internal_ci/macos/grpc_cfstream.cfg create mode 100644 tools/internal_ci/macos/grpc_run_bazel_tests.sh diff --git a/BUILD b/BUILD index a566057e926..c8c49ff4a41 100644 --- a/BUILD +++ b/BUILD @@ -63,6 +63,11 @@ config_setting( values = {"cpu": "x64_windows_msvc"}, ) +config_setting( + name = "mac_x86_64", + values = {"cpu": "darwin"}, +) + # This should be updated along with build.yaml g_stands_for = "godric" @@ -981,6 +986,7 @@ grpc_cc_library( ], language = "c++", public_hdrs = GRPC_PUBLIC_HDRS, + use_cfstream = True, deps = [ "gpr_base", "grpc_codegen", @@ -1044,6 +1050,7 @@ grpc_cc_library( "src/core/lib/iomgr/endpoint_cfstream.h", "src/core/lib/iomgr/error_cfstream.h", ], + use_cfstream = True, deps = [ ":gpr_base", ":grpc_base", diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index be85bc87324..3ea8e305ca5 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -35,6 +35,12 @@ def if_not_windows(a): "//conditions:default": a, }) +def if_mac(a): + return select({ + "//:mac_x86_64": a, + "//conditions:default": [], + }) + def _get_external_deps(external_deps): ret = [] for dep in external_deps: @@ -73,10 +79,16 @@ def grpc_cc_library( testonly = False, visibility = None, alwayslink = 0, - data = []): + data = [], + use_cfstream = False): copts = [] + if use_cfstream: + copts = if_mac(["-DGRPC_CFSTREAM"]) if language.upper() == "C": - copts = if_not_windows(["-std=c99"]) + copts = copts + if_not_windows(["-std=c99"]) + linkopts = if_not_windows(["-pthread"]) + if use_cfstream: + linkopts = linkopts + if_mac(["-framework CoreFoundation"]) native.cc_library( name = name, srcs = srcs, @@ -98,7 +110,7 @@ def grpc_cc_library( copts = copts, visibility = visibility, testonly = testonly, - linkopts = if_not_windows(["-pthread"]), + linkopts = linkopts, includes = [ "include", ], @@ -113,7 +125,6 @@ def grpc_proto_plugin(name, srcs = [], deps = []): deps = deps, ) - def grpc_proto_library( name, srcs = [], @@ -133,9 +144,9 @@ def grpc_proto_library( ) def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = None, tags = [], exec_compatible_with = []): - copts = [] + copts = if_mac(["-DGRPC_CFSTREAM"]) if language.upper() == "C": - copts = if_not_windows(["-std=c99"]) + copts = copts + if_not_windows(["-std=c99"]) args = { "name": name, "srcs": srcs, diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 64b3eae60da..1970f3693cb 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -625,3 +625,24 @@ grpc_cc_test( "//test/cpp/util:test_util", ], ) + +grpc_cc_test( + name = "cfstream_test", + srcs = ["cfstream_test.cc"], + external_deps = [ + "gtest", + ], + tags = ["manual"], # test requires root, won't work with bazel RBE + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//:grpc_cfstream", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing:simple_messages_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) diff --git a/test/cpp/end2end/cfstream_test.cc b/test/cpp/end2end/cfstream_test.cc new file mode 100644 index 00000000000..9039329d815 --- /dev/null +++ b/test/cpp/end2end/cfstream_test.cc @@ -0,0 +1,278 @@ +/* + * + * Copyright 2019 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "src/core/lib/iomgr/port.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/gpr/env.h" + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#ifdef GRPC_CFSTREAM +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +class CFStreamTest : public ::testing::Test { + protected: + CFStreamTest() + : server_host_("grpctest"), + interface_("lo0"), + ipv4_address_("10.0.0.1"), + netmask_("/32"), + kRequestMessage_("🖖") {} + + void DNSUp() { + std::ostringstream cmd; + // Add DNS entry for server_host_ in /etc/hosts + cmd << "echo '" << ipv4_address_ << " " << server_host_ + << " ' | sudo tee -a /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DNSDown() { + std::ostringstream cmd; + // Remove DNS entry for server_host_ in /etc/hosts + cmd << "sudo sed -i '.bak' '/" << server_host_ << "/d' /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void InterfaceUp() { + std::ostringstream cmd; + cmd << "sudo /sbin/ifconfig " << interface_ << " alias " << ipv4_address_; + std::system(cmd.str().c_str()); + } + + void InterfaceDown() { + std::ostringstream cmd; + cmd << "sudo /sbin/ifconfig " << interface_ << " -alias " << ipv4_address_; + std::system(cmd.str().c_str()); + } + + void NetworkUp() { + InterfaceUp(); + DNSUp(); + } + + void NetworkDown() { + InterfaceDown(); + DNSDown(); + } + + void SetUp() override { + NetworkUp(); + grpc_init(); + StartServer(); + } + + void TearDown() override { + NetworkDown(); + StopServer(); + grpc_shutdown(); + } + + void StartServer() { + port_ = grpc_pick_unused_port_or_die(); + server_.reset(new ServerData(port_)); + server_->Start(server_host_); + } + void StopServer() { server_->Shutdown(); } + + std::unique_ptr BuildStub( + const std::shared_ptr& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr BuildChannel() { + std::ostringstream server_address; + server_address << server_host_ << ":" << port_; + return CreateCustomChannel( + server_address.str(), InsecureChannelCredentials(), ChannelArguments()); + } + + void SendRpc( + const std::unique_ptr& stub, + bool expect_success = false) { + auto response = std::unique_ptr(new EchoResponse()); + EchoRequest request; + request.set_message(kRequestMessage_); + ClientContext context; + Status status = stub->Echo(&context, request, response.get()); + if (status.ok()) { + gpr_log(GPR_DEBUG, "RPC returned %s\n", response->message().c_str()); + } else { + gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str()); + } + if (expect_success) { + EXPECT_TRUE(status.ok()); + } + } + + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 10) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + private: + struct ServerData { + int port_; + std::unique_ptr server_; + TestServiceImpl service_; + std::unique_ptr thread_; + bool server_ready_ = false; + + explicit ServerData(int port) { port_ = port; } + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting server on port %d", port_); + std::mutex mu; + std::unique_lock lock(mu); + std::condition_variable cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.wait(lock, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + + void Serve(const grpc::string& server_host, std::mutex* mu, + std::condition_variable* cond) { + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + builder.AddListeningPort(server_address.str(), + InsecureServerCredentials()); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + std::lock_guard lock(*mu); + server_ready_ = true; + cond->notify_one(); + } + + void Shutdown(bool join = true) { + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + if (join) thread_->join(); + } + }; + + const grpc::string server_host_; + const grpc::string interface_; + const grpc::string ipv4_address_; + const grpc::string netmask_; + std::unique_ptr stub_; + std::unique_ptr server_; + int port_; + const grpc::string kRequestMessage_; +}; + +// gRPC should automatically detech network flaps (without enabling keepalives) +// when CFStream is enabled +TEST_F(CFStreamTest, NetworkTransition) { + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + SendRpc(stub, /*expect_success=*/true); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // bring down network + NetworkDown(); + + // network going down should be detected by cfstream + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + + // bring network interface back up + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + NetworkUp(); + + // channel should reconnect + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); +} + +} // namespace +} // namespace testing +} // namespace grpc +#endif // GRPC_CFSTREAM + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_test_init(argc, argv); + gpr_setenv("grpc_cfstream", "1"); + // TODO (pjaikumar): remove the line below when + // https://github.com/grpc/grpc/issues/18080 has been fixed. + gpr_setenv("GRPC_DNS_RESOLVER", "native"); + const auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/tools/internal_ci/macos/grpc_cfstream.cfg b/tools/internal_ci/macos/grpc_cfstream.cfg new file mode 100644 index 00000000000..2b1ce0a89c7 --- /dev/null +++ b/tools/internal_ci/macos/grpc_cfstream.cfg @@ -0,0 +1,19 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_bazel_tests.sh" + diff --git a/tools/internal_ci/macos/grpc_run_bazel_tests.sh b/tools/internal_ci/macos/grpc_run_bazel_tests.sh new file mode 100644 index 00000000000..ef02a675d5b --- /dev/null +++ b/tools/internal_ci/macos/grpc_run_bazel_tests.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -ex + +# change to grpc repo root +cd $(dirname $0)/../../.. + + +./tools/run_tests/start_port_server.py + +# run cfstream_test separately because it messes with the network +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all //test/cpp/end2end:cfstream_test + +# kill port_server.py to prevent the build from hanging +ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9 + From b889461b4606b291a337ce3591a660b6f095630b Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 15 Feb 2019 15:05:23 -0800 Subject: [PATCH 475/814] Fixed cast in endpoint_cfstream.cc --- src/core/lib/iomgr/endpoint_cfstream.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index 7c4bc1ace2a..25146e7861c 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -182,7 +182,7 @@ static void ReadAction(void* arg, grpc_error* error) { GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), ep)); EP_UNREF(ep, "read"); } else { - if (read_size < len) { + if (read_size < static_cast(len)) { grpc_slice_buffer_trim_end(ep->read_slices, len - read_size, nullptr); } CallReadCb(ep, GRPC_ERROR_NONE); @@ -217,7 +217,7 @@ static void WriteAction(void* arg, grpc_error* error) { CallWriteCb(ep, error); EP_UNREF(ep, "write"); } else { - if (write_size < GRPC_SLICE_LENGTH(slice)) { + if (write_size < static_cast(GRPC_SLICE_LENGTH(slice))) { grpc_slice_buffer_undo_take_first( ep->write_slices, grpc_slice_sub(slice, write_size, slice_len)); } From c1451e83d569b27ca0ed920ab72ef4c060591fcc Mon Sep 17 00:00:00 2001 From: Nikolai Lifanov Date: Wed, 20 Feb 2019 18:48:56 -0800 Subject: [PATCH 476/814] generalize macOS workaround for -std=c++11 passed in C mode GCC allows this, but notably clang does not. Other systems, like FreeBSD and some Linux distros ship with clang as default compiler. While here, switch the approach to filtering out std flag since the make workaround relies on GNU make syntax and 'make' binary could be bmake and/or gmake could be absent. The idea to filter the flags was taken from an answer to this Stack Overflow question: https://stackoverflow.com/questions/15527611/how-do-i-specify-different-compiler-flags-in-distutils-for-just-one-python-c-ext --- src/python/grpcio/commands.py | 80 +++++++++++++++-------------------- 1 file changed, 33 insertions(+), 47 deletions(-) diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index b805f4277b0..ec03cbf4992 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -149,11 +149,10 @@ def check_and_update_cythonization(extensions): for source in extension.sources: base, file_ext = os.path.splitext(source) if file_ext == '.pyx': - generated_pyx_source = next( - (base + gen_ext for gen_ext in ( - '.c', - '.cpp', - ) if os.path.isfile(base + gen_ext)), None) + generated_pyx_source = next((base + gen_ext for gen_ext in ( + '.c', + '.cpp', + ) if os.path.isfile(base + gen_ext)), None) if generated_pyx_source: generated_pyx_sources.append(generated_pyx_source) else: @@ -195,8 +194,7 @@ def try_cythonize(extensions, linetracing=False, mandatory=True): return Cython.Build.cythonize( extensions, include_path=[ - include_dir - for extension in extensions + include_dir for extension in extensions for include_dir in extension.include_dirs ] + [CYTHON_STEM], compiler_directives=cython_compiler_directives) @@ -212,50 +210,38 @@ class BuildExt(build_ext.build_ext): LINK_OPTIONS = {} def build_extensions(self): + + def compiler_ok_with_extra_std(): + """Test if default compiler is okay with specifying c++ version + when invokec in C mode. GCC is okay with this, while clang is not. + """ + cc_test = subprocess.Popen(['cc', '-x', 'c', '-std=c++11', '-'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + _, cc_err = cc_test.communicate(input='int main(){return 0;}') + return not 'invalid argument' in cc_err + # This special conditioning is here due to difference of compiler # behavior in gcc and clang. The clang doesn't take --stdc++11 # flags but gcc does. Since the setuptools of Python only support # all C or all C++ compilation, the mix of C and C++ will crash. - # *By default*, the macOS use clang and Linux use gcc, that's why - # the special condition here is checking platform. - if "darwin" in sys.platform: - config = os.environ.get('CONFIG', 'opt') - target_path = os.path.abspath( - os.path.join( - os.path.dirname(os.path.realpath(__file__)), '..', '..', - '..', 'libs', config)) - targets = [ - os.path.join(target_path, 'libboringssl.a'), - os.path.join(target_path, 'libares.a'), - os.path.join(target_path, 'libgpr.a'), - os.path.join(target_path, 'libgrpc.a') - ] - # Running make separately for Mac means we lose all - # Extension.define_macros configured in setup.py. Re-add the macro - # for gRPC Core's fork handlers. - # TODO(ericgribkoff) Decide what to do about the other missing core - # macros, including GRPC_ENABLE_FORK_SUPPORT, which defaults to 1 - # on Linux but remains unset on Mac. - extra_defines = [ - 'EXTRA_DEFINES="GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1"' - ] - # Ensure the BoringSSL are built instead of using system provided - # libraries. It prevents dependency issues while distributing to - # Mac users who use MacPorts to manage their libraries. #17002 - mod_env = dict(os.environ) - mod_env['REQUIRE_CUSTOM_LIBRARIES_opt'] = '1' - make_process = subprocess.Popen( - ['make'] + extra_defines + targets, - env=mod_env, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - make_out, make_err = make_process.communicate() - if make_out and make_process.returncode != 0: - sys.stdout.write(str(make_out) + '\n') - if make_err: - sys.stderr.write(str(make_err) + '\n') - if make_process.returncode != 0: - raise Exception("make command failed!") + # *By default*, macOS and FreBSD use clang and Linux use gcc + # + # If we are not using a permissive compiler that's OK with being + # passed wrong std flags, swap out compile function by adding a filter + # for it. + if not compiler_ok_with_extra_std(): + old_compile = self.compiler._compile + + def new_compile(obj, src, ext, cc_args, extra_postargs, pp_opts): + if src[-2:] == '.c': + extra_postargs = [ + arg for arg in extra_postargs if not '-std=c++' in arg + ] + return old_compile(obj, src, ext, cc_args, extra_postargs, + pp_opts) + + self.compiler._compile = new_compile compiler = self.compiler.compiler_type if compiler in BuildExt.C_OPTIONS: From ad093660ffceb27d2bf69c41e06c7a5ea8024e3d Mon Sep 17 00:00:00 2001 From: Nikolai Lifanov Date: Thu, 21 Feb 2019 16:15:33 -0800 Subject: [PATCH 477/814] format with yapf This was already formatted with yapf, but perhaps I didn't do this correctly. I copied the diff directly from kokoro build log this time. --- src/python/grpcio/commands.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index ec03cbf4992..e80b90c6a34 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -149,10 +149,11 @@ def check_and_update_cythonization(extensions): for source in extension.sources: base, file_ext = os.path.splitext(source) if file_ext == '.pyx': - generated_pyx_source = next((base + gen_ext for gen_ext in ( - '.c', - '.cpp', - ) if os.path.isfile(base + gen_ext)), None) + generated_pyx_source = next( + (base + gen_ext for gen_ext in ( + '.c', + '.cpp', + ) if os.path.isfile(base + gen_ext)), None) if generated_pyx_source: generated_pyx_sources.append(generated_pyx_source) else: @@ -194,7 +195,8 @@ def try_cythonize(extensions, linetracing=False, mandatory=True): return Cython.Build.cythonize( extensions, include_path=[ - include_dir for extension in extensions + include_dir + for extension in extensions for include_dir in extension.include_dirs ] + [CYTHON_STEM], compiler_directives=cython_compiler_directives) @@ -215,9 +217,10 @@ class BuildExt(build_ext.build_ext): """Test if default compiler is okay with specifying c++ version when invokec in C mode. GCC is okay with this, while clang is not. """ - cc_test = subprocess.Popen(['cc', '-x', 'c', '-std=c++11', '-'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + cc_test = subprocess.Popen( + ['cc', '-x', 'c', '-std=c++11', '-'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) _, cc_err = cc_test.communicate(input='int main(){return 0;}') return not 'invalid argument' in cc_err From 0ac72037771958bcee8fc0ee5507c7bcb88bef63 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Thu, 21 Feb 2019 17:21:35 -0800 Subject: [PATCH 478/814] Removed unused ChannelCredentials.c_credentials --- src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi index 1cef7269707..af069acc287 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi @@ -53,9 +53,6 @@ cdef class ChannelCredentials: cdef grpc_channel_credentials *c(self) except * - # TODO(https://github.com/grpc/grpc/issues/12531): remove. - cdef grpc_channel_credentials *c_credentials - cdef class SSLSessionCacheLRU: From 1232f60ac2dfc46f314cbe35326d7508cbf5a4e9 Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Thu, 21 Feb 2019 17:26:54 -0800 Subject: [PATCH 479/814] Make UserState non-virtual; add protected impl Makes the public UserState property non-virtual and adds a protected virtual UserStateCore that can be overridden. This follows the pattern of the other members. --- src/csharp/Grpc.Core.Api/ServerCallContext.cs | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/csharp/Grpc.Core.Api/ServerCallContext.cs b/src/csharp/Grpc.Core.Api/ServerCallContext.cs index 7cc03cb3a0b..8d7dbf544d6 100644 --- a/src/csharp/Grpc.Core.Api/ServerCallContext.cs +++ b/src/csharp/Grpc.Core.Api/ServerCallContext.cs @@ -120,18 +120,7 @@ namespace Grpc.Core /// Gets a dictionary that can be used by the various interceptors and handlers of this /// call to store arbitrary state. /// - public virtual IDictionary UserState - { - get - { - if (userState == null) - { - userState = new Dictionary(); - } - - return userState; - } - } + public IDictionary UserState => UserStateCore; /// Provides implementation of a non-virtual public member. protected abstract Task WriteResponseHeadersAsyncCore(Metadata responseHeaders); @@ -157,5 +146,18 @@ namespace Grpc.Core protected abstract WriteOptions WriteOptionsCore { get; set; } /// Provides implementation of a non-virtual public member. protected abstract AuthContext AuthContextCore { get; } + /// Provides implementation of a non-virtual public member. + protected virtual IDictionary UserStateCore + { + get + { + if (userState == null) + { + userState = new Dictionary(); + } + + return userState; + } + } } } From 9eb1171dfb6f198b61336ca589c55442ab8dea59 Mon Sep 17 00:00:00 2001 From: Nikolai Lifanov Date: Thu, 21 Feb 2019 17:54:27 -0800 Subject: [PATCH 480/814] be compatible with Python 2 and Python 3 In Python 3, cc_err is going to be bytes(). --- src/python/grpcio/commands.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index e80b90c6a34..ca69527431f 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -33,6 +33,8 @@ from setuptools.command import test import support +from typing import Text + PYTHON_STEM = os.path.dirname(os.path.abspath(__file__)) GRPC_STEM = os.path.abspath(PYTHON_STEM + '../../../../') PROTO_STEM = os.path.join(GRPC_STEM, 'src', 'proto') @@ -222,7 +224,7 @@ class BuildExt(build_ext.build_ext): stdout=subprocess.PIPE, stderr=subprocess.PIPE) _, cc_err = cc_test.communicate(input='int main(){return 0;}') - return not 'invalid argument' in cc_err + return not 'invalid argument' in Text(cc_err) # This special conditioning is here due to difference of compiler # behavior in gcc and clang. The clang doesn't take --stdc++11 From 85979e9a5830782f0fc028676a0ae85b8f2f86f1 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 21 Feb 2019 18:23:33 -0800 Subject: [PATCH 481/814] List c-ares tracers in documentation --- doc/environment_variables.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index 132de81a7bd..435edbcfdb4 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -41,6 +41,9 @@ some configuration as environment variables that can be set. - bdp_estimator - traces behavior of bdp estimation logic - call_combiner - traces call combiner state - call_error - traces the possible errors contributing to final call status + - cares_resolver - traces operations of the c-ares based DNS resolver + - cares_address_sorting - traces operations of the c-ares based DNS + resolver's resolved address sorter - channel - traces operations on the C core channel stack - client_channel - traces client channel activity, including resolver and load balancing policy interaction From 7eb08ad72e5d59bbee55b387bd2dd9b42fe6688d Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 21 Feb 2019 21:29:12 -0800 Subject: [PATCH 482/814] Add interceptors, secure credentials, and cancellation to client callback test --- CMakeLists.txt | 1 + Makefile | 3 + build.yaml | 1 + test/cpp/end2end/BUILD | 1 + .../end2end/client_callback_end2end_test.cc | 640 ++++++++++++++---- .../generated/sources_and_headers.json | 3 +- 6 files changed, 505 insertions(+), 144 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e3a09cc4b7..fb732bf53f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12441,6 +12441,7 @@ if (gRPC_BUILD_TESTS) add_executable(client_callback_end2end_test test/cpp/end2end/client_callback_end2end_test.cc + test/cpp/end2end/interceptors_util.cc third_party/googletest/googletest/src/gtest-all.cc third_party/googletest/googlemock/src/gmock-all.cc ) diff --git a/Makefile b/Makefile index 7cfe37384aa..1657faf739e 100644 --- a/Makefile +++ b/Makefile @@ -17464,6 +17464,7 @@ endif CLIENT_CALLBACK_END2END_TEST_SRC = \ test/cpp/end2end/client_callback_end2end_test.cc \ + test/cpp/end2end/interceptors_util.cc \ CLIENT_CALLBACK_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CLIENT_CALLBACK_END2END_TEST_SRC)))) ifeq ($(NO_SECURE),true) @@ -17496,6 +17497,8 @@ endif $(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_callback_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/interceptors_util.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + deps_client_callback_end2end_test: $(CLIENT_CALLBACK_END2END_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) diff --git a/build.yaml b/build.yaml index 73929526cd2..aac6e78976b 100644 --- a/build.yaml +++ b/build.yaml @@ -4468,6 +4468,7 @@ targets: language: c++ src: - test/cpp/end2end/client_callback_end2end_test.cc + - test/cpp/end2end/interceptors_util.cc deps: - grpc++_test_util - grpc_test_util diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index a9db19dfe8e..d80fa33a83a 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -150,6 +150,7 @@ grpc_cc_test( "gtest", ], deps = [ + ":interceptors_util", ":test_service_impl", "//:gpr", "//:grpc", diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 30db5b8c01c..a076c1f0cec 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -35,9 +35,11 @@ #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" +#include "test/cpp/end2end/interceptors_util.h" #include "test/cpp/end2end/test_service_impl.h" #include "test/cpp/util/byte_buffer_proto_helper.h" #include "test/cpp/util/string_ref_helper.h" +#include "test/cpp/util/test_credentials_provider.h" #include @@ -60,11 +62,17 @@ enum class Protocol { INPROC, TCP }; class TestScenario { public: - TestScenario(bool serve_callback, Protocol protocol) - : callback_server(serve_callback), protocol(protocol) {} + TestScenario(bool serve_callback, Protocol protocol, bool intercept, + const grpc::string& creds_type) + : callback_server(serve_callback), + protocol(protocol), + use_interceptors(intercept), + credentials_type(creds_type) {} void Log() const; bool callback_server; Protocol protocol; + bool use_interceptors; + const grpc::string credentials_type; }; static std::ostream& operator<<(std::ostream& out, @@ -87,6 +95,10 @@ class ClientCallbackEnd2endTest void SetUp() override { ServerBuilder builder; + auto server_creds = GetCredentialsProvider()->GetServerCredentials( + GetParam().credentials_type); + // TODO(vjpai): Support testing of AuthMetadataProcessor + if (GetParam().protocol == Protocol::TCP) { if (!grpc_iomgr_run_in_background()) { do_not_test_ = true; @@ -94,8 +106,7 @@ class ClientCallbackEnd2endTest } int port = grpc_pick_unused_port_or_die(); server_address_ << "localhost:" << port; - builder.AddListeningPort(server_address_.str(), - InsecureServerCredentials()); + builder.AddListeningPort(server_address_.str(), server_creds); } if (!GetParam().callback_server) { builder.RegisterService(&service_); @@ -103,25 +114,52 @@ class ClientCallbackEnd2endTest builder.RegisterService(&callback_service_); } + if (GetParam().use_interceptors) { + std::vector< + std::unique_ptr> + creators; + // Add 20 dummy server interceptors + creators.reserve(20); + for (auto i = 0; i < 20; i++) { + creators.push_back(std::unique_ptr( + new DummyInterceptorFactory())); + } + builder.experimental().SetInterceptorCreators(std::move(creators)); + } + server_ = builder.BuildAndStart(); is_server_started_ = true; } void ResetStub() { ChannelArguments args; + auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); switch (GetParam().protocol) { case Protocol::TCP: - channel_ = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + if (!GetParam().use_interceptors) { + channel_ = + CreateCustomChannel(server_address_.str(), channel_creds, args); + } else { + channel_ = CreateCustomChannelWithInterceptors( + server_address_.str(), channel_creds, args, + CreateDummyClientInterceptors()); + } break; case Protocol::INPROC: - channel_ = server_->InProcessChannel(args); + if (!GetParam().use_interceptors) { + channel_ = server_->InProcessChannel(args); + } else { + channel_ = server_->experimental().InProcessChannelWithInterceptors( + args, CreateDummyClientInterceptors()); + } break; default: assert(false); } stub_ = grpc::testing::EchoTestService::NewStub(channel_); generic_stub_.reset(new GenericStub(channel_)); + DummyInterceptor::Reset(); } void TearDown() override { @@ -419,168 +457,484 @@ TEST_P(ClientCallbackEnd2endTest, CancelRpcBeforeStart) { while (!done) { cv.wait(l); } + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } } +TEST_P(ClientCallbackEnd2endTest, RequestEchoServerCancel) { + MAYBE_SKIP_TEST; + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + request.set_message("hello"); + context.AddMetadata(kServerTryCancelRequest, + grpc::to_string(CANCEL_BEFORE_PROCESSING)); + + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->Echo( + &context, &request, &response, [&done, &mu, &cv](Status s) { + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } +} + +class WriteClient : public grpc::experimental::ClientWriteReactor { + public: + WriteClient(grpc::testing::EchoTestService::Stub* stub, + ServerTryCancelRequestPhase server_try_cancel, + int num_msgs_to_send) + : server_try_cancel_(server_try_cancel), + num_msgs_to_send_(num_msgs_to_send) { + grpc::string msg{"Hello server."}; + for (int i = 0; i < num_msgs_to_send; i++) { + desired_ += msg; + } + if (server_try_cancel != DO_NOT_CANCEL) { + // Send server_try_cancel value in the client metadata + context_.AddMetadata(kServerTryCancelRequest, + grpc::to_string(server_try_cancel)); + } + context_.set_initial_metadata_corked(true); + stub->experimental_async()->RequestStream(&context_, &response_, this); + StartCall(); + request_.set_message(msg); + MaybeWrite(); + } + void OnWriteDone(bool ok) override { + num_msgs_sent_++; + if (ok) { + MaybeWrite(); + } + } + void OnDone(const Status& s) override { + gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent_); + switch (server_try_cancel_) { + case CANCEL_BEFORE_PROCESSING: + case CANCEL_DURING_PROCESSING: + // If the RPC is canceled by server before / during messages from the + // client, it means that the client most likely did not get a chance to + // send all the messages it wanted to send. i.e num_msgs_sent <= + // num_msgs_to_send + EXPECT_LE(num_msgs_sent_, num_msgs_to_send_); + break; + case DO_NOT_CANCEL: + case CANCEL_AFTER_PROCESSING: + // If the RPC was not canceled or canceled after all messages were read + // by the server, the client did get a chance to send all its messages + EXPECT_EQ(num_msgs_sent_, num_msgs_to_send_); + break; + default: + assert(false); + break; + } + if (server_try_cancel_ == DO_NOT_CANCEL) { + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response_.message(), desired_); + } else { + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + } + std::unique_lock l(mu_); + done_ = true; + cv_.notify_one(); + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + cv_.wait(l); + } + } + + private: + void MaybeWrite() { + if (num_msgs_to_send_ > num_msgs_sent_ + 1) { + StartWrite(&request_); + } else if (num_msgs_to_send_ == num_msgs_sent_ + 1) { + StartWriteLast(&request_, WriteOptions()); + } + } + EchoRequest request_; + EchoResponse response_; + ClientContext context_; + const ServerTryCancelRequestPhase server_try_cancel_; + int num_msgs_sent_{0}; + const int num_msgs_to_send_; + grpc::string desired_; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; +}; + TEST_P(ClientCallbackEnd2endTest, RequestStream) { MAYBE_SKIP_TEST; ResetStub(); - class Client : public grpc::experimental::ClientWriteReactor { - public: - explicit Client(grpc::testing::EchoTestService::Stub* stub) { - context_.set_initial_metadata_corked(true); - stub->experimental_async()->RequestStream(&context_, &response_, this); - StartCall(); - request_.set_message("Hello server."); - StartWrite(&request_); - } - void OnWriteDone(bool ok) override { - writes_left_--; - if (writes_left_ > 1) { - StartWrite(&request_); - } else if (writes_left_ == 1) { - StartWriteLast(&request_, WriteOptions()); - } - } - void OnDone(const Status& s) override { - EXPECT_TRUE(s.ok()); - EXPECT_EQ(response_.message(), "Hello server.Hello server.Hello server."); - std::unique_lock l(mu_); - done_ = true; - cv_.notify_one(); - } - void Await() { - std::unique_lock l(mu_); - while (!done_) { - cv_.wait(l); - } - } - - private: - EchoRequest request_; - EchoResponse response_; - ClientContext context_; - int writes_left_{3}; - std::mutex mu_; - std::condition_variable cv_; - bool done_ = false; - } test{stub_.get()}; - + WriteClient test{stub_.get(), DO_NOT_CANCEL, 3}; test.Await(); + // Make sure that the server interceptors were not notified to cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel()); + } } +// Server to cancel before doing reading the request +TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelBeforeReads) { + MAYBE_SKIP_TEST; + ResetStub(); + WriteClient test{stub_.get(), CANCEL_BEFORE_PROCESSING, 1}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel while reading a request from the stream in parallel +TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelDuringRead) { + MAYBE_SKIP_TEST; + ResetStub(); + WriteClient test{stub_.get(), CANCEL_DURING_PROCESSING, 10}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel after reading all the requests but before returning to the +// client +TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelAfterReads) { + MAYBE_SKIP_TEST; + ResetStub(); + WriteClient test{stub_.get(), CANCEL_AFTER_PROCESSING, 4}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +class ReadClient : public grpc::experimental::ClientReadReactor { + public: + ReadClient(grpc::testing::EchoTestService::Stub* stub, + ServerTryCancelRequestPhase server_try_cancel) + : server_try_cancel_(server_try_cancel) { + if (server_try_cancel_ != DO_NOT_CANCEL) { + // Send server_try_cancel value in the client metadata + context_.AddMetadata(kServerTryCancelRequest, + grpc::to_string(server_try_cancel)); + } + request_.set_message("Hello client "); + stub->experimental_async()->ResponseStream(&context_, &request_, this); + StartRead(&response_); + StartCall(); + } + void OnReadDone(bool ok) override { + if (!ok) { + if (server_try_cancel_ == DO_NOT_CANCEL) { + EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); + } + } else { + EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); + EXPECT_EQ(response_.message(), + request_.message() + grpc::to_string(reads_complete_)); + reads_complete_++; + StartRead(&response_); + } + } + void OnDone(const Status& s) override { + gpr_log(GPR_INFO, "Read %d messages", reads_complete_); + switch (server_try_cancel_) { + case DO_NOT_CANCEL: + EXPECT_TRUE(s.ok()); + EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); + break; + case CANCEL_BEFORE_PROCESSING: + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + EXPECT_EQ(reads_complete_, 0); + break; + case CANCEL_DURING_PROCESSING: + case CANCEL_AFTER_PROCESSING: + // If server canceled while writing messages, client must have read + // less than or equal to the expected number of messages. Even if the + // server canceled after writing all messages, the RPC may be canceled + // before the Client got a chance to read all the messages. + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); + break; + default: + assert(false); + } + std::unique_lock l(mu_); + done_ = true; + cv_.notify_one(); + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + cv_.wait(l); + } + } + + private: + EchoRequest request_; + EchoResponse response_; + ClientContext context_; + const ServerTryCancelRequestPhase server_try_cancel_; + int reads_complete_{0}; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; +}; + TEST_P(ClientCallbackEnd2endTest, ResponseStream) { MAYBE_SKIP_TEST; ResetStub(); - class Client : public grpc::experimental::ClientReadReactor { - public: - explicit Client(grpc::testing::EchoTestService::Stub* stub) { - request_.set_message("Hello client "); - stub->experimental_async()->ResponseStream(&context_, &request_, this); - StartCall(); + ReadClient test{stub_.get(), DO_NOT_CANCEL}; + test.Await(); + // Make sure that the server interceptors were not notified of a cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel before sending any response messages +TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelBefore) { + MAYBE_SKIP_TEST; + ResetStub(); + ReadClient test{stub_.get(), CANCEL_BEFORE_PROCESSING}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel while writing a response to the stream in parallel +TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelDuring) { + MAYBE_SKIP_TEST; + ResetStub(); + ReadClient test{stub_.get(), CANCEL_DURING_PROCESSING}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel after writing all the respones to the stream but before +// returning to the client +TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelAfter) { + MAYBE_SKIP_TEST; + ResetStub(); + ReadClient test{stub_.get(), CANCEL_AFTER_PROCESSING}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +class BidiClient + : public grpc::experimental::ClientBidiReactor { + public: + BidiClient(grpc::testing::EchoTestService::Stub* stub, + ServerTryCancelRequestPhase server_try_cancel, + int num_msgs_to_send) + : server_try_cancel_(server_try_cancel), msgs_to_send_{num_msgs_to_send} { + if (server_try_cancel_ != DO_NOT_CANCEL) { + // Send server_try_cancel value in the client metadata + context_.AddMetadata(kServerTryCancelRequest, + grpc::to_string(server_try_cancel)); + } + request_.set_message("Hello fren "); + stub->experimental_async()->BidiStream(&context_, this); + StartRead(&response_); + StartWrite(&request_); + StartCall(); + } + void OnReadDone(bool ok) override { + if (!ok) { + if (server_try_cancel_ == DO_NOT_CANCEL) { + EXPECT_EQ(reads_complete_, msgs_to_send_); + } + } else { + EXPECT_LE(reads_complete_, msgs_to_send_); + EXPECT_EQ(response_.message(), request_.message()); + reads_complete_++; StartRead(&response_); } - void OnReadDone(bool ok) override { - if (!ok) { - EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); - } else { - EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); - EXPECT_EQ(response_.message(), - request_.message() + grpc::to_string(reads_complete_)); - reads_complete_++; - StartRead(&response_); - } + } + void OnWriteDone(bool ok) override { + if (server_try_cancel_ == DO_NOT_CANCEL) { + EXPECT_TRUE(ok); + } else if (!ok) { + return; } - void OnDone(const Status& s) override { - EXPECT_TRUE(s.ok()); - std::unique_lock l(mu_); - done_ = true; - cv_.notify_one(); + if (++writes_complete_ == msgs_to_send_) { + StartWritesDone(); + } else { + StartWrite(&request_); } - void Await() { - std::unique_lock l(mu_); - while (!done_) { - cv_.wait(l); - } + } + void OnDone(const Status& s) override { + gpr_log(GPR_INFO, "Sent %d messages", writes_complete_); + gpr_log(GPR_INFO, "Read %d messages", reads_complete_); + switch (server_try_cancel_) { + case DO_NOT_CANCEL: + EXPECT_TRUE(s.ok()); + EXPECT_EQ(writes_complete_, msgs_to_send_); + EXPECT_EQ(reads_complete_, writes_complete_); + break; + case CANCEL_BEFORE_PROCESSING: + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + // The RPC is canceled before the server did any work or returned any + // reads, but it's possible that some writes took place first from the + // client + EXPECT_LE(writes_complete_, msgs_to_send_); + EXPECT_EQ(reads_complete_, 0); + break; + case CANCEL_DURING_PROCESSING: + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + EXPECT_LE(writes_complete_, msgs_to_send_); + EXPECT_LE(reads_complete_, writes_complete_); + break; + case CANCEL_AFTER_PROCESSING: + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + EXPECT_EQ(writes_complete_, msgs_to_send_); + // The Server canceled after reading the last message and after writing + // the message to the client. However, the RPC cancellation might have + // taken effect before the client actually read the response. + EXPECT_LE(reads_complete_, writes_complete_); + break; + default: + assert(false); } + std::unique_lock l(mu_); + done_ = true; + cv_.notify_one(); + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + cv_.wait(l); + } + } - private: - EchoRequest request_; - EchoResponse response_; - ClientContext context_; - int reads_complete_{0}; - std::mutex mu_; - std::condition_variable cv_; - bool done_ = false; - } test{stub_.get()}; - - test.Await(); -} + private: + EchoRequest request_; + EchoResponse response_; + ClientContext context_; + const ServerTryCancelRequestPhase server_try_cancel_; + int reads_complete_{0}; + int writes_complete_{0}; + const int msgs_to_send_; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; +}; TEST_P(ClientCallbackEnd2endTest, BidiStream) { MAYBE_SKIP_TEST; ResetStub(); - class Client : public grpc::experimental::ClientBidiReactor { - public: - explicit Client(grpc::testing::EchoTestService::Stub* stub) { - request_.set_message("Hello fren "); - stub->experimental_async()->BidiStream(&context_, this); - StartCall(); - StartRead(&response_); - StartWrite(&request_); - } - void OnReadDone(bool ok) override { - if (!ok) { - EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); - } else { - EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); - EXPECT_EQ(response_.message(), request_.message()); - reads_complete_++; - StartRead(&response_); - } - } - void OnWriteDone(bool ok) override { - EXPECT_TRUE(ok); - if (++writes_complete_ == kServerDefaultResponseStreamsToSend) { - StartWritesDone(); - } else { - StartWrite(&request_); - } - } - void OnDone(const Status& s) override { - EXPECT_TRUE(s.ok()); - std::unique_lock l(mu_); - done_ = true; - cv_.notify_one(); - } - void Await() { - std::unique_lock l(mu_); - while (!done_) { - cv_.wait(l); - } - } - - private: - EchoRequest request_; - EchoResponse response_; - ClientContext context_; - int reads_complete_{0}; - int writes_complete_{0}; - std::mutex mu_; - std::condition_variable cv_; - bool done_ = false; - } test{stub_.get()}; - + BidiClient test{stub_.get(), DO_NOT_CANCEL, + kServerDefaultResponseStreamsToSend}; test.Await(); + // Make sure that the server interceptors were not notified of a cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel()); + } } -TestScenario scenarios[]{{false, Protocol::INPROC}, - {false, Protocol::TCP}, - {true, Protocol::INPROC}, - {true, Protocol::TCP}}; +// Server to cancel before reading/writing any requests/responses on the stream +TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelBefore) { + MAYBE_SKIP_TEST; + ResetStub(); + BidiClient test{stub_.get(), CANCEL_BEFORE_PROCESSING, 2}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel while reading/writing requests/responses on the stream in +// parallel +TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelDuring) { + MAYBE_SKIP_TEST; + ResetStub(); + BidiClient test{stub_.get(), CANCEL_DURING_PROCESSING, 10}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +// Server to cancel after reading/writing all requests/responses on the stream +// but before returning to the client +TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelAfter) { + MAYBE_SKIP_TEST; + ResetStub(); + BidiClient test{stub_.get(), CANCEL_AFTER_PROCESSING, 5}; + test.Await(); + // Make sure that the server interceptors were notified + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + +std::vector CreateTestScenarios(bool test_insecure) { + std::vector scenarios; + std::vector credentials_types{ + GetCredentialsProvider()->GetSecureCredentialsTypeList()}; + auto insec_ok = [] { + // Only allow insecure credentials type when it is registered with the + // provider. User may create providers that do not have insecure. + return GetCredentialsProvider()->GetChannelCredentials( + kInsecureCredentialsType, nullptr) != nullptr; + }; + if (test_insecure && insec_ok()) { + credentials_types.push_back(kInsecureCredentialsType); + } + GPR_ASSERT(!credentials_types.empty()); + + bool barr[]{false, true}; + Protocol parr[]{Protocol::INPROC, Protocol::TCP}; + for (Protocol p : parr) { + for (const auto& cred : credentials_types) { + // TODO(vjpai): Test inproc with secure credentials when feasible + if (p == Protocol::INPROC && + (cred != kInsecureCredentialsType || !insec_ok())) { + continue; + } + for (bool callback_server : barr) { + for (bool use_interceptors : barr) { + scenarios.emplace_back(callback_server, p, use_interceptors, cred); + } + } + } + } + return scenarios; +} INSTANTIATE_TEST_CASE_P(ClientCallbackEnd2endTest, ClientCallbackEnd2endTest, - ::testing::ValuesIn(scenarios)); + ::testing::ValuesIn(CreateTestScenarios(true))); } // namespace } // namespace testing diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index f94357b2c62..0520665bd1e 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3300,7 +3300,8 @@ "language": "c++", "name": "client_callback_end2end_test", "src": [ - "test/cpp/end2end/client_callback_end2end_test.cc" + "test/cpp/end2end/client_callback_end2end_test.cc", + "test/cpp/end2end/interceptors_util.cc" ], "third_party": false, "type": "target" From 148ae20e440612ef5ab344f5d7b4596d903e8eb8 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 22 Feb 2019 07:36:18 -0800 Subject: [PATCH 483/814] Code review changes. --- .../lb_policy/pick_first/pick_first.cc | 11 +++++------ .../ext/filters/client_channel/lb_policy/xds/xds.cc | 13 +++---------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index c222b7ba292..e90e396936f 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -278,7 +278,7 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args, // READY, then select it immediately. This can happen when the // currently selected subchannel is also present in the update. It // can also happen if one of the subchannels in the update is already - // in the subchannel index because it's in use by another channel. + // in the global subchannel pool because it's in use by another channel. // TODO(roth): If we're in IDLE state, we should probably defer this // check and instead do it in ExitIdleLocked(). for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) { @@ -376,11 +376,10 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( UniquePtr(New(new_error))); } else { if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { - // If the selected subchannel goes bad, request a re-resolution. We also - // set the channel state to IDLE and reset idle_. The reason - // is that if the new state is TRANSIENT_FAILURE due to a GOAWAY - // reception we don't want to connect to the re-resolved backends until - // we leave the IDLE state. + // If the selected subchannel goes bad, request a re-resolution. We + // also set the channel state to IDLE. The reason is that if the new + // state is TRANSIENT_FAILURE due to a GOAWAY reception we don't want + // to connect to the re-resolved backends until we leave IDLE state. p->idle_ = true; p->channel_control_helper()->RequestReresolution(); // In transient failure. Rely on re-resolution to recover. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index a1d2002079d..283e6bb5899 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1138,11 +1138,7 @@ void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && !fallback_timer_callback_pending_) { grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = Ref(DEBUG_LOCATION, "on_fallback_timer"); - self.release(); + Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Held by closure GRPC_CLOSURE_INIT(&lb_on_fallback_, &XdsLb::OnFallbackTimerLocked, this, grpc_combiner_scheduler(combiner())); fallback_timer_callback_pending_ = true; @@ -1159,11 +1155,8 @@ void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { grpc_channel_get_channel_stack(lb_channel_)); GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); watching_lb_channel_ = true; - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity"); - self.release(); + // Ref held by closure. + Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity").release(); grpc_client_channel_watch_connectivity_state( client_channel_elem, grpc_polling_entity_create_from_pollset_set(interested_parties()), From 428fa7602cf82bd4eced7f60e95c35dc6453f08f Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 22 Feb 2019 10:31:16 -0800 Subject: [PATCH 484/814] Transition into state CONNECTING when we start name resolution. --- .../client_channel/resolving_lb_policy.cc | 3 +++ test/cpp/end2end/client_lb_end2end_test.cc | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 22050cba59e..9f3d4bad999 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -218,6 +218,9 @@ void ResolvingLoadBalancingPolicy::StartResolvingLocked() { } GPR_ASSERT(!started_resolving_); started_resolving_ = true; + channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + UniquePtr(New(Ref()))); Ref().release(); resolver_->NextLocked(&resolver_result_, &on_resolver_result_changed_); } diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index d0d39586710..049b732e1a0 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -402,6 +402,27 @@ class ClientLbEnd2endTest : public ::testing::Test { std::shared_ptr creds_; }; +TEST_F(ClientLbEnd2endTest, ChannelStateConnectingWhenResolving) { + const int kNumServers = 3; + StartServers(kNumServers); + auto channel = BuildChannel(""); + auto stub = BuildStub(channel); + // Initial state should be IDLE. + EXPECT_EQ(channel->GetState(false /* try_to_connect */), GRPC_CHANNEL_IDLE); + // Tell the channel to try to connect. + // Note that this call also returns IDLE, since the state change has + // not yet occurred; it just gets triggered by this call. + EXPECT_EQ(channel->GetState(true /* try_to_connect */), GRPC_CHANNEL_IDLE); + // Now that the channel is trying to connect, we should be in state + // CONNECTING. + EXPECT_EQ(channel->GetState(false /* try_to_connect */), + GRPC_CHANNEL_CONNECTING); + // Return a resolver result, which allows the connection attempt to proceed. + SetNextResolution(GetServersPorts()); + // We should eventually transition into state READY. + EXPECT_TRUE(WaitForChannelReady(channel.get())); +} + TEST_F(ClientLbEnd2endTest, PickFirst) { // Start servers and send one RPC per server. const int kNumServers = 3; From 91db94b278b12a6de7afe69805d3678bb670fd46 Mon Sep 17 00:00:00 2001 From: Nikolai Lifanov Date: Fri, 22 Feb 2019 11:15:54 -0800 Subject: [PATCH 485/814] build grpc libraries now that submake for macOS is removed --- setup.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/setup.py b/setup.py index f533e7b77cf..1992976198d 100644 --- a/setup.py +++ b/setup.py @@ -265,15 +265,8 @@ def cython_extensions_and_necessity(): for name in CYTHON_EXTENSION_MODULE_NAMES] config = os.environ.get('CONFIG', 'opt') prefix = 'libs/' + config + '/' - if "darwin" in sys.platform or USE_PREBUILT_GRPC_CORE: - extra_objects = [prefix + 'libares.a', - prefix + 'libboringssl.a', - prefix + 'libgpr.a', - prefix + 'libgrpc.a'] - core_c_files = [] - else: - core_c_files = list(CORE_C_FILES) - extra_objects = [] + core_c_files = list(CORE_C_FILES) + extra_objects = [] extensions = [ _extension.Extension( name=module_name, From a916a533470d1ada80cece9d3be63af5d404486c Mon Sep 17 00:00:00 2001 From: Nikolai Lifanov Date: Fri, 22 Feb 2019 11:32:26 -0800 Subject: [PATCH 486/814] use str instead of Text to appease Python 2.7 The Python 2.7 Linux test runner doesn't have typing module available. --- src/python/grpcio/commands.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index ca69527431f..6b89a6a73a8 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -33,8 +33,6 @@ from setuptools.command import test import support -from typing import Text - PYTHON_STEM = os.path.dirname(os.path.abspath(__file__)) GRPC_STEM = os.path.abspath(PYTHON_STEM + '../../../../') PROTO_STEM = os.path.join(GRPC_STEM, 'src', 'proto') @@ -224,7 +222,7 @@ class BuildExt(build_ext.build_ext): stdout=subprocess.PIPE, stderr=subprocess.PIPE) _, cc_err = cc_test.communicate(input='int main(){return 0;}') - return not 'invalid argument' in Text(cc_err) + return not 'invalid argument' in str(cc_err) # This special conditioning is here due to difference of compiler # behavior in gcc and clang. The clang doesn't take --stdc++11 From 9dd94ea1fa24aee24722867e21059e5735270c44 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 14 Feb 2019 16:50:20 -0500 Subject: [PATCH 487/814] Use std::atomic for CQ data. There was a sub-optimality in the CAS operation. vjpai@ and I decided to move to std::atomic. This commit basically moves CQ data to C++ structures, and makes grpc_cq_event_queue a proper c++ class called CQEventQueue. --- src/core/lib/gprpp/atomic.h | 12 +- src/core/lib/surface/completion_queue.cc | 282 +++++++++++------------ 2 files changed, 140 insertions(+), 154 deletions(-) diff --git a/src/core/lib/gprpp/atomic.h b/src/core/lib/gprpp/atomic.h index 622df1b7889..5bc14d15ea0 100644 --- a/src/core/lib/gprpp/atomic.h +++ b/src/core/lib/gprpp/atomic.h @@ -49,8 +49,9 @@ class Atomic { bool CompareExchangeWeak(T* expected, T desired, MemoryOrder success, MemoryOrder failure) { - return GPR_ATM_INC_CAS_THEN( - storage_.compare_exchange_weak(*expected, desired, success, failure)); + return GPR_ATM_INC_CAS_THEN(storage_.compare_exchange_weak( + *expected, desired, static_cast(success), + static_cast(failure))); } bool CompareExchangeStrong(T* expected, T desired, MemoryOrder success, @@ -74,7 +75,7 @@ class Atomic { // Atomically increment a counter only if the counter value is not zero. // Returns true if increment took place; false if counter is zero. - bool IncrementIfNonzero(MemoryOrder load_order = MemoryOrder::ACQ_REL) { + bool IncrementIfNonzero(MemoryOrder load_order = MemoryOrder::ACQUIRE) { T count = storage_.load(static_cast(load_order)); do { // If zero, we are done (without an increment). If not, we must do a CAS @@ -83,9 +84,8 @@ class Atomic { if (count == 0) { return false; } - } while (!storage_.AtomicCompareExchangeWeak( - &count, count + 1, static_cast(MemoryOrder::ACQ_REL), - static_cast(load_order))); + } while (!CompareExchangeWeak(&count, count + 1, MemoryOrder::ACQ_REL, + load_order)); return true; } diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index bfd8445f70e..7d679204bac 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -33,6 +33,7 @@ #include "src/core/lib/gpr/spinlock.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/tls.h" +#include "src/core/lib/gprpp/atomic.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" @@ -44,6 +45,8 @@ grpc_core::TraceFlag grpc_trace_operation_failures(false, "op_failure"); grpc_core::DebugOnlyTraceFlag grpc_trace_pending_tags(false, "pending_tags"); grpc_core::DebugOnlyTraceFlag grpc_trace_cq_refcount(false, "cq_refcount"); +namespace { + // Specifies a cq thread local cache. // The first event that occurs on a thread // with a cq cache will go into that cache, and @@ -84,24 +87,22 @@ typedef struct { grpc_closure* shutdown; } non_polling_poller; -static size_t non_polling_poller_size(void) { - return sizeof(non_polling_poller); -} +size_t non_polling_poller_size(void) { return sizeof(non_polling_poller); } -static void non_polling_poller_init(grpc_pollset* pollset, gpr_mu** mu) { +void non_polling_poller_init(grpc_pollset* pollset, gpr_mu** mu) { non_polling_poller* npp = reinterpret_cast(pollset); gpr_mu_init(&npp->mu); *mu = &npp->mu; } -static void non_polling_poller_destroy(grpc_pollset* pollset) { +void non_polling_poller_destroy(grpc_pollset* pollset) { non_polling_poller* npp = reinterpret_cast(pollset); gpr_mu_destroy(&npp->mu); } -static grpc_error* non_polling_poller_work(grpc_pollset* pollset, - grpc_pollset_worker** worker, - grpc_millis deadline) { +grpc_error* non_polling_poller_work(grpc_pollset* pollset, + grpc_pollset_worker** worker, + grpc_millis deadline) { non_polling_poller* npp = reinterpret_cast(pollset); if (npp->shutdown) return GRPC_ERROR_NONE; if (npp->kicked_without_poller) { @@ -141,8 +142,8 @@ static grpc_error* non_polling_poller_work(grpc_pollset* pollset, return GRPC_ERROR_NONE; } -static grpc_error* non_polling_poller_kick( - grpc_pollset* pollset, grpc_pollset_worker* specific_worker) { +grpc_error* non_polling_poller_kick(grpc_pollset* pollset, + grpc_pollset_worker* specific_worker) { non_polling_poller* p = reinterpret_cast(pollset); if (specific_worker == nullptr) specific_worker = reinterpret_cast(p->root); @@ -159,8 +160,7 @@ static grpc_error* non_polling_poller_kick( return GRPC_ERROR_NONE; } -static void non_polling_poller_shutdown(grpc_pollset* pollset, - grpc_closure* closure) { +void non_polling_poller_shutdown(grpc_pollset* pollset, grpc_closure* closure) { non_polling_poller* p = reinterpret_cast(pollset); GPR_ASSERT(closure != nullptr); p->shutdown = closure; @@ -175,7 +175,7 @@ static void non_polling_poller_shutdown(grpc_pollset* pollset, } } -static const cq_poller_vtable g_poller_vtable_by_poller_type[] = { +const cq_poller_vtable g_poller_vtable_by_poller_type[] = { /* GRPC_CQ_DEFAULT_POLLING */ {true, true, grpc_pollset_size, grpc_pollset_init, grpc_pollset_kick, grpc_pollset_work, grpc_pollset_shutdown, grpc_pollset_destroy}, @@ -188,7 +188,9 @@ static const cq_poller_vtable g_poller_vtable_by_poller_type[] = { non_polling_poller_shutdown, non_polling_poller_destroy}, }; -typedef struct cq_vtable { +} // namespace + +struct cq_vtable { grpc_cq_completion_type cq_completion_type; size_t data_size; void (*init)(void* data, @@ -203,80 +205,116 @@ typedef struct cq_vtable { void* reserved); grpc_event (*pluck)(grpc_completion_queue* cq, void* tag, gpr_timespec deadline, void* reserved); -} cq_vtable; +}; + +namespace { /* Queue that holds the cq_completion_events. Internally uses gpr_mpscq queue * (a lockfree multiproducer single consumer queue). It uses a queue_lock * to support multiple consumers. * Only used in completion queues whose completion_type is GRPC_CQ_NEXT */ -typedef struct grpc_cq_event_queue { - /* Spinlock to serialize consumers i.e pop() operations */ - gpr_spinlock queue_lock; +class CqEventQueue { + public: + CqEventQueue() { gpr_mpscq_init(&queue_); } + ~CqEventQueue() { gpr_mpscq_destroy(&queue_); } - gpr_mpscq queue; + /* Note: The counter is not incremented/decremented atomically with push/pop. + * The count is only eventually consistent */ + intptr_t num_items() const { + return num_queue_items_.Load(grpc_core::MemoryOrder::RELAXED); + } + + bool Push(grpc_cq_completion* c); + grpc_cq_completion* Pop(); + + private: + /* Spinlock to serialize consumers i.e pop() operations */ + gpr_spinlock queue_lock_ = GPR_SPINLOCK_INITIALIZER; + + gpr_mpscq queue_; /* A lazy counter of number of items in the queue. This is NOT atomically incremented/decremented along with push/pop operations and hence is only eventually consistent */ - gpr_atm num_queue_items; -} grpc_cq_event_queue; + grpc_core::Atomic num_queue_items_{0}; +}; + +struct cq_next_data { + ~cq_next_data() { GPR_ASSERT(queue.num_items() == 0); } -typedef struct cq_next_data { /** Completed events for completion-queues of type GRPC_CQ_NEXT */ - grpc_cq_event_queue queue; + CqEventQueue queue; /** Counter of how many things have ever been queued on this completion queue useful for avoiding locks to check the queue */ - gpr_atm things_queued_ever; + grpc_core::Atomic things_queued_ever{0}; - /* Number of outstanding events (+1 if not shut down) */ - gpr_atm pending_events; + /** Number of outstanding events (+1 if not shut down) + Initial count is dropped by grpc_completion_queue_shutdown */ + grpc_core::Atomic pending_events{1}; /** 0 initially. 1 once we initiated shutdown */ - bool shutdown_called; -} cq_next_data; + bool shutdown_called = false; +}; + +struct cq_pluck_data { + cq_pluck_data() { + completed_tail = &completed_head; + completed_head.next = reinterpret_cast(completed_tail); + } + + ~cq_pluck_data() { + GPR_ASSERT(completed_head.next == + reinterpret_cast(&completed_head)); + } -typedef struct cq_pluck_data { /** Completed events for completion-queues of type GRPC_CQ_PLUCK */ grpc_cq_completion completed_head; grpc_cq_completion* completed_tail; - /** Number of pending events (+1 if we're not shutdown) */ - gpr_atm pending_events; + /** Number of pending events (+1 if we're not shutdown). + Initial count is dropped by grpc_completion_queue_shutdown. */ + grpc_core::Atomic pending_events{1}; /** Counter of how many things have ever been queued on this completion queue useful for avoiding locks to check the queue */ - gpr_atm things_queued_ever; + grpc_core::Atomic things_queued_ever{0}; /** 0 initially. 1 once we completed shutting */ /* TODO: (sreek) This is not needed since (shutdown == 1) if and only if * (pending_events == 0). So consider removing this in future and use * pending_events */ - gpr_atm shutdown; + grpc_core::Atomic shutdown{false}; /** 0 initially. 1 once we initiated shutdown */ - bool shutdown_called; + bool shutdown_called = false; - int num_pluckers; + int num_pluckers = 0; plucker pluckers[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS]; -} cq_pluck_data; +}; -typedef struct cq_callback_data { +struct cq_callback_data { + cq_callback_data( + grpc_experimental_completion_queue_functor* shutdown_callback) + : shutdown_callback(shutdown_callback) {} /** No actual completed events queue, unlike other types */ - /** Number of pending events (+1 if we're not shutdown) */ - gpr_atm pending_events; + /** Number of pending events (+1 if we're not shutdown). + Initial count is dropped by grpc_completion_queue_shutdown. */ + grpc_core::Atomic pending_events{1}; /** Counter of how many things have ever been queued on this completion queue useful for avoiding locks to check the queue */ - gpr_atm things_queued_ever; + grpc_core::Atomic things_queued_ever{0}; /** 0 initially. 1 once we initiated shutdown */ - bool shutdown_called; + bool shutdown_called = false; /** A callback that gets invoked when the CQ completes shutdown */ grpc_experimental_completion_queue_functor* shutdown_callback; -} cq_callback_data; +}; + +} // namespace /* Completion queue structure */ struct grpc_completion_queue { @@ -408,7 +446,7 @@ int grpc_completion_queue_thread_local_cache_flush(grpc_completion_queue* cq, storage->done(storage->done_arg, storage); ret = 1; cq_next_data* cqd = static_cast DATA_FROM_CQ(cq); - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { GRPC_CQ_INTERNAL_REF(cq, "shutting_down"); gpr_mu_lock(cq->mu); cq_finish_shutdown_next(cq); @@ -422,31 +460,21 @@ int grpc_completion_queue_thread_local_cache_flush(grpc_completion_queue* cq, return ret; } -static void cq_event_queue_init(grpc_cq_event_queue* q) { - gpr_mpscq_init(&q->queue); - q->queue_lock = GPR_SPINLOCK_INITIALIZER; - gpr_atm_no_barrier_store(&q->num_queue_items, 0); +bool CqEventQueue::Push(grpc_cq_completion* c) { + gpr_mpscq_push(&queue_, reinterpret_cast(c)); + return num_queue_items_.FetchAdd(1, grpc_core::MemoryOrder::RELAXED) == 0; } -static void cq_event_queue_destroy(grpc_cq_event_queue* q) { - gpr_mpscq_destroy(&q->queue); -} - -static bool cq_event_queue_push(grpc_cq_event_queue* q, grpc_cq_completion* c) { - gpr_mpscq_push(&q->queue, reinterpret_cast(c)); - return gpr_atm_no_barrier_fetch_add(&q->num_queue_items, 1) == 0; -} - -static grpc_cq_completion* cq_event_queue_pop(grpc_cq_event_queue* q) { +grpc_cq_completion* CqEventQueue::Pop() { grpc_cq_completion* c = nullptr; - if (gpr_spinlock_trylock(&q->queue_lock)) { + if (gpr_spinlock_trylock(&queue_lock_)) { GRPC_STATS_INC_CQ_EV_QUEUE_TRYLOCK_SUCCESSES(); bool is_empty = false; c = reinterpret_cast( - gpr_mpscq_pop_and_check_end(&q->queue, &is_empty)); - gpr_spinlock_unlock(&q->queue_lock); + gpr_mpscq_pop_and_check_end(&queue_, &is_empty)); + gpr_spinlock_unlock(&queue_lock_); if (c == nullptr && !is_empty) { GRPC_STATS_INC_CQ_EV_QUEUE_TRANSIENT_POP_FAILURES(); @@ -456,18 +484,12 @@ static grpc_cq_completion* cq_event_queue_pop(grpc_cq_event_queue* q) { } if (c) { - gpr_atm_no_barrier_fetch_add(&q->num_queue_items, -1); + num_queue_items_.FetchSub(1, grpc_core::MemoryOrder::RELAXED); } return c; } -/* Note: The counter is not incremented/decremented atomically with push/pop. - * The count is only eventually consistent */ -static long cq_event_queue_num_items(grpc_cq_event_queue* q) { - return static_cast(gpr_atm_no_barrier_load(&q->num_queue_items)); -} - grpc_completion_queue* grpc_completion_queue_create_internal( grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type, grpc_experimental_completion_queue_functor* shutdown_callback) { @@ -507,49 +529,33 @@ grpc_completion_queue* grpc_completion_queue_create_internal( static void cq_init_next( void* data, grpc_experimental_completion_queue_functor* shutdown_callback) { - cq_next_data* cqd = static_cast(data); - /* Initial count is dropped by grpc_completion_queue_shutdown */ - gpr_atm_no_barrier_store(&cqd->pending_events, 1); - cqd->shutdown_called = false; - gpr_atm_no_barrier_store(&cqd->things_queued_ever, 0); - cq_event_queue_init(&cqd->queue); + new (data) cq_next_data(); } static void cq_destroy_next(void* data) { cq_next_data* cqd = static_cast(data); - GPR_ASSERT(cq_event_queue_num_items(&cqd->queue) == 0); - cq_event_queue_destroy(&cqd->queue); + cqd->~cq_next_data(); } static void cq_init_pluck( void* data, grpc_experimental_completion_queue_functor* shutdown_callback) { - cq_pluck_data* cqd = static_cast(data); - /* Initial count is dropped by grpc_completion_queue_shutdown */ - gpr_atm_no_barrier_store(&cqd->pending_events, 1); - cqd->completed_tail = &cqd->completed_head; - cqd->completed_head.next = (uintptr_t)cqd->completed_tail; - gpr_atm_no_barrier_store(&cqd->shutdown, 0); - cqd->shutdown_called = false; - cqd->num_pluckers = 0; - gpr_atm_no_barrier_store(&cqd->things_queued_ever, 0); + new (data) cq_pluck_data(); } static void cq_destroy_pluck(void* data) { cq_pluck_data* cqd = static_cast(data); - GPR_ASSERT(cqd->completed_head.next == (uintptr_t)&cqd->completed_head); + cqd->~cq_pluck_data(); } static void cq_init_callback( void* data, grpc_experimental_completion_queue_functor* shutdown_callback) { - cq_callback_data* cqd = static_cast(data); - /* Initial count is dropped by grpc_completion_queue_shutdown */ - gpr_atm_no_barrier_store(&cqd->pending_events, 1); - cqd->shutdown_called = false; - gpr_atm_no_barrier_store(&cqd->things_queued_ever, 0); - cqd->shutdown_callback = shutdown_callback; + new (data) cq_callback_data(shutdown_callback); } -static void cq_destroy_callback(void* data) {} +static void cq_destroy_callback(void* data) { + cq_callback_data* cqd = static_cast(data); + cqd->~cq_callback_data(); +} grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue* cq) { return cq->vtable->cq_completion_type; @@ -632,37 +638,19 @@ static void cq_check_tag(grpc_completion_queue* cq, void* tag, bool lock_cq) { static void cq_check_tag(grpc_completion_queue* cq, void* tag, bool lock_cq) {} #endif -/* Atomically increments a counter only if the counter is not zero. Returns - * true if the increment was successful; false if the counter is zero */ -static bool atm_inc_if_nonzero(gpr_atm* counter) { - while (true) { - gpr_atm count = gpr_atm_acq_load(counter); - /* If zero, we are done. If not, we must to a CAS (instead of an atomic - * increment) to maintain the contract: do not increment the counter if it - * is zero. */ - if (count == 0) { - return false; - } else if (gpr_atm_full_cas(counter, count, count + 1)) { - break; - } - } - - return true; -} - static bool cq_begin_op_for_next(grpc_completion_queue* cq, void* tag) { cq_next_data* cqd = static_cast DATA_FROM_CQ(cq); - return atm_inc_if_nonzero(&cqd->pending_events); + return cqd->pending_events.IncrementIfNonzero(); } static bool cq_begin_op_for_pluck(grpc_completion_queue* cq, void* tag) { cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); - return atm_inc_if_nonzero(&cqd->pending_events); + return cqd->pending_events.IncrementIfNonzero(); } static bool cq_begin_op_for_callback(grpc_completion_queue* cq, void* tag) { cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); - return atm_inc_if_nonzero(&cqd->pending_events); + return cqd->pending_events.IncrementIfNonzero(); } bool grpc_cq_begin_op(grpc_completion_queue* cq, void* tag) { @@ -716,17 +704,14 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, gpr_tls_set(&g_cached_event, (intptr_t)storage); } else { /* Add the completion to the queue */ - bool is_first = cq_event_queue_push(&cqd->queue, storage); - gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1); - + bool is_first = cqd->queue.Push(storage); + cqd->things_queued_ever.FetchAdd(1, grpc_core::MemoryOrder::RELAXED); /* Since we do not hold the cq lock here, it is important to do an 'acquire' load here (instead of a 'no_barrier' load) to match with the release store - (done via gpr_atm_full_fetch_add(pending_events, -1)) in cq_shutdown_next + (done via pending_events.FetchSub(1, ACQ_REL)) in cq_shutdown_next */ - bool will_definitely_shutdown = gpr_atm_acq_load(&cqd->pending_events) == 1; - - if (!will_definitely_shutdown) { + if (cqd->pending_events.Load(grpc_core::MemoryOrder::ACQUIRE) != 1) { /* Only kick if this is the first item queued */ if (is_first) { gpr_mu_lock(cq->mu); @@ -740,7 +725,8 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, GRPC_ERROR_UNREF(kick_error); } } - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == + 1) { GRPC_CQ_INTERNAL_REF(cq, "shutting_down"); gpr_mu_lock(cq->mu); cq_finish_shutdown_next(cq); @@ -749,7 +735,7 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, } } else { GRPC_CQ_INTERNAL_REF(cq, "shutting_down"); - gpr_atm_rel_store(&cqd->pending_events, 0); + cqd->pending_events.Store(0, grpc_core::MemoryOrder::RELEASE); gpr_mu_lock(cq->mu); cq_finish_shutdown_next(cq); gpr_mu_unlock(cq->mu); @@ -795,12 +781,12 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, cq_check_tag(cq, tag, false); /* Used in debug builds only */ /* Add to the list of completions */ - gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1); + cqd->things_queued_ever.FetchAdd(1, grpc_core::MemoryOrder::RELAXED); cqd->completed_tail->next = ((uintptr_t)storage) | (1u & cqd->completed_tail->next); cqd->completed_tail = storage; - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { cq_finish_shutdown_pluck(cq); gpr_mu_unlock(cq->mu); } else { @@ -856,8 +842,8 @@ static void cq_end_op_for_callback( cq_check_tag(cq, tag, true); /* Used in debug builds only */ - gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1); - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + cqd->things_queued_ever.FetchAdd(1, grpc_core::MemoryOrder::RELAXED); + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { cq_finish_shutdown_callback(cq); } @@ -893,20 +879,20 @@ class ExecCtxNext : public grpc_core::ExecCtx { cq_next_data* cqd = static_cast DATA_FROM_CQ(cq); GPR_ASSERT(a->stolen_completion == nullptr); - gpr_atm current_last_seen_things_queued_ever = - gpr_atm_no_barrier_load(&cqd->things_queued_ever); + intptr_t current_last_seen_things_queued_ever = + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED); if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) { a->last_seen_things_queued_ever = - gpr_atm_no_barrier_load(&cqd->things_queued_ever); + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED); /* Pop a cq_completion from the queue. Returns NULL if the queue is empty * might return NULL in some cases even if the queue is not empty; but * that * is ok and doesn't affect correctness. Might effect the tail latencies a * bit) */ - a->stolen_completion = cq_event_queue_pop(&cqd->queue); + a->stolen_completion = cqd->queue.Pop(); if (a->stolen_completion != nullptr) { return true; } @@ -965,7 +951,7 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, grpc_millis deadline_millis = grpc_timespec_to_millis_round_up(deadline); cq_is_finished_arg is_finished_arg = { - gpr_atm_no_barrier_load(&cqd->things_queued_ever), + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED), cq, deadline_millis, nullptr, @@ -985,7 +971,7 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, break; } - grpc_cq_completion* c = cq_event_queue_pop(&cqd->queue); + grpc_cq_completion* c = cqd->queue.Pop(); if (c != nullptr) { ret.type = GRPC_OP_COMPLETE; @@ -999,16 +985,16 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, so that the thread comes back quickly from poll to make a second attempt at popping. Not doing this can potentially deadlock this thread forever (if the deadline is infinity) */ - if (cq_event_queue_num_items(&cqd->queue) > 0) { + if (cqd->queue.num_items() > 0) { iteration_deadline = 0; } } - if (gpr_atm_acq_load(&cqd->pending_events) == 0) { + if (cqd->pending_events.Load(grpc_core::MemoryOrder::ACQUIRE) == 0) { /* Before returning, check if the queue has any items left over (since gpr_mpscq_pop() can sometimes return NULL even if the queue is not empty. If so, keep retrying but do not return GRPC_QUEUE_SHUTDOWN */ - if (cq_event_queue_num_items(&cqd->queue) > 0) { + if (cqd->queue.num_items() > 0) { /* Go to the beginning of the loop. No point doing a poll because (cq->shutdown == true) is only possible when there is no pending work (i.e cq->pending_events == 0) and any outstanding completion @@ -1049,8 +1035,8 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, is_finished_arg.first_loop = false; } - if (cq_event_queue_num_items(&cqd->queue) > 0 && - gpr_atm_acq_load(&cqd->pending_events) > 0) { + if (cqd->queue.num_items() > 0 && + cqd->pending_events.Load(grpc_core::MemoryOrder::ACQUIRE) > 0) { gpr_mu_lock(cq->mu); cq->poller_vtable->kick(POLLSET_FROM_CQ(cq), nullptr); gpr_mu_unlock(cq->mu); @@ -1074,7 +1060,7 @@ static void cq_finish_shutdown_next(grpc_completion_queue* cq) { cq_next_data* cqd = static_cast DATA_FROM_CQ(cq); GPR_ASSERT(cqd->shutdown_called); - GPR_ASSERT(gpr_atm_no_barrier_load(&cqd->pending_events) == 0); + GPR_ASSERT(cqd->pending_events.Load(grpc_core::MemoryOrder::RELAXED) == 0); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); } @@ -1096,10 +1082,10 @@ static void cq_shutdown_next(grpc_completion_queue* cq) { return; } cqd->shutdown_called = true; - /* Doing a full_fetch_add (i.e acq/release) here to match with + /* Doing acq/release FetchSub here to match with * cq_begin_op_for_next and cq_end_op_for_next functions which read/write * on this counter without necessarily holding a lock on cq */ - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { cq_finish_shutdown_next(cq); } gpr_mu_unlock(cq->mu); @@ -1148,12 +1134,12 @@ class ExecCtxPluck : public grpc_core::ExecCtx { GPR_ASSERT(a->stolen_completion == nullptr); gpr_atm current_last_seen_things_queued_ever = - gpr_atm_no_barrier_load(&cqd->things_queued_ever); + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED); if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) { gpr_mu_lock(cq->mu); a->last_seen_things_queued_ever = - gpr_atm_no_barrier_load(&cqd->things_queued_ever); + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED); grpc_cq_completion* c; grpc_cq_completion* prev = &cqd->completed_head; while ((c = (grpc_cq_completion*)(prev->next & @@ -1209,7 +1195,7 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, gpr_mu_lock(cq->mu); grpc_millis deadline_millis = grpc_timespec_to_millis_round_up(deadline); cq_is_finished_arg is_finished_arg = { - gpr_atm_no_barrier_load(&cqd->things_queued_ever), + cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED), cq, deadline_millis, nullptr, @@ -1246,7 +1232,7 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, } prev = c; } - if (gpr_atm_no_barrier_load(&cqd->shutdown)) { + if (cqd->shutdown.Load(grpc_core::MemoryOrder::RELAXED)) { gpr_mu_unlock(cq->mu); memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_SHUTDOWN; @@ -1309,8 +1295,8 @@ static void cq_finish_shutdown_pluck(grpc_completion_queue* cq) { cq_pluck_data* cqd = static_cast DATA_FROM_CQ(cq); GPR_ASSERT(cqd->shutdown_called); - GPR_ASSERT(!gpr_atm_no_barrier_load(&cqd->shutdown)); - gpr_atm_no_barrier_store(&cqd->shutdown, 1); + GPR_ASSERT(!cqd->shutdown.Load(grpc_core::MemoryOrder::RELAXED)); + cqd->shutdown.Store(1, grpc_core::MemoryOrder::RELAXED); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); } @@ -1334,7 +1320,7 @@ static void cq_shutdown_pluck(grpc_completion_queue* cq) { return; } cqd->shutdown_called = true; - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { cq_finish_shutdown_pluck(cq); } gpr_mu_unlock(cq->mu); @@ -1368,7 +1354,7 @@ static void cq_shutdown_callback(grpc_completion_queue* cq) { return; } cqd->shutdown_called = true; - if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) { gpr_mu_unlock(cq->mu); cq_finish_shutdown_callback(cq); } else { From 829455187c5ec75bd139a9d6c04399548f733237 Mon Sep 17 00:00:00 2001 From: Nikolai Lifanov Date: Fri, 22 Feb 2019 13:16:28 -0800 Subject: [PATCH 488/814] specify -stdlib=libc++ for darwin It's not the default with older Apple clang builds and without it c++11 features don't work on at least OS X 10.7: ./src/core/lib/gprpp/ref_counted.h:28:10: fatal error: 'atomic' file not found #include ^~~~~~~~ I manually tested it on macOS 10.11 image and there was not a regression. This should fix the "Artifact Build MacOS (internal CI)" test failure. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1992976198d..db6e2173da3 100644 --- a/setup.py +++ b/setup.py @@ -159,7 +159,7 @@ if EXTRA_ENV_COMPILE_ARGS is None: elif "linux" in sys.platform: EXTRA_ENV_COMPILE_ARGS += ' -std=gnu99 -fvisibility=hidden -fno-wrapv -fno-exceptions' elif "darwin" in sys.platform: - EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden -fno-wrapv -fno-exceptions' + EXTRA_ENV_COMPILE_ARGS += ' -stdlib=libc++ -fvisibility=hidden -fno-wrapv -fno-exceptions' EXTRA_ENV_COMPILE_ARGS += ' -DPB_FIELD_32BIT' if EXTRA_ENV_LINK_ARGS is None: From dc3aadb6a51075660fa598d67ba6926b5c7f7a30 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Fri, 22 Feb 2019 15:25:59 -0800 Subject: [PATCH 489/814] Revert "Fix-forward: avoid data race on detached thread deletion" --- src/core/lib/gprpp/thd.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index 5631c5f1f0e..0d94f2ec0c5 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -112,22 +112,19 @@ class Thread { } /// The destructor is strictly optional; either the thread never came to life - /// and the constructor itself killed it, or it has already been joined and - /// the Join function kills it, or it was detached (non-joinable) and it has - /// run to completion and is now killing itself. The destructor shouldn't have - /// to do anything. - ~Thread() { GPR_ASSERT(!options_.joinable() || impl_ == nullptr); } + /// and the constructor itself killed it or it has already been joined and + /// the Join function kills it. The destructor shouldn't have to do anything. + ~Thread() { GPR_ASSERT(impl_ == nullptr); } void Start() { if (impl_ != nullptr) { GPR_ASSERT(state_ == ALIVE); state_ = STARTED; impl_->Start(); - // If the Thread is not joinable, then the impl_ will cause the deletion - // of this Thread object when the thread function completes. Since no - // other operation is allowed to a detached thread after Start, there is - // no need to change the value of the impl_ or state_ . The next operation - // on this object will be the deletion, which will trigger the destructor. + if (!options_.joinable()) { + state_ = DONE; + impl_ = nullptr; + } } else { GPR_ASSERT(state_ == FAILED); } From 580b720a39abd83a0d32a6bca737331276de1757 Mon Sep 17 00:00:00 2001 From: Nikolai Lifanov Date: Fri, 22 Feb 2019 15:55:59 -0800 Subject: [PATCH 490/814] address comments by ericgribkoff@ o re-add USE_PREBUILT_GRPC_CORE option that was erroneously removed o fix typo in comment --- setup.py | 11 +++++++++-- src/python/grpcio/commands.py | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index db6e2173da3..1e205bdf91d 100644 --- a/setup.py +++ b/setup.py @@ -265,8 +265,15 @@ def cython_extensions_and_necessity(): for name in CYTHON_EXTENSION_MODULE_NAMES] config = os.environ.get('CONFIG', 'opt') prefix = 'libs/' + config + '/' - core_c_files = list(CORE_C_FILES) - extra_objects = [] + if USE_PREBUILT_GRPC_CORE: + extra_objects = [prefix + 'libares.a', + prefix + 'libboringssl.a', + prefix + 'libgpr.a', + prefix + 'libgrpc.a'] + core_c_files = [] + else: + core_c_files = list(CORE_C_FILES) + extra_objects = [] extensions = [ _extension.Extension( name=module_name, diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index 6b89a6a73a8..27b98362c11 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -215,7 +215,7 @@ class BuildExt(build_ext.build_ext): def compiler_ok_with_extra_std(): """Test if default compiler is okay with specifying c++ version - when invokec in C mode. GCC is okay with this, while clang is not. + when invoked in C mode. GCC is okay with this, while clang is not. """ cc_test = subprocess.Popen( ['cc', '-x', 'c', '-std=c++11', '-'], From e40177fad043af0a84392ace8a6cf577da50d4eb Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 22 Feb 2019 16:33:50 -0800 Subject: [PATCH 491/814] Make service config ref-counted and hold refs to it in LB config. --- .../filters/client_channel/client_channel.cc | 7 +- .../ext/filters/client_channel/lb_policy.h | 23 +++- .../client_channel/lb_policy/grpclb/grpclb.cc | 7 +- .../lb_policy/pick_first/pick_first.cc | 4 +- .../lb_policy/round_robin/round_robin.cc | 4 +- .../client_channel/lb_policy/xds/xds.cc | 106 ++++++++---------- .../client_channel/lb_policy_factory.h | 4 +- .../client_channel/resolver_result_parsing.cc | 3 +- .../client_channel/resolver_result_parsing.h | 9 +- .../client_channel/resolving_lb_policy.cc | 11 +- .../client_channel/resolving_lb_policy.h | 15 ++- .../ext/filters/client_channel/subchannel.cc | 2 +- .../message_size/message_size_filter.cc | 2 +- src/core/lib/transport/service_config.cc | 4 +- src/core/lib/transport/service_config.h | 8 +- test/core/util/test_lb_policies.cc | 25 ++--- 16 files changed, 123 insertions(+), 111 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 6de27369ea4..3566ef8fb35 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -249,10 +249,9 @@ class ClientChannelControlHelper // Synchronous callback from chand->resolving_lb_policy to process a resolver // result update. -static bool process_resolver_result_locked(void* arg, - const grpc_channel_args& args, - const char** lb_policy_name, - grpc_json** lb_policy_config) { +static bool process_resolver_result_locked( + void* arg, const grpc_channel_args& args, const char** lb_policy_name, + grpc_core::RefCountedPtr* lb_policy_config) { channel_data* chand = static_cast(arg); chand->have_service_config = true; ProcessedResolverResult resolver_result(args, chand->enable_retries); diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 20a94ed9ab9..5040ddc5047 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -30,6 +30,7 @@ #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/transport/connectivity_state.h" +#include "src/core/lib/transport/service_config.h" extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount; @@ -214,6 +215,23 @@ class LoadBalancingPolicy : public InternallyRefCounted { GRPC_ABSTRACT_BASE_CLASS }; + // Configuration for an LB policy instance. + class Config : public RefCounted { + public: + Config(const grpc_json* lb_config, + RefCountedPtr service_config) + : json_(lb_config), service_config_(std::move(service_config)) {} + + const grpc_json* json() const { return json_; } + RefCountedPtr service_config() const { + return service_config_; + } + + private: + const grpc_json* json_; + RefCountedPtr service_config_; + }; + /// Args used to instantiate an LB policy. struct Args { /// The combiner under which all LB policy calls will be run. @@ -243,7 +261,10 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. virtual void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) GRPC_ABSTRACT; + RefCountedPtr lb_config) { + std::move(lb_config); // Suppress clang-tidy complaint. + GRPC_ABSTRACT; + } /// Tries to enter a READY connectivity state. /// This is a no-op by default, since most LB policies never go into diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index ae5cfbca7a1..90398aac7f4 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -127,7 +127,7 @@ class GrpcLb : public LoadBalancingPolicy { const char* name() const override { return kGrpclb; } void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override; + RefCountedPtr lb_config) override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, @@ -1171,7 +1171,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // ctor and dtor // -GrpcLb::GrpcLb(LoadBalancingPolicy::Args args) +GrpcLb::GrpcLb(Args args) : LoadBalancingPolicy(std::move(args)), response_generator_(MakeRefCounted()), lb_call_backoff_( @@ -1321,7 +1321,8 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { grpc_channel_args_destroy(lb_channel_args); } -void GrpcLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { +void GrpcLb::UpdateLocked(const grpc_channel_args& args, + RefCountedPtr lb_config) { const bool is_initial_update = lb_channel_ == nullptr; ProcessChannelArgsLocked(args); // Update the existing RR policy. diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index e90e396936f..0ac0f41d4ef 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -51,7 +51,7 @@ class PickFirst : public LoadBalancingPolicy { const char* name() const override { return kPickFirst; } void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override; + RefCountedPtr lb_config) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -231,7 +231,7 @@ void PickFirst::UpdateChildRefsLocked() { } void PickFirst::UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) { + RefCountedPtr lb_config) { AutoChildRefsUpdater guard(this); const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); if (addresses == nullptr) { diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index b9250f92033..704a5c28c9e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -62,7 +62,7 @@ class RoundRobin : public LoadBalancingPolicy { const char* name() const override { return kRoundRobin; } void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override; + RefCountedPtr lb_config) override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* ignored) override; @@ -477,7 +477,7 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( } void RoundRobin::UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) { + RefCountedPtr lb_config) { AutoChildRefsUpdater guard(this); const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); if (addresses == nullptr) { diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 283e6bb5899..e1291da50af 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -122,7 +122,7 @@ class XdsLb : public LoadBalancingPolicy { const char* name() const override { return kXds; } void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override; + RefCountedPtr lb_config) override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, @@ -242,9 +242,9 @@ class XdsLb : public LoadBalancingPolicy { // Parses the xds config given the JSON node of the first child of XdsConfig. // If parsing succeeds, updates \a balancer_name, and updates \a - // child_policy_json_dump_ and \a fallback_policy_json_dump_ if they are also + // child_policy_config_ and \a fallback_policy_config_ if they are also // found. Does nothing upon failure. - void ParseLbConfig(grpc_json* xds_config_json); + void ParseLbConfig(Config* xds_config); // Methods for dealing with the balancer channel and call. void StartBalancerCallLocked(); @@ -303,7 +303,8 @@ class XdsLb : public LoadBalancingPolicy { // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. - UniquePtr fallback_policy_json_string_; + UniquePtr fallback_policy_name_; + RefCountedPtr fallback_policy_config_; int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. UniquePtr fallback_backend_addresses_; @@ -313,8 +314,9 @@ class XdsLb : public LoadBalancingPolicy { grpc_closure lb_on_fallback_; // The policy to use for the backends. + UniquePtr child_policy_name_; + RefCountedPtr child_policy_config_; OrphanablePtr child_policy_; - UniquePtr child_policy_json_string_; }; // @@ -952,8 +954,7 @@ grpc_channel_args* BuildBalancerChannelArgs( // ctor and dtor // -// TODO(vishalpowar): Use lb_config in args to configure LB policy. -XdsLb::XdsLb(LoadBalancingPolicy::Args args) +XdsLb::XdsLb(Args args) : LoadBalancingPolicy(std::move(args)), response_generator_(MakeRefCounted()), lb_call_backoff_( @@ -1087,11 +1088,12 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { grpc_channel_args_destroy(lb_channel_args); } -void XdsLb::ParseLbConfig(grpc_json* xds_config_json) { +void XdsLb::ParseLbConfig(Config* xds_config) { + const grpc_json* xds_config_json = xds_config->json(); const char* balancer_name = nullptr; grpc_json* child_policy = nullptr; grpc_json* fallback_policy = nullptr; - for (grpc_json* field = xds_config_json; field != nullptr; + for (const grpc_json* field = xds_config_json; field != nullptr; field = field->next) { if (field->key == nullptr) return; if (strcmp(field->key, "balancerName") == 0) { @@ -1108,19 +1110,22 @@ void XdsLb::ParseLbConfig(grpc_json* xds_config_json) { } if (balancer_name == nullptr) return; // Required field. if (child_policy != nullptr) { - child_policy_json_string_ = - UniquePtr(grpc_json_dump_to_string(child_policy, 0 /* indent */)); + child_policy_name_ = UniquePtr(gpr_strdup(child_policy->key)); + child_policy_config_ = MakeRefCounted(child_policy->child, + xds_config->service_config()); } if (fallback_policy != nullptr) { - fallback_policy_json_string_ = UniquePtr( - grpc_json_dump_to_string(fallback_policy, 0 /* indent */)); + fallback_policy_name_ = UniquePtr(gpr_strdup(fallback_policy->key)); + fallback_policy_config_ = MakeRefCounted( + fallback_policy->child, xds_config->service_config()); } balancer_name_ = UniquePtr(gpr_strdup(balancer_name)); } -void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) { +void XdsLb::UpdateLocked(const grpc_channel_args& args, + RefCountedPtr lb_config) { const bool is_initial_update = lb_channel_ == nullptr; - ParseLbConfig(lb_config); + ParseLbConfig(lb_config.get()); // TODO(juanlishen): Pass fallback policy config update after fallback policy // is added. if (balancer_name_ == nullptr) { @@ -1285,6 +1290,30 @@ void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg, // code for interacting with the child policy // +grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { + // This should never be invoked if we do not have serverlist_, as fallback + // mode is disabled for xDS plugin. + GPR_ASSERT(serverlist_ != nullptr); + GPR_ASSERT(serverlist_->num_servers > 0); + UniquePtr addresses = ProcessServerlist(serverlist_); + GPR_ASSERT(addresses != nullptr); + // Replace the server address list in the channel args that we pass down to + // the subchannel. + static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; + const grpc_arg args_to_add[] = { + CreateServerAddressListChannelArg(addresses.get()), + // A channel arg indicating if the target is a backend inferred from a + // grpclb load balancer. + grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_XDS_LOAD_BALANCER), + 1), + }; + grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( + args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, + GPR_ARRAY_SIZE(args_to_add)); + return args; +} + void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { GPR_ASSERT(child_policy_ == nullptr); child_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( @@ -1300,51 +1329,12 @@ void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { interested_parties()); } -grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { - bool is_backend_from_grpclb_load_balancer = false; - // This should never be invoked if we do not have serverlist_, as fallback - // mode is disabled for xDS plugin. - GPR_ASSERT(serverlist_ != nullptr); - GPR_ASSERT(serverlist_->num_servers > 0); - UniquePtr addresses = ProcessServerlist(serverlist_); - GPR_ASSERT(addresses != nullptr); - is_backend_from_grpclb_load_balancer = true; - // Replace the server address list in the channel args that we pass down to - // the subchannel. - static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; - const grpc_arg args_to_add[] = { - CreateServerAddressListChannelArg(addresses.get()), - // A channel arg indicating if the target is a backend inferred from a - // grpclb load balancer. - grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_XDS_LOAD_BALANCER), - is_backend_from_grpclb_load_balancer), - }; - grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( - args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, - GPR_ARRAY_SIZE(args_to_add)); - return args; -} - void XdsLb::CreateOrUpdateChildPolicyLocked() { if (shutting_down_) return; grpc_channel_args* args = CreateChildPolicyArgsLocked(); GPR_ASSERT(args != nullptr); - const char* child_policy_name = nullptr; - grpc_json* child_policy_config = nullptr; - grpc_json* child_policy_json = - grpc_json_parse_string(child_policy_json_string_.get()); // TODO(juanlishen): If the child policy is not configured via service config, // use whatever algorithm is specified by the balancer. - if (child_policy_json != nullptr) { - child_policy_name = child_policy_json->key; - child_policy_config = child_policy_json->child; - } else { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] No valid child policy LB config", this); - } - child_policy_name = "round_robin"; - } // TODO(juanlishen): Switch policy according to child_policy_config->key. if (child_policy_ == nullptr) { LoadBalancingPolicy::Args lb_policy_args; @@ -1352,7 +1342,10 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { lb_policy_args.args = args; lb_policy_args.channel_control_helper = UniquePtr(New(Ref())); - CreateChildPolicyLocked(child_policy_name, std::move(lb_policy_args)); + CreateChildPolicyLocked(child_policy_name_ == nullptr + ? "round_robin" + : child_policy_name_.get(), + std::move(lb_policy_args)); if (grpc_lb_xds_trace.enabled()) { gpr_log(GPR_INFO, "[xdslb %p] Created a new child policy %p", this, child_policy_.get()); @@ -1362,9 +1355,8 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { gpr_log(GPR_INFO, "[xdslb %p] Updating child policy %p", this, child_policy_.get()); } - child_policy_->UpdateLocked(*args, child_policy_config); + child_policy_->UpdateLocked(*args, child_policy_config_); grpc_channel_args_destroy(args); - grpc_json_destroy(child_policy_json); } // diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h index 770bcbeee5c..79503f2a562 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -33,9 +33,7 @@ class LoadBalancingPolicyFactory { virtual OrphanablePtr CreateLoadBalancingPolicy( LoadBalancingPolicy::Args args) const { std::move(args); // Suppress clang-tidy complaint. - // The rest of this is copied from the GRPC_ABSTRACT macro. - gpr_log(GPR_ERROR, "Function marked GRPC_ABSTRACT was not implemented"); - GPR_ASSERT(false); + GRPC_ABSTRACT; } /// Returns the LB policy name that this factory provides. diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 0af07dc4e64..aaa63178793 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -148,7 +148,8 @@ void ProcessedResolverResult::ParseLbConfigFromServiceConfig( LoadBalancingPolicy::ParseLoadBalancingConfig(field); if (policy != nullptr) { lb_policy_name_.reset(gpr_strdup(policy->key)); - lb_policy_config_ = policy->child; + lb_policy_config_ = MakeRefCounted( + policy->child, service_config_); } } diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 98a9d26c467..3bac45e7664 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -21,6 +21,7 @@ #include +#include "src/core/ext/filters/client_channel/lb_policy.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" #include "src/core/lib/channel/status_util.h" #include "src/core/lib/gprpp/ref_counted.h" @@ -60,7 +61,9 @@ class ProcessedResolverResult { return std::move(method_params_table_); } UniquePtr lb_policy_name() { return std::move(lb_policy_name_); } - grpc_json* lb_policy_config() { return lb_policy_config_; } + RefCountedPtr lb_policy_config() { + return std::move(lb_policy_config_); + } private: // Finds the service config; extracts LB config and (maybe) retry throttle @@ -82,10 +85,10 @@ class ProcessedResolverResult { // Service config. UniquePtr service_config_json_; - UniquePtr service_config_; + RefCountedPtr service_config_; // LB policy. - grpc_json* lb_policy_config_ = nullptr; UniquePtr lb_policy_name_; + RefCountedPtr lb_policy_config_; // Retry throttle data. char* server_name_ = nullptr; RefCountedPtr retry_throttle_data_; diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 22050cba59e..ba548c2b505 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -117,14 +117,13 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( Args args, TraceFlag* tracer, UniquePtr target_uri, - UniquePtr child_policy_name, grpc_json* child_lb_config, + UniquePtr child_policy_name, RefCountedPtr child_lb_config, grpc_error** error) : LoadBalancingPolicy(std::move(args)), tracer_(tracer), target_uri_(std::move(target_uri)), child_policy_name_(std::move(child_policy_name)), - child_lb_config_str_(grpc_json_dump_to_string(child_lb_config, 0)), - child_lb_config_(grpc_json_parse_string(child_lb_config_str_.get())) { + child_lb_config_(std::move(child_lb_config)) { GPR_ASSERT(child_policy_name_ != nullptr); // Don't fetch service config, since this ctor is for use in nested LB // policies, not at the top level, and we only fetch the service @@ -170,7 +169,6 @@ grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) { ResolvingLoadBalancingPolicy::~ResolvingLoadBalancingPolicy() { GPR_ASSERT(resolver_ == nullptr); GPR_ASSERT(lb_policy_ == nullptr); - grpc_json_destroy(child_lb_config_); } void ResolvingLoadBalancingPolicy::ShutdownLocked() { @@ -403,7 +401,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( } else { // Parse the resolver result. const char* lb_policy_name = nullptr; - grpc_json* lb_policy_config = nullptr; + RefCountedPtr lb_policy_config; bool service_config_changed = false; if (self->process_resolver_result_ != nullptr) { service_config_changed = self->process_resolver_result_( @@ -429,7 +427,8 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( gpr_log(GPR_INFO, "resolving_lb=%p: updating LB policy \"%s\" (%p)", self, lb_policy_name, self->lb_policy_.get()); } - self->lb_policy_->UpdateLocked(*self->resolver_result_, lb_policy_config); + self->lb_policy_->UpdateLocked(*self->resolver_result_, + std::move(lb_policy_config)); // Add channel trace event. if (self->channelz_node() != nullptr) { if (service_config_changed) { diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index 19ca62fc556..d068a41f96f 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -56,17 +56,17 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ResolvingLoadBalancingPolicy(Args args, TraceFlag* tracer, UniquePtr target_uri, UniquePtr child_policy_name, - grpc_json* child_lb_config, grpc_error** error); + RefCountedPtr child_lb_config, + grpc_error** error); // Private ctor, to be used by client_channel only! // // Synchronous callback that takes the resolver result and sets // lb_policy_name and lb_policy_config to point to the right data. // Returns true if the service config has changed since the last result. - typedef bool (*ProcessResolverResultCallback)(void* user_data, - const grpc_channel_args& args, - const char** lb_policy_name, - grpc_json** lb_policy_config); + typedef bool (*ProcessResolverResultCallback)( + void* user_data, const grpc_channel_args& args, + const char** lb_policy_name, RefCountedPtr* lb_policy_config); // If error is set when this returns, then construction failed, and // the caller may not use the new object. ResolvingLoadBalancingPolicy( @@ -80,7 +80,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // TODO(roth): Need to support updating child LB policy's config for xds // use case. void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override {} + RefCountedPtr lb_config) override {} void ExitIdleLocked() override; @@ -116,8 +116,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ProcessResolverResultCallback process_resolver_result_ = nullptr; void* process_resolver_result_user_data_ = nullptr; UniquePtr child_policy_name_; - UniquePtr child_lb_config_str_; - grpc_json* child_lb_config_ = nullptr; + RefCountedPtr child_lb_config_; // Resolver and associated state. OrphanablePtr resolver_; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index e2e19a32fd6..f795901b15b 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -590,7 +590,7 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, const char* service_config_json = grpc_channel_arg_get_string( grpc_channel_args_find(args_, GRPC_ARG_SERVICE_CONFIG)); if (service_config_json != nullptr) { - UniquePtr service_config = + RefCountedPtr service_config = ServiceConfig::Create(service_config_json); if (service_config != nullptr) { HealthCheckParams params; diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index 94d6942aa4f..e41496789be 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -319,7 +319,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG); const char* service_config_str = grpc_channel_arg_get_string(channel_arg); if (service_config_str != nullptr) { - grpc_core::UniquePtr service_config = + grpc_core::RefCountedPtr service_config = grpc_core::ServiceConfig::Create(service_config_str); if (service_config != nullptr) { chand->method_limit_table = service_config->CreateMethodConfigTable( diff --git a/src/core/lib/transport/service_config.cc b/src/core/lib/transport/service_config.cc index 405e3360287..713c1796439 100644 --- a/src/core/lib/transport/service_config.cc +++ b/src/core/lib/transport/service_config.cc @@ -33,14 +33,14 @@ namespace grpc_core { -UniquePtr ServiceConfig::Create(const char* json) { +RefCountedPtr ServiceConfig::Create(const char* json) { UniquePtr json_string(gpr_strdup(json)); grpc_json* json_tree = grpc_json_parse_string(json_string.get()); if (json_tree == nullptr) { gpr_log(GPR_INFO, "failed to parse JSON for service config"); return nullptr; } - return MakeUnique(std::move(json_string), json_tree); + return MakeRefCounted(std::move(json_string), json_tree); } ServiceConfig::ServiceConfig(UniquePtr json_string, grpc_json* json_tree) diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h index 0d78016ab05..af24501e3df 100644 --- a/src/core/lib/transport/service_config.h +++ b/src/core/lib/transport/service_config.h @@ -23,6 +23,7 @@ #include #include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/json/json.h" #include "src/core/lib/slice/slice_hash_table.h" @@ -41,8 +42,7 @@ // } // ], // // remaining fields are optional. -// // see -// https://developers.google.com/protocol-buffers/docs/proto3#json +// // see https://developers.google.com/protocol-buffers/docs/proto3#json // // for format details. // "waitForReady": bool, // "timeout": "duration_string", @@ -54,11 +54,11 @@ namespace grpc_core { -class ServiceConfig { +class ServiceConfig : public RefCounted { public: /// Creates a new service config from parsing \a json_string. /// Returns null on parse error. - static UniquePtr Create(const char* json); + static RefCountedPtr Create(const char* json); ~ServiceConfig(); diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index bfdd7441563..0a01e483f13 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -65,8 +65,8 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { ~ForwardingLoadBalancingPolicy() override = default; void UpdateLocked(const grpc_channel_args& args, - grpc_json* lb_config) override { - delegate_->UpdateLocked(args, lb_config); + RefCountedPtr lb_config) override { + delegate_->UpdateLocked(args, std::move(lb_config)); } void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } @@ -102,7 +102,8 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy RefCountedPtr( this), cb, user_data)), - std::move(args), /*delegate_lb_policy_name=*/"pick_first", + std::move(args), + /*delegate_lb_policy_name=*/"pick_first", /*initial_refcount=*/2) {} ~InterceptRecvTrailingMetadataLoadBalancingPolicy() override = default; @@ -210,12 +211,11 @@ class InterceptTrailingFactory : public LoadBalancingPolicyFactory { void* user_data) : cb_(cb), user_data_(user_data) {} - grpc_core::OrphanablePtr - CreateLoadBalancingPolicy( - grpc_core::LoadBalancingPolicy::Args args) const override { - return grpc_core::OrphanablePtr( - grpc_core::New( - std::move(args), cb_, user_data_)); + OrphanablePtr CreateLoadBalancingPolicy( + LoadBalancingPolicy::Args args) const override { + return OrphanablePtr( + New(std::move(args), + cb_, user_data_)); } const char* name() const override { @@ -231,10 +231,9 @@ class InterceptTrailingFactory : public LoadBalancingPolicyFactory { void RegisterInterceptRecvTrailingMetadataLoadBalancingPolicy( InterceptRecvTrailingMetadataCallback cb, void* user_data) { - grpc_core::LoadBalancingPolicyRegistry::Builder:: - RegisterLoadBalancingPolicyFactory( - grpc_core::UniquePtr( - grpc_core::New(cb, user_data))); + LoadBalancingPolicyRegistry::Builder::RegisterLoadBalancingPolicyFactory( + UniquePtr( + New(cb, user_data))); } } // namespace grpc_core From 4bc2ca4de6c5622483a13664a13bade1485ebe38 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Fri, 22 Feb 2019 16:34:24 -0800 Subject: [PATCH 492/814] Revert "Move grpc_shutdown internals to a detached thread" --- grpc.def | 1 - include/grpc/grpc.h | 13 +-- src/core/lib/debug/trace.h | 3 +- src/core/lib/gprpp/thd.h | 40 +------ src/core/lib/gprpp/thd_posix.cc | 44 +++---- src/core/lib/gprpp/thd_windows.cc | 54 +++------ src/core/lib/surface/init.cc | 108 +++++------------- src/core/lib/surface/init.h | 1 - src/php/ext/grpc/php_grpc.c | 2 +- .../grpcio/grpc/_cython/_cygrpc/call.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/channel.pyx.pxi | 2 +- .../_cython/_cygrpc/completion_queue.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/credentials.pyx.pxi | 8 +- .../grpcio/grpc/_cython/_cygrpc/grpc.pxi | 2 +- .../grpc/_cython/_cygrpc/records.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/server.pyx.pxi | 2 +- src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 - src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 - .../resolvers/dns_resolver_cooldown_test.cc | 3 +- test/core/end2end/fuzzers/api_fuzzer.cc | 2 +- test/core/end2end/fuzzers/client_fuzzer.cc | 10 +- test/core/end2end/fuzzers/server_fuzzer.cc | 8 +- .../readahead_handshaker_server_ssl.cc | 2 +- test/core/iomgr/resolve_address_test.cc | 14 +-- test/core/json/fuzzer.cc | 6 +- test/core/memory_usage/client.cc | 2 +- test/core/memory_usage/server.cc | 2 +- test/core/security/alts_credentials_fuzzer.cc | 10 +- test/core/security/ssl_server_fuzzer.cc | 10 +- test/core/slice/percent_decode_fuzzer.cc | 33 +++--- test/core/slice/percent_encode_fuzzer.cc | 40 ++++--- test/core/surface/init_test.cc | 21 +--- .../core/surface/public_headers_must_be_c89.c | 1 - test/core/util/memory_counters.cc | 31 ----- test/core/util/memory_counters.h | 18 --- test/core/util/port.cc | 2 +- test/core/util/test_config.cc | 3 +- test/cpp/naming/address_sorting_test.cc | 2 +- test/cpp/util/grpc_tool_test.cc | 16 ++- 39 files changed, 183 insertions(+), 344 deletions(-) diff --git a/grpc.def b/grpc.def index e0a08d22c19..59e29e0d168 100644 --- a/grpc.def +++ b/grpc.def @@ -16,7 +16,6 @@ EXPORTS grpc_init grpc_shutdown grpc_is_initialized - grpc_shutdown_blocking grpc_version_string grpc_g_stands_for grpc_completion_queue_factory_lookup diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index c4715ccc05e..fec7f5269e1 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -73,11 +73,10 @@ GRPCAPI void grpc_init(void); Before it's called, there should haven been a matching invocation to grpc_init(). - The last call to grpc_shutdown will initiate cleaning up of grpc library - internals, which can happen in another thread. Once the clean-up is done, - no memory is used by grpc, nor are any instructions executing within the - grpc library. Prior to calling, all application owned grpc objects must - have been destroyed. */ + No memory is used by grpc after this call returns, nor are any instructions + executing within the grpc library. + Prior to calling, all application owned grpc objects must have been + destroyed. */ GRPCAPI void grpc_shutdown(void); /** EXPERIMENTAL. Returns 1 if the grpc library has been initialized. @@ -86,10 +85,6 @@ GRPCAPI void grpc_shutdown(void); https://github.com/grpc/grpc/issues/15334 */ GRPCAPI int grpc_is_initialized(void); -/** EXPERIMENTAL. Blocking shut down grpc library. - This is only for wrapped language to use now. */ -GRPCAPI void grpc_shutdown_blocking(void); - /** Return a string representing the current version of grpc */ GRPCAPI const char* grpc_version_string(void); diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h index 6108fb239bd..4623494520e 100644 --- a/src/core/lib/debug/trace.h +++ b/src/core/lib/debug/trace.h @@ -53,8 +53,7 @@ void grpc_tracer_enable_flag(grpc_core::TraceFlag* flag); class TraceFlag { public: TraceFlag(bool default_enabled, const char* name); - // TraceFlag needs to be trivially destructible since it is used as global - // variable. + // This needs to be trivially destructible as it is used as global variable. ~TraceFlag() = default; const char* name() const { return name_; } diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index 0d94f2ec0c5..e61e1c8ed04 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -47,27 +47,6 @@ class ThreadInternalsInterface { class Thread { public: - class Options { - public: - Options() : joinable_(true), tracked_(true) {} - /// Set whether the thread is joinable or detached. - Options& set_joinable(bool joinable) { - joinable_ = joinable; - return *this; - } - bool joinable() const { return joinable_; } - - /// Set whether the thread is tracked for fork support. - Options& set_tracked(bool tracked) { - tracked_ = tracked; - return *this; - } - bool tracked() const { return tracked_; } - - private: - bool joinable_; - bool tracked_; - }; /// Default constructor only to allow use in structs that lack constructors /// Does not produce a validly-constructed thread; must later /// use placement new to construct a real thread. Does not init mu_ and cv_ @@ -78,17 +57,14 @@ class Thread { /// with argument \a arg once it is started. /// The optional \a success argument indicates whether the thread /// is successfully created. - /// The optional \a options can be used to set the thread detachable. Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success = nullptr, const Options& options = Options()); + bool* success = nullptr); /// Move constructor for thread. After this is called, the other thread /// no longer represents a living thread object - Thread(Thread&& other) - : state_(other.state_), impl_(other.impl_), options_(other.options_) { + Thread(Thread&& other) : state_(other.state_), impl_(other.impl_) { other.state_ = MOVED; other.impl_ = nullptr; - other.options_ = Options(); } /// Move assignment operator for thread. After this is called, the other @@ -103,10 +79,8 @@ class Thread { // assert it for the time being. state_ = other.state_; impl_ = other.impl_; - options_ = other.options_; other.state_ = MOVED; other.impl_ = nullptr; - other.options_ = Options(); } return *this; } @@ -121,16 +95,11 @@ class Thread { GPR_ASSERT(state_ == ALIVE); state_ = STARTED; impl_->Start(); - if (!options_.joinable()) { - state_ = DONE; - impl_ = nullptr; - } } else { GPR_ASSERT(state_ == FAILED); } - } + }; - // It is only legal to call Join if the Thread is created as joinable. void Join() { if (impl_ != nullptr) { impl_->Join(); @@ -150,13 +119,12 @@ class Thread { /// FAKE -- just a dummy placeholder Thread created by the default constructor /// ALIVE -- an actual thread of control exists associated with this thread /// STARTED -- the thread of control has been started - /// DONE -- the thread of control has completed and been joined/detached + /// DONE -- the thread of control has completed and been joined /// FAILED -- the thread of control never came alive /// MOVED -- contents were moved out and we're no longer tracking them enum ThreadState { FAKE, ALIVE, STARTED, DONE, FAILED, MOVED }; ThreadState state_; internal::ThreadInternalsInterface* impl_; - Options options_; }; } // namespace grpc_core diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 28932081538..2751b221a8f 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -44,14 +44,13 @@ struct thd_arg { void (*body)(void* arg); /* body of a thread */ void* arg; /* argument to a thread */ const char* name; /* name of thread. Can be nullptr. */ - bool joinable; - bool tracked; }; -class ThreadInternalsPosix : public internal::ThreadInternalsInterface { +class ThreadInternalsPosix + : public grpc_core::internal::ThreadInternalsInterface { public: ThreadInternalsPosix(const char* thd_name, void (*thd_body)(void* arg), - void* arg, bool* success, const Thread::Options& options) + void* arg, bool* success) : started_(false) { gpr_mu_init(&mu_); gpr_cv_init(&ready_); @@ -64,20 +63,11 @@ class ThreadInternalsPosix : public internal::ThreadInternalsInterface { info->body = thd_body; info->arg = arg; info->name = thd_name; - info->joinable = options.joinable(); - info->tracked = options.tracked(); - if (options.tracked()) { - Fork::IncThreadCount(); - } + grpc_core::Fork::IncThreadCount(); GPR_ASSERT(pthread_attr_init(&attr) == 0); - if (options.joinable()) { - GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == - 0); - } else { - GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == - 0); - } + GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == + 0); *success = (pthread_create(&pthread_id_, &attr, @@ -107,14 +97,8 @@ class ThreadInternalsPosix : public internal::ThreadInternalsInterface { } gpr_mu_unlock(&arg.thread->mu_); - if (!arg.joinable) { - Delete(arg.thread); - } - (*arg.body)(arg.arg); - if (arg.tracked) { - Fork::DecThreadCount(); - } + grpc_core::Fork::DecThreadCount(); return nullptr; }, info) == 0); @@ -124,11 +108,9 @@ class ThreadInternalsPosix : public internal::ThreadInternalsInterface { if (!(*success)) { /* don't use gpr_free, as this was allocated using malloc (see above) */ free(info); - if (options.tracked()) { - Fork::DecThreadCount(); - } + grpc_core::Fork::DecThreadCount(); } - } + }; ~ThreadInternalsPosix() override { gpr_mu_destroy(&mu_); @@ -154,15 +136,15 @@ class ThreadInternalsPosix : public internal::ThreadInternalsInterface { } // namespace Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success, const Options& options) - : options_(options) { + bool* success) { bool outcome = false; - impl_ = New(thd_name, thd_body, arg, &outcome, options); + impl_ = + grpc_core::New(thd_name, thd_body, arg, &outcome); if (outcome) { state_ = ALIVE; } else { state_ = FAILED; - Delete(impl_); + grpc_core::Delete(impl_); impl_ = nullptr; } diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index bbb48a58cd6..2512002a96c 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -46,7 +46,6 @@ struct thd_info { void (*body)(void* arg); /* body of a thread */ void* arg; /* argument to a thread */ HANDLE join_event; /* the join event */ - bool joinable; /* whether it is joinable */ }; thread_local struct thd_info* g_thd_info; @@ -54,8 +53,7 @@ thread_local struct thd_info* g_thd_info; class ThreadInternalsWindows : public grpc_core::internal::ThreadInternalsInterface { public: - ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success, - const grpc_core::Thread::Options& options) + ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success) : started_(false) { gpr_mu_init(&mu_); gpr_cv_init(&ready_); @@ -65,23 +63,20 @@ class ThreadInternalsWindows info_->thread = this; info_->body = thd_body; info_->arg = arg; - info_->join_event = nullptr; - info_->joinable = options.joinable(); - if (info_->joinable) { - info_->join_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (info_->join_event == nullptr) { - gpr_free(info_); - *success = false; - return; - } - } - handle = CreateThread(nullptr, 64 * 1024, thread_body, info_, 0, nullptr); - if (handle == nullptr) { - destroy_thread(); + + info_->join_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + if (info_->join_event == nullptr) { + gpr_free(info_); *success = false; } else { - CloseHandle(handle); - *success = true; + handle = CreateThread(nullptr, 64 * 1024, thread_body, info_, 0, nullptr); + if (handle == nullptr) { + destroy_thread(); + *success = false; + } else { + CloseHandle(handle); + *success = true; + } } } @@ -112,24 +107,14 @@ class ThreadInternalsWindows gpr_inf_future(GPR_CLOCK_MONOTONIC)); } gpr_mu_unlock(&g_thd_info->thread->mu_); - if (!g_thd_info->joinable) { - grpc_core::Delete(g_thd_info->thread); - g_thd_info->thread = nullptr; - } g_thd_info->body(g_thd_info->arg); - if (g_thd_info->joinable) { - BOOL ret = SetEvent(g_thd_info->join_event); - GPR_ASSERT(ret); - } else { - gpr_free(g_thd_info); - } + BOOL ret = SetEvent(g_thd_info->join_event); + GPR_ASSERT(ret); return 0; } void destroy_thread() { - if (info_ != nullptr && info_->joinable) { - CloseHandle(info_->join_event); - } + CloseHandle(info_->join_event); gpr_free(info_); } @@ -144,15 +129,14 @@ class ThreadInternalsWindows namespace grpc_core { Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success, const Options& options) - : options_(options) { + bool* success) { bool outcome = false; - impl_ = New(thd_body, arg, &outcome, options); + impl_ = grpc_core::New(thd_body, arg, &outcome); if (outcome) { state_ = ALIVE; } else { state_ = FAILED; - Delete(impl_); + grpc_core::Delete(impl_); impl_ = nullptr; } diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index fdb584da68f..e507de87c2a 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -33,7 +33,6 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/fork.h" -#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/call_combiner.h" #include "src/core/lib/iomgr/combiner.h" @@ -62,15 +61,10 @@ extern void grpc_register_built_in_plugins(void); static gpr_once g_basic_init = GPR_ONCE_INIT; static gpr_mu g_init_mu; static int g_initializations; -static gpr_cv* g_shutting_down_cv; -static bool g_shutting_down; static void do_basic_init(void) { gpr_log_verbosity_init(); gpr_mu_init(&g_init_mu); - g_shutting_down_cv = static_cast(malloc(sizeof(gpr_cv))); - gpr_cv_init(g_shutting_down_cv); - g_shutting_down = false; grpc_register_built_in_plugins(); grpc_cq_global_init(); g_initializations = 0; @@ -124,12 +118,8 @@ void grpc_init(void) { int i; gpr_once_init(&g_basic_init, do_basic_init); - grpc_core::MutexLock lock(&g_init_mu); + gpr_mu_lock(&g_init_mu); if (++g_initializations == 1) { - if (g_shutting_down) { - g_shutting_down = false; - gpr_cv_broadcast(g_shutting_down_cv); - } grpc_core::Fork::GlobalInit(); grpc_fork_handlers_auto_register(); gpr_time_init(); @@ -160,88 +150,50 @@ void grpc_init(void) { grpc_channel_init_finalize(); grpc_iomgr_start(); } + gpr_mu_unlock(&g_init_mu); GRPC_API_TRACE("grpc_init(void)", 0, ()); } -void grpc_shutdown_internal_locked(void) { +void grpc_shutdown(void) { int i; - { - grpc_core::ExecCtx exec_ctx(0); - grpc_iomgr_shutdown_background_closure(); + GRPC_API_TRACE("grpc_shutdown(void)", 0, ()); + gpr_mu_lock(&g_init_mu); + if (--g_initializations == 0) { { - grpc_timer_manager_set_threading(false); // shutdown timer_manager thread - grpc_core::Executor::ShutdownAll(); - for (i = g_number_of_plugins; i >= 0; i--) { - if (g_all_of_the_plugins[i].destroy != nullptr) { - g_all_of_the_plugins[i].destroy(); + grpc_core::ExecCtx exec_ctx(0); + grpc_iomgr_shutdown_background_closure(); + { + grpc_timer_manager_set_threading( + false); // shutdown timer_manager thread + grpc_core::Executor::ShutdownAll(); + for (i = g_number_of_plugins; i >= 0; i--) { + if (g_all_of_the_plugins[i].destroy != nullptr) { + g_all_of_the_plugins[i].destroy(); + } } } + grpc_iomgr_shutdown(); + gpr_timers_global_destroy(); + grpc_tracer_shutdown(); + grpc_mdctx_global_shutdown(); + grpc_core::HandshakerRegistry::Shutdown(); + grpc_slice_intern_shutdown(); + grpc_core::channelz::ChannelzRegistry::Shutdown(); + grpc_stats_shutdown(); + grpc_core::Fork::GlobalShutdown(); } - grpc_iomgr_shutdown(); - gpr_timers_global_destroy(); - grpc_tracer_shutdown(); - grpc_mdctx_global_shutdown(); - grpc_core::HandshakerRegistry::Shutdown(); - grpc_slice_intern_shutdown(); - grpc_core::channelz::ChannelzRegistry::Shutdown(); - grpc_stats_shutdown(); - grpc_core::Fork::GlobalShutdown(); - } - grpc_core::ExecCtx::GlobalShutdown(); - grpc_core::ApplicationCallbackExecCtx::GlobalShutdown(); - g_shutting_down = false; - gpr_cv_broadcast(g_shutting_down_cv); -} - -void grpc_shutdown_internal(void* ignored) { - GRPC_API_TRACE("grpc_shutdown_internal", 0, ()); - grpc_core::MutexLock lock(&g_init_mu); - // We have released lock from the shutdown thread and it is possible that - // another grpc_init has been called, and do nothing if that is the case. - if (--g_initializations != 0) { - return; - } - grpc_shutdown_internal_locked(); -} - -void grpc_shutdown(void) { - GRPC_API_TRACE("grpc_shutdown(void)", 0, ()); - grpc_core::MutexLock lock(&g_init_mu); - if (--g_initializations == 0) { - g_initializations++; - g_shutting_down = true; - // spawn a detached thread to do the actual clean up in case we are - // currently in an executor thread. - grpc_core::Thread cleanup_thread( - "grpc_shutdown", grpc_shutdown_internal, nullptr, nullptr, - grpc_core::Thread::Options().set_joinable(false).set_tracked(false)); - cleanup_thread.Start(); - } -} - -void grpc_shutdown_blocking(void) { - GRPC_API_TRACE("grpc_shutdown_blocking(void)", 0, ()); - grpc_core::MutexLock lock(&g_init_mu); - if (--g_initializations == 0) { - g_shutting_down = true; - grpc_shutdown_internal_locked(); + grpc_core::ExecCtx::GlobalShutdown(); + grpc_core::ApplicationCallbackExecCtx::GlobalShutdown(); } + gpr_mu_unlock(&g_init_mu); } int grpc_is_initialized(void) { int r; gpr_once_init(&g_basic_init, do_basic_init); - grpc_core::MutexLock lock(&g_init_mu); + gpr_mu_lock(&g_init_mu); r = g_initializations > 0; + gpr_mu_unlock(&g_init_mu); return r; } - -void grpc_maybe_wait_for_async_shutdown(void) { - gpr_once_init(&g_basic_init, do_basic_init); - grpc_core::MutexLock lock(&g_init_mu); - while (g_shutting_down) { - gpr_cv_wait(g_shutting_down_cv, &g_init_mu, - gpr_inf_future(GPR_CLOCK_REALTIME)); - } -} diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 6eaa488d054..193f51447d9 100644 --- a/src/core/lib/surface/init.h +++ b/src/core/lib/surface/init.h @@ -22,6 +22,5 @@ void grpc_register_security_filters(void); void grpc_security_pre_init(void); void grpc_security_init(void); -void grpc_maybe_wait_for_async_shutdown(void); #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index fa6f0be837b..111c6f4867d 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -361,7 +361,7 @@ PHP_MSHUTDOWN_FUNCTION(grpc) { zend_hash_destroy(&grpc_target_upper_bound_map); grpc_shutdown_timeval(TSRMLS_C); grpc_php_shutdown_completion_queue(TSRMLS_C); - grpc_shutdown_blocking(); + grpc_shutdown(); GRPC_G(initialized) = 0; } return SUCCESS; diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi index 0a31d9c52ff..24e85b08e72 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi @@ -87,7 +87,7 @@ cdef class Call: def __dealloc__(self): if self.c_call != NULL: grpc_call_unref(self.c_call) - grpc_shutdown_blocking() + grpc_shutdown() # The object *should* always be valid from Python. Used for debugging. @property diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index 24c11e63a6b..70d4abb7308 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -399,7 +399,7 @@ cdef _close(Channel channel, grpc_status_code code, object details, _destroy_c_completion_queue(state.c_connectivity_completion_queue) grpc_channel_destroy(state.c_channel) state.c_channel = NULL - grpc_shutdown_blocking() + grpc_shutdown() state.condition.notify_all() else: # Another call to close already completed in the past or is currently diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi index a4d425ac564..3c33b46dbb8 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -118,4 +118,4 @@ cdef class CompletionQueue: self.c_completion_queue, c_deadline, NULL) self._interpret_event(event) grpc_completion_queue_destroy(self.c_completion_queue) - grpc_shutdown_blocking() + grpc_shutdown() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 5fb9ddf7b7d..2f51be40ce4 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -61,7 +61,7 @@ cdef int _get_metadata( cdef void _destroy(void *state) with gil: cpython.Py_DECREF(state) - grpc_shutdown_blocking() + grpc_shutdown() cdef class MetadataPluginCallCredentials(CallCredentials): @@ -125,7 +125,7 @@ cdef class SSLSessionCacheLRU: def __dealloc__(self): if self._cache != NULL: grpc_ssl_session_cache_destroy(self._cache) - grpc_shutdown_blocking() + grpc_shutdown() cdef class SSLChannelCredentials(ChannelCredentials): @@ -191,7 +191,7 @@ cdef class ServerCertificateConfig: def __dealloc__(self): grpc_ssl_server_certificate_config_destroy(self.c_cert_config) gpr_free(self.c_ssl_pem_key_cert_pairs) - grpc_shutdown_blocking() + grpc_shutdown() cdef class ServerCredentials: @@ -207,7 +207,7 @@ cdef class ServerCredentials: def __dealloc__(self): if self.c_credentials != NULL: grpc_server_credentials_release(self.c_credentials) - grpc_shutdown_blocking() + grpc_shutdown() cdef const char* _get_c_pem_root_certs(pem_root_certs): if pem_root_certs is None: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 759479089d4..fc7a9ba4395 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -319,7 +319,7 @@ cdef extern from "grpc/grpc.h": grpc_op_data data void grpc_init() nogil - void grpc_shutdown_blocking() nogil + void grpc_shutdown() nogil int grpc_is_initialized() nogil ctypedef struct grpc_completion_queue_factory: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index d612199a482..fe98d559f34 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -134,7 +134,7 @@ cdef class CallDetails: def __dealloc__(self): with nogil: grpc_call_details_destroy(&self.c_details) - grpc_shutdown_blocking() + grpc_shutdown() @property def method(self): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index fe55ea885e4..ef74f61e043 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -151,4 +151,4 @@ cdef class Server: def __dealloc__(self): if self.c_server == NULL: - grpc_shutdown_blocking() + grpc_shutdown() diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index fdbe0df4e52..47250ec7141 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -39,7 +39,6 @@ grpc_register_plugin_type grpc_register_plugin_import; grpc_init_type grpc_init_import; grpc_shutdown_type grpc_shutdown_import; grpc_is_initialized_type grpc_is_initialized_import; -grpc_shutdown_blocking_type grpc_shutdown_blocking_import; grpc_version_string_type grpc_version_string_import; grpc_g_stands_for_type grpc_g_stands_for_import; grpc_completion_queue_factory_lookup_type grpc_completion_queue_factory_lookup_import; @@ -307,7 +306,6 @@ void grpc_rb_load_imports(HMODULE library) { grpc_init_import = (grpc_init_type) GetProcAddress(library, "grpc_init"); grpc_shutdown_import = (grpc_shutdown_type) GetProcAddress(library, "grpc_shutdown"); grpc_is_initialized_import = (grpc_is_initialized_type) GetProcAddress(library, "grpc_is_initialized"); - grpc_shutdown_blocking_import = (grpc_shutdown_blocking_type) GetProcAddress(library, "grpc_shutdown_blocking"); grpc_version_string_import = (grpc_version_string_type) GetProcAddress(library, "grpc_version_string"); grpc_g_stands_for_import = (grpc_g_stands_for_type) GetProcAddress(library, "grpc_g_stands_for"); grpc_completion_queue_factory_lookup_import = (grpc_completion_queue_factory_lookup_type) GetProcAddress(library, "grpc_completion_queue_factory_lookup"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index cf16f0ca33b..9437f6d3918 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -92,9 +92,6 @@ extern grpc_shutdown_type grpc_shutdown_import; typedef int(*grpc_is_initialized_type)(void); extern grpc_is_initialized_type grpc_is_initialized_import; #define grpc_is_initialized grpc_is_initialized_import -typedef void(*grpc_shutdown_blocking_type)(void); -extern grpc_shutdown_blocking_type grpc_shutdown_blocking_import; -#define grpc_shutdown_blocking grpc_shutdown_blocking_import typedef const char*(*grpc_version_string_type)(void); extern grpc_version_string_type grpc_version_string_import; #define grpc_version_string grpc_version_string_import diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index 3157d6019f3..16210b8164b 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -18,7 +18,6 @@ #include -#include #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" @@ -282,7 +281,7 @@ int main(int argc, char** argv) { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); } - grpc_shutdown_blocking(); + grpc_shutdown(); GPR_ASSERT(g_all_callbacks_invoked); return 0; } diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index 74a30913b24..57bc8ad768c 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -1200,6 +1200,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_resource_quota_unref(g_resource_quota); - grpc_shutdown_blocking(); + grpc_shutdown(); return 0; } diff --git a/test/core/end2end/fuzzers/client_fuzzer.cc b/test/core/end2end/fuzzers/client_fuzzer.cc index 55e6ce695ad..8520fb53755 100644 --- a/test/core/end2end/fuzzers/client_fuzzer.cc +++ b/test/core/end2end/fuzzers/client_fuzzer.cc @@ -40,8 +40,9 @@ static void dont_log(gpr_log_func_args* args) {} extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_test_only_set_slice_hash_seed(0); + struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - grpc_core::testing::LeakDetector leak_detector(leak_check); + if (leak_check) grpc_memory_counters_init(); grpc_init(); { grpc_core::ExecCtx exec_ctx; @@ -158,6 +159,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_byte_buffer_destroy(response_payload_recv); } } - grpc_shutdown_blocking(); + grpc_shutdown(); + if (leak_check) { + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + GPR_ASSERT(counters.total_size_relative == 0); + } return 0; } diff --git a/test/core/end2end/fuzzers/server_fuzzer.cc b/test/core/end2end/fuzzers/server_fuzzer.cc index f010066ea27..644f98e37ac 100644 --- a/test/core/end2end/fuzzers/server_fuzzer.cc +++ b/test/core/end2end/fuzzers/server_fuzzer.cc @@ -37,8 +37,9 @@ static void dont_log(gpr_log_func_args* args) {} extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_test_only_set_slice_hash_seed(0); + struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - grpc_core::testing::LeakDetector leak_detector(leak_check); + if (leak_check) grpc_memory_counters_init(); grpc_init(); { grpc_core::ExecCtx exec_ctx; @@ -135,5 +136,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_completion_queue_destroy(cq); } grpc_shutdown(); + if (leak_check) { + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + GPR_ASSERT(counters.total_size_relative == 0); + } return 0; } diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc index d91f2d2fe63..e4584105e65 100644 --- a/test/core/handshake/readahead_handshaker_server_ssl.cc +++ b/test/core/handshake/readahead_handshaker_server_ssl.cc @@ -83,6 +83,6 @@ int main(int argc, char* argv[]) { UniquePtr(New())); const char* full_alpn_list[] = {"grpc-exp", "h2"}; GPR_ASSERT(server_ssl_test(full_alpn_list, 2, "grpc-exp")); - grpc_shutdown_blocking(); + grpc_shutdown(); return 0; } diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index f59a992416d..b041a15ff34 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -323,11 +323,7 @@ static bool mock_ipv6_disabled_source_addr_factory_get_source_addr( } void mock_ipv6_disabled_source_addr_factory_destroy( - address_sorting_source_addr_factory* factory) { - mock_ipv6_disabled_source_addr_factory* f = - reinterpret_cast(factory); - gpr_free(f); -} + address_sorting_source_addr_factory* factory) {} const address_sorting_source_addr_factory_vtable kMockIpv6DisabledSourceAddrFactoryVtable = { @@ -394,11 +390,9 @@ int main(int argc, char** argv) { // Run a test case in which c-ares's address sorter // thinks that IPv4 is available and IPv6 isn't. grpc_init(); - mock_ipv6_disabled_source_addr_factory* factory = - static_cast( - gpr_malloc(sizeof(mock_ipv6_disabled_source_addr_factory))); - factory->base.vtable = &kMockIpv6DisabledSourceAddrFactoryVtable; - address_sorting_override_source_addr_factory_for_testing(&factory->base); + mock_ipv6_disabled_source_addr_factory factory; + factory.base.vtable = &kMockIpv6DisabledSourceAddrFactoryVtable; + address_sorting_override_source_addr_factory_for_testing(&factory.base); test_localhost_result_has_ipv4_first_when_ipv6_isnt_available(); grpc_shutdown(); } diff --git a/test/core/json/fuzzer.cc b/test/core/json/fuzzer.cc index 8b3e9792d15..6dafabb95b3 100644 --- a/test/core/json/fuzzer.cc +++ b/test/core/json/fuzzer.cc @@ -31,7 +31,8 @@ bool leak_check = true; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { char* s; - grpc_core::testing::LeakDetector leak_detector(true); + struct grpc_memory_counters counters; + grpc_memory_counters_init(); s = static_cast(gpr_malloc(size)); memcpy(s, data, size); grpc_json* x; @@ -39,5 +40,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_json_destroy(x); } gpr_free(s); + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + GPR_ASSERT(counters.total_size_relative == 0); return 0; } diff --git a/test/core/memory_usage/client.cc b/test/core/memory_usage/client.cc index 097288c5efa..467586ea5f4 100644 --- a/test/core/memory_usage/client.cc +++ b/test/core/memory_usage/client.cc @@ -285,7 +285,7 @@ int main(int argc, char** argv) { grpc_slice_unref(slice); grpc_completion_queue_destroy(cq); - grpc_shutdown_blocking(); + grpc_shutdown(); gpr_log(GPR_INFO, "---------client stats--------"); gpr_log( diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 6fb14fa31a0..7424797e6f5 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -318,7 +318,7 @@ int main(int argc, char** argv) { grpc_server_destroy(server); grpc_completion_queue_destroy(cq); - grpc_shutdown_blocking(); + grpc_shutdown(); grpc_memory_counters_destroy(); return 0; } diff --git a/test/core/security/alts_credentials_fuzzer.cc b/test/core/security/alts_credentials_fuzzer.cc index abe50031687..bf18f0a589e 100644 --- a/test/core/security/alts_credentials_fuzzer.cc +++ b/test/core/security/alts_credentials_fuzzer.cc @@ -66,7 +66,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { gpr_set_log_function(dont_log); } gpr_free(grpc_trace_fuzzer); - grpc_core::testing::LeakDetector leak_detector(leak_check); + struct grpc_memory_counters counters; + if (leak_check) { + grpc_memory_counters_init(); + } input_stream inp = {data, data + size}; grpc_init(); bool is_on_gcp = grpc_alts_is_running_on_gcp(); @@ -108,5 +111,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { gpr_free(handshaker_service_url); } grpc_shutdown(); + if (leak_check) { + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + GPR_ASSERT(counters.total_size_relative == 0); + } return 0; } diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc index 5846964eb90..8533644aceb 100644 --- a/test/core/security/ssl_server_fuzzer.cc +++ b/test/core/security/ssl_server_fuzzer.cc @@ -52,8 +52,9 @@ static void on_handshake_done(void* arg, grpc_error* error) { } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - grpc_core::testing::LeakDetector leak_detector(leak_check); + if (leak_check) grpc_memory_counters_init(); grpc_init(); { grpc_core::ExecCtx exec_ctx; @@ -117,6 +118,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_core::ExecCtx::Get()->Flush(); } - grpc_shutdown_blocking(); + grpc_shutdown(); + if (leak_check) { + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + GPR_ASSERT(counters.total_size_relative == 0); + } return 0; } diff --git a/test/core/slice/percent_decode_fuzzer.cc b/test/core/slice/percent_decode_fuzzer.cc index 11f71d92c46..81eb031014f 100644 --- a/test/core/slice/percent_decode_fuzzer.cc +++ b/test/core/slice/percent_decode_fuzzer.cc @@ -31,23 +31,24 @@ bool squelch = true; bool leak_check = true; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + struct grpc_memory_counters counters; grpc_init(); - { - grpc_core::testing::LeakDetector leak_detector(true); - grpc_slice input = grpc_slice_from_copied_buffer((const char*)data, size); - grpc_slice output; - if (grpc_strict_percent_decode_slice( - input, grpc_url_percent_encoding_unreserved_bytes, &output)) { - grpc_slice_unref(output); - } - if (grpc_strict_percent_decode_slice( - input, grpc_compatible_percent_encoding_unreserved_bytes, - &output)) { - grpc_slice_unref(output); - } - grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); - grpc_slice_unref(input); + grpc_memory_counters_init(); + grpc_slice input = grpc_slice_from_copied_buffer((const char*)data, size); + grpc_slice output; + if (grpc_strict_percent_decode_slice( + input, grpc_url_percent_encoding_unreserved_bytes, &output)) { + grpc_slice_unref(output); } - grpc_shutdown_blocking(); + if (grpc_strict_percent_decode_slice( + input, grpc_compatible_percent_encoding_unreserved_bytes, &output)) { + grpc_slice_unref(output); + } + grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); + grpc_slice_unref(input); + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + grpc_shutdown(); + GPR_ASSERT(counters.total_size_relative == 0); return 0; } diff --git a/test/core/slice/percent_encode_fuzzer.cc b/test/core/slice/percent_encode_fuzzer.cc index 1da982bba28..1fd197e180a 100644 --- a/test/core/slice/percent_encode_fuzzer.cc +++ b/test/core/slice/percent_encode_fuzzer.cc @@ -31,26 +31,28 @@ bool squelch = true; bool leak_check = true; static void test(const uint8_t* data, size_t size, const uint8_t* dict) { + struct grpc_memory_counters counters; grpc_init(); - { - grpc_core::testing::LeakDetector leak_detector(true); - grpc_slice input = grpc_slice_from_copied_buffer( - reinterpret_cast(data), size); - grpc_slice output = grpc_percent_encode_slice(input, dict); - grpc_slice decoded_output; - // encoder must always produce decodable output - GPR_ASSERT(grpc_strict_percent_decode_slice(output, dict, &decoded_output)); - grpc_slice permissive_decoded_output = - grpc_permissive_percent_decode_slice(output); - // and decoded output must always match the input - GPR_ASSERT(grpc_slice_eq(input, decoded_output)); - GPR_ASSERT(grpc_slice_eq(input, permissive_decoded_output)); - grpc_slice_unref(input); - grpc_slice_unref(output); - grpc_slice_unref(decoded_output); - grpc_slice_unref(permissive_decoded_output); - } - grpc_shutdown_blocking(); + grpc_memory_counters_init(); + grpc_slice input = + grpc_slice_from_copied_buffer(reinterpret_cast(data), size); + grpc_slice output = grpc_percent_encode_slice(input, dict); + grpc_slice decoded_output; + // encoder must always produce decodable output + GPR_ASSERT(grpc_strict_percent_decode_slice(output, dict, &decoded_output)); + grpc_slice permissive_decoded_output = + grpc_permissive_percent_decode_slice(output); + // and decoded output must always match the input + GPR_ASSERT(grpc_slice_eq(input, decoded_output)); + GPR_ASSERT(grpc_slice_eq(input, permissive_decoded_output)); + grpc_slice_unref(input); + grpc_slice_unref(output); + grpc_slice_unref(decoded_output); + grpc_slice_unref(permissive_decoded_output); + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + grpc_shutdown(); + GPR_ASSERT(counters.total_size_relative == 0); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/test/core/surface/init_test.cc b/test/core/surface/init_test.cc index 583dd1b6de9..1bcd13a0b89 100644 --- a/test/core/surface/init_test.cc +++ b/test/core/surface/init_test.cc @@ -18,9 +18,6 @@ #include #include -#include - -#include "src/core/lib/surface/init.h" #include "test/core/util/test_config.h" static int g_flag; @@ -33,17 +30,6 @@ static void test(int rounds) { for (i = 0; i < rounds; i++) { grpc_shutdown(); } - grpc_maybe_wait_for_async_shutdown(); -} - -static void test_blocking(int rounds) { - int i; - for (i = 0; i < rounds; i++) { - grpc_init(); - } - for (i = 0; i < rounds; i++) { - grpc_shutdown_blocking(); - } } static void test_mixed(void) { @@ -53,7 +39,6 @@ static void test_mixed(void) { grpc_init(); grpc_shutdown(); grpc_shutdown(); - grpc_maybe_wait_for_async_shutdown(); } static void plugin_init(void) { g_flag = 1; } @@ -63,7 +48,7 @@ static void test_plugin() { grpc_register_plugin(plugin_init, plugin_destroy); grpc_init(); GPR_ASSERT(g_flag == 1); - grpc_shutdown_blocking(); + grpc_shutdown(); GPR_ASSERT(g_flag == 2); } @@ -72,7 +57,6 @@ static void test_repeatedly() { grpc_init(); grpc_shutdown(); } - grpc_maybe_wait_for_async_shutdown(); } int main(int argc, char** argv) { @@ -80,9 +64,6 @@ int main(int argc, char** argv) { test(1); test(2); test(3); - test_blocking(1); - test_blocking(2); - test_blocking(3); test_mixed(); test_plugin(); test_repeatedly(); diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 04d0506b3c2..1c9b67027c5 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -78,7 +78,6 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_init); printf("%lx", (unsigned long) grpc_shutdown); printf("%lx", (unsigned long) grpc_is_initialized); - printf("%lx", (unsigned long) grpc_shutdown_blocking); printf("%lx", (unsigned long) grpc_version_string); printf("%lx", (unsigned long) grpc_g_stands_for); printf("%lx", (unsigned long) grpc_completion_queue_factory_lookup); diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index 787fb76e48b..d0da05d9b4d 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -16,18 +16,13 @@ * */ -#include #include #include -#include #include -#include #include -#include #include "src/core/lib/gpr/alloc.h" -#include "src/core/lib/surface/init.h" #include "test/core/util/memory_counters.h" static struct grpc_memory_counters g_memory_counters; @@ -115,29 +110,3 @@ struct grpc_memory_counters grpc_memory_counters_snapshot() { NO_BARRIER_LOAD(&g_memory_counters.total_allocs_absolute); return counters; } - -namespace grpc_core { -namespace testing { - -LeakDetector::LeakDetector(bool enable) : enabled_(enable) { - if (enabled_) { - grpc_memory_counters_init(); - } -} - -LeakDetector::~LeakDetector() { - // Wait for grpc_shutdown() to finish its async work. - grpc_maybe_wait_for_async_shutdown(); - if (enabled_) { - struct grpc_memory_counters counters = grpc_memory_counters_snapshot(); - if (counters.total_size_relative != 0) { - gpr_log(GPR_ERROR, "Leaking %" PRIuPTR " bytes", - static_cast(counters.total_size_relative)); - GPR_ASSERT(0); - } - grpc_memory_counters_destroy(); - } -} - -} // namespace testing -} // namespace grpc_core diff --git a/test/core/util/memory_counters.h b/test/core/util/memory_counters.h index c92a001ff13..c23a13e5c85 100644 --- a/test/core/util/memory_counters.h +++ b/test/core/util/memory_counters.h @@ -32,22 +32,4 @@ void grpc_memory_counters_init(); void grpc_memory_counters_destroy(); struct grpc_memory_counters grpc_memory_counters_snapshot(); -namespace grpc_core { -namespace testing { - -// At destruction time, it will check there is no memory leak. -// The object should be created before grpc_init() is called and destroyed after -// grpc_shutdown() is returned. -class LeakDetector { - public: - explicit LeakDetector(bool enable); - ~LeakDetector(); - - private: - const bool enabled_; -}; - -} // namespace testing -} // namespace grpc_core - #endif diff --git a/test/core/util/port.cc b/test/core/util/port.cc index fe4caa6faf6..303306de452 100644 --- a/test/core/util/port.cc +++ b/test/core/util/port.cc @@ -66,7 +66,7 @@ static void free_chosen_ports(void) { for (i = 0; i < num_chosen_ports; i++) { grpc_free_port_using_server(chosen_ports[i]); } - grpc_shutdown_blocking(); + grpc_shutdown(); gpr_free(chosen_ports); } diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 0c0492fdbbd..fe80bb2d4d0 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -31,7 +31,6 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/surface/init.h" int64_t g_fixture_slowdown_factor = 1; int64_t g_poller_slowdown_factor = 1; @@ -406,7 +405,7 @@ TestEnvironment::TestEnvironment(int argc, char** argv) { grpc_test_init(argc, argv); } -TestEnvironment::~TestEnvironment() { grpc_maybe_wait_for_async_shutdown(); } +TestEnvironment::~TestEnvironment() {} } // namespace testing } // namespace grpc diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index e6b14888ffb..09e705df789 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -197,7 +197,7 @@ void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses, class AddressSortingTest : public ::testing::Test { protected: void SetUp() override { grpc_init(); } - void TearDown() override { grpc_shutdown_blocking(); } + void TearDown() override { grpc_shutdown(); } }; /* Tests for rule 1 */ diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index 57cdbeb7b76..b96b00f2db2 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -258,6 +258,14 @@ class GrpcToolTest : public ::testing::Test { void ShutdownServer() { server_->Shutdown(); } + void ExitWhenError(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback) { + int result = GrpcToolMainLib(argc, argv, cred, callback); + if (result) { + exit(result); + } + } + std::unique_ptr server_; TestServiceImpl service_; reflection::ProtoServerReflectionPlugin plugin_; @@ -410,9 +418,11 @@ TEST_F(GrpcToolTest, TypeNotFound) { const char* argv[] = {"grpc_cli", "type", server_address.c_str(), "grpc.testing.DummyRequest"}; - EXPECT_TRUE(1 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); + EXPECT_DEATH(ExitWhenError(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1)), + ".*Type grpc.testing.DummyRequest not found.*"); + ShutdownServer(); } From b4e069a5c3ffd967beb37547666b6dc954ca592b Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 22 Feb 2019 21:55:14 -0500 Subject: [PATCH 493/814] Convert grpc malloc slice to use grpc_core::RefCount. This shows up in profiles. Using grpc_core::RefCount lowers the time spent in grpc_slice_malloc_large() by 8%. --- src/core/lib/slice/slice.cc | 44 +++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index e842d84f11f..31437aa4600 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -26,6 +26,7 @@ #include +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/iomgr/exec_ctx.h" char* grpc_slice_to_c_string(grpc_slice slice) { @@ -213,21 +214,35 @@ grpc_slice grpc_slice_from_copied_string(const char* source) { return grpc_slice_from_copied_buffer(source, strlen(source)); } -typedef struct { +namespace { + +struct MallocRefCount { + MallocRefCount(const grpc_slice_refcount_vtable* vtable) { + base.vtable = vtable; + base.sub_refcount = &base; + } + + void Ref() { refs.Ref(); } + void Unref() { + if (refs.Unref()) { + gpr_free(this); + } + } + grpc_slice_refcount base; - gpr_refcount refs; -} malloc_refcount; + grpc_core::RefCount refs; +}; + +} // namespace static void malloc_ref(void* p) { - malloc_refcount* r = static_cast(p); - gpr_ref(&r->refs); + MallocRefCount* r = static_cast(p); + r->Ref(); } static void malloc_unref(void* p) { - malloc_refcount* r = static_cast(p); - if (gpr_unref(&r->refs)) { - gpr_free(r); - } + MallocRefCount* r = static_cast(p); + r->Unref(); } static const grpc_slice_refcount_vtable malloc_vtable = { @@ -246,15 +261,10 @@ grpc_slice grpc_slice_malloc_large(size_t length) { refcount is a malloc_refcount bytes is an array of bytes of the requested length Both parts are placed in the same allocation returned from gpr_malloc */ - malloc_refcount* rc = static_cast( - gpr_malloc(sizeof(malloc_refcount) + length)); + void* data = + static_cast(gpr_malloc(sizeof(MallocRefCount) + length)); - /* Initial refcount on rc is 1 - and it's up to the caller to release - this reference. */ - gpr_ref_init(&rc->refs, 1); - - rc->base.vtable = &malloc_vtable; - rc->base.sub_refcount = &rc->base; + auto* rc = new (data) MallocRefCount(&malloc_vtable); /* Build up the slice to be returned. */ /* The slices refcount points back to the allocated block. */ From 6bde9122a70ed8c0f99187a123dffb5657d3d25c Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 22 Feb 2019 22:02:34 -0500 Subject: [PATCH 494/814] Add missing header to gprpp/atomic.h I missed to include atm.h for the stat macros. --- src/core/lib/gprpp/atomic.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/lib/gprpp/atomic.h b/src/core/lib/gprpp/atomic.h index 622df1b7889..8cb9e9342ec 100644 --- a/src/core/lib/gprpp/atomic.h +++ b/src/core/lib/gprpp/atomic.h @@ -23,6 +23,8 @@ #include +#include + namespace grpc_core { enum class MemoryOrder { From 05b98a48969f402b2325b37de96de584882f85ea Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Sat, 23 Feb 2019 10:33:39 -0800 Subject: [PATCH 495/814] Also add streaming tests that cancel from client --- .../end2end/client_callback_end2end_test.cc | 142 ++++++++++++++---- 1 file changed, 116 insertions(+), 26 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index a076c1f0cec..1792269c943 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -16,6 +16,7 @@ * */ +#include #include #include #include @@ -104,8 +105,8 @@ class ClientCallbackEnd2endTest do_not_test_ = true; return; } - int port = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port; + picked_port_ = grpc_pick_unused_port_or_die(); + server_address_ << "localhost:" << picked_port_; builder.AddListeningPort(server_address_.str(), server_creds); } if (!GetParam().callback_server) { @@ -166,6 +167,9 @@ class ClientCallbackEnd2endTest if (is_server_started_) { server_->Shutdown(); } + if (picked_port_ > 0) { + grpc_recycle_unused_port(picked_port_); + } } void SendRpcs(int num_rpcs, bool with_binary_metadata) { @@ -321,6 +325,7 @@ class ClientCallbackEnd2endTest } bool do_not_test_{false}; bool is_server_started_{false}; + int picked_port_{0}; std::shared_ptr channel_; std::unique_ptr stub_; std::unique_ptr generic_stub_; @@ -489,13 +494,22 @@ TEST_P(ClientCallbackEnd2endTest, RequestEchoServerCancel) { } } +struct ClientCancelInfo { + bool cancel{false}; + int ops_before_cancel; + ClientCancelInfo() : cancel{false} {} + // Allow the single-op version to be non-explicit for ease of use + ClientCancelInfo(int ops) : cancel{true}, ops_before_cancel{ops} {} +}; + class WriteClient : public grpc::experimental::ClientWriteReactor { public: WriteClient(grpc::testing::EchoTestService::Stub* stub, ServerTryCancelRequestPhase server_try_cancel, - int num_msgs_to_send) + int num_msgs_to_send, ClientCancelInfo client_cancel = {}) : server_try_cancel_(server_try_cancel), - num_msgs_to_send_(num_msgs_to_send) { + num_msgs_to_send_(num_msgs_to_send), + client_cancel_{client_cancel} { grpc::string msg{"Hello server."}; for (int i = 0; i < num_msgs_to_send; i++) { desired_ += msg; @@ -512,13 +526,17 @@ class WriteClient : public grpc::experimental::ClientWriteReactor { MaybeWrite(); } void OnWriteDone(bool ok) override { - num_msgs_sent_++; if (ok) { + num_msgs_sent_++; MaybeWrite(); } } void OnDone(const Status& s) override { gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent_); + int num_to_send = + (client_cancel_.cancel) + ? std::min(num_msgs_to_send_, client_cancel_.ops_before_cancel) + : num_msgs_to_send_; switch (server_try_cancel_) { case CANCEL_BEFORE_PROCESSING: case CANCEL_DURING_PROCESSING: @@ -526,19 +544,19 @@ class WriteClient : public grpc::experimental::ClientWriteReactor { // client, it means that the client most likely did not get a chance to // send all the messages it wanted to send. i.e num_msgs_sent <= // num_msgs_to_send - EXPECT_LE(num_msgs_sent_, num_msgs_to_send_); + EXPECT_LE(num_msgs_sent_, num_to_send); break; case DO_NOT_CANCEL: case CANCEL_AFTER_PROCESSING: // If the RPC was not canceled or canceled after all messages were read // by the server, the client did get a chance to send all its messages - EXPECT_EQ(num_msgs_sent_, num_msgs_to_send_); + EXPECT_EQ(num_msgs_sent_, num_to_send); break; default: assert(false); break; } - if (server_try_cancel_ == DO_NOT_CANCEL) { + if ((server_try_cancel_ == DO_NOT_CANCEL) && !client_cancel_.cancel) { EXPECT_TRUE(s.ok()); EXPECT_EQ(response_.message(), desired_); } else { @@ -558,7 +576,10 @@ class WriteClient : public grpc::experimental::ClientWriteReactor { private: void MaybeWrite() { - if (num_msgs_to_send_ > num_msgs_sent_ + 1) { + if (client_cancel_.cancel && + num_msgs_sent_ == client_cancel_.ops_before_cancel) { + context_.TryCancel(); + } else if (num_msgs_to_send_ > num_msgs_sent_ + 1) { StartWrite(&request_); } else if (num_msgs_to_send_ == num_msgs_sent_ + 1) { StartWriteLast(&request_, WriteOptions()); @@ -571,6 +592,7 @@ class WriteClient : public grpc::experimental::ClientWriteReactor { int num_msgs_sent_{0}; const int num_msgs_to_send_; grpc::string desired_; + const ClientCancelInfo client_cancel_; std::mutex mu_; std::condition_variable cv_; bool done_ = false; @@ -627,8 +649,9 @@ TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelAfterReads) { class ReadClient : public grpc::experimental::ClientReadReactor { public: ReadClient(grpc::testing::EchoTestService::Stub* stub, - ServerTryCancelRequestPhase server_try_cancel) - : server_try_cancel_(server_try_cancel) { + ServerTryCancelRequestPhase server_try_cancel, + ClientCancelInfo client_cancel = {}) + : server_try_cancel_(server_try_cancel), client_cancel_{client_cancel} { if (server_try_cancel_ != DO_NOT_CANCEL) { // Send server_try_cancel value in the client metadata context_.AddMetadata(kServerTryCancelRequest, @@ -636,12 +659,18 @@ class ReadClient : public grpc::experimental::ClientReadReactor { } request_.set_message("Hello client "); stub->experimental_async()->ResponseStream(&context_, &request_, this); + if (client_cancel_.cancel && + reads_complete_ == client_cancel_.ops_before_cancel) { + context_.TryCancel(); + } + // Even if we cancel, read until failure because there might be responses + // pending StartRead(&response_); StartCall(); } void OnReadDone(bool ok) override { if (!ok) { - if (server_try_cancel_ == DO_NOT_CANCEL) { + if (server_try_cancel_ == DO_NOT_CANCEL && !client_cancel_.cancel) { EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); } } else { @@ -649,6 +678,12 @@ class ReadClient : public grpc::experimental::ClientReadReactor { EXPECT_EQ(response_.message(), request_.message() + grpc::to_string(reads_complete_)); reads_complete_++; + if (client_cancel_.cancel && + reads_complete_ == client_cancel_.ops_before_cancel) { + context_.TryCancel(); + } + // Even if we cancel, read until failure because there might be responses + // pending StartRead(&response_); } } @@ -656,8 +691,19 @@ class ReadClient : public grpc::experimental::ClientReadReactor { gpr_log(GPR_INFO, "Read %d messages", reads_complete_); switch (server_try_cancel_) { case DO_NOT_CANCEL: - EXPECT_TRUE(s.ok()); - EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); + if (!client_cancel_.cancel || client_cancel_.ops_before_cancel > + kServerDefaultResponseStreamsToSend) { + EXPECT_TRUE(s.ok()); + EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend); + } else { + EXPECT_GE(reads_complete_, client_cancel_.ops_before_cancel); + EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend); + // Status might be ok or cancelled depending on whether server + // sent status before client cancel went through + if (!s.ok()) { + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + } + } break; case CANCEL_BEFORE_PROCESSING: EXPECT_FALSE(s.ok()); @@ -694,6 +740,7 @@ class ReadClient : public grpc::experimental::ClientReadReactor { ClientContext context_; const ServerTryCancelRequestPhase server_try_cancel_; int reads_complete_{0}; + const ClientCancelInfo client_cancel_; std::mutex mu_; std::condition_variable cv_; bool done_ = false; @@ -710,6 +757,15 @@ TEST_P(ClientCallbackEnd2endTest, ResponseStream) { } } +TEST_P(ClientCallbackEnd2endTest, ClientCancelsResponseStream) { + MAYBE_SKIP_TEST; + ResetStub(); + ReadClient test{stub_.get(), DO_NOT_CANCEL, 2}; + test.Await(); + // Because cancel in this case races with server finish, we can't be sure that + // server interceptors even see cancellation +} + // Server to cancel before sending any response messages TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelBefore) { MAYBE_SKIP_TEST; @@ -752,8 +808,10 @@ class BidiClient public: BidiClient(grpc::testing::EchoTestService::Stub* stub, ServerTryCancelRequestPhase server_try_cancel, - int num_msgs_to_send) - : server_try_cancel_(server_try_cancel), msgs_to_send_{num_msgs_to_send} { + int num_msgs_to_send, ClientCancelInfo client_cancel = {}) + : server_try_cancel_(server_try_cancel), + msgs_to_send_{num_msgs_to_send}, + client_cancel_{client_cancel} { if (server_try_cancel_ != DO_NOT_CANCEL) { // Send server_try_cancel value in the client metadata context_.AddMetadata(kServerTryCancelRequest, @@ -761,14 +819,18 @@ class BidiClient } request_.set_message("Hello fren "); stub->experimental_async()->BidiStream(&context_, this); + MaybeWrite(); StartRead(&response_); - StartWrite(&request_); StartCall(); } void OnReadDone(bool ok) override { if (!ok) { if (server_try_cancel_ == DO_NOT_CANCEL) { - EXPECT_EQ(reads_complete_, msgs_to_send_); + if (!client_cancel_.cancel) { + EXPECT_EQ(reads_complete_, msgs_to_send_); + } else { + EXPECT_LE(reads_complete_, writes_complete_); + } } } else { EXPECT_LE(reads_complete_, msgs_to_send_); @@ -783,20 +845,25 @@ class BidiClient } else if (!ok) { return; } - if (++writes_complete_ == msgs_to_send_) { - StartWritesDone(); - } else { - StartWrite(&request_); - } + writes_complete_++; + MaybeWrite(); } void OnDone(const Status& s) override { gpr_log(GPR_INFO, "Sent %d messages", writes_complete_); gpr_log(GPR_INFO, "Read %d messages", reads_complete_); switch (server_try_cancel_) { case DO_NOT_CANCEL: - EXPECT_TRUE(s.ok()); - EXPECT_EQ(writes_complete_, msgs_to_send_); - EXPECT_EQ(reads_complete_, writes_complete_); + if (!client_cancel_.cancel || + client_cancel_.ops_before_cancel > msgs_to_send_) { + EXPECT_TRUE(s.ok()); + EXPECT_EQ(writes_complete_, msgs_to_send_); + EXPECT_EQ(reads_complete_, writes_complete_); + } else { + EXPECT_FALSE(s.ok()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + EXPECT_EQ(writes_complete_, client_cancel_.ops_before_cancel); + EXPECT_LE(reads_complete_, writes_complete_); + } break; case CANCEL_BEFORE_PROCESSING: EXPECT_FALSE(s.ok()); @@ -837,6 +904,16 @@ class BidiClient } private: + void MaybeWrite() { + if (client_cancel_.cancel && + writes_complete_ == client_cancel_.ops_before_cancel) { + context_.TryCancel(); + } else if (writes_complete_ == msgs_to_send_) { + StartWritesDone(); + } else { + StartWrite(&request_); + } + } EchoRequest request_; EchoResponse response_; ClientContext context_; @@ -844,6 +921,7 @@ class BidiClient int reads_complete_{0}; int writes_complete_{0}; const int msgs_to_send_; + const ClientCancelInfo client_cancel_; std::mutex mu_; std::condition_variable cv_; bool done_ = false; @@ -861,6 +939,18 @@ TEST_P(ClientCallbackEnd2endTest, BidiStream) { } } +TEST_P(ClientCallbackEnd2endTest, ClientCancelsBidiStream) { + MAYBE_SKIP_TEST; + ResetStub(); + BidiClient test{stub_.get(), DO_NOT_CANCEL, + kServerDefaultResponseStreamsToSend, 2}; + test.Await(); + // Make sure that the server interceptors were notified of a cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + // Server to cancel before reading/writing any requests/responses on the stream TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelBefore) { MAYBE_SKIP_TEST; From 23f39363c458bffc361f80182c4581b3af77cd9b Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 25 Feb 2019 00:01:16 -0800 Subject: [PATCH 496/814] Inproc: properly handle send message that won't go to other side --- src/core/ext/transport/inproc/inproc_transport.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index b0f93eb63f4..d46c24a1de0 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -1032,6 +1032,11 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs, } } else { if (error != GRPC_ERROR_NONE) { + // Consume any send message that was sent here but that we are not pushing + // to the other side + if (op->send_message) { + op->payload->send_message.send_message.reset(); + } // Schedule op's closures that we didn't push to op state machine if (op->recv_initial_metadata) { if (op->payload->recv_initial_metadata.trailing_metadata_available != From ac5f5c4fe230a62a101a7274768b6b512e1c9ced Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 25 Feb 2019 00:03:18 -0800 Subject: [PATCH 497/814] Add ClientCancelsRequestStream test --- test/cpp/end2end/client_callback_end2end_test.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 1792269c943..2b362745653 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -609,6 +609,17 @@ TEST_P(ClientCallbackEnd2endTest, RequestStream) { } } +TEST_P(ClientCallbackEnd2endTest, ClientCancelsRequestStream) { + MAYBE_SKIP_TEST; + ResetStub(); + WriteClient test{stub_.get(), DO_NOT_CANCEL, 3, {2}}; + test.Await(); + // Make sure that the server interceptors got the cancel + if (GetParam().use_interceptors) { + EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel()); + } +} + // Server to cancel before doing reading the request TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelBeforeReads) { MAYBE_SKIP_TEST; From 5f8fe7d5cc13ffabe11e419215eb872d82b6d0b3 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 25 Feb 2019 00:21:42 -0800 Subject: [PATCH 498/814] Test for simultaneous Read and WritesDone --- .../end2end/client_callback_end2end_test.cc | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 2b362745653..7ed15beabe1 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -1000,6 +1000,54 @@ TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelAfter) { } } +TEST_P(ClientCallbackEnd2endTest, SimultaneousReadAndWritesDone) { + MAYBE_SKIP_TEST; + ResetStub(); + class Client : public grpc::experimental::ClientBidiReactor { + public: + Client(grpc::testing::EchoTestService::Stub* stub) { + request_.set_message("Hello bidi "); + stub->experimental_async()->BidiStream(&context_, this); + StartWrite(&request_); + StartCall(); + } + void OnReadDone(bool ok) override { + EXPECT_TRUE(ok); + EXPECT_EQ(response_.message(), request_.message()); + } + void OnWriteDone(bool ok) override { + EXPECT_TRUE(ok); + // Now send out the simultaneous Read and WritesDone + StartWritesDone(); + StartRead(&response_); + } + void OnDone(const Status& s) override { + EXPECT_TRUE(s.ok()); + EXPECT_EQ(response_.message(), request_.message()); + std::unique_lock l(mu_); + done_ = true; + cv_.notify_one(); + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + cv_.wait(l); + } + } + + private: + EchoRequest request_; + EchoResponse response_; + ClientContext context_; + std::mutex mu_; + std::condition_variable cv_; + bool done_ = false; + } test{stub_.get()}; + + test.Await(); +} + std::vector CreateTestScenarios(bool test_insecure) { std::vector scenarios; std::vector credentials_types{ From 8feb16171a3633339ec6d11b5aba3ebca2e4c0de Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 25 Feb 2019 00:48:11 -0800 Subject: [PATCH 499/814] Add an expectation and fix a ServerContext bug --- src/cpp/server/server_context.cc | 15 ++++++++++----- test/cpp/end2end/test_service_impl.cc | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index 1b524bc3e83..e116cf6e7d2 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -138,7 +138,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { } internal::Call call_; - internal::ServerReactor* reactor_; + internal::ServerReactor* const reactor_; bool has_tag_; void* tag_; void* core_cq_tag_; @@ -200,12 +200,17 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { cancelled_ = 1; } - if (cancelled_ && (reactor_ != nullptr)) { + // Decide whether to call the cancel callback before releasing the lock + bool call_cancel = (cancelled_ != 0); + + // Release the lock since we are going to be calling a callback and + // interceptors now + lock.unlock(); + + if (call_cancel && (reactor_ != nullptr)) { reactor_->OnCancel(); } - /* Release the lock since we are going to be running through interceptors now - */ - lock.unlock(); + /* Add interception point and run through interceptors */ interceptor_methods_.AddInterceptionHookPoint( experimental::InterceptionHookPoints::POST_RECV_CLOSE); diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 8c2df1acc33..baebdbc8091 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -583,7 +583,10 @@ CallbackTestServiceImpl::RequestStream() { StartRead(&request_); } void OnDone() override { delete this; } - void OnCancel() override { FinishOnce(Status::CANCELLED); } + void OnCancel() override { + EXPECT_TRUE(ctx_->IsCancelled()); + FinishOnce(Status::CANCELLED); + } void OnReadDone(bool ok) override { if (ok) { response_->mutable_message()->append(request_.message()); @@ -666,7 +669,10 @@ CallbackTestServiceImpl::ResponseStream() { } } void OnDone() override { delete this; } - void OnCancel() override { FinishOnce(Status::CANCELLED); } + void OnCancel() override { + EXPECT_TRUE(ctx_->IsCancelled()); + FinishOnce(Status::CANCELLED); + } void OnWriteDone(bool ok) override { if (num_msgs_sent_ < server_responses_to_send_) { NextWrite(); @@ -749,7 +755,10 @@ CallbackTestServiceImpl::BidiStream() { StartRead(&request_); } void OnDone() override { delete this; } - void OnCancel() override { FinishOnce(Status::CANCELLED); } + void OnCancel() override { + EXPECT_TRUE(ctx_->IsCancelled()); + FinishOnce(Status::CANCELLED); + } void OnReadDone(bool ok) override { if (ok) { num_msgs_read_++; From 60f060e0785ede3a292bf740de9594e3b4edb30f Mon Sep 17 00:00:00 2001 From: Michael Behr Date: Thu, 14 Feb 2019 16:51:04 -0500 Subject: [PATCH 500/814] Let interop_client send additional metadata, controlled by a flag. --- test/cpp/interop/client.cc | 27 ++++- test/cpp/interop/client_helper.cc | 50 ++++++++- test/cpp/interop/client_helper.h | 38 ++++++- test/cpp/util/create_test_channel.cc | 151 ++++++++++++++++++++------- test/cpp/util/create_test_channel.h | 33 ++++++ 5 files changed, 254 insertions(+), 45 deletions(-) diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index c9458ff40ce..8a934845ab4 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -92,6 +92,9 @@ DEFINE_int32(soak_iterations, 1000, DEFINE_int32(iteration_interval, 10, "The interval in seconds between rpcs. This is used by " "long_connection test"); +DEFINE_string(additional_metadata, "", + "Additional metadata to send in each request, as a " + "semicolon-separated list of key:value pairs."); using grpc::testing::CreateChannelForTestCase; using grpc::testing::GetServiceAccountJsonKey; @@ -101,8 +104,28 @@ int main(int argc, char** argv) { grpc::testing::InitTest(&argc, &argv, true); gpr_log(GPR_INFO, "Testing these cases: %s", FLAGS_test_case.c_str()); int ret = 0; - grpc::testing::ChannelCreationFunc channel_creation_func = - std::bind(&CreateChannelForTestCase, FLAGS_test_case); + + grpc::testing::ChannelCreationFunc channel_creation_func; + grpc::string test_case = FLAGS_test_case; + if (FLAGS_additional_metadata == "") { + channel_creation_func = [test_case]() { + return CreateChannelForTestCase(test_case); + }; + } else { + std::multimap additional_metadata = + grpc::testing::ParseAdditionalMetadataFlag(FLAGS_additional_metadata); + + channel_creation_func = [test_case, additional_metadata]() { + std::vector> + factories; + factories.emplace_back( + new grpc::testing::AdditionalMetadataInterceptorFactory( + additional_metadata)); + return CreateChannelForTestCase(test_case, std::move(factories)); + }; + } + grpc::testing::InteropClient client(channel_creation_func, true, FLAGS_do_not_abort_on_transient_failures); diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc index fb7b7bb7d03..ff4fab9cb01 100644 --- a/test/cpp/interop/client_helper.cc +++ b/test/cpp/interop/client_helper.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -79,7 +80,10 @@ void UpdateActions( std::unordered_map>* actions) {} std::shared_ptr CreateChannelForTestCase( - const grpc::string& test_case) { + const grpc::string& test_case, + std::vector< + std::unique_ptr> + interceptor_creators) { GPR_ASSERT(FLAGS_server_port); const int host_port_buf_size = 1024; char host_port[host_port_buf_size]; @@ -107,11 +111,51 @@ std::shared_ptr CreateChannelForTestCase( transport_security security_type = FLAGS_use_alts ? ALTS : (FLAGS_use_tls ? TLS : INSECURE); return CreateTestChannel(host_port, FLAGS_server_host_override, - security_type, !FLAGS_use_test_ca, creds); + security_type, !FLAGS_use_test_ca, creds, + std::move(interceptor_creators)); } else { - return CreateTestChannel(host_port, FLAGS_custom_credentials_type, creds); + if (interceptor_creators.empty()) { + return CreateTestChannel(host_port, FLAGS_custom_credentials_type, creds); + } else { + return CreateTestChannel(host_port, FLAGS_custom_credentials_type, creds, + std::move(interceptor_creators)); + } } } +std::multimap ParseAdditionalMetadataFlag( + const grpc::string& flag) { + std::multimap additional_metadata; + + // Key in group 1; value in group 2. + std::regex re("([-a-zA-Z0-9]+):([^;]*);?"); + auto metadata_entries_begin = std::sregex_iterator( + flag.begin(), flag.end(), re, std::regex_constants::match_continuous); + auto metadata_entries_end = std::sregex_iterator(); + + for (std::sregex_iterator i = metadata_entries_begin; + i != metadata_entries_end; ++i) { + std::smatch match = *i; + gpr_log(GPR_INFO, "Adding additional metadata with key %s and value %s", + match[1].str().c_str(), match[2].str().c_str()); + additional_metadata.insert({match[1].str(), match[2].str()}); + } + + return additional_metadata; +} + +void AdditionalMetadataInterceptor::Intercept( + experimental::InterceptorBatchMethods* methods) { + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + std::multimap* metadata = + methods->GetSendInitialMetadata(); + for (const auto& entry : additional_metadata_) { + metadata->insert(entry); + } + } + methods->Proceed(); +} + } // namespace testing } // namespace grpc diff --git a/test/cpp/interop/client_helper.h b/test/cpp/interop/client_helper.h index 7dee85cc980..895f7625baa 100644 --- a/test/cpp/interop/client_helper.h +++ b/test/cpp/interop/client_helper.h @@ -39,7 +39,16 @@ void UpdateActions( std::unordered_map>* actions); std::shared_ptr CreateChannelForTestCase( - const grpc::string& test_case); + const grpc::string& test_case, + std::vector< + std::unique_ptr> + interceptor_creators = {}); + +// Parse the contents of FLAGS_additional_metadata into a map. Allow +// alphanumeric characters and dashes in keys, and any character but semicolons +// in values. +std::multimap ParseAdditionalMetadataFlag( + const grpc::string& flag); class InteropClientContextInspector { public: @@ -59,6 +68,33 @@ class InteropClientContextInspector { const ::grpc::ClientContext& context_; }; +class AdditionalMetadataInterceptor : public experimental::Interceptor { + public: + AdditionalMetadataInterceptor( + std::multimap additional_metadata) + : additional_metadata_(std::move(additional_metadata)) {} + + void Intercept(experimental::InterceptorBatchMethods* methods) override; + + private: + const std::multimap additional_metadata_; +}; + +class AdditionalMetadataInterceptorFactory + : public experimental::ClientInterceptorFactoryInterface { + public: + AdditionalMetadataInterceptorFactory( + std::multimap additional_metadata) + : additional_metadata_(std::move(additional_metadata)) {} + + experimental::Interceptor* CreateClientInterceptor( + experimental::ClientRpcInfo* info) override { + return new AdditionalMetadataInterceptor(additional_metadata_); + } + + const std::multimap additional_metadata_; +}; + } // namespace testing } // namespace grpc diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index 0bcd4dbc844..e0c0bd064fc 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -71,38 +71,9 @@ std::shared_ptr CreateTestChannel( const grpc::string& override_hostname, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args) { - ChannelArguments channel_args(args); - std::shared_ptr channel_creds; - if (cred_type.empty()) { - return CreateCustomChannel(server, InsecureChannelCredentials(), args); - } else if (cred_type == testing::kTlsCredentialsType) { // cred_type == "ssl" - if (use_prod_roots) { - gpr_once_init(&g_once_init_add_prod_ssl_provider, &AddProdSslType); - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - kProdTlsCredentialsType, &channel_args); - if (!server.empty() && !override_hostname.empty()) { - channel_args.SetSslTargetNameOverride(override_hostname); - } - } else { - // override_hostname is discarded as the provider handles it. - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - testing::kTlsCredentialsType, &channel_args); - } - GPR_ASSERT(channel_creds != nullptr); - - const grpc::string& connect_to = - server.empty() ? override_hostname : server; - if (creds.get()) { - channel_creds = CompositeChannelCredentials(channel_creds, creds); - } - return CreateCustomChannel(connect_to, channel_creds, channel_args); - } else { - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - cred_type, &channel_args); - GPR_ASSERT(channel_creds != nullptr); - - return CreateCustomChannel(server, channel_creds, args); - } + return CreateTestChannel(server, cred_type, override_hostname, + use_prod_roots, creds, args, + /*interceptor_creators=*/{}); } std::shared_ptr CreateTestChannel( @@ -110,13 +81,9 @@ std::shared_ptr CreateTestChannel( testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args) { - grpc::string type = - security_type == testing::ALTS - ? testing::kAltsCredentialsType - : (security_type == testing::TLS ? testing::kTlsCredentialsType - : testing::kInsecureCredentialsType); - return CreateTestChannel(server, type, override_hostname, use_prod_roots, - creds, args); + return CreateTestChannel(server, override_hostname, security_type, + use_prod_roots, creds, args, + /*interceptor_creators=*/{}); } std::shared_ptr CreateTestChannel( @@ -154,4 +121,110 @@ std::shared_ptr CreateTestChannel( return CreateCustomChannel(server, channel_creds, channel_args); } +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& cred_type, + const grpc::string& override_hostname, bool use_prod_roots, + const std::shared_ptr& creds, + const ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators) { + ChannelArguments channel_args(args); + std::shared_ptr channel_creds; + if (cred_type.empty()) { + if (interceptor_creators.empty()) { + return CreateCustomChannel(server, InsecureChannelCredentials(), args); + } else { + return experimental::CreateCustomChannelWithInterceptors( + server, InsecureChannelCredentials(), args, + std::move(interceptor_creators)); + } + } else if (cred_type == testing::kTlsCredentialsType) { // cred_type == "ssl" + if (use_prod_roots) { + gpr_once_init(&g_once_init_add_prod_ssl_provider, &AddProdSslType); + channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( + kProdTlsCredentialsType, &channel_args); + if (!server.empty() && !override_hostname.empty()) { + channel_args.SetSslTargetNameOverride(override_hostname); + } + } else { + // override_hostname is discarded as the provider handles it. + channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( + testing::kTlsCredentialsType, &channel_args); + } + GPR_ASSERT(channel_creds != nullptr); + + const grpc::string& connect_to = + server.empty() ? override_hostname : server; + if (creds.get()) { + channel_creds = CompositeChannelCredentials(channel_creds, creds); + } + if (interceptor_creators.empty()) { + return CreateCustomChannel(connect_to, channel_creds, channel_args); + } else { + return experimental::CreateCustomChannelWithInterceptors( + connect_to, channel_creds, channel_args, + std::move(interceptor_creators)); + } + } else { + channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( + cred_type, &channel_args); + GPR_ASSERT(channel_creds != nullptr); + + if (interceptor_creators.empty()) { + return CreateCustomChannel(server, channel_creds, args); + } else { + return experimental::CreateCustomChannelWithInterceptors( + server, channel_creds, args, std::move(interceptor_creators)); + } + } +} + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& override_hostname, + testing::transport_security security_type, bool use_prod_roots, + const std::shared_ptr& creds, const ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators) { + grpc::string credential_type = + security_type == testing::ALTS + ? testing::kAltsCredentialsType + : (security_type == testing::TLS ? testing::kTlsCredentialsType + : testing::kInsecureCredentialsType); + return CreateTestChannel( + server, credential_type, override_hostname, use_prod_roots, creds, args, + std::move(interceptor_creators)); +} + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& override_hostname, + testing::transport_security security_type, bool use_prod_roots, + const std::shared_ptr& creds, + std::vector< + std::unique_ptr> + interceptor_creators) { + return CreateTestChannel( + server, override_hostname, security_type, use_prod_roots, creds, + ChannelArguments(), std::move(interceptor_creators)); +} + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& credential_type, + const std::shared_ptr& creds, + std::vector< + std::unique_ptr> + interceptor_creators) { + ChannelArguments channel_args; + std::shared_ptr channel_creds = + testing::GetCredentialsProvider()->GetChannelCredentials(credential_type, + &channel_args); + GPR_ASSERT(channel_creds != nullptr); + if (creds.get()) { + channel_creds = CompositeChannelCredentials(channel_creds, creds); + } + return experimental::CreateCustomChannelWithInterceptors( + server, channel_creds, channel_args, std::move(interceptor_creators)); +} + } // namespace grpc diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index c615fb76536..e706acc6072 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -21,6 +21,7 @@ #include +#include #include namespace grpc { @@ -60,6 +61,38 @@ std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& credential_type, const std::shared_ptr& creds); +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& override_hostname, + testing::transport_security security_type, bool use_prod_roots, + const std::shared_ptr& creds, + std::vector< + std::unique_ptr> + interceptor_creators); + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& override_hostname, + testing::transport_security security_type, bool use_prod_roots, + const std::shared_ptr& creds, const ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& cred_type, + const grpc::string& override_hostname, bool use_prod_roots, + const std::shared_ptr& creds, + const ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); + +std::shared_ptr CreateTestChannel( + const grpc::string& server, const grpc::string& credential_type, + const std::shared_ptr& creds, + std::vector< + std::unique_ptr> + interceptor_creators); + } // namespace grpc #endif // GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H From 7afcb32650d1bfb012b8a21ba7d651779a42746f Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 25 Feb 2019 09:30:37 -0800 Subject: [PATCH 501/814] Avoid calling ares_library_init and ares_library_cleanup except for windows --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 2 +- .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 33 ++++++++----------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 69d4ee24368..c99943ab2f1 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -489,7 +489,7 @@ void grpc_resolver_dns_ares_init() { address_sorting_init(); grpc_error* error = grpc_ares_init(); if (error != GRPC_ERROR_NONE) { - GRPC_LOG_IF_ERROR("ares_library_init() failed", error); + GRPC_LOG_IF_ERROR("grpc_ares_init() failed", error); return; } if (default_resolver == nullptr) { diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index d41c8238f1c..501bfcb9464 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -8,11 +8,11 @@ * * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. * */ @@ -47,9 +47,6 @@ using grpc_core::ServerAddress; using grpc_core::ServerAddressList; -static gpr_once g_basic_init = GPR_ONCE_INIT; -static gpr_mu g_init_mu; - grpc_core::TraceFlag grpc_trace_cares_address_sorting(false, "cares_address_sorting"); @@ -89,8 +86,6 @@ typedef struct grpc_ares_hostbyname_request { bool is_balancer; } grpc_ares_hostbyname_request; -static void do_basic_init(void) { gpr_mu_init(&g_init_mu); } - static void log_address_sorting_list(const ServerAddressList& addresses, const char* input_output_str) { for (size_t i = 0; i < addresses.size(); i++) { @@ -588,12 +583,12 @@ static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) { void (*grpc_cancel_ares_request_locked)(grpc_ares_request* r) = grpc_cancel_ares_request_locked_impl; +// ares_library_init and ares_library_cleanup are currently no-op except under +// Windows. Calling them may cause race conditions when other parts of the +// binary calls these functions concurrently. +#ifdef GPR_WINDOWS grpc_error* grpc_ares_init(void) { - gpr_once_init(&g_basic_init, do_basic_init); - gpr_mu_lock(&g_init_mu); int status = ares_library_init(ARES_LIB_INIT_ALL); - gpr_mu_unlock(&g_init_mu); - if (status != ARES_SUCCESS) { char* error_msg; gpr_asprintf(&error_msg, "ares_library_init failed: %s", @@ -605,11 +600,11 @@ grpc_error* grpc_ares_init(void) { return GRPC_ERROR_NONE; } -void grpc_ares_cleanup(void) { - gpr_mu_lock(&g_init_mu); - ares_library_cleanup(); - gpr_mu_unlock(&g_init_mu); -} +void grpc_ares_cleanup(void) { ares_library_cleanup(); } +#else +grpc_error* grpc_ares_init(void) { return GRPC_ERROR_NONE; } +void grpc_ares_cleanup(void) {} +#endif // GPR_WINDOWS /* * grpc_resolve_address_ares related structs and functions From 6f3a00c1a337a165f6b745e2ef0e8a6ea3d302d2 Mon Sep 17 00:00:00 2001 From: Laurent Le Brun Date: Mon, 25 Feb 2019 18:33:33 +0100 Subject: [PATCH 502/814] Fix for future Bazel changes This fixes issues found by running Bazel with `--incompatible_no_support_tools_in_action_inputs` and `--incompatible_new_actions_api`. --- bazel/generate_cc.bzl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index 2f14071f92d..8f30c84f6b9 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -28,7 +28,7 @@ def generate_cc_impl(ctx): else: outs += [proto.path[label_len:-len(".proto")] + ".pb.h" for proto in protos] outs += [proto.path[label_len:-len(".proto")] + ".pb.cc" for proto in protos] - out_files = [ctx.new_file(out) for out in outs] + out_files = [ctx.actions.declare_file(out) for out in outs] dir_out = str(ctx.genfiles_dir.path + proto_root) arguments = [] @@ -38,10 +38,10 @@ def generate_cc_impl(ctx): if ctx.attr.generate_mocks: flags.append("generate_mock_code=true") arguments += ["--PLUGIN_out=" + ",".join(flags) + ":" + dir_out] - additional_input = [ctx.executable.plugin] + tools = [ctx.executable.plugin] else: arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] - additional_input = [] + tools = [] # Import protos relative to their workspace root so that protoc prints the # right include paths. @@ -70,8 +70,9 @@ def generate_cc_impl(ctx): arguments += ["-I{0}".format(f + "/../..")] well_known_proto_files = [f for f in ctx.attr.well_known_protos.files] - ctx.action( - inputs = protos + includes + additional_input + well_known_proto_files, + ctx.actions.run( + inputs = protos + includes + well_known_proto_files, + tools = tools, outputs = out_files, executable = ctx.executable._protoc, arguments = arguments, From 1b6b84d697f1ebd7d05385cb9903f4fea75637d1 Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Mon, 25 Feb 2019 09:34:40 -0800 Subject: [PATCH 503/814] bump version to v1.19.0 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index d18530bddc4..78e5e771bb0 100644 --- a/BUILD +++ b/BUILD @@ -68,7 +68,7 @@ g_stands_for = "gold" core_version = "7.0.0" -version = "1.19.0-pre1" +version = "1.19.0" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index fccc88afeb3..89f4eed7206 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gold - version: 1.19.0-pre1 + version: 1.19.0 filegroups: - name: alts_proto headers: From d63f0087671e0653e95a106eebf72d384875e5ce Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Mon, 25 Feb 2019 09:40:44 -0800 Subject: [PATCH 504/814] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 29 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23811c5b116..3e2fe1f9e0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.19.0-pre1") +set(PACKAGE_VERSION "1.19.0") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 8166dcf3a1d..b45a2398922 100644 --- a/Makefile +++ b/Makefile @@ -438,8 +438,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.19.0-pre1 -CSHARP_VERSION = 1.19.0-pre1 +CPP_VERSION = 1.19.0 +CSHARP_VERSION = 1.19.0 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 07b02cf8dfb..a50efc6aee9 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,15 +23,15 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.19.0-pre1' - version = '0.0.8-pre1' + # version = '1.19.0' + version = '0.0.8' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.19.0-pre1' + grpc_version = '1.19.0' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 6ac7c7e586e..32bc84ae179 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.19.0-pre1' + version = '1.19.0' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 9b4cd5a5568..80912221546 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.19.0-pre1' + version = '1.19.0' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 4ea2ff2e127..25d2f778464 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.19.0-pre1' + version = '1.19.0' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 1882471af68..77c6f7abd8c 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.19.0-pre1' + version = '1.19.0' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 2aea1a5bc4e..04cea9ac5fa 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-19 - 1.19.0RC1 - 1.19.0RC1 + 1.19.0 + 1.19.0 - beta - beta + stable + stable Apache 2.0 diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 49359fa4fbb..9fde35b0690 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.19.0-pre1"; } +grpc::string Version() { return "1.19.0"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index e967fb59e5c..0b9aafb8278 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.19.0-pre1 + 1.19.0 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 9885928f68a..f683477975d 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.19.0-pre1"; + public const string CurrentVersion = "1.19.0"; } } diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 636211ad360..8874a11020e 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.19.0-pre1 +set VERSION=1.19.0 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index e214b3980b5..16598be3f1f 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.19.0-pre1' + v = '1.19.0' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index c47780fb0b4..a48bd904087 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.19.0-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.19.0" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 962b699b38f..a9bb2178393 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.19.0-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.19.0" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index cf7761eb724..e673da4374b 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.19.0RC1" +#define PHP_GRPC_VERSION "1.19.0" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 17f82a81ce1..571243bda0c 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.19.0rc1""" +__version__ = """1.19.0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 6cf1234a392..82c8859089e 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.19.0rc1' +VERSION = '1.19.0' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index 922abf2ec70..bd30f636223 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.19.0rc1' +VERSION = '1.19.0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index d9eb56c5e9c..c37c99e6b63 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.19.0rc1' +VERSION = '1.19.0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 28fef1dc56b..f540ffe904c 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.19.0rc1' +VERSION = '1.19.0' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index efa6ff2c508..89419367f2e 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.19.0rc1' +VERSION = '1.19.0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 0e593340ab2..4b92d7c28ef 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.19.0rc1' +VERSION = '1.19.0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index c8f6940e1a4..02c20a41887 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.19.0rc1' +VERSION = '1.19.0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 630d064fa05..8c161167ec7 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.19.0.pre1' + VERSION = '1.19.0' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index a4a115ac2c9..d53d6b47bf2 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.19.0.pre1' + VERSION = '1.19.0' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index a58218b3718..09c7466bfeb 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.19.0rc1' +VERSION = '1.19.0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index ae4e398051e..db3d593b75f 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.19.0-pre1 +PROJECT_NUMBER = 1.19.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index e19fd05c0c1..7b3efe72309 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.19.0-pre1 +PROJECT_NUMBER = 1.19.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From 456f748b2f63be2197da033fc250be753439fb48 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 25 Feb 2019 10:11:06 -0800 Subject: [PATCH 505/814] Revert "Merge pull request #18146 from grpc/revert-17308-shutdown" This reverts commit 9079e98dfc6ed759aecee04a55476df3fb08545c, reversing changes made to 76a38bfcc2bd433f1f7d1eda61ef300f5b3e1665. --- grpc.def | 1 + include/grpc/grpc.h | 13 ++- src/core/lib/debug/trace.h | 3 +- src/core/lib/gprpp/thd.h | 40 ++++++- src/core/lib/gprpp/thd_posix.cc | 44 ++++--- src/core/lib/gprpp/thd_windows.cc | 54 ++++++--- src/core/lib/surface/init.cc | 108 +++++++++++++----- src/core/lib/surface/init.h | 1 + src/php/ext/grpc/php_grpc.c | 2 +- .../grpcio/grpc/_cython/_cygrpc/call.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/channel.pyx.pxi | 2 +- .../_cython/_cygrpc/completion_queue.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/credentials.pyx.pxi | 8 +- .../grpcio/grpc/_cython/_cygrpc/grpc.pxi | 2 +- .../grpc/_cython/_cygrpc/records.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/server.pyx.pxi | 2 +- src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 + src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 + .../resolvers/dns_resolver_cooldown_test.cc | 3 +- test/core/end2end/fuzzers/api_fuzzer.cc | 2 +- test/core/end2end/fuzzers/client_fuzzer.cc | 10 +- test/core/end2end/fuzzers/server_fuzzer.cc | 8 +- .../readahead_handshaker_server_ssl.cc | 2 +- test/core/iomgr/resolve_address_test.cc | 14 ++- test/core/json/fuzzer.cc | 6 +- test/core/memory_usage/client.cc | 2 +- test/core/memory_usage/server.cc | 2 +- test/core/security/alts_credentials_fuzzer.cc | 10 +- test/core/security/ssl_server_fuzzer.cc | 10 +- test/core/slice/percent_decode_fuzzer.cc | 33 +++--- test/core/slice/percent_encode_fuzzer.cc | 40 +++---- test/core/surface/init_test.cc | 21 +++- .../core/surface/public_headers_must_be_c89.c | 1 + test/core/util/memory_counters.cc | 31 +++++ test/core/util/memory_counters.h | 18 +++ test/core/util/port.cc | 2 +- test/core/util/test_config.cc | 3 +- test/cpp/naming/address_sorting_test.cc | 2 +- test/cpp/util/grpc_tool_test.cc | 16 +-- 39 files changed, 344 insertions(+), 183 deletions(-) diff --git a/grpc.def b/grpc.def index 59e29e0d168..e0a08d22c19 100644 --- a/grpc.def +++ b/grpc.def @@ -16,6 +16,7 @@ EXPORTS grpc_init grpc_shutdown grpc_is_initialized + grpc_shutdown_blocking grpc_version_string grpc_g_stands_for grpc_completion_queue_factory_lookup diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index fec7f5269e1..c4715ccc05e 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -73,10 +73,11 @@ GRPCAPI void grpc_init(void); Before it's called, there should haven been a matching invocation to grpc_init(). - No memory is used by grpc after this call returns, nor are any instructions - executing within the grpc library. - Prior to calling, all application owned grpc objects must have been - destroyed. */ + The last call to grpc_shutdown will initiate cleaning up of grpc library + internals, which can happen in another thread. Once the clean-up is done, + no memory is used by grpc, nor are any instructions executing within the + grpc library. Prior to calling, all application owned grpc objects must + have been destroyed. */ GRPCAPI void grpc_shutdown(void); /** EXPERIMENTAL. Returns 1 if the grpc library has been initialized. @@ -85,6 +86,10 @@ GRPCAPI void grpc_shutdown(void); https://github.com/grpc/grpc/issues/15334 */ GRPCAPI int grpc_is_initialized(void); +/** EXPERIMENTAL. Blocking shut down grpc library. + This is only for wrapped language to use now. */ +GRPCAPI void grpc_shutdown_blocking(void); + /** Return a string representing the current version of grpc */ GRPCAPI const char* grpc_version_string(void); diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h index 4623494520e..6108fb239bd 100644 --- a/src/core/lib/debug/trace.h +++ b/src/core/lib/debug/trace.h @@ -53,7 +53,8 @@ void grpc_tracer_enable_flag(grpc_core::TraceFlag* flag); class TraceFlag { public: TraceFlag(bool default_enabled, const char* name); - // This needs to be trivially destructible as it is used as global variable. + // TraceFlag needs to be trivially destructible since it is used as global + // variable. ~TraceFlag() = default; const char* name() const { return name_; } diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index e61e1c8ed04..0d94f2ec0c5 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -47,6 +47,27 @@ class ThreadInternalsInterface { class Thread { public: + class Options { + public: + Options() : joinable_(true), tracked_(true) {} + /// Set whether the thread is joinable or detached. + Options& set_joinable(bool joinable) { + joinable_ = joinable; + return *this; + } + bool joinable() const { return joinable_; } + + /// Set whether the thread is tracked for fork support. + Options& set_tracked(bool tracked) { + tracked_ = tracked; + return *this; + } + bool tracked() const { return tracked_; } + + private: + bool joinable_; + bool tracked_; + }; /// Default constructor only to allow use in structs that lack constructors /// Does not produce a validly-constructed thread; must later /// use placement new to construct a real thread. Does not init mu_ and cv_ @@ -57,14 +78,17 @@ class Thread { /// with argument \a arg once it is started. /// The optional \a success argument indicates whether the thread /// is successfully created. + /// The optional \a options can be used to set the thread detachable. Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success = nullptr); + bool* success = nullptr, const Options& options = Options()); /// Move constructor for thread. After this is called, the other thread /// no longer represents a living thread object - Thread(Thread&& other) : state_(other.state_), impl_(other.impl_) { + Thread(Thread&& other) + : state_(other.state_), impl_(other.impl_), options_(other.options_) { other.state_ = MOVED; other.impl_ = nullptr; + other.options_ = Options(); } /// Move assignment operator for thread. After this is called, the other @@ -79,8 +103,10 @@ class Thread { // assert it for the time being. state_ = other.state_; impl_ = other.impl_; + options_ = other.options_; other.state_ = MOVED; other.impl_ = nullptr; + other.options_ = Options(); } return *this; } @@ -95,11 +121,16 @@ class Thread { GPR_ASSERT(state_ == ALIVE); state_ = STARTED; impl_->Start(); + if (!options_.joinable()) { + state_ = DONE; + impl_ = nullptr; + } } else { GPR_ASSERT(state_ == FAILED); } - }; + } + // It is only legal to call Join if the Thread is created as joinable. void Join() { if (impl_ != nullptr) { impl_->Join(); @@ -119,12 +150,13 @@ class Thread { /// FAKE -- just a dummy placeholder Thread created by the default constructor /// ALIVE -- an actual thread of control exists associated with this thread /// STARTED -- the thread of control has been started - /// DONE -- the thread of control has completed and been joined + /// DONE -- the thread of control has completed and been joined/detached /// FAILED -- the thread of control never came alive /// MOVED -- contents were moved out and we're no longer tracking them enum ThreadState { FAKE, ALIVE, STARTED, DONE, FAILED, MOVED }; ThreadState state_; internal::ThreadInternalsInterface* impl_; + Options options_; }; } // namespace grpc_core diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc index 2751b221a8f..28932081538 100644 --- a/src/core/lib/gprpp/thd_posix.cc +++ b/src/core/lib/gprpp/thd_posix.cc @@ -44,13 +44,14 @@ struct thd_arg { void (*body)(void* arg); /* body of a thread */ void* arg; /* argument to a thread */ const char* name; /* name of thread. Can be nullptr. */ + bool joinable; + bool tracked; }; -class ThreadInternalsPosix - : public grpc_core::internal::ThreadInternalsInterface { +class ThreadInternalsPosix : public internal::ThreadInternalsInterface { public: ThreadInternalsPosix(const char* thd_name, void (*thd_body)(void* arg), - void* arg, bool* success) + void* arg, bool* success, const Thread::Options& options) : started_(false) { gpr_mu_init(&mu_); gpr_cv_init(&ready_); @@ -63,11 +64,20 @@ class ThreadInternalsPosix info->body = thd_body; info->arg = arg; info->name = thd_name; - grpc_core::Fork::IncThreadCount(); + info->joinable = options.joinable(); + info->tracked = options.tracked(); + if (options.tracked()) { + Fork::IncThreadCount(); + } GPR_ASSERT(pthread_attr_init(&attr) == 0); - GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == - 0); + if (options.joinable()) { + GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == + 0); + } else { + GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == + 0); + } *success = (pthread_create(&pthread_id_, &attr, @@ -97,8 +107,14 @@ class ThreadInternalsPosix } gpr_mu_unlock(&arg.thread->mu_); + if (!arg.joinable) { + Delete(arg.thread); + } + (*arg.body)(arg.arg); - grpc_core::Fork::DecThreadCount(); + if (arg.tracked) { + Fork::DecThreadCount(); + } return nullptr; }, info) == 0); @@ -108,9 +124,11 @@ class ThreadInternalsPosix if (!(*success)) { /* don't use gpr_free, as this was allocated using malloc (see above) */ free(info); - grpc_core::Fork::DecThreadCount(); + if (options.tracked()) { + Fork::DecThreadCount(); + } } - }; + } ~ThreadInternalsPosix() override { gpr_mu_destroy(&mu_); @@ -136,15 +154,15 @@ class ThreadInternalsPosix } // namespace Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success) { + bool* success, const Options& options) + : options_(options) { bool outcome = false; - impl_ = - grpc_core::New(thd_name, thd_body, arg, &outcome); + impl_ = New(thd_name, thd_body, arg, &outcome, options); if (outcome) { state_ = ALIVE; } else { state_ = FAILED; - grpc_core::Delete(impl_); + Delete(impl_); impl_ = nullptr; } diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc index 2512002a96c..bbb48a58cd6 100644 --- a/src/core/lib/gprpp/thd_windows.cc +++ b/src/core/lib/gprpp/thd_windows.cc @@ -46,6 +46,7 @@ struct thd_info { void (*body)(void* arg); /* body of a thread */ void* arg; /* argument to a thread */ HANDLE join_event; /* the join event */ + bool joinable; /* whether it is joinable */ }; thread_local struct thd_info* g_thd_info; @@ -53,7 +54,8 @@ thread_local struct thd_info* g_thd_info; class ThreadInternalsWindows : public grpc_core::internal::ThreadInternalsInterface { public: - ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success) + ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success, + const grpc_core::Thread::Options& options) : started_(false) { gpr_mu_init(&mu_); gpr_cv_init(&ready_); @@ -63,20 +65,23 @@ class ThreadInternalsWindows info_->thread = this; info_->body = thd_body; info_->arg = arg; - - info_->join_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (info_->join_event == nullptr) { - gpr_free(info_); + info_->join_event = nullptr; + info_->joinable = options.joinable(); + if (info_->joinable) { + info_->join_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + if (info_->join_event == nullptr) { + gpr_free(info_); + *success = false; + return; + } + } + handle = CreateThread(nullptr, 64 * 1024, thread_body, info_, 0, nullptr); + if (handle == nullptr) { + destroy_thread(); *success = false; } else { - handle = CreateThread(nullptr, 64 * 1024, thread_body, info_, 0, nullptr); - if (handle == nullptr) { - destroy_thread(); - *success = false; - } else { - CloseHandle(handle); - *success = true; - } + CloseHandle(handle); + *success = true; } } @@ -107,14 +112,24 @@ class ThreadInternalsWindows gpr_inf_future(GPR_CLOCK_MONOTONIC)); } gpr_mu_unlock(&g_thd_info->thread->mu_); + if (!g_thd_info->joinable) { + grpc_core::Delete(g_thd_info->thread); + g_thd_info->thread = nullptr; + } g_thd_info->body(g_thd_info->arg); - BOOL ret = SetEvent(g_thd_info->join_event); - GPR_ASSERT(ret); + if (g_thd_info->joinable) { + BOOL ret = SetEvent(g_thd_info->join_event); + GPR_ASSERT(ret); + } else { + gpr_free(g_thd_info); + } return 0; } void destroy_thread() { - CloseHandle(info_->join_event); + if (info_ != nullptr && info_->joinable) { + CloseHandle(info_->join_event); + } gpr_free(info_); } @@ -129,14 +144,15 @@ class ThreadInternalsWindows namespace grpc_core { Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg, - bool* success) { + bool* success, const Options& options) + : options_(options) { bool outcome = false; - impl_ = grpc_core::New(thd_body, arg, &outcome); + impl_ = New(thd_body, arg, &outcome, options); if (outcome) { state_ = ALIVE; } else { state_ = FAILED; - grpc_core::Delete(impl_); + Delete(impl_); impl_ = nullptr; } diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index e507de87c2a..fdb584da68f 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -33,6 +33,7 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/gprpp/fork.h" +#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/call_combiner.h" #include "src/core/lib/iomgr/combiner.h" @@ -61,10 +62,15 @@ extern void grpc_register_built_in_plugins(void); static gpr_once g_basic_init = GPR_ONCE_INIT; static gpr_mu g_init_mu; static int g_initializations; +static gpr_cv* g_shutting_down_cv; +static bool g_shutting_down; static void do_basic_init(void) { gpr_log_verbosity_init(); gpr_mu_init(&g_init_mu); + g_shutting_down_cv = static_cast(malloc(sizeof(gpr_cv))); + gpr_cv_init(g_shutting_down_cv); + g_shutting_down = false; grpc_register_built_in_plugins(); grpc_cq_global_init(); g_initializations = 0; @@ -118,8 +124,12 @@ void grpc_init(void) { int i; gpr_once_init(&g_basic_init, do_basic_init); - gpr_mu_lock(&g_init_mu); + grpc_core::MutexLock lock(&g_init_mu); if (++g_initializations == 1) { + if (g_shutting_down) { + g_shutting_down = false; + gpr_cv_broadcast(g_shutting_down_cv); + } grpc_core::Fork::GlobalInit(); grpc_fork_handlers_auto_register(); gpr_time_init(); @@ -150,50 +160,88 @@ void grpc_init(void) { grpc_channel_init_finalize(); grpc_iomgr_start(); } - gpr_mu_unlock(&g_init_mu); GRPC_API_TRACE("grpc_init(void)", 0, ()); } -void grpc_shutdown(void) { +void grpc_shutdown_internal_locked(void) { int i; - GRPC_API_TRACE("grpc_shutdown(void)", 0, ()); - gpr_mu_lock(&g_init_mu); - if (--g_initializations == 0) { + { + grpc_core::ExecCtx exec_ctx(0); + grpc_iomgr_shutdown_background_closure(); { - grpc_core::ExecCtx exec_ctx(0); - grpc_iomgr_shutdown_background_closure(); - { - grpc_timer_manager_set_threading( - false); // shutdown timer_manager thread - grpc_core::Executor::ShutdownAll(); - for (i = g_number_of_plugins; i >= 0; i--) { - if (g_all_of_the_plugins[i].destroy != nullptr) { - g_all_of_the_plugins[i].destroy(); - } + grpc_timer_manager_set_threading(false); // shutdown timer_manager thread + grpc_core::Executor::ShutdownAll(); + for (i = g_number_of_plugins; i >= 0; i--) { + if (g_all_of_the_plugins[i].destroy != nullptr) { + g_all_of_the_plugins[i].destroy(); } } - grpc_iomgr_shutdown(); - gpr_timers_global_destroy(); - grpc_tracer_shutdown(); - grpc_mdctx_global_shutdown(); - grpc_core::HandshakerRegistry::Shutdown(); - grpc_slice_intern_shutdown(); - grpc_core::channelz::ChannelzRegistry::Shutdown(); - grpc_stats_shutdown(); - grpc_core::Fork::GlobalShutdown(); } - grpc_core::ExecCtx::GlobalShutdown(); - grpc_core::ApplicationCallbackExecCtx::GlobalShutdown(); + grpc_iomgr_shutdown(); + gpr_timers_global_destroy(); + grpc_tracer_shutdown(); + grpc_mdctx_global_shutdown(); + grpc_core::HandshakerRegistry::Shutdown(); + grpc_slice_intern_shutdown(); + grpc_core::channelz::ChannelzRegistry::Shutdown(); + grpc_stats_shutdown(); + grpc_core::Fork::GlobalShutdown(); + } + grpc_core::ExecCtx::GlobalShutdown(); + grpc_core::ApplicationCallbackExecCtx::GlobalShutdown(); + g_shutting_down = false; + gpr_cv_broadcast(g_shutting_down_cv); +} + +void grpc_shutdown_internal(void* ignored) { + GRPC_API_TRACE("grpc_shutdown_internal", 0, ()); + grpc_core::MutexLock lock(&g_init_mu); + // We have released lock from the shutdown thread and it is possible that + // another grpc_init has been called, and do nothing if that is the case. + if (--g_initializations != 0) { + return; + } + grpc_shutdown_internal_locked(); +} + +void grpc_shutdown(void) { + GRPC_API_TRACE("grpc_shutdown(void)", 0, ()); + grpc_core::MutexLock lock(&g_init_mu); + if (--g_initializations == 0) { + g_initializations++; + g_shutting_down = true; + // spawn a detached thread to do the actual clean up in case we are + // currently in an executor thread. + grpc_core::Thread cleanup_thread( + "grpc_shutdown", grpc_shutdown_internal, nullptr, nullptr, + grpc_core::Thread::Options().set_joinable(false).set_tracked(false)); + cleanup_thread.Start(); + } +} + +void grpc_shutdown_blocking(void) { + GRPC_API_TRACE("grpc_shutdown_blocking(void)", 0, ()); + grpc_core::MutexLock lock(&g_init_mu); + if (--g_initializations == 0) { + g_shutting_down = true; + grpc_shutdown_internal_locked(); } - gpr_mu_unlock(&g_init_mu); } int grpc_is_initialized(void) { int r; gpr_once_init(&g_basic_init, do_basic_init); - gpr_mu_lock(&g_init_mu); + grpc_core::MutexLock lock(&g_init_mu); r = g_initializations > 0; - gpr_mu_unlock(&g_init_mu); return r; } + +void grpc_maybe_wait_for_async_shutdown(void) { + gpr_once_init(&g_basic_init, do_basic_init); + grpc_core::MutexLock lock(&g_init_mu); + while (g_shutting_down) { + gpr_cv_wait(g_shutting_down_cv, &g_init_mu, + gpr_inf_future(GPR_CLOCK_REALTIME)); + } +} diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 193f51447d9..6eaa488d054 100644 --- a/src/core/lib/surface/init.h +++ b/src/core/lib/surface/init.h @@ -22,5 +22,6 @@ void grpc_register_security_filters(void); void grpc_security_pre_init(void); void grpc_security_init(void); +void grpc_maybe_wait_for_async_shutdown(void); #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 111c6f4867d..fa6f0be837b 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -361,7 +361,7 @@ PHP_MSHUTDOWN_FUNCTION(grpc) { zend_hash_destroy(&grpc_target_upper_bound_map); grpc_shutdown_timeval(TSRMLS_C); grpc_php_shutdown_completion_queue(TSRMLS_C); - grpc_shutdown(); + grpc_shutdown_blocking(); GRPC_G(initialized) = 0; } return SUCCESS; diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi index 24e85b08e72..0a31d9c52ff 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi @@ -87,7 +87,7 @@ cdef class Call: def __dealloc__(self): if self.c_call != NULL: grpc_call_unref(self.c_call) - grpc_shutdown() + grpc_shutdown_blocking() # The object *should* always be valid from Python. Used for debugging. @property diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index 70d4abb7308..24c11e63a6b 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -399,7 +399,7 @@ cdef _close(Channel channel, grpc_status_code code, object details, _destroy_c_completion_queue(state.c_connectivity_completion_queue) grpc_channel_destroy(state.c_channel) state.c_channel = NULL - grpc_shutdown() + grpc_shutdown_blocking() state.condition.notify_all() else: # Another call to close already completed in the past or is currently diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi index 3c33b46dbb8..a4d425ac564 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -118,4 +118,4 @@ cdef class CompletionQueue: self.c_completion_queue, c_deadline, NULL) self._interpret_event(event) grpc_completion_queue_destroy(self.c_completion_queue) - grpc_shutdown() + grpc_shutdown_blocking() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 2f51be40ce4..5fb9ddf7b7d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -61,7 +61,7 @@ cdef int _get_metadata( cdef void _destroy(void *state) with gil: cpython.Py_DECREF(state) - grpc_shutdown() + grpc_shutdown_blocking() cdef class MetadataPluginCallCredentials(CallCredentials): @@ -125,7 +125,7 @@ cdef class SSLSessionCacheLRU: def __dealloc__(self): if self._cache != NULL: grpc_ssl_session_cache_destroy(self._cache) - grpc_shutdown() + grpc_shutdown_blocking() cdef class SSLChannelCredentials(ChannelCredentials): @@ -191,7 +191,7 @@ cdef class ServerCertificateConfig: def __dealloc__(self): grpc_ssl_server_certificate_config_destroy(self.c_cert_config) gpr_free(self.c_ssl_pem_key_cert_pairs) - grpc_shutdown() + grpc_shutdown_blocking() cdef class ServerCredentials: @@ -207,7 +207,7 @@ cdef class ServerCredentials: def __dealloc__(self): if self.c_credentials != NULL: grpc_server_credentials_release(self.c_credentials) - grpc_shutdown() + grpc_shutdown_blocking() cdef const char* _get_c_pem_root_certs(pem_root_certs): if pem_root_certs is None: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index fc7a9ba4395..759479089d4 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -319,7 +319,7 @@ cdef extern from "grpc/grpc.h": grpc_op_data data void grpc_init() nogil - void grpc_shutdown() nogil + void grpc_shutdown_blocking() nogil int grpc_is_initialized() nogil ctypedef struct grpc_completion_queue_factory: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index fe98d559f34..d612199a482 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -134,7 +134,7 @@ cdef class CallDetails: def __dealloc__(self): with nogil: grpc_call_details_destroy(&self.c_details) - grpc_shutdown() + grpc_shutdown_blocking() @property def method(self): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index ef74f61e043..fe55ea885e4 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -151,4 +151,4 @@ cdef class Server: def __dealloc__(self): if self.c_server == NULL: - grpc_shutdown() + grpc_shutdown_blocking() diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 47250ec7141..fdbe0df4e52 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -39,6 +39,7 @@ grpc_register_plugin_type grpc_register_plugin_import; grpc_init_type grpc_init_import; grpc_shutdown_type grpc_shutdown_import; grpc_is_initialized_type grpc_is_initialized_import; +grpc_shutdown_blocking_type grpc_shutdown_blocking_import; grpc_version_string_type grpc_version_string_import; grpc_g_stands_for_type grpc_g_stands_for_import; grpc_completion_queue_factory_lookup_type grpc_completion_queue_factory_lookup_import; @@ -306,6 +307,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_init_import = (grpc_init_type) GetProcAddress(library, "grpc_init"); grpc_shutdown_import = (grpc_shutdown_type) GetProcAddress(library, "grpc_shutdown"); grpc_is_initialized_import = (grpc_is_initialized_type) GetProcAddress(library, "grpc_is_initialized"); + grpc_shutdown_blocking_import = (grpc_shutdown_blocking_type) GetProcAddress(library, "grpc_shutdown_blocking"); grpc_version_string_import = (grpc_version_string_type) GetProcAddress(library, "grpc_version_string"); grpc_g_stands_for_import = (grpc_g_stands_for_type) GetProcAddress(library, "grpc_g_stands_for"); grpc_completion_queue_factory_lookup_import = (grpc_completion_queue_factory_lookup_type) GetProcAddress(library, "grpc_completion_queue_factory_lookup"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 9437f6d3918..cf16f0ca33b 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -92,6 +92,9 @@ extern grpc_shutdown_type grpc_shutdown_import; typedef int(*grpc_is_initialized_type)(void); extern grpc_is_initialized_type grpc_is_initialized_import; #define grpc_is_initialized grpc_is_initialized_import +typedef void(*grpc_shutdown_blocking_type)(void); +extern grpc_shutdown_blocking_type grpc_shutdown_blocking_import; +#define grpc_shutdown_blocking grpc_shutdown_blocking_import typedef const char*(*grpc_version_string_type)(void); extern grpc_version_string_type grpc_version_string_import; #define grpc_version_string grpc_version_string_import diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index 16210b8164b..3157d6019f3 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -18,6 +18,7 @@ #include +#include #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" @@ -281,7 +282,7 @@ int main(int argc, char** argv) { grpc_core::ExecCtx exec_ctx; GRPC_COMBINER_UNREF(g_combiner, "test"); } - grpc_shutdown(); + grpc_shutdown_blocking(); GPR_ASSERT(g_all_callbacks_invoked); return 0; } diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index 57bc8ad768c..74a30913b24 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -1200,6 +1200,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_resource_quota_unref(g_resource_quota); - grpc_shutdown(); + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/end2end/fuzzers/client_fuzzer.cc b/test/core/end2end/fuzzers/client_fuzzer.cc index 8520fb53755..55e6ce695ad 100644 --- a/test/core/end2end/fuzzers/client_fuzzer.cc +++ b/test/core/end2end/fuzzers/client_fuzzer.cc @@ -40,9 +40,8 @@ static void dont_log(gpr_log_func_args* args) {} extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_test_only_set_slice_hash_seed(0); - struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - if (leak_check) grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(leak_check); grpc_init(); { grpc_core::ExecCtx exec_ctx; @@ -159,11 +158,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_byte_buffer_destroy(response_payload_recv); } } - grpc_shutdown(); - if (leak_check) { - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); - } + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/end2end/fuzzers/server_fuzzer.cc b/test/core/end2end/fuzzers/server_fuzzer.cc index 644f98e37ac..f010066ea27 100644 --- a/test/core/end2end/fuzzers/server_fuzzer.cc +++ b/test/core/end2end/fuzzers/server_fuzzer.cc @@ -37,9 +37,8 @@ static void dont_log(gpr_log_func_args* args) {} extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_test_only_set_slice_hash_seed(0); - struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - if (leak_check) grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(leak_check); grpc_init(); { grpc_core::ExecCtx exec_ctx; @@ -136,10 +135,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_completion_queue_destroy(cq); } grpc_shutdown(); - if (leak_check) { - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); - } return 0; } diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc index e4584105e65..d91f2d2fe63 100644 --- a/test/core/handshake/readahead_handshaker_server_ssl.cc +++ b/test/core/handshake/readahead_handshaker_server_ssl.cc @@ -83,6 +83,6 @@ int main(int argc, char* argv[]) { UniquePtr(New())); const char* full_alpn_list[] = {"grpc-exp", "h2"}; GPR_ASSERT(server_ssl_test(full_alpn_list, 2, "grpc-exp")); - grpc_shutdown(); + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index b041a15ff34..f59a992416d 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -323,7 +323,11 @@ static bool mock_ipv6_disabled_source_addr_factory_get_source_addr( } void mock_ipv6_disabled_source_addr_factory_destroy( - address_sorting_source_addr_factory* factory) {} + address_sorting_source_addr_factory* factory) { + mock_ipv6_disabled_source_addr_factory* f = + reinterpret_cast(factory); + gpr_free(f); +} const address_sorting_source_addr_factory_vtable kMockIpv6DisabledSourceAddrFactoryVtable = { @@ -390,9 +394,11 @@ int main(int argc, char** argv) { // Run a test case in which c-ares's address sorter // thinks that IPv4 is available and IPv6 isn't. grpc_init(); - mock_ipv6_disabled_source_addr_factory factory; - factory.base.vtable = &kMockIpv6DisabledSourceAddrFactoryVtable; - address_sorting_override_source_addr_factory_for_testing(&factory.base); + mock_ipv6_disabled_source_addr_factory* factory = + static_cast( + gpr_malloc(sizeof(mock_ipv6_disabled_source_addr_factory))); + factory->base.vtable = &kMockIpv6DisabledSourceAddrFactoryVtable; + address_sorting_override_source_addr_factory_for_testing(&factory->base); test_localhost_result_has_ipv4_first_when_ipv6_isnt_available(); grpc_shutdown(); } diff --git a/test/core/json/fuzzer.cc b/test/core/json/fuzzer.cc index 6dafabb95b3..8b3e9792d15 100644 --- a/test/core/json/fuzzer.cc +++ b/test/core/json/fuzzer.cc @@ -31,8 +31,7 @@ bool leak_check = true; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { char* s; - struct grpc_memory_counters counters; - grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(true); s = static_cast(gpr_malloc(size)); memcpy(s, data, size); grpc_json* x; @@ -40,8 +39,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_json_destroy(x); } gpr_free(s); - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); return 0; } diff --git a/test/core/memory_usage/client.cc b/test/core/memory_usage/client.cc index 467586ea5f4..097288c5efa 100644 --- a/test/core/memory_usage/client.cc +++ b/test/core/memory_usage/client.cc @@ -285,7 +285,7 @@ int main(int argc, char** argv) { grpc_slice_unref(slice); grpc_completion_queue_destroy(cq); - grpc_shutdown(); + grpc_shutdown_blocking(); gpr_log(GPR_INFO, "---------client stats--------"); gpr_log( diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc index 7424797e6f5..6fb14fa31a0 100644 --- a/test/core/memory_usage/server.cc +++ b/test/core/memory_usage/server.cc @@ -318,7 +318,7 @@ int main(int argc, char** argv) { grpc_server_destroy(server); grpc_completion_queue_destroy(cq); - grpc_shutdown(); + grpc_shutdown_blocking(); grpc_memory_counters_destroy(); return 0; } diff --git a/test/core/security/alts_credentials_fuzzer.cc b/test/core/security/alts_credentials_fuzzer.cc index bf18f0a589e..abe50031687 100644 --- a/test/core/security/alts_credentials_fuzzer.cc +++ b/test/core/security/alts_credentials_fuzzer.cc @@ -66,10 +66,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { gpr_set_log_function(dont_log); } gpr_free(grpc_trace_fuzzer); - struct grpc_memory_counters counters; - if (leak_check) { - grpc_memory_counters_init(); - } + grpc_core::testing::LeakDetector leak_detector(leak_check); input_stream inp = {data, data + size}; grpc_init(); bool is_on_gcp = grpc_alts_is_running_on_gcp(); @@ -111,10 +108,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { gpr_free(handshaker_service_url); } grpc_shutdown(); - if (leak_check) { - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); - } return 0; } diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc index 8533644aceb..5846964eb90 100644 --- a/test/core/security/ssl_server_fuzzer.cc +++ b/test/core/security/ssl_server_fuzzer.cc @@ -52,9 +52,8 @@ static void on_handshake_done(void* arg, grpc_error* error) { } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - struct grpc_memory_counters counters; if (squelch) gpr_set_log_function(dont_log); - if (leak_check) grpc_memory_counters_init(); + grpc_core::testing::LeakDetector leak_detector(leak_check); grpc_init(); { grpc_core::ExecCtx exec_ctx; @@ -118,11 +117,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_core::ExecCtx::Get()->Flush(); } - grpc_shutdown(); - if (leak_check) { - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - GPR_ASSERT(counters.total_size_relative == 0); - } + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/slice/percent_decode_fuzzer.cc b/test/core/slice/percent_decode_fuzzer.cc index 81eb031014f..11f71d92c46 100644 --- a/test/core/slice/percent_decode_fuzzer.cc +++ b/test/core/slice/percent_decode_fuzzer.cc @@ -31,24 +31,23 @@ bool squelch = true; bool leak_check = true; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - struct grpc_memory_counters counters; grpc_init(); - grpc_memory_counters_init(); - grpc_slice input = grpc_slice_from_copied_buffer((const char*)data, size); - grpc_slice output; - if (grpc_strict_percent_decode_slice( - input, grpc_url_percent_encoding_unreserved_bytes, &output)) { - grpc_slice_unref(output); + { + grpc_core::testing::LeakDetector leak_detector(true); + grpc_slice input = grpc_slice_from_copied_buffer((const char*)data, size); + grpc_slice output; + if (grpc_strict_percent_decode_slice( + input, grpc_url_percent_encoding_unreserved_bytes, &output)) { + grpc_slice_unref(output); + } + if (grpc_strict_percent_decode_slice( + input, grpc_compatible_percent_encoding_unreserved_bytes, + &output)) { + grpc_slice_unref(output); + } + grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); + grpc_slice_unref(input); } - if (grpc_strict_percent_decode_slice( - input, grpc_compatible_percent_encoding_unreserved_bytes, &output)) { - grpc_slice_unref(output); - } - grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); - grpc_slice_unref(input); - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - grpc_shutdown(); - GPR_ASSERT(counters.total_size_relative == 0); + grpc_shutdown_blocking(); return 0; } diff --git a/test/core/slice/percent_encode_fuzzer.cc b/test/core/slice/percent_encode_fuzzer.cc index 1fd197e180a..1da982bba28 100644 --- a/test/core/slice/percent_encode_fuzzer.cc +++ b/test/core/slice/percent_encode_fuzzer.cc @@ -31,28 +31,26 @@ bool squelch = true; bool leak_check = true; static void test(const uint8_t* data, size_t size, const uint8_t* dict) { - struct grpc_memory_counters counters; grpc_init(); - grpc_memory_counters_init(); - grpc_slice input = - grpc_slice_from_copied_buffer(reinterpret_cast(data), size); - grpc_slice output = grpc_percent_encode_slice(input, dict); - grpc_slice decoded_output; - // encoder must always produce decodable output - GPR_ASSERT(grpc_strict_percent_decode_slice(output, dict, &decoded_output)); - grpc_slice permissive_decoded_output = - grpc_permissive_percent_decode_slice(output); - // and decoded output must always match the input - GPR_ASSERT(grpc_slice_eq(input, decoded_output)); - GPR_ASSERT(grpc_slice_eq(input, permissive_decoded_output)); - grpc_slice_unref(input); - grpc_slice_unref(output); - grpc_slice_unref(decoded_output); - grpc_slice_unref(permissive_decoded_output); - counters = grpc_memory_counters_snapshot(); - grpc_memory_counters_destroy(); - grpc_shutdown(); - GPR_ASSERT(counters.total_size_relative == 0); + { + grpc_core::testing::LeakDetector leak_detector(true); + grpc_slice input = grpc_slice_from_copied_buffer( + reinterpret_cast(data), size); + grpc_slice output = grpc_percent_encode_slice(input, dict); + grpc_slice decoded_output; + // encoder must always produce decodable output + GPR_ASSERT(grpc_strict_percent_decode_slice(output, dict, &decoded_output)); + grpc_slice permissive_decoded_output = + grpc_permissive_percent_decode_slice(output); + // and decoded output must always match the input + GPR_ASSERT(grpc_slice_eq(input, decoded_output)); + GPR_ASSERT(grpc_slice_eq(input, permissive_decoded_output)); + grpc_slice_unref(input); + grpc_slice_unref(output); + grpc_slice_unref(decoded_output); + grpc_slice_unref(permissive_decoded_output); + } + grpc_shutdown_blocking(); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { diff --git a/test/core/surface/init_test.cc b/test/core/surface/init_test.cc index 1bcd13a0b89..583dd1b6de9 100644 --- a/test/core/surface/init_test.cc +++ b/test/core/surface/init_test.cc @@ -18,6 +18,9 @@ #include #include +#include + +#include "src/core/lib/surface/init.h" #include "test/core/util/test_config.h" static int g_flag; @@ -30,6 +33,17 @@ static void test(int rounds) { for (i = 0; i < rounds; i++) { grpc_shutdown(); } + grpc_maybe_wait_for_async_shutdown(); +} + +static void test_blocking(int rounds) { + int i; + for (i = 0; i < rounds; i++) { + grpc_init(); + } + for (i = 0; i < rounds; i++) { + grpc_shutdown_blocking(); + } } static void test_mixed(void) { @@ -39,6 +53,7 @@ static void test_mixed(void) { grpc_init(); grpc_shutdown(); grpc_shutdown(); + grpc_maybe_wait_for_async_shutdown(); } static void plugin_init(void) { g_flag = 1; } @@ -48,7 +63,7 @@ static void test_plugin() { grpc_register_plugin(plugin_init, plugin_destroy); grpc_init(); GPR_ASSERT(g_flag == 1); - grpc_shutdown(); + grpc_shutdown_blocking(); GPR_ASSERT(g_flag == 2); } @@ -57,6 +72,7 @@ static void test_repeatedly() { grpc_init(); grpc_shutdown(); } + grpc_maybe_wait_for_async_shutdown(); } int main(int argc, char** argv) { @@ -64,6 +80,9 @@ int main(int argc, char** argv) { test(1); test(2); test(3); + test_blocking(1); + test_blocking(2); + test_blocking(3); test_mixed(); test_plugin(); test_repeatedly(); diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 1c9b67027c5..04d0506b3c2 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -78,6 +78,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_init); printf("%lx", (unsigned long) grpc_shutdown); printf("%lx", (unsigned long) grpc_is_initialized); + printf("%lx", (unsigned long) grpc_shutdown_blocking); printf("%lx", (unsigned long) grpc_version_string); printf("%lx", (unsigned long) grpc_g_stands_for); printf("%lx", (unsigned long) grpc_completion_queue_factory_lookup); diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index d0da05d9b4d..787fb76e48b 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -16,13 +16,18 @@ * */ +#include #include #include +#include #include +#include #include +#include #include "src/core/lib/gpr/alloc.h" +#include "src/core/lib/surface/init.h" #include "test/core/util/memory_counters.h" static struct grpc_memory_counters g_memory_counters; @@ -110,3 +115,29 @@ struct grpc_memory_counters grpc_memory_counters_snapshot() { NO_BARRIER_LOAD(&g_memory_counters.total_allocs_absolute); return counters; } + +namespace grpc_core { +namespace testing { + +LeakDetector::LeakDetector(bool enable) : enabled_(enable) { + if (enabled_) { + grpc_memory_counters_init(); + } +} + +LeakDetector::~LeakDetector() { + // Wait for grpc_shutdown() to finish its async work. + grpc_maybe_wait_for_async_shutdown(); + if (enabled_) { + struct grpc_memory_counters counters = grpc_memory_counters_snapshot(); + if (counters.total_size_relative != 0) { + gpr_log(GPR_ERROR, "Leaking %" PRIuPTR " bytes", + static_cast(counters.total_size_relative)); + GPR_ASSERT(0); + } + grpc_memory_counters_destroy(); + } +} + +} // namespace testing +} // namespace grpc_core diff --git a/test/core/util/memory_counters.h b/test/core/util/memory_counters.h index c23a13e5c85..c92a001ff13 100644 --- a/test/core/util/memory_counters.h +++ b/test/core/util/memory_counters.h @@ -32,4 +32,22 @@ void grpc_memory_counters_init(); void grpc_memory_counters_destroy(); struct grpc_memory_counters grpc_memory_counters_snapshot(); +namespace grpc_core { +namespace testing { + +// At destruction time, it will check there is no memory leak. +// The object should be created before grpc_init() is called and destroyed after +// grpc_shutdown() is returned. +class LeakDetector { + public: + explicit LeakDetector(bool enable); + ~LeakDetector(); + + private: + const bool enabled_; +}; + +} // namespace testing +} // namespace grpc_core + #endif diff --git a/test/core/util/port.cc b/test/core/util/port.cc index 303306de452..fe4caa6faf6 100644 --- a/test/core/util/port.cc +++ b/test/core/util/port.cc @@ -66,7 +66,7 @@ static void free_chosen_ports(void) { for (i = 0; i < num_chosen_ports; i++) { grpc_free_port_using_server(chosen_ports[i]); } - grpc_shutdown(); + grpc_shutdown_blocking(); gpr_free(chosen_ports); } diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index fe80bb2d4d0..0c0492fdbbd 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -31,6 +31,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/surface/init.h" int64_t g_fixture_slowdown_factor = 1; int64_t g_poller_slowdown_factor = 1; @@ -405,7 +406,7 @@ TestEnvironment::TestEnvironment(int argc, char** argv) { grpc_test_init(argc, argv); } -TestEnvironment::~TestEnvironment() {} +TestEnvironment::~TestEnvironment() { grpc_maybe_wait_for_async_shutdown(); } } // namespace testing } // namespace grpc diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index 09e705df789..e6b14888ffb 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -197,7 +197,7 @@ void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses, class AddressSortingTest : public ::testing::Test { protected: void SetUp() override { grpc_init(); } - void TearDown() override { grpc_shutdown(); } + void TearDown() override { grpc_shutdown_blocking(); } }; /* Tests for rule 1 */ diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index b96b00f2db2..57cdbeb7b76 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -258,14 +258,6 @@ class GrpcToolTest : public ::testing::Test { void ShutdownServer() { server_->Shutdown(); } - void ExitWhenError(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback) { - int result = GrpcToolMainLib(argc, argv, cred, callback); - if (result) { - exit(result); - } - } - std::unique_ptr server_; TestServiceImpl service_; reflection::ProtoServerReflectionPlugin plugin_; @@ -418,11 +410,9 @@ TEST_F(GrpcToolTest, TypeNotFound) { const char* argv[] = {"grpc_cli", "type", server_address.c_str(), "grpc.testing.DummyRequest"}; - EXPECT_DEATH(ExitWhenError(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1)), - ".*Type grpc.testing.DummyRequest not found.*"); - + EXPECT_TRUE(1 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); ShutdownServer(); } From 4adf0b1aaeb66ab19b31012d5b087af97c33fe27 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 25 Feb 2019 10:15:57 -0800 Subject: [PATCH 506/814] Reproduce #18120 --- src/core/lib/gprpp/thd.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index 0d94f2ec0c5..5631c5f1f0e 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -112,19 +112,22 @@ class Thread { } /// The destructor is strictly optional; either the thread never came to life - /// and the constructor itself killed it or it has already been joined and - /// the Join function kills it. The destructor shouldn't have to do anything. - ~Thread() { GPR_ASSERT(impl_ == nullptr); } + /// and the constructor itself killed it, or it has already been joined and + /// the Join function kills it, or it was detached (non-joinable) and it has + /// run to completion and is now killing itself. The destructor shouldn't have + /// to do anything. + ~Thread() { GPR_ASSERT(!options_.joinable() || impl_ == nullptr); } void Start() { if (impl_ != nullptr) { GPR_ASSERT(state_ == ALIVE); state_ = STARTED; impl_->Start(); - if (!options_.joinable()) { - state_ = DONE; - impl_ = nullptr; - } + // If the Thread is not joinable, then the impl_ will cause the deletion + // of this Thread object when the thread function completes. Since no + // other operation is allowed to a detached thread after Start, there is + // no need to change the value of the impl_ or state_ . The next operation + // on this object will be the deletion, which will trigger the destructor. } else { GPR_ASSERT(state_ == FAILED); } From 5480dc5cd6ebefaf10f76526ad1835abcc4a968f Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 25 Feb 2019 10:28:06 -0800 Subject: [PATCH 507/814] fix client_lb_e2e_test --- test/cpp/end2end/client_lb_end2end_test.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 049b732e1a0..996ba0edbbe 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -153,7 +153,13 @@ class ClientLbEnd2endTest : public ::testing::Test { for (size_t i = 0; i < servers_.size(); ++i) { servers_[i]->Shutdown(); } - grpc_shutdown(); + // Explicitly destroy all the members so that we can make sure grpc_shutdown + // has finished by the end of this function, and thus all the registered + // LB policy factories are removed. + stub_.reset(); + servers_.clear(); + creds_.reset(); + grpc_shutdown_blocking(); } void CreateServers(size_t num_servers, From 8259bc25ceaa2d2e03f03e00c086c518aeca1503 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 25 Feb 2019 10:43:26 -0800 Subject: [PATCH 508/814] fix format --- .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 501bfcb9464..986af89454f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -8,11 +8,11 @@ * * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software * - * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. * */ From b003ae6eb942ef13348a788107dc8e16a561fe65 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 25 Feb 2019 11:23:56 -0800 Subject: [PATCH 509/814] Update comment --- src/core/lib/gprpp/thd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h index 5631c5f1f0e..cae707061e0 100644 --- a/src/core/lib/gprpp/thd.h +++ b/src/core/lib/gprpp/thd.h @@ -153,7 +153,7 @@ class Thread { /// FAKE -- just a dummy placeholder Thread created by the default constructor /// ALIVE -- an actual thread of control exists associated with this thread /// STARTED -- the thread of control has been started - /// DONE -- the thread of control has completed and been joined/detached + /// DONE -- the thread of control has completed and been joined /// FAILED -- the thread of control never came alive /// MOVED -- contents were moved out and we're no longer tracking them enum ThreadState { FAKE, ALIVE, STARTED, DONE, FAILED, MOVED }; From 9d81e9ef61041d4143f489df255bd950baa8613c Mon Sep 17 00:00:00 2001 From: billfeng327 Date: Mon, 25 Feb 2019 15:21:08 -0800 Subject: [PATCH 510/814] updated version of abseil for enabling windows bazel build --- bazel/grpc_deps.bzl | 8 ++++---- third_party/abseil-cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 61a46e1ee5c..e2e47292242 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -170,8 +170,8 @@ def grpc_deps(): if "com_google_absl" not in native.existing_rules(): http_archive( name = "com_google_absl", - strip_prefix = "abseil-cpp-cd95e71df6eaf8f2a282b1da556c2cf1c9b09207", - url = "https://github.com/abseil/abseil-cpp/archive/cd95e71df6eaf8f2a282b1da556c2cf1c9b09207.tar.gz", + strip_prefix = "abseil-cpp-308ce31528a7edfa39f5f6d36142278a0ae1bf45", + url = "https://github.com/abseil/abseil-cpp/archive/308ce31528a7edfa39f5f6d36142278a0ae1bf45.tar.gz", ) if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): @@ -196,8 +196,8 @@ def grpc_deps(): if "io_opencensus_cpp" not in native.existing_rules(): http_archive( name = "io_opencensus_cpp", - strip_prefix = "opencensus-cpp-fdf0f308b1631bb4a942e32ba5d22536a6170274", - url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz", + strip_prefix = "opencensus-cpp-03dff0352522983ffdee48cedbf87cbe37f1bb7f", + url = "https://github.com/census-instrumentation/opencensus-cpp/archive/03dff0352522983ffdee48cedbf87cbe37f1bb7f.tar.gz", ) if "upb" not in native.existing_rules(): diff --git a/third_party/abseil-cpp b/third_party/abseil-cpp index cc4bed2d74f..308ce31528a 160000 --- a/third_party/abseil-cpp +++ b/third_party/abseil-cpp @@ -1 +1 @@ -Subproject commit cc4bed2d74f7c8717e31f9579214ab52a9c9c610 +Subproject commit 308ce31528a7edfa39f5f6d36142278a0ae1bf45 From e5509e36d64f315efd5395b9d22113b1c5e2c1a7 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 25 Feb 2019 16:08:45 -0800 Subject: [PATCH 511/814] Prevent overflow --- src/core/ext/transport/chttp2/transport/hpack_parser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc index ccf2256974a..7b47c9bc18e 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -1452,7 +1452,7 @@ static grpc_error* begin_parse_string(grpc_chttp2_hpack_parser* p, uint8_t binary, grpc_chttp2_hpack_parser_string* str) { if (!p->huff && binary == NOT_BINARY && - (end - cur) >= static_cast(p->strlen) && + static_cast(end - cur) >= p->strlen && p->current_slice_refcount != nullptr) { GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED(); str->copied = false; From 2a80f0edc72a444b726ac96e7312488920bed8d1 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 25 Feb 2019 16:28:59 -0800 Subject: [PATCH 512/814] Support use of ByteBuffer for request-side of code-gen unary --- src/compiler/cpp_generator.cc | 18 ++++++++++ .../end2end/client_callback_end2end_test.cc | 36 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index b0046872502..96e9ab8dcfb 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -580,6 +580,10 @@ void PrintHeaderClientMethodCallbackInterfaces( "virtual void $Method$(::grpc::ClientContext* context, " "const $Request$* request, $Response$* response, " "std::function) = 0;\n"); + printer->Print(*vars, + "virtual void $Method$(::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "std::function) = 0;\n"); } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, "virtual void $Method$(::grpc::ClientContext* context, " @@ -642,6 +646,10 @@ void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer, "void $Method$(::grpc::ClientContext* context, " "const $Request$* request, $Response$* response, " "std::function) override;\n"); + printer->Print(*vars, + "void $Method$(::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "std::function) override;\n"); } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, "void $Method$(::grpc::ClientContext* context, " @@ -1643,6 +1651,16 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " "context, request, response, std::move(f));\n}\n\n"); + printer->Print(*vars, + "void $ns$$Service$::Stub::experimental_async::$Method$(" + "::grpc::ClientContext* context, " + "const ::grpc::ByteBuffer* request, $Response$* response, " + "std::function f) {\n"); + printer->Print(*vars, + " return ::grpc::internal::CallbackUnaryCall" + "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " + "context, request, response, std::move(f));\n}\n\n"); + for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncStart"] = async_prefix.start; diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 7ed15beabe1..893d009392d 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -220,6 +220,36 @@ class ClientCallbackEnd2endTest } } + void SendRpcsRawReq(int num_rpcs) { + grpc::string test_string("Hello raw world."); + EchoRequest request; + request.set_message(test_string); + std::unique_ptr send_buf = SerializeToByteBuffer(&request); + + for (int i = 0; i < num_rpcs; i++) { + EchoResponse response; + ClientContext cli_ctx; + + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->Echo( + &cli_ctx, send_buf.get(), &response, + [&request, &response, &done, &mu, &cv](Status s) { + GPR_ASSERT(s.ok()); + + EXPECT_EQ(request.message(), response.message()); + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } + } + } + void SendRpcsGeneric(int num_rpcs, bool maybe_except) { const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo"); grpc::string test_string(""); @@ -347,6 +377,12 @@ TEST_P(ClientCallbackEnd2endTest, SequentialRpcs) { SendRpcs(10, false); } +TEST_P(ClientCallbackEnd2endTest, SequentialRpcsRawReq) { + MAYBE_SKIP_TEST; + ResetStub(); + SendRpcsRawReq(10); +} + TEST_P(ClientCallbackEnd2endTest, SendClientInitialMetadata) { MAYBE_SKIP_TEST; ResetStub(); From 179eb2b4a513bd1322dc0636083f6059e34d72e0 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 25 Feb 2019 16:34:57 -0800 Subject: [PATCH 513/814] update dependency version for bazel --- bazel/grpc_deps.bzl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 61a46e1ee5c..e2e47292242 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -170,8 +170,8 @@ def grpc_deps(): if "com_google_absl" not in native.existing_rules(): http_archive( name = "com_google_absl", - strip_prefix = "abseil-cpp-cd95e71df6eaf8f2a282b1da556c2cf1c9b09207", - url = "https://github.com/abseil/abseil-cpp/archive/cd95e71df6eaf8f2a282b1da556c2cf1c9b09207.tar.gz", + strip_prefix = "abseil-cpp-308ce31528a7edfa39f5f6d36142278a0ae1bf45", + url = "https://github.com/abseil/abseil-cpp/archive/308ce31528a7edfa39f5f6d36142278a0ae1bf45.tar.gz", ) if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): @@ -196,8 +196,8 @@ def grpc_deps(): if "io_opencensus_cpp" not in native.existing_rules(): http_archive( name = "io_opencensus_cpp", - strip_prefix = "opencensus-cpp-fdf0f308b1631bb4a942e32ba5d22536a6170274", - url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz", + strip_prefix = "opencensus-cpp-03dff0352522983ffdee48cedbf87cbe37f1bb7f", + url = "https://github.com/census-instrumentation/opencensus-cpp/archive/03dff0352522983ffdee48cedbf87cbe37f1bb7f.tar.gz", ) if "upb" not in native.existing_rules(): From 1cf86aea6090e519dd23061bc4aad1ca6cc01516 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 25 Feb 2019 16:41:48 -0800 Subject: [PATCH 514/814] Bump up !ProtoCompiler.podspec version --- src/objective-c/!ProtoCompiler.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index b98339941e5..44e86aaaf89 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -36,7 +36,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler' - v = '3.6.0' + v = '3.6.1' s.version = v s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files' s.description = <<-DESC From 9e7bb5d17d1cc91dbcae424fcfc4c8a6e2fb3a6f Mon Sep 17 00:00:00 2001 From: Kim Bao Long Date: Tue, 26 Feb 2019 11:10:25 +0700 Subject: [PATCH 515/814] Remove duplicated word 'for for' in doc Although it is spelling mistakes, it might make an affects while reading. Co-Authored-By: Nguyen Phuong An Signed-off-by: Kim Bao Long --- doc/server_reflection_tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/server_reflection_tutorial.md b/doc/server_reflection_tutorial.md index 06a257c1e87..acbb4a6ab2d 100644 --- a/doc/server_reflection_tutorial.md +++ b/doc/server_reflection_tutorial.md @@ -15,8 +15,8 @@ server reflection, you can link this library to your server binary. Some platforms (e.g. Ubuntu 11.10 onwards) only link in libraries that directly contain symbols used by the application. On these platforms, LD flag -`--no-as-needed` is needed for for dynamic linking and `--whole-archive` is -needed for for static linking. +`--no-as-needed` is needed for dynamic linking and `--whole-archive` is +needed for static linking. This [Makefile](../examples/cpp/helloworld/Makefile#L37#L45) demonstrates enabling c++ server reflection on Linux and MacOS. From 1c2303c63546b9d662fff6c773ae68dfea40e6fe Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 25 Feb 2019 20:43:57 -0800 Subject: [PATCH 516/814] use isinstance for internal api to not catch mocks --- src/python/grpcio/grpc/_server.py | 5 +++-- src/python/grpcio_tests/tests/unit/thread_pool.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 6e300ee6c5d..9224b2ac672 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -19,6 +19,7 @@ import logging import threading import time +from concurrent import futures import six import grpc @@ -565,8 +566,8 @@ def _send_message_callback_to_blocking_iterator_adapter( def _select_thread_pool_for_behavior(behavior, default_thread_pool): - if hasattr(behavior, 'experimental_thread_pool' - ) and behavior.experimental_thread_pool is not None: + if hasattr(behavior, 'experimental_thread_pool') and isinstance( + behavior.experimental_thread_pool, futures.ThreadPoolExecutor): return behavior.experimental_thread_pool else: return default_thread_pool diff --git a/src/python/grpcio_tests/tests/unit/thread_pool.py b/src/python/grpcio_tests/tests/unit/thread_pool.py index e99efc3e927..bc0f0e523bc 100644 --- a/src/python/grpcio_tests/tests/unit/thread_pool.py +++ b/src/python/grpcio_tests/tests/unit/thread_pool.py @@ -16,7 +16,7 @@ import threading from concurrent import futures -class RecordingThreadPool(futures.Executor): +class RecordingThreadPool(futures.ThreadPoolExecutor): """A thread pool that records if used.""" def __init__(self, max_workers): From 44a646bc398db05c2d9dbcad16f06f8e429a4aa8 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 25 Feb 2019 23:25:56 -0800 Subject: [PATCH 517/814] more commits for v1.19.0 --- gRPC-Core.podspec | 1 - src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/!ProtoCompiler.podspec | 1 + src/objective-c/BoringSSL-GRPC.podspec | 2 +- templates/gRPC-Core.podspec.template | 2 ++ .../src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template | 2 +- templates/src/objective-c/BoringSSL-GRPC.podspec.template | 2 +- 7 files changed, 7 insertions(+), 5 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 32bc84ae179..f2b824372f7 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1236,7 +1236,6 @@ Pod::Spec.new do |s| 'test/core/util/port_isolated_runtime_environment.cc', 'test/core/util/port_server_client.cc', 'test/core/util/slice_splitter.cc', - 'test/core/util/subprocess_posix.cc', 'test/core/util/subprocess_windows.cc', 'test/core/util/test_config.cc', 'test/core/util/test_lb_policies.cc', diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 16598be3f1f..d4b836e98ff 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -101,7 +101,7 @@ Pod::Spec.new do |s| s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.6.0' + s.dependency '!ProtoCompiler', '3.6.1' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index 44e86aaaf89..789265470c1 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -112,6 +112,7 @@ Pod::Spec.new do |s| # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' + s.tvos.deployment_target = '10.0' # This is only for local development of protoc: If the Podfile brings this pod from a local # directory using `:path`, CocoaPods won't download the zip file and so the compiler won't be diff --git a/src/objective-c/BoringSSL-GRPC.podspec b/src/objective-c/BoringSSL-GRPC.podspec index 528b96f32aa..2ec146e7ebe 100644 --- a/src/objective-c/BoringSSL-GRPC.podspec +++ b/src/objective-c/BoringSSL-GRPC.podspec @@ -79,7 +79,7 @@ Pod::Spec.new do |s| :commit => "b29b21a81b32ec273f118f589f46d56ad3332420", } - s.ios.deployment_target = '5.0' + s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.7' s.tvos.deployment_target = '10.0' diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 17048765437..93dc73532d5 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -61,6 +61,8 @@ def grpc_test_util_files(libs): out = grpc_lib_files(libs, ("grpc_test_util",), ("src", "headers")) excl = grpc_private_files(libs) + # Subprocess is not supported in tvOS and not needed by our tests. + excl += ["test/core/util/subprocess_posix.cc"] return [file for file in out if not file in excl] def end2end_tests_files(libs): diff --git a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template index 3e095d7aab7..5a416eb6471 100644 --- a/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template +++ b/templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template @@ -103,7 +103,7 @@ s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.6.0' + s.dependency '!ProtoCompiler', '3.6.1' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.9' diff --git a/templates/src/objective-c/BoringSSL-GRPC.podspec.template b/templates/src/objective-c/BoringSSL-GRPC.podspec.template index d86aa0c6cb4..408970e25e3 100644 --- a/templates/src/objective-c/BoringSSL-GRPC.podspec.template +++ b/templates/src/objective-c/BoringSSL-GRPC.podspec.template @@ -84,7 +84,7 @@ :commit => "b29b21a81b32ec273f118f589f46d56ad3332420", } - s.ios.deployment_target = '5.0' + s.ios.deployment_target = '7.0' s.osx.deployment_target = '10.7' s.tvos.deployment_target = '10.0' From de29ab752ebb2714a114463302e3796b75fea330 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 25 Feb 2019 23:29:02 -0800 Subject: [PATCH 518/814] Fix golden-file test --- test/cpp/codegen/compiler_test_golden | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 1871e1375ed..7f9fd29026e 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -113,6 +113,7 @@ class ServiceA final { virtual ~experimental_async_interface() {} // MethodA1 leading comment 1 virtual void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) = 0; + virtual void MethodA1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, std::function) = 0; // MethodA1 trailing comment 1 // MethodA2 detached leading comment 1 // @@ -182,6 +183,7 @@ class ServiceA final { public StubInterface::experimental_async_interface { public: void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) override; + void MethodA1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, std::function) override; void MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::experimental::ClientWriteReactor< ::grpc::testing::Request>* reactor) override; void MethodA3(::grpc::ClientContext* context, ::grpc::testing::Request* request, ::grpc::experimental::ClientReadReactor< ::grpc::testing::Response>* reactor) override; void MethodA4(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor< ::grpc::testing::Request,::grpc::testing::Response>* reactor) override; @@ -714,6 +716,7 @@ class ServiceB final { virtual ~experimental_async_interface() {} // MethodB1 leading comment 1 virtual void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) = 0; + virtual void MethodB1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, std::function) = 0; // MethodB1 trailing comment 1 }; virtual class experimental_async_interface* experimental_async() { return nullptr; } @@ -735,6 +738,7 @@ class ServiceB final { public StubInterface::experimental_async_interface { public: void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) override; + void MethodB1(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::grpc::testing::Response* response, std::function) override; private: friend class Stub; explicit experimental_async(Stub* stub): stub_(stub) { } From 029f6850c23040513efaaef76c3153454083bdd1 Mon Sep 17 00:00:00 2001 From: Nguyen Hai Truong Date: Tue, 26 Feb 2019 00:02:21 -0800 Subject: [PATCH 519/814] Remove duplicated word in document Although it is spelling mistakes, it might make an affects while reading. Signed-off-by: Nguyen Hai Truong --- doc/server_reflection_tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/server_reflection_tutorial.md b/doc/server_reflection_tutorial.md index 06a257c1e87..acbb4a6ab2d 100644 --- a/doc/server_reflection_tutorial.md +++ b/doc/server_reflection_tutorial.md @@ -15,8 +15,8 @@ server reflection, you can link this library to your server binary. Some platforms (e.g. Ubuntu 11.10 onwards) only link in libraries that directly contain symbols used by the application. On these platforms, LD flag -`--no-as-needed` is needed for for dynamic linking and `--whole-archive` is -needed for for static linking. +`--no-as-needed` is needed for dynamic linking and `--whole-archive` is +needed for static linking. This [Makefile](../examples/cpp/helloworld/Makefile#L37#L45) demonstrates enabling c++ server reflection on Linux and MacOS. From c9acd8380f5ea530ea0cbe60854f7f4298c5db4a Mon Sep 17 00:00:00 2001 From: Nguyen Quang Huy Date: Tue, 26 Feb 2019 11:05:58 +0700 Subject: [PATCH 520/814] Fix some typos Correct some words spelling for reading more easily. --- .../alts_zero_copy_grpc_protector.cc | 2 +- .../grpcio_tests/tests/unit/_resource_exhausted_test.py | 2 +- .../alts_zero_copy_grpc_protector_test.cc | 2 +- tools/internal_ci/README.md | 4 ++-- tools/interop_matrix/README.md | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc index 58aba9b747e..fc40aaa698c 100644 --- a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc @@ -105,7 +105,7 @@ static bool read_frame_size(const grpc_slice_buffer* sb, * Creates an alts_grpc_record_protocol object, given key, key size, and flags * to indicate whether the record_protocol object uses the rekeying AEAD, * whether the object is for client or server, whether the object is for - * integrity-only or privacy-integrity mode, and whether the object is is used + * integrity-only or privacy-integrity mode, and whether the object is used * for protect or unprotect. */ static tsi_result create_alts_grpc_record_protocol( diff --git a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py index 517c2d2f97b..ecd2ccadbde 100644 --- a/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py +++ b/src/python/grpcio_tests/tests/unit/_resource_exhausted_test.py @@ -42,7 +42,7 @@ class _TestTrigger(object): self._finish_condition = threading.Condition() self._start_condition = threading.Condition() - # Wait for all calls be be blocked in their handler + # Wait for all calls be blocked in their handler def await_calls(self): with self._start_condition: while self._pending_calls < self._total_call_count: diff --git a/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc b/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc index 3ee8323a310..62d799f18b3 100644 --- a/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc +++ b/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc @@ -175,7 +175,7 @@ static void seal_unseal_small_buffer(tsi_zero_copy_grpc_protector* sender, GPR_ASSERT(tsi_zero_copy_grpc_protector_protect( sender, &var->original_sb, &var->protected_sb) == TSI_OK); /* Splits protected slice buffer into two: first one is staging_sb, and - * second one is is protected_sb. */ + * second one is protected_sb. */ uint32_t staging_sb_size = gsec_test_bias_random_uint32( static_cast(var->protected_sb.length - 1)) + diff --git a/tools/internal_ci/README.md b/tools/internal_ci/README.md index af582c471e4..fdf70774327 100644 --- a/tools/internal_ci/README.md +++ b/tools/internal_ci/README.md @@ -1,7 +1,7 @@ # Kokoro CI job configurations and testing scripts -gRPC uses a continous integration tool called "Kokoro" (a.k.a "internal CI") +gRPC uses a continuous integration tool called "Kokoro" (a.k.a "internal CI") for running majority of its open source tests. This directory contains the external part of kokoro test job configurations (the actual job definitions live in an internal repository) and the shell -scripts that act as entry points to exectute the actual tests. +scripts that act as entry points to execute the actual tests. diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index ecd71be7f87..9d5c777cdee 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -3,7 +3,7 @@ This directory contains scripts that facilitate building and running gRPC interoperability tests for combinations of language/runtimes (known as matrix). The setup builds gRPC docker images for each language/runtime and upload it to Google Container Registry (GCR). These images, encapsulating gRPC stack -from specific releases/tag, are used to test version compatiblity between gRPC release versions. +from specific releases/tag, are used to test version compatibility between gRPC release versions. ## Step-by-step instructions for adding a GCR image for a new release for compatibility test We have continuous nightly test setup to test gRPC backward compatibility between old clients and latest server. When a gRPC developer creates a new gRPC release, s/he is also responsible to add the just-released gRPC client to the nightly test. The steps are: From 0f6a3d0a7c04bb02b8dd1fbf6e9ab4658acf323a Mon Sep 17 00:00:00 2001 From: tzik Date: Tue, 26 Feb 2019 17:43:54 +0900 Subject: [PATCH 521/814] Remove no-effect std::move() that causes MSVC warning In C++17 mode of MSVC, std::move() has nodiscard attribute, and causes a warning if its result is unused. --- src/core/ext/filters/client_channel/lb_policy.h | 6 ++---- src/core/ext/filters/client_channel/lb_policy_factory.h | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 5040ddc5047..0ef10a31aae 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -202,8 +202,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// by the client channel. virtual void UpdateState(grpc_connectivity_state state, grpc_error* state_error, - UniquePtr picker) { - std::move(picker); // Suppress clang-tidy complaint. + UniquePtr) { // The rest of this is copied from the GRPC_ABSTRACT macro. gpr_log(GPR_ERROR, "Function marked GRPC_ABSTRACT was not implemented"); GPR_ASSERT(false); @@ -261,8 +260,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. virtual void UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) { - std::move(lb_config); // Suppress clang-tidy complaint. + RefCountedPtr) { GRPC_ABSTRACT; } diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h index 79503f2a562..091cf4ecba6 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -31,8 +31,7 @@ class LoadBalancingPolicyFactory { public: /// Returns a new LB policy instance. virtual OrphanablePtr CreateLoadBalancingPolicy( - LoadBalancingPolicy::Args args) const { - std::move(args); // Suppress clang-tidy complaint. + LoadBalancingPolicy::Args) const { GRPC_ABSTRACT; } From 2eb25c871e41b730e44360a8055b3d4a2e3cffb9 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 26 Feb 2019 03:08:06 -0800 Subject: [PATCH 522/814] Avoid build errors --- include/grpcpp/impl/codegen/byte_buffer.h | 15 ++++++++++++--- src/cpp/util/byte_buffer_cc.cc | 14 -------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h index a77e36dfc50..7b82f49a84e 100644 --- a/include/grpcpp/impl/codegen/byte_buffer.h +++ b/include/grpcpp/impl/codegen/byte_buffer.h @@ -96,7 +96,7 @@ class ByteBuffer final { /// \a buf. Wrapper of core function grpc_byte_buffer_copy . This is not /// a deep copy; it is just a referencing. As a result, its performance is /// size-independent. - ByteBuffer(const ByteBuffer& buf); + ByteBuffer(const ByteBuffer& buf) : buffer_(nullptr) { operator=(buf); } ~ByteBuffer() { if (buffer_) { @@ -107,7 +107,16 @@ class ByteBuffer final { /// Wrapper of core function grpc_byte_buffer_copy . This is not /// a deep copy; it is just a referencing. As a result, its performance is /// size-independent. - ByteBuffer& operator=(const ByteBuffer&); + ByteBuffer& operator=(const ByteBuffer& buf) { + if (this != &buf) { + Clear(); // first remove existing data + } + if (buf.buffer_) { + // then copy + buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buf.buffer_); + } + return *this; + } /// Dump (read) the buffer contents into \a slices. Status Dump(std::vector* slices) const; @@ -215,7 +224,7 @@ class SerializationTraits { bool* own_buffer) { *buffer = source; *own_buffer = true; - return Status::OK; + return g_core_codegen_interface->ok(); } }; diff --git a/src/cpp/util/byte_buffer_cc.cc b/src/cpp/util/byte_buffer_cc.cc index a7e16454352..fb705906455 100644 --- a/src/cpp/util/byte_buffer_cc.cc +++ b/src/cpp/util/byte_buffer_cc.cc @@ -43,18 +43,4 @@ Status ByteBuffer::Dump(std::vector* slices) const { return Status::OK; } -ByteBuffer::ByteBuffer(const ByteBuffer& buf) : buffer_(nullptr) { - operator=(buf); -} - -ByteBuffer& ByteBuffer::operator=(const ByteBuffer& buf) { - if (this != &buf) { - Clear(); // first remove existing data - } - if (buf.buffer_) { - buffer_ = grpc_byte_buffer_copy(buf.buffer_); // then copy - } - return *this; -} - } // namespace grpc From 715e18fbef7da80a60dc26c37e4bd6a95c4f11c0 Mon Sep 17 00:00:00 2001 From: tzik Date: Tue, 26 Feb 2019 22:05:42 +0900 Subject: [PATCH 523/814] Suppress clang-tidy --- src/core/ext/filters/client_channel/lb_policy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 0ef10a31aae..5c21b1c82b7 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -260,7 +260,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. virtual void UpdateLocked(const grpc_channel_args& args, - RefCountedPtr) { + RefCountedPtr lb_config) { // NOLINT GRPC_ABSTRACT; } From 79f4b4cba6cd1352267eb0033e5e1e4e0a7dc728 Mon Sep 17 00:00:00 2001 From: Taiju Tsuiki Date: Wed, 27 Feb 2019 02:12:38 +0900 Subject: [PATCH 524/814] Lint fix for NOLINT --- src/core/ext/filters/client_channel/lb_policy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 5c21b1c82b7..47ee97cbce3 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -260,7 +260,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. virtual void UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) { // NOLINT + RefCountedPtr lb_config) { // NOLINT GRPC_ABSTRACT; } From 0eaa2cd6bd6732c943fe93df37b2a5d8399aa190 Mon Sep 17 00:00:00 2001 From: billfeng327 Date: Tue, 26 Feb 2019 10:28:18 -0800 Subject: [PATCH 525/814] added selective header inclusion for Windows --- .../filters/load_reporting/server_load_reporting_filter.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc index d7fd73fd6b2..b5b756c7407 100644 --- a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc +++ b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc @@ -30,7 +30,13 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/context.h" #include "src/core/lib/iomgr/resolve_address.h" + +#ifdef WIN32 +#include "src/core/lib/iomgr/sockaddr_windows.h" +#else #include "src/core/lib/iomgr/sockaddr_posix.h" +#endif + #include "src/core/lib/iomgr/socket_utils.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/slice/slice_internal.h" From 3f3da2e23f32e640ab4e8c71eed49ffedc6c0bf3 Mon Sep 17 00:00:00 2001 From: billfeng327 Date: Tue, 26 Feb 2019 10:42:18 -0800 Subject: [PATCH 526/814] submodule update --- third_party/abseil-cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/abseil-cpp b/third_party/abseil-cpp index 308ce31528a..cc4bed2d74f 160000 --- a/third_party/abseil-cpp +++ b/third_party/abseil-cpp @@ -1 +1 @@ -Subproject commit 308ce31528a7edfa39f5f6d36142278a0ae1bf45 +Subproject commit cc4bed2d74f7c8717e31f9579214ab52a9c9c610 From 969f698cf229f0784668fca8866d8504e64392fe Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 26 Feb 2019 12:33:53 -0800 Subject: [PATCH 527/814] Enable deadline propagation --- src/python/grpcio/grpc/_channel.py | 24 ++++++++++-- .../grpc/_cython/_cygrpc/_hooks.pyx.pxi | 5 ++- src/python/grpcio/grpc/_server.py | 39 ++++++++----------- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 1d2495cdd21..7d4133c6165 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -488,6 +488,18 @@ def _stream_unary_invocation_operationses_and_tags(metadata, metadata, initial_metadata_flags)) +def _determine_deadline(user_deadline): + parent_deadline = cygrpc.get_deadline_from_context() + if parent_deadline is None and user_deadline is None: + return None + elif parent_deadline is not None and user_deadline is None: + return parent_deadline + elif user_deadline is not None and parent_deadline is None: + return user_deadline + else: + return min(parent_deadline, user_deadline) + + class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): # pylint: disable=too-many-arguments @@ -527,9 +539,10 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): if state is None: raise rendezvous # pylint: disable-msg=raising-bad-type else: + deadline_to_propagate = _determine_deadline(deadline) call = self._channel.segregated_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, - self._method, None, deadline, metadata, None + self._method, None, deadline_to_propagate, metadata, None if credentials is None else credentials._credentials, (( operations, None, @@ -617,9 +630,10 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),), ) event_handler = _event_handler(state, self._response_deserializer) + deadline_to_propagate = _determine_deadline(deadline) call = self._managed_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, - self._method, None, deadline, metadata, None + self._method, None, deadline_to_propagate, metadata, None if credentials is None else credentials._credentials, operationses, event_handler, self._context) return _Rendezvous(state, call, self._response_deserializer, @@ -644,9 +658,10 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None) initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) + deadline_to_propagate = _determine_deadline(deadline) call = self._channel.segregated_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, - None, deadline, metadata, None + None, deadline_to_propagate, metadata, None if credentials is None else credentials._credentials, _stream_unary_invocation_operationses_and_tags( metadata, initial_metadata_flags), self._context) @@ -734,9 +749,10 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),), ) event_handler = _event_handler(state, self._response_deserializer) + deadline_to_propagate = _determine_deadline(deadline) call = self._managed_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, - None, deadline, metadata, None + None, deadline_to_propagate, metadata, None if credentials is None else credentials._credentials, operationses, event_handler, self._context) _consume_request_iterator(request_iterator, state, call, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi index 6d1c36b2b35..de4d71b8196 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi @@ -16,7 +16,7 @@ cdef object _custom_op_on_c_call(int op, grpc_call *call): raise NotImplementedError("No custom hooks are implemented") -def install_context_from_call(Call call): +def install_context_from_request_call_event(RequestCallEvent event): pass def uninstall_context(): @@ -30,3 +30,6 @@ cdef class CensusContext: def set_census_context_on_call(_CallState call_state, CensusContext census_ctx): pass + +def get_deadline_from_context(): + return None diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 31f31b0f208..e29ec42d997 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -302,9 +302,6 @@ class _Context(grpc.ServicerContext): with self._state.condition: self._state.details = _common.encode(details) - def _finalize_state(self): - pass - class _RequestIterator(object): @@ -390,24 +387,20 @@ def _unary_request(rpc_event, state, request_deserializer): def _call_behavior(rpc_event, state, behavior, argument, request_deserializer): - from grpc import _create_servicer_context - with _create_servicer_context(rpc_event, state, - request_deserializer) as context: - try: - response = behavior(argument, context) - return response, True - except Exception as exception: # pylint: disable=broad-except - with state.condition: - if state.aborted: - _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, - b'RPC Aborted') - elif exception not in state.rpc_errors: - details = 'Exception calling application: {}'.format( - exception) - _LOGGER.exception(details) - _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, - _common.encode(details)) - return None, False + context = _Context(rpc_event, state, request_deserializer) + try: + return behavior(argument, context), True + except Exception as exception: # pylint: disable=broad-except + with state.condition: + if state.aborted: + _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, + b'RPC Aborted') + elif exception not in state.rpc_errors: + details = 'Exception calling application: {}'.format(exception) + _LOGGER.exception(details) + _abort(state, rpc_event.call, cygrpc.StatusCode.unknown, + _common.encode(details)) + return None, False def _take_response_from_response_iterator(rpc_event, state, response_iterator): @@ -490,7 +483,7 @@ def _status(rpc_event, state, serialized_response): def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - cygrpc.install_context_from_call(rpc_event.call) + cygrpc.install_context_from_request_call_event(rpc_event) try: argument = argument_thunk() if argument is not None: @@ -507,7 +500,7 @@ def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - cygrpc.install_context_from_call(rpc_event.call) + cygrpc.install_context_from_request_call_event(rpc_event) try: argument = argument_thunk() if argument is not None: From 29191d5eda70a81f6d3e83130562e4407a6bdf07 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 26 Feb 2019 12:44:13 -0800 Subject: [PATCH 528/814] Need to properly init library for microbenchmarks --- test/cpp/microbenchmarks/helpers.cc | 11 +++++++++++ test/cpp/microbenchmarks/helpers.h | 8 +------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc index bce72985dc2..d4070de7481 100644 --- a/test/cpp/microbenchmarks/helpers.cc +++ b/test/cpp/microbenchmarks/helpers.cc @@ -20,6 +20,17 @@ #include "test/cpp/microbenchmarks/helpers.h" +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; + +Library::Library() { + g_gli_initializer.summon(); +#ifdef GPR_LOW_LEVEL_COUNTERS + grpc_memory_counters_init(); +#endif + init_lib_.init(); + rq_ = grpc_resource_quota_create("bm"); +} + void TrackCounters::Finish(benchmark::State& state) { std::ostringstream out; for (const auto& l : labels_) { diff --git a/test/cpp/microbenchmarks/helpers.h b/test/cpp/microbenchmarks/helpers.h index 25d34b5f871..770966aa189 100644 --- a/test/cpp/microbenchmarks/helpers.h +++ b/test/cpp/microbenchmarks/helpers.h @@ -39,13 +39,7 @@ class Library { grpc_resource_quota* rq() { return rq_; } private: - Library() { -#ifdef GPR_LOW_LEVEL_COUNTERS - grpc_memory_counters_init(); -#endif - init_lib_.init(); - rq_ = grpc_resource_quota_create("bm"); - } + Library(); ~Library() { init_lib_.shutdown(); } From 3e88dcaef277f792f7320840f12ad86bf48eb3d5 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Tue, 26 Feb 2019 12:46:33 -0800 Subject: [PATCH 529/814] Makefile: fix shared library resolution on linux when installed to e.g. /opt For issue 18131. --- templates/Makefile.template | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/templates/Makefile.template b/templates/Makefile.template index 8bb06176bf8..7111801211b 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -274,6 +274,28 @@ LDFLAGS += -pthread endif + # If we are installing into a non-default prefix, both + # the libraries we build, and the apps users build, + # need to know how to find the libraries they depend on. + # There is much gnashing of teeth about this subject. + # It's tricky to do that without editing images during install, + # as you don't want tests during build to find previously installed and + # now stale libraries, etc. + ifeq ($(SYSTEM),Linux) + ifneq ($(prefix),/usr) + # Linux best practice for rpath on installed files is probably: + # 1) .pc file provides -Wl,-rpath,$(prefix)/lib + # 2) binaries we install into $(prefix)/bin use -Wl,-rpath,$ORIGIN/../lib + # 3) libraries we install into $(prefix)/lib use -Wl,-rpath,$ORIGIN + # cf. https://www.akkadia.org/drepper/dsohowto.pdf + # Doing all of that right is hard, but using -Wl,-rpath,$ORIGIN is always + # safe, and solves problems seen in the wild. Note that $ORIGIN + # is a literal string interpreted much later by ld.so. Escape it + # here with a dollar sign so Make doesn't expand $O. + LDFLAGS += '-Wl,-rpath,$$ORIGIN' + endif + endif + # # The steps for cross-compiling are as follows: # First, clone and make install of grpc using the native compilers for the host. From add794c982fa14f0c37354e87e6dae9c59206547 Mon Sep 17 00:00:00 2001 From: Dan Kegel Date: Tue, 26 Feb 2019 12:47:37 -0800 Subject: [PATCH 530/814] Regenerate projects. --- Makefile | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Makefile b/Makefile index efa08cdfb0a..4206d7b88d8 100644 --- a/Makefile +++ b/Makefile @@ -404,6 +404,28 @@ LIBS = m pthread ws2_32 LDFLAGS += -pthread endif +# If we are installing into a non-default prefix, both +# the libraries we build, and the apps users build, +# need to know how to find the libraries they depend on. +# There is much gnashing of teeth about this subject. +# It's tricky to do that without editing images during install, +# as you don't want tests during build to find previously installed and +# now stale libraries, etc. +ifeq ($(SYSTEM),Linux) +ifneq ($(prefix),/usr) +# Linux best practice for rpath on installed files is probably: +# 1) .pc file provides -Wl,-rpath,$(prefix)/lib +# 2) binaries we install into $(prefix)/bin use -Wl,-rpath,$ORIGIN/../lib +# 3) libraries we install into $(prefix)/lib use -Wl,-rpath,$ORIGIN +# cf. https://www.akkadia.org/drepper/dsohowto.pdf +# Doing all of that right is hard, but using -Wl,-rpath,$ORIGIN is always +# safe, and solves problems seen in the wild. Note that $ORIGIN +# is a literal string interpreted much later by ld.so. Escape it +# here with a dollar sign so Make doesn't expand $O. +LDFLAGS += '-Wl,-rpath,$$ORIGIN' +endif +endif + # # The steps for cross-compiling are as follows: # First, clone and make install of grpc using the native compilers for the host. From 1e4b70606886d1e880185377c35a06a42900142c Mon Sep 17 00:00:00 2001 From: billfeng327 Date: Tue, 26 Feb 2019 12:51:54 -0800 Subject: [PATCH 531/814] used universal header file --- .../load_reporting/server_load_reporting_filter.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc index b5b756c7407..1d373c5b994 100644 --- a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc +++ b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc @@ -30,13 +30,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/context.h" #include "src/core/lib/iomgr/resolve_address.h" - -#ifdef WIN32 -#include "src/core/lib/iomgr/sockaddr_windows.h" -#else -#include "src/core/lib/iomgr/sockaddr_posix.h" -#endif - +#include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/slice/slice_internal.h" From 8665767aa59fc0d90b4f40f59b4a4420277a6fa5 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 26 Feb 2019 13:12:53 -0800 Subject: [PATCH 532/814] Fix bad merge --- src/python/grpcio/grpc/_server.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index e1da3e5b4d3..90136aef3c2 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -303,6 +303,9 @@ class _Context(grpc.ServicerContext): with self._state.condition: self._state.details = _common.encode(details) + def _finalize_state(self): + pass + class _RequestIterator(object): From 1027149f8dd7e11b69dd399cd854aab3fea2f6e3 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Mon, 25 Feb 2019 18:53:16 -0500 Subject: [PATCH 533/814] Run run_after_write closures in h2 once write action is done. We flush these closures only when the connection goes IDLE. This will cause no completion being sent, if we have a continuous stream of bytes that never stops, causing a memory bloat because we never call the callbacks of the ops. For example, we use 100s of GiB of memory after a minute of exchanging 1MiB RPCs with callback API. This patch runs the closures when we have done running one write action. After this change memory remains stable for the 1MiB benchmark. QPS is increased by 200 QPS (520 -> 749), and latency is dropped by 70ms, because we were basically page-faulting on every RPC. --- .../transport/chttp2/transport/chttp2_transport.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 1c9b37dada2..970c71b663d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1062,12 +1062,15 @@ static void write_action_end_locked(void* tp, grpc_error* error) { GPR_TIMER_SCOPE("terminate_writing_with_lock", 0); grpc_chttp2_transport* t = static_cast(tp); + bool closed = false; if (error != GRPC_ERROR_NONE) { close_transport_locked(t, GRPC_ERROR_REF(error)); + closed = true; } if (t->sent_goaway_state == GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED) { t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SENT; + closed = true; if (grpc_chttp2_stream_map_size(&t->stream_map) == 0) { close_transport_locked( t, GRPC_ERROR_CREATE_FROM_STATIC_STRING("goaway sent")); @@ -1086,6 +1089,14 @@ static void write_action_end_locked(void* tp, grpc_error* error) { set_write_state(t, GRPC_CHTTP2_WRITE_STATE_WRITING, "continue writing"); t->is_first_write_in_batch = false; GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); + // If the transport is closed, we will retry writing on the endpoint + // and next write may contain part of the currently serialized frames. + // So, we should only call the run_after_write callbacks when the next + // write finishes, or the callbacks will be invoked when the stream is + // closed. + if (!closed) { + GRPC_CLOSURE_LIST_SCHED(&t->run_after_write); + } GRPC_CLOSURE_RUN( GRPC_CLOSURE_INIT(&t->write_action_begin_locked, write_action_begin_locked, t, From 795efaa108f2eb75bb9c172787d46376c4591003 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 26 Feb 2019 16:35:19 -0800 Subject: [PATCH 534/814] Appease the pylint gods --- src/python/grpcio/grpc/_channel.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 7d4133c6165..b106216c97c 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -630,10 +630,9 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),), ) event_handler = _event_handler(state, self._response_deserializer) - deadline_to_propagate = _determine_deadline(deadline) call = self._managed_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, - self._method, None, deadline_to_propagate, metadata, None + self._method, None, _determine_deadline(deadline), metadata, None if credentials is None else credentials._credentials, operationses, event_handler, self._context) return _Rendezvous(state, call, self._response_deserializer, From 3c3eb36b367146bda686c39c21f1d54344ee7efb Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 26 Feb 2019 17:00:23 -0800 Subject: [PATCH 535/814] Yapf --- src/python/grpcio/grpc/_channel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index b106216c97c..f6c22d09b77 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -632,8 +632,8 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, - self._method, None, _determine_deadline(deadline), metadata, None - if credentials is None else credentials._credentials, + self._method, None, _determine_deadline(deadline), metadata, + None if credentials is None else credentials._credentials, operationses, event_handler, self._context) return _Rendezvous(state, call, self._response_deserializer, deadline) From 9c4de5a0ffef2a8a5b91c0c343b28a1605e82cba Mon Sep 17 00:00:00 2001 From: Vu Cong Tuan Date: Tue, 26 Feb 2019 16:41:13 +0700 Subject: [PATCH 536/814] Fix typos in test code Signed-off-by: Vu Cong Tuan --- test/core/end2end/bad_server_response_test.cc | 2 +- test/core/end2end/tests/bad_ping.cc | 2 +- test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc | 2 +- test/cpp/interop/metrics_client.cc | 2 +- test/cpp/naming/address_sorting_test.cc | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index f8ffb551805..99cfec7adf6 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -65,7 +65,7 @@ #define HTTP1_DETAIL_MSG "Trying to connect an http1.x server" -/* TODO(zyc) Check the content of incomming data instead of using this length */ +/* TODO(zyc) Check the content of incoming data instead of using this length */ /* The 'bad' server will start sending responses after reading this amount of * data from the client. */ #define SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD (size_t)200 diff --git a/test/core/end2end/tests/bad_ping.cc b/test/core/end2end/tests/bad_ping.cc index 98d893f64d9..a07bf16876a 100644 --- a/test/core/end2end/tests/bad_ping.cc +++ b/test/core/end2end/tests/bad_ping.cc @@ -312,7 +312,7 @@ static void test_pings_without_data(grpc_end2end_test_config config) { CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); - // Send too many pings to the server similar to the prevous test case. + // Send too many pings to the server similar to the previous test case. // However, since we set the MAX_PINGS_WITHOUT_DATA at the client side, only // MAX_PING_STRIKES will actually be sent and the rpc will still succeed. int i; diff --git a/test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc b/test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc index 98c5d236415..8d75d35368d 100644 --- a/test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc +++ b/test/core/tsi/alts/handshaker/alts_tsi_utils_test.cc @@ -51,7 +51,7 @@ static void deserialize_response_test() { GPR_ASSERT(grpc_gcp_handshaker_resp_equals(resp, decoded_resp)); grpc_byte_buffer_destroy(buffer); - /* Invalid serializaiton. */ + /* Invalid serialization. */ grpc_slice bad_slice = grpc_slice_split_head(&slice, GRPC_SLICE_LENGTH(slice) - 1); buffer = grpc_raw_byte_buffer_create(&bad_slice, 1 /* number of slices */); diff --git a/test/cpp/interop/metrics_client.cc b/test/cpp/interop/metrics_client.cc index 02cd5643355..dca8e07b96c 100644 --- a/test/cpp/interop/metrics_client.cc +++ b/test/cpp/interop/metrics_client.cc @@ -88,7 +88,7 @@ bool PrintMetrics(std::unique_ptr stub, bool total_only, int main(int argc, char** argv) { grpc::testing::InitTest(&argc, &argv, true); - // The output of metrics client is in some cases programatically parsed (for + // The output of metrics client is in some cases programmatically parsed (for // example by the stress test framework). So, we do not want any of the log // from the grpc library appearing on stdout. gpr_set_log_function(BlackholeLogger); diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index 09e705df789..db784a6476a 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -790,7 +790,7 @@ TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) { /* Try to rule out false positives in the above two tests in which * the sorter might think that neither ipv6 or ipv4 loopback is * available, but ipv6 loopback is still preferred only due - * to precedance table lookups. */ + * to precedence table lookups. */ TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) { sockaddr_in6 ipv6_loopback; memset(&ipv6_loopback, 0, sizeof(ipv6_loopback)); From e94a11482ac17d17750bfbc4e249ba54134bef2e Mon Sep 17 00:00:00 2001 From: tzik Date: Wed, 27 Feb 2019 13:01:29 +0900 Subject: [PATCH 537/814] Use GRPC_ABSTRACT --- src/core/ext/filters/client_channel/lb_policy.h | 11 +++-------- .../ext/filters/client_channel/lb_policy_factory.h | 4 +--- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 47ee97cbce3..813bad1b7f0 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -202,11 +202,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// by the client channel. virtual void UpdateState(grpc_connectivity_state state, grpc_error* state_error, - UniquePtr) { - // The rest of this is copied from the GRPC_ABSTRACT macro. - gpr_log(GPR_ERROR, "Function marked GRPC_ABSTRACT was not implemented"); - GPR_ASSERT(false); - } + UniquePtr) GRPC_ABSTRACT; /// Requests that the resolver re-resolve. virtual void RequestReresolution() GRPC_ABSTRACT; @@ -260,9 +256,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Note that the LB policy gets the set of addresses from the /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. virtual void UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) { // NOLINT - GRPC_ABSTRACT; - } + RefCountedPtr) // NOLINT + GRPC_ABSTRACT; /// Tries to enter a READY connectivity state. /// This is a no-op by default, since most LB policies never go into diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h index 091cf4ecba6..1da4b7c6956 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -31,9 +31,7 @@ class LoadBalancingPolicyFactory { public: /// Returns a new LB policy instance. virtual OrphanablePtr CreateLoadBalancingPolicy( - LoadBalancingPolicy::Args) const { - GRPC_ABSTRACT; - } + LoadBalancingPolicy::Args) const GRPC_ABSTRACT; /// Returns the LB policy name that this factory provides. /// Caller does NOT take ownership of result. From 55e9e96ac3c67de2c8b05ca202c7c046431fe840 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 27 Feb 2019 08:36:22 +0100 Subject: [PATCH 538/814] also generate C# docs for Grpc.Core.Api --- src/csharp/doc/docfx.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/csharp/doc/docfx.json b/src/csharp/doc/docfx.json index 0ce5f7262a0..36bf6573bb4 100644 --- a/src/csharp/doc/docfx.json +++ b/src/csharp/doc/docfx.json @@ -3,7 +3,8 @@ { "src": [ { - "files": ["Grpc.Core/Grpc.Core.csproj", + "files": ["Grpc.Core.Api/Grpc.Core.Api.csproj", + "Grpc.Core/Grpc.Core.csproj", "Grpc.Auth/Grpc.Auth.csproj", "Grpc.Core.Testing/Grpc.Core.Testing.csproj", "Grpc.HealthCheck/Grpc.HealthCheck.csproj", From 7f37d1cb0e5a6f865da2742ce783b4fa116e47a7 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Mon, 25 Feb 2019 12:10:47 -0800 Subject: [PATCH 539/814] Fix test flakes in flaky_network_test - Set channel arg for maximum time between reconnection attempts. - Don't check status of RPCs that can fail due to network flakiness. --- test/cpp/end2end/flaky_network_test.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/cpp/end2end/flaky_network_test.cc b/test/cpp/end2end/flaky_network_test.cc index 20c8fb59fa2..d0c95740959 100644 --- a/test/cpp/end2end/flaky_network_test.cc +++ b/test/cpp/end2end/flaky_network_test.cc @@ -339,11 +339,14 @@ TEST_F(FlakyNetworkTest, NetworkTransition) { TEST_F(FlakyNetworkTest, ServerUnreachableWithKeepalive) { const int kKeepAliveTimeMs = 1000; const int kKeepAliveTimeoutMs = 1000; + const int kReconnectBackoffMs = 1000; ChannelArguments args; args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); + args.SetInt(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); auto channel = BuildChannel("pick_first", args); auto stub = BuildStub(channel); @@ -421,7 +424,7 @@ TEST_F(FlakyNetworkTest, FlakyNetwork) { // simulate flaky network (packet loss, corruption and delays) FlakeNetwork(); for (int i = 0; i < kMessageCount; ++i) { - EXPECT_TRUE(SendRpc(stub)); + SendRpc(stub); } // remove network flakiness UnflakeNetwork(); From 473041e06b728414799bca7f6ca4a53ac504ce32 Mon Sep 17 00:00:00 2001 From: Michael Behr Date: Wed, 27 Feb 2019 10:52:45 -0500 Subject: [PATCH 540/814] Format code. --- test/cpp/util/create_test_channel.cc | 29 ++++++++++++++-------------- test/cpp/util/create_test_channel.h | 3 +-- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index e0c0bd064fc..79a5e13d993 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -71,8 +71,8 @@ std::shared_ptr CreateTestChannel( const grpc::string& override_hostname, bool use_prod_roots, const std::shared_ptr& creds, const ChannelArguments& args) { - return CreateTestChannel(server, cred_type, override_hostname, - use_prod_roots, creds, args, + return CreateTestChannel(server, cred_type, override_hostname, use_prod_roots, + creds, args, /*interceptor_creators=*/{}); } @@ -124,11 +124,10 @@ std::shared_ptr CreateTestChannel( std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& cred_type, const grpc::string& override_hostname, bool use_prod_roots, - const std::shared_ptr& creds, - const ChannelArguments& args, + const std::shared_ptr& creds, const ChannelArguments& args, std::vector< std::unique_ptr> - interceptor_creators) { + interceptor_creators) { ChannelArguments channel_args(args); std::shared_ptr channel_creds; if (cred_type.empty()) { @@ -174,8 +173,8 @@ std::shared_ptr CreateTestChannel( if (interceptor_creators.empty()) { return CreateCustomChannel(server, channel_creds, args); } else { - return experimental::CreateCustomChannelWithInterceptors( - server, channel_creds, args, std::move(interceptor_creators)); + return experimental::CreateCustomChannelWithInterceptors( + server, channel_creds, args, std::move(interceptor_creators)); } } } @@ -186,15 +185,15 @@ std::shared_ptr CreateTestChannel( const std::shared_ptr& creds, const ChannelArguments& args, std::vector< std::unique_ptr> - interceptor_creators) { + interceptor_creators) { grpc::string credential_type = security_type == testing::ALTS ? testing::kAltsCredentialsType : (security_type == testing::TLS ? testing::kTlsCredentialsType : testing::kInsecureCredentialsType); - return CreateTestChannel( - server, credential_type, override_hostname, use_prod_roots, creds, args, - std::move(interceptor_creators)); + return CreateTestChannel(server, credential_type, override_hostname, + use_prod_roots, creds, args, + std::move(interceptor_creators)); } std::shared_ptr CreateTestChannel( @@ -204,9 +203,9 @@ std::shared_ptr CreateTestChannel( std::vector< std::unique_ptr> interceptor_creators) { - return CreateTestChannel( - server, override_hostname, security_type, use_prod_roots, creds, - ChannelArguments(), std::move(interceptor_creators)); + return CreateTestChannel(server, override_hostname, security_type, + use_prod_roots, creds, ChannelArguments(), + std::move(interceptor_creators)); } std::shared_ptr CreateTestChannel( @@ -214,7 +213,7 @@ std::shared_ptr CreateTestChannel( const std::shared_ptr& creds, std::vector< std::unique_ptr> - interceptor_creators) { + interceptor_creators) { ChannelArguments channel_args; std::shared_ptr channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials(credential_type, diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h index e706acc6072..b50131b385c 100644 --- a/test/cpp/util/create_test_channel.h +++ b/test/cpp/util/create_test_channel.h @@ -80,8 +80,7 @@ std::shared_ptr CreateTestChannel( std::shared_ptr CreateTestChannel( const grpc::string& server, const grpc::string& cred_type, const grpc::string& override_hostname, bool use_prod_roots, - const std::shared_ptr& creds, - const ChannelArguments& args, + const std::shared_ptr& creds, const ChannelArguments& args, std::vector< std::unique_ptr> interceptor_creators); From 0a53c2ed2e99c10c70801108d6642ca794088844 Mon Sep 17 00:00:00 2001 From: Michael Behr Date: Wed, 27 Feb 2019 12:04:32 -0500 Subject: [PATCH 541/814] Move new functions out of client_helper.cc --- test/cpp/interop/client.cc | 31 ++++++++++++++++++++++++++- test/cpp/interop/client_helper.cc | 35 ------------------------------- test/cpp/interop/client_helper.h | 18 +++++++++------- 3 files changed, 41 insertions(+), 43 deletions(-) diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index 8a934845ab4..f091aa0e1a1 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -100,6 +101,34 @@ using grpc::testing::CreateChannelForTestCase; using grpc::testing::GetServiceAccountJsonKey; using grpc::testing::UpdateActions; +namespace { + +// Parse the contents of FLAGS_additional_metadata into a map. Allow +// alphanumeric characters and dashes in keys, and any character but semicolons +// in values. +std::multimap ParseAdditionalMetadataFlag( + const grpc::string& flag) { + std::multimap additional_metadata; + + // Key in group 1; value in group 2. + std::regex re("([-a-zA-Z0-9]+):([^;]*);?"); + auto metadata_entries_begin = std::sregex_iterator( + flag.begin(), flag.end(), re, std::regex_constants::match_continuous); + auto metadata_entries_end = std::sregex_iterator(); + + for (std::sregex_iterator i = metadata_entries_begin; + i != metadata_entries_end; ++i) { + std::smatch match = *i; + gpr_log(GPR_INFO, "Adding additional metadata with key %s and value %s", + match[1].str().c_str(), match[2].str().c_str()); + additional_metadata.insert({match[1].str(), match[2].str()}); + } + + return additional_metadata; +} + +} // namespace + int main(int argc, char** argv) { grpc::testing::InitTest(&argc, &argv, true); gpr_log(GPR_INFO, "Testing these cases: %s", FLAGS_test_case.c_str()); @@ -113,7 +142,7 @@ int main(int argc, char** argv) { }; } else { std::multimap additional_metadata = - grpc::testing::ParseAdditionalMetadataFlag(FLAGS_additional_metadata); + ParseAdditionalMetadataFlag(FLAGS_additional_metadata); channel_creation_func = [test_case, additional_metadata]() { std::vector #include -#include #include #include @@ -123,39 +122,5 @@ std::shared_ptr CreateChannelForTestCase( } } -std::multimap ParseAdditionalMetadataFlag( - const grpc::string& flag) { - std::multimap additional_metadata; - - // Key in group 1; value in group 2. - std::regex re("([-a-zA-Z0-9]+):([^;]*);?"); - auto metadata_entries_begin = std::sregex_iterator( - flag.begin(), flag.end(), re, std::regex_constants::match_continuous); - auto metadata_entries_end = std::sregex_iterator(); - - for (std::sregex_iterator i = metadata_entries_begin; - i != metadata_entries_end; ++i) { - std::smatch match = *i; - gpr_log(GPR_INFO, "Adding additional metadata with key %s and value %s", - match[1].str().c_str(), match[2].str().c_str()); - additional_metadata.insert({match[1].str(), match[2].str()}); - } - - return additional_metadata; -} - -void AdditionalMetadataInterceptor::Intercept( - experimental::InterceptorBatchMethods* methods) { - if (methods->QueryInterceptionHookPoint( - experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { - std::multimap* metadata = - methods->GetSendInitialMetadata(); - for (const auto& entry : additional_metadata_) { - metadata->insert(entry); - } - } - methods->Proceed(); -} - } // namespace testing } // namespace grpc diff --git a/test/cpp/interop/client_helper.h b/test/cpp/interop/client_helper.h index 895f7625baa..4afce27470b 100644 --- a/test/cpp/interop/client_helper.h +++ b/test/cpp/interop/client_helper.h @@ -44,12 +44,6 @@ std::shared_ptr CreateChannelForTestCase( std::unique_ptr> interceptor_creators = {}); -// Parse the contents of FLAGS_additional_metadata into a map. Allow -// alphanumeric characters and dashes in keys, and any character but semicolons -// in values. -std::multimap ParseAdditionalMetadataFlag( - const grpc::string& flag); - class InteropClientContextInspector { public: InteropClientContextInspector(const ::grpc::ClientContext& context) @@ -74,7 +68,17 @@ class AdditionalMetadataInterceptor : public experimental::Interceptor { std::multimap additional_metadata) : additional_metadata_(std::move(additional_metadata)) {} - void Intercept(experimental::InterceptorBatchMethods* methods) override; + void Intercept(experimental::InterceptorBatchMethods* methods) override { + if (methods->QueryInterceptionHookPoint( + experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { + std::multimap* metadata = + methods->GetSendInitialMetadata(); + for (const auto& entry : additional_metadata_) { + metadata->insert(entry); + } + } + methods->Proceed(); + } private: const std::multimap additional_metadata_; From 1c05218497a8e9b7bb0111507edb590b81a33bb1 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 27 Feb 2019 09:43:39 -0800 Subject: [PATCH 542/814] Fix new pylint errors. --- src/python/grpcio/grpc/_channel.py | 2 +- src/python/grpcio/grpc/_interceptor.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index f6c22d09b77..ed4c871b684 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -247,7 +247,7 @@ def _consume_request_iterator(request_iterator, state, call, request_serializer, consumption_thread.start() -class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): +class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too-many-ancestors def __init__(self, state, call, response_deserializer, deadline): super(_Rendezvous, self).__init__() diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py index fc0ad77eb9e..fdd484c25ab 100644 --- a/src/python/grpcio/grpc/_interceptor.py +++ b/src/python/grpcio/grpc/_interceptor.py @@ -80,7 +80,7 @@ def _unwrap_client_call_details(call_details, default_details): return method, timeout, metadata, credentials, wait_for_ready -class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): +class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too-many-ancestors def __init__(self, exception, traceback): super(_FailureOutcome, self).__init__() @@ -127,6 +127,7 @@ class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): return self._traceback def add_callback(self, callback): + del callback return False def add_done_callback(self, fn): From 33be6cd732a0258f9fad81f944d9e717c444dcb8 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 27 Feb 2019 10:29:53 -0800 Subject: [PATCH 543/814] Switch pattern for marking unused argument --- src/python/grpcio/grpc/_interceptor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py index fdd484c25ab..6c4e396ac23 100644 --- a/src/python/grpcio/grpc/_interceptor.py +++ b/src/python/grpcio/grpc/_interceptor.py @@ -126,8 +126,7 @@ class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable def traceback(self, ignored_timeout=None): return self._traceback - def add_callback(self, callback): - del callback + def add_callback(self, unused_callback): return False def add_done_callback(self, fn): From 2af39ded226795a37b0e5de9570e7ce5c8f7379d Mon Sep 17 00:00:00 2001 From: Carl Mastrangelo Date: Wed, 27 Feb 2019 14:12:50 -0800 Subject: [PATCH 544/814] update to 1.19.0 --- tools/interop_matrix/client_matrix.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index dba10c7e7fd..654dfd6faef 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -142,6 +142,7 @@ LANG_RELEASE_MATRIX = { ('v1.16.1', ReleaseInfo()), ('v1.17.1', ReleaseInfo()), ('v1.18.0', ReleaseInfo()), + ('v1.19.0', ReleaseInfo()), ]), 'python': OrderedDict([ From 030149df8f47cef67589d9df7dca55229513f4aa Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 27 Feb 2019 16:07:01 -0800 Subject: [PATCH 545/814] Print the peer string, instead of the address of the peer string --- src/core/ext/transport/chttp2/transport/writing.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index cf77ddc8278..bc8968a0209 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -108,7 +108,7 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) { GRPC_STATS_INC_HTTP2_PINGS_SENT(); t->ping_state.last_ping_sent_time = now; if (grpc_http_trace.enabled() || grpc_bdp_estimator_trace.enabled()) { - gpr_log(GPR_INFO, "%s: Ping sent [%p]: %d/%d", + gpr_log(GPR_INFO, "%s: Ping sent [%s]: %d/%d", t->is_client ? "CLIENT" : "SERVER", t->peer_string, t->ping_state.pings_before_data_required, t->ping_policy.max_pings_without_data); From 80f1eb57af12728a0d35f00b33a98f9c4de82651 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 27 Feb 2019 16:15:29 -0800 Subject: [PATCH 546/814] Add peer string to ping sent log --- .../ext/transport/chttp2/transport/chttp2_transport.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 1c9b37dada2..7c8c3cafed7 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -824,10 +824,10 @@ static const char* write_state_name(grpc_chttp2_write_state st) { static void set_write_state(grpc_chttp2_transport* t, grpc_chttp2_write_state st, const char* reason) { - GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_INFO, "W:%p %s state %s -> %s [%s]", t, - t->is_client ? "CLIENT" : "SERVER", - write_state_name(t->write_state), - write_state_name(st), reason)); + GRPC_CHTTP2_IF_TRACING( + gpr_log(GPR_INFO, "W:%p %s [%s] state %s -> %s [%s]", t, + t->is_client ? "CLIENT" : "SERVER", t->peer_string, + write_state_name(t->write_state), write_state_name(st), reason)); t->write_state = st; /* If the state is being reset back to idle, it means a write was just * finished. Make sure all the run_after_write closures are scheduled. From 9644e588f6ef011ec8e0d6f58d5c2cdb04eb0f03 Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Wed, 27 Feb 2019 23:01:24 -0800 Subject: [PATCH 547/814] Build c-ares bazel lib with alwayslink=1 --- test/cpp/end2end/cfstream_test.cc | 3 --- third_party/cares/cares.BUILD | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/test/cpp/end2end/cfstream_test.cc b/test/cpp/end2end/cfstream_test.cc index 9039329d815..6ca206e5f36 100644 --- a/test/cpp/end2end/cfstream_test.cc +++ b/test/cpp/end2end/cfstream_test.cc @@ -270,9 +270,6 @@ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); grpc_test_init(argc, argv); gpr_setenv("grpc_cfstream", "1"); - // TODO (pjaikumar): remove the line below when - // https://github.com/grpc/grpc/issues/18080 has been fixed. - gpr_setenv("GRPC_DNS_RESOLVER", "native"); const auto result = RUN_ALL_TESTS(); return result; } diff --git a/third_party/cares/cares.BUILD b/third_party/cares/cares.BUILD index 54b8c57b1d6..ffa03aeb12c 100644 --- a/third_party/cares/cares.BUILD +++ b/third_party/cares/cares.BUILD @@ -170,4 +170,5 @@ cc_library( visibility = [ "//visibility:public", ], + alwayslink = 1, ) From 2a4c8ad617a616f08e1055c6d9c69d7cddd475dc Mon Sep 17 00:00:00 2001 From: Alex Polcyn Date: Wed, 27 Feb 2019 23:29:35 -0800 Subject: [PATCH 548/814] Backport c-ares bazel build fix --- third_party/cares/cares.BUILD | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/third_party/cares/cares.BUILD b/third_party/cares/cares.BUILD index fd14007e804..ffa03aeb12c 100644 --- a/third_party/cares/cares.BUILD +++ b/third_party/cares/cares.BUILD @@ -3,6 +3,11 @@ config_setting( values = {"cpu": "darwin"}, ) +config_setting( + name = "darwin_x86_64", + values = {"cpu": "darwin_x86_64"}, +) + config_setting( name = "windows", values = {"cpu": "x64_windows"}, @@ -54,6 +59,7 @@ genrule( ":ios_armv7s": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], ":ios_arm64": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], ":darwin": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], + ":darwin_x86_64": ["@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h"], ":windows": ["@com_github_grpc_grpc//third_party/cares:config_windows/ares_config.h"], ":android": ["@com_github_grpc_grpc//third_party/cares:config_android/ares_config.h"], "//conditions:default": ["@com_github_grpc_grpc//third_party/cares:config_linux/ares_config.h"], @@ -164,4 +170,5 @@ cc_library( visibility = [ "//visibility:public", ], + alwayslink = 1, ) From 4f86edeb2304eae86dcfbcd50d5630c4665368ac Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 28 Feb 2019 10:27:07 -0800 Subject: [PATCH 549/814] Revert "Enable deadline propagation" --- src/python/grpcio/grpc/_channel.py | 25 ++++--------------- .../grpc/_cython/_cygrpc/_hooks.pyx.pxi | 5 +--- src/python/grpcio/grpc/_server.py | 4 +-- 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index ed4c871b684..9661c5e5b38 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -488,18 +488,6 @@ def _stream_unary_invocation_operationses_and_tags(metadata, metadata, initial_metadata_flags)) -def _determine_deadline(user_deadline): - parent_deadline = cygrpc.get_deadline_from_context() - if parent_deadline is None and user_deadline is None: - return None - elif parent_deadline is not None and user_deadline is None: - return parent_deadline - elif user_deadline is not None and parent_deadline is None: - return user_deadline - else: - return min(parent_deadline, user_deadline) - - class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): # pylint: disable=too-many-arguments @@ -539,10 +527,9 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): if state is None: raise rendezvous # pylint: disable-msg=raising-bad-type else: - deadline_to_propagate = _determine_deadline(deadline) call = self._channel.segregated_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, - self._method, None, deadline_to_propagate, metadata, None + self._method, None, deadline, metadata, None if credentials is None else credentials._credentials, (( operations, None, @@ -632,8 +619,8 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, - self._method, None, _determine_deadline(deadline), metadata, - None if credentials is None else credentials._credentials, + self._method, None, deadline, metadata, None + if credentials is None else credentials._credentials, operationses, event_handler, self._context) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -657,10 +644,9 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None) initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) - deadline_to_propagate = _determine_deadline(deadline) call = self._channel.segregated_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, - None, deadline_to_propagate, metadata, None + None, deadline, metadata, None if credentials is None else credentials._credentials, _stream_unary_invocation_operationses_and_tags( metadata, initial_metadata_flags), self._context) @@ -748,10 +734,9 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),), ) event_handler = _event_handler(state, self._response_deserializer) - deadline_to_propagate = _determine_deadline(deadline) call = self._managed_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, - None, deadline_to_propagate, metadata, None + None, deadline, metadata, None if credentials is None else credentials._credentials, operationses, event_handler, self._context) _consume_request_iterator(request_iterator, state, call, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi index de4d71b8196..6d1c36b2b35 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi @@ -16,7 +16,7 @@ cdef object _custom_op_on_c_call(int op, grpc_call *call): raise NotImplementedError("No custom hooks are implemented") -def install_context_from_request_call_event(RequestCallEvent event): +def install_context_from_call(Call call): pass def uninstall_context(): @@ -30,6 +30,3 @@ cdef class CensusContext: def set_census_context_on_call(_CallState call_state, CensusContext census_ctx): pass - -def get_deadline_from_context(): - return None diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 90136aef3c2..9224b2ac672 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -498,7 +498,7 @@ def _status(rpc_event, state, serialized_response): def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - cygrpc.install_context_from_request_call_event(rpc_event) + cygrpc.install_context_from_call(rpc_event.call) try: argument = argument_thunk() if argument is not None: @@ -515,7 +515,7 @@ def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - cygrpc.install_context_from_request_call_event(rpc_event) + cygrpc.install_context_from_call(rpc_event.call) def send_response(response): if response is None: From 9e811bef4dc153efa827bb00fdcc433f63edf2bf Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 28 Feb 2019 15:44:09 -0800 Subject: [PATCH 550/814] Don't to try to watch connectivity state of balancer channel. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 78 +------------------ 1 file changed, 2 insertions(+), 76 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 90398aac7f4..b5218ba7a1e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -295,8 +295,6 @@ class GrpcLb : public LoadBalancingPolicy { static void OnFallbackTimerLocked(void* arg, grpc_error* error); void StartBalancerCallRetryTimerLocked(); static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error); - static void OnBalancerChannelConnectivityChangedLocked(void* arg, - grpc_error* error); // Methods for dealing with the RR policy. grpc_channel_args* CreateRoundRobinPolicyArgsLocked(); @@ -316,10 +314,6 @@ class GrpcLb : public LoadBalancingPolicy { grpc_channel* lb_channel_ = nullptr; // Uuid of the lb channel. Used for channelz. gpr_atm lb_channel_uuid_ = 0; - grpc_connectivity_state lb_channel_connectivity_; - grpc_closure lb_channel_on_connectivity_changed_; - // Are we already watching the LB channel's connectivity? - bool watching_lb_channel_ = false; // Response generator to inject address updates into lb_channel_. RefCountedPtr response_generator_; @@ -1182,10 +1176,6 @@ GrpcLb::GrpcLb(Args args) .set_jitter(GRPC_GRPCLB_RECONNECT_JITTER) .set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { - // Initialization. - GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, - &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, - grpc_combiner_scheduler(args.combiner)); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -1327,7 +1317,8 @@ void GrpcLb::UpdateLocked(const grpc_channel_args& args, ProcessChannelArgsLocked(args); // Update the existing RR policy. if (rr_policy_ != nullptr) CreateOrUpdateRoundRobinPolicyLocked(); - // If this is the initial update, start the fallback timer. + // If this is the initial update, start the fallback timer and the + // balancer call. if (is_initial_update) { if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && !fallback_timer_callback_pending_) { @@ -1339,26 +1330,6 @@ void GrpcLb::UpdateLocked(const grpc_channel_args& args, grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); } StartBalancerCallLocked(); - } else if (!watching_lb_channel_) { - // If this is not the initial update and we're not already watching - // the LB channel's connectivity state, start a watch now. This - // ensures that we'll know when to switch to a new balancer call. - lb_channel_connectivity_ = grpc_channel_check_connectivity_state( - lb_channel_, true /* try to connect */); - grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(lb_channel_)); - GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); - watching_lb_channel_ = true; - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity"); - self.release(); - grpc_client_channel_watch_connectivity_state( - client_channel_elem, - grpc_polling_entity_create_from_pollset_set(interested_parties()), - &lb_channel_connectivity_, &lb_channel_on_connectivity_changed_, - nullptr); } } @@ -1436,51 +1407,6 @@ void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) { grpclb_policy->Unref(DEBUG_LOCATION, "on_balancer_call_retry_timer"); } -// Invoked as part of the update process. It continues watching the LB channel -// until it shuts down or becomes READY. It's invoked even if the LB channel -// stayed READY throughout the update (for example if the update is identical). -void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, - grpc_error* error) { - GrpcLb* grpclb_policy = static_cast(arg); - if (grpclb_policy->shutting_down_) goto done; - // Re-initialize the lb_call. This should also take care of updating the - // embedded RR policy. Note that the current RR policy, if any, will stay in - // effect until an update from the new lb_call is received. - switch (grpclb_policy->lb_channel_connectivity_) { - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_TRANSIENT_FAILURE: { - // Keep watching the LB channel. - grpc_channel_element* client_channel_elem = - grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(grpclb_policy->lb_channel_)); - GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); - grpc_client_channel_watch_connectivity_state( - client_channel_elem, - grpc_polling_entity_create_from_pollset_set( - grpclb_policy->interested_parties()), - &grpclb_policy->lb_channel_connectivity_, - &grpclb_policy->lb_channel_on_connectivity_changed_, nullptr); - break; - } - // The LB channel may be IDLE because it's shut down before the update. - // Restart the LB call to kick the LB channel into gear. - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_READY: - grpclb_policy->lb_calld_.reset(); - if (grpclb_policy->retry_timer_callback_pending_) { - grpc_timer_cancel(&grpclb_policy->lb_call_retry_timer_); - } - grpclb_policy->lb_call_backoff_.Reset(); - grpclb_policy->StartBalancerCallLocked(); - // fallthrough - case GRPC_CHANNEL_SHUTDOWN: - done: - grpclb_policy->watching_lb_channel_ = false; - grpclb_policy->Unref(DEBUG_LOCATION, - "watch_lb_channel_connectivity_cb_shutdown"); - } -} - // // code for interacting with the RR policy // From 1112d52f03fac1045d852a58681d0100d0153bc8 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 28 Feb 2019 15:50:20 -0800 Subject: [PATCH 551/814] Revert "Merge pull request #18206 from grpc/revert-18182-enable-deadline-propagation" This reverts commit 63ef07ebb538ab15bc30e1c1b1b15855f8cd0ea1, reversing changes made to 046e3e4ab5cdb867bda7a5c40fd9b0ac84ad0ff8. --- src/python/grpcio/grpc/_channel.py | 25 +++++++++++++++---- .../grpc/_cython/_cygrpc/_hooks.pyx.pxi | 5 +++- src/python/grpcio/grpc/_server.py | 4 +-- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 9661c5e5b38..ed4c871b684 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -488,6 +488,18 @@ def _stream_unary_invocation_operationses_and_tags(metadata, metadata, initial_metadata_flags)) +def _determine_deadline(user_deadline): + parent_deadline = cygrpc.get_deadline_from_context() + if parent_deadline is None and user_deadline is None: + return None + elif parent_deadline is not None and user_deadline is None: + return parent_deadline + elif user_deadline is not None and parent_deadline is None: + return user_deadline + else: + return min(parent_deadline, user_deadline) + + class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): # pylint: disable=too-many-arguments @@ -527,9 +539,10 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable): if state is None: raise rendezvous # pylint: disable-msg=raising-bad-type else: + deadline_to_propagate = _determine_deadline(deadline) call = self._channel.segregated_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, - self._method, None, deadline, metadata, None + self._method, None, deadline_to_propagate, metadata, None if credentials is None else credentials._credentials, (( operations, None, @@ -619,8 +632,8 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable): event_handler = _event_handler(state, self._response_deserializer) call = self._managed_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, - self._method, None, deadline, metadata, None - if credentials is None else credentials._credentials, + self._method, None, _determine_deadline(deadline), metadata, + None if credentials is None else credentials._credentials, operationses, event_handler, self._context) return _Rendezvous(state, call, self._response_deserializer, deadline) @@ -644,9 +657,10 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable): state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None) initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready( wait_for_ready) + deadline_to_propagate = _determine_deadline(deadline) call = self._channel.segregated_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, - None, deadline, metadata, None + None, deadline_to_propagate, metadata, None if credentials is None else credentials._credentials, _stream_unary_invocation_operationses_and_tags( metadata, initial_metadata_flags), self._context) @@ -734,9 +748,10 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable): (cygrpc.ReceiveInitialMetadataOperation(_EMPTY_FLAGS),), ) event_handler = _event_handler(state, self._response_deserializer) + deadline_to_propagate = _determine_deadline(deadline) call = self._managed_call( cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method, - None, deadline, metadata, None + None, deadline_to_propagate, metadata, None if credentials is None else credentials._credentials, operationses, event_handler, self._context) _consume_request_iterator(request_iterator, state, call, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi index 6d1c36b2b35..de4d71b8196 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi @@ -16,7 +16,7 @@ cdef object _custom_op_on_c_call(int op, grpc_call *call): raise NotImplementedError("No custom hooks are implemented") -def install_context_from_call(Call call): +def install_context_from_request_call_event(RequestCallEvent event): pass def uninstall_context(): @@ -30,3 +30,6 @@ cdef class CensusContext: def set_census_context_on_call(_CallState call_state, CensusContext census_ctx): pass + +def get_deadline_from_context(): + return None diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 9224b2ac672..90136aef3c2 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -498,7 +498,7 @@ def _status(rpc_event, state, serialized_response): def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - cygrpc.install_context_from_call(rpc_event.call) + cygrpc.install_context_from_request_call_event(rpc_event) try: argument = argument_thunk() if argument is not None: @@ -515,7 +515,7 @@ def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk, def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk, request_deserializer, response_serializer): - cygrpc.install_context_from_call(rpc_event.call) + cygrpc.install_context_from_request_call_event(rpc_event) def send_response(response): if response is None: From 30934aeb833bb51ed9cb981202349b9f900202c2 Mon Sep 17 00:00:00 2001 From: Mikael Grimstad Date: Fri, 1 Mar 2019 09:14:25 +0100 Subject: [PATCH 552/814] Fixed dead examples link Case matched link with folder name (Helloworld example) --- src/csharp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/README.md b/src/csharp/README.md index 9a91035d06a..291772ff939 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -103,5 +103,5 @@ THE NATIVE DEPENDENCY Internally, gRPC C# uses a native library written in C (gRPC C core) and invokes its functionality via P/Invoke. The fact that a native library is used should be fully transparent to the users and just installing the `Grpc.Core` NuGet package is the only step needed to use gRPC C# on all supported platforms. [API Reference]: https://grpc.io/grpc/csharp/api/Grpc.Core.html -[Helloworld Example]: ../../examples/csharp/helloworld +[Helloworld Example]: ../../examples/csharp/Helloworld [RouteGuide Tutorial]: https://grpc.io/docs/tutorials/basic/csharp.html From 7c717838797438d2925c4e45e4d65ac1c83c352d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 1 Mar 2019 09:30:18 +0100 Subject: [PATCH 553/814] grpc-dotnet now support unimplemented handlers --- tools/run_tests/run_interop_tests.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 33128c87320..fd5b7ea21d9 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -58,10 +58,9 @@ _SKIP_SERVER_COMPRESSION = [ _SKIP_COMPRESSION = _SKIP_CLIENT_COMPRESSION + _SKIP_SERVER_COMPRESSION -_SKIP_UNIMPLEMENTED_HANDLERS = ['unimplemented_method', 'unimplemented_service'] - -_SKIP_ADVANCED = _SKIP_UNIMPLEMENTED_HANDLERS + [ - 'status_code_and_message', 'custom_metadata' +_SKIP_ADVANCED = [ + 'status_code_and_message', 'custom_metadata', 'unimplemented_method', + 'unimplemented_service' ] _SKIP_SPECIAL_STATUS_MESSAGE = ['special_status_message'] @@ -199,7 +198,7 @@ class AspNetCoreLanguage: return _TEST_CASES + _AUTH_TEST_CASES def unimplemented_test_cases_server(self): - return _SKIP_COMPRESSION + _SKIP_UNIMPLEMENTED_HANDLERS + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE def __str__(self): return 'aspnetcore' From 1c52c309919d56553f78ab7df29d05c2bfca17f3 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 1 Mar 2019 07:44:23 -0800 Subject: [PATCH 554/814] Inhibit client-side health checking for backends from balancer in xds. --- src/core/ext/filters/client_channel/lb_policy/xds/xds.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index e1291da50af..4c7316f4242 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1307,11 +1307,14 @@ grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { grpc_channel_arg_integer_create( const_cast(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_XDS_LOAD_BALANCER), 1), + // Inhibit client-side health checking, since the balancer does + // this for us. + grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1), }; - grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( + return grpc_channel_args_copy_and_add_and_remove( args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, GPR_ARRAY_SIZE(args_to_add)); - return args; } void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { From 251d66aac6959524dd7e88b23274e5ef3792a7ea Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 1 Mar 2019 08:40:21 -0800 Subject: [PATCH 555/814] Convert client channel factory to C++ --- src/core/ext/filters/client_channel/README.md | 14 +- .../filters/client_channel/client_channel.cc | 29 +- .../client_channel/client_channel_factory.cc | 62 ++-- .../client_channel/client_channel_factory.h | 61 ++-- .../ext/filters/client_channel/lb_policy.h | 6 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 8 +- .../client_channel/lb_policy/xds/xds.cc | 8 +- .../client_channel/resolving_lb_policy.cc | 4 +- .../chttp2/client/insecure/channel_create.cc | 92 +++--- .../client/secure/secure_channel_create.cc | 271 +++++++++--------- test/core/util/test_lb_policies.cc | 4 +- test/cpp/microbenchmarks/bm_call_create.cc | 32 +-- 12 files changed, 264 insertions(+), 327 deletions(-) diff --git a/src/core/ext/filters/client_channel/README.md b/src/core/ext/filters/client_channel/README.md index 9676a4535b2..ffb09fd34e7 100644 --- a/src/core/ext/filters/client_channel/README.md +++ b/src/core/ext/filters/client_channel/README.md @@ -4,7 +4,7 @@ Client Configuration Support for GRPC This library provides high level configuration machinery to construct client channels and load balance between them. -Each grpc_channel is created with a grpc_resolver. It is the resolver's duty +Each `grpc_channel` is created with a `Resolver`. It is the resolver's duty to resolve a name into a set of arguments for the channel. Such arguments might include: @@ -12,7 +12,7 @@ might include: - a load balancing policy to decide which server to send a request to - a set of filters to mutate outgoing requests (say, by adding metadata) -The resolver provides this data as a stream of grpc_channel_args objects to +The resolver provides this data as a stream of `grpc_channel_args` objects to the channel. We represent arguments as a stream so that they can be changed by the resolver during execution, by reacting to external events (such as new service configuration data being pushed to some store). @@ -21,11 +21,11 @@ new service configuration data being pushed to some store). Load Balancing -------------- -Load balancing configuration is provided by a grpc_lb_policy object. +Load balancing configuration is provided by a `LoadBalancingPolicy` object. The primary job of the load balancing policies is to pick a target server given only the initial metadata for a request. It does this by providing -a grpc_subchannel object to the owning channel. +a `ConnectedSubchannel` object to the owning channel. Sub-Channels @@ -38,9 +38,9 @@ decisions (for example, by avoiding disconnected backends). Configured sub-channels are fully setup to participate in the grpc data plane. Their behavior is specified by a set of grpc channel filters defined at their -construction. To customize this behavior, resolvers build -grpc_client_channel_factory objects, which use the decorator pattern to customize -construction arguments for concrete grpc_subchannel instances. +construction. To customize this behavior, transports build +`ClientChannelFactory` objects, which customize construction arguments for +concrete subchannel instances. Naming for GRPC diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 3566ef8fb35..3fb32f7e823 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -107,8 +107,8 @@ typedef struct client_channel_channel_data { grpc_channel_stack* owning_stack; /** interested parties (owned) */ grpc_pollset_set* interested_parties; - // Client channel factory. Holds a ref. - grpc_client_channel_factory* client_channel_factory; + // Client channel factory. + grpc_core::ClientChannelFactory* client_channel_factory; // Subchannel pool. grpc_core::RefCountedPtr subchannel_pool; @@ -205,16 +205,15 @@ class ClientChannelControlHelper chand_->subchannel_pool.get()); grpc_channel_args* new_args = grpc_channel_args_copy_and_add(&args, &arg, 1); - Subchannel* subchannel = grpc_client_channel_factory_create_subchannel( - chand_->client_channel_factory, new_args); + Subchannel* subchannel = + chand_->client_channel_factory->CreateSubchannel(new_args); grpc_channel_args_destroy(new_args); return subchannel; } - grpc_channel* CreateChannel(const char* target, grpc_client_channel_type type, + grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override { - return grpc_client_channel_factory_create_channel( - chand_->client_channel_factory, target, type, &args); + return chand_->client_channel_factory->CreateChannel(target, &args); } void UpdateState( @@ -420,19 +419,12 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_ENABLE_RETRIES); chand->enable_retries = grpc_channel_arg_get_bool(arg, true); // Record client channel factory. - arg = grpc_channel_args_find(args->channel_args, - GRPC_ARG_CLIENT_CHANNEL_FACTORY); - if (arg == nullptr) { + chand->client_channel_factory = + grpc_core::ClientChannelFactory::GetFromChannelArgs(args->channel_args); + if (chand->client_channel_factory == nullptr) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Missing client channel factory in args for client channel filter"); } - if (arg->type != GRPC_ARG_POINTER) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "client channel factory arg must be a pointer"); - } - chand->client_channel_factory = - static_cast(arg->value.pointer.p); - grpc_client_channel_factory_ref(chand->client_channel_factory); // Get server name to resolve, using proxy mapper if needed. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI); if (arg == nullptr) { @@ -509,9 +501,6 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { // longer be any need to explicitly reset these smart pointer data members. chand->picker.reset(); chand->subchannel_pool.reset(); - if (chand->client_channel_factory != nullptr) { - grpc_client_channel_factory_unref(chand->client_channel_factory); - } chand->info_lb_policy_name.reset(); chand->info_service_config_json.reset(); chand->retry_throttle_data.reset(); diff --git a/src/core/ext/filters/client_channel/client_channel_factory.cc b/src/core/ext/filters/client_channel/client_channel_factory.cc index 8c558382fdf..671a38430ef 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.cc +++ b/src/core/ext/filters/client_channel/client_channel_factory.cc @@ -21,47 +21,35 @@ #include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/lib/channel/channel_args.h" -void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory) { - factory->vtable->ref(factory); -} +// Channel arg key for client channel factory. +#define GRPC_ARG_CLIENT_CHANNEL_FACTORY "grpc.client_channel_factory" -void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory) { - factory->vtable->unref(factory); -} +namespace grpc_core { -grpc_core::Subchannel* grpc_client_channel_factory_create_subchannel( - grpc_client_channel_factory* factory, const grpc_channel_args* args) { - return factory->vtable->create_subchannel(factory, args); -} +namespace { -grpc_channel* grpc_client_channel_factory_create_channel( - grpc_client_channel_factory* factory, const char* target, - grpc_client_channel_type type, const grpc_channel_args* args) { - return factory->vtable->create_client_channel(factory, target, type, args); +void* factory_arg_copy(void* f) { return f; } +void factory_arg_destroy(void* f) {} +int factory_arg_cmp(void* factory1, void* factory2) { + return GPR_ICMP(factory1, factory2); } - -static void* factory_arg_copy(void* factory) { - grpc_client_channel_factory_ref( - static_cast(factory)); - return factory; -} - -static void factory_arg_destroy(void* factory) { - grpc_client_channel_factory_unref( - static_cast(factory)); -} - -static int factory_arg_cmp(void* factory1, void* factory2) { - if (factory1 < factory2) return -1; - if (factory1 > factory2) return 1; - return 0; -} - -static const grpc_arg_pointer_vtable factory_arg_vtable = { +const grpc_arg_pointer_vtable factory_arg_vtable = { factory_arg_copy, factory_arg_destroy, factory_arg_cmp}; -grpc_arg grpc_client_channel_factory_create_channel_arg( - grpc_client_channel_factory* factory) { - return grpc_channel_arg_pointer_create((char*)GRPC_ARG_CLIENT_CHANNEL_FACTORY, - factory, &factory_arg_vtable); +} // namespace + +grpc_arg ClientChannelFactory::CreateChannelArg(ClientChannelFactory* factory) { + return grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_CLIENT_CHANNEL_FACTORY), factory, + &factory_arg_vtable); } + +ClientChannelFactory* ClientChannelFactory::GetFromChannelArgs( + const grpc_channel_args* args) { + const grpc_arg* arg = + grpc_channel_args_find(args, GRPC_ARG_CLIENT_CHANNEL_FACTORY); + if (arg == nullptr || arg->type != GRPC_ARG_POINTER) return nullptr; + return static_cast(arg->value.pointer.p); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/client_channel_factory.h b/src/core/ext/filters/client_channel/client_channel_factory.h index 4b72aa46499..21f78a833df 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -24,51 +24,32 @@ #include #include "src/core/ext/filters/client_channel/subchannel.h" -#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/gprpp/abstract.h" -// Channel arg key for client channel factory. -#define GRPC_ARG_CLIENT_CHANNEL_FACTORY "grpc.client_channel_factory" +namespace grpc_core { -typedef struct grpc_client_channel_factory grpc_client_channel_factory; -typedef struct grpc_client_channel_factory_vtable - grpc_client_channel_factory_vtable; +class ClientChannelFactory { + public: + virtual ~ClientChannelFactory() = default; -typedef enum { - GRPC_CLIENT_CHANNEL_TYPE_REGULAR, /** for the user-level regular calls */ - GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, /** for communication with a load - balancing service */ -} grpc_client_channel_type; + // Creates a subchannel with the specified args. + virtual Subchannel* CreateSubchannel(const grpc_channel_args* args) + GRPC_ABSTRACT; -/** Constructor for new configured channels. - Creating decorators around this type is encouraged to adapt behavior. */ -struct grpc_client_channel_factory { - const grpc_client_channel_factory_vtable* vtable; + // Creates a channel for the specified target with the specified args. + virtual grpc_channel* CreateChannel( + const char* target, const grpc_channel_args* args) GRPC_ABSTRACT; + + // Returns a channel arg containing the specified factory. + static grpc_arg CreateChannelArg(ClientChannelFactory* factory); + + // Returns the factory from args, or null if not found. + static ClientChannelFactory* GetFromChannelArgs( + const grpc_channel_args* args); + + GRPC_ABSTRACT_BASE_CLASS }; -struct grpc_client_channel_factory_vtable { - void (*ref)(grpc_client_channel_factory* factory); - void (*unref)(grpc_client_channel_factory* factory); - grpc_core::Subchannel* (*create_subchannel)( - grpc_client_channel_factory* factory, const grpc_channel_args* args); - grpc_channel* (*create_client_channel)(grpc_client_channel_factory* factory, - const char* target, - grpc_client_channel_type type, - const grpc_channel_args* args); -}; - -void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory); -void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory); - -/** Create a new grpc_subchannel */ -grpc_core::Subchannel* grpc_client_channel_factory_create_subchannel( - grpc_client_channel_factory* factory, const grpc_channel_args* args); - -/** Create a new grpc_channel */ -grpc_channel* grpc_client_channel_factory_create_channel( - grpc_client_channel_factory* factory, const char* target, - grpc_client_channel_type type, const grpc_channel_args* args); - -grpc_arg grpc_client_channel_factory_create_channel_arg( - grpc_client_channel_factory* factory); +} // namespace grpc_core #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H */ diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 813bad1b7f0..1bb8c5e96c0 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -22,7 +22,6 @@ #include #include "src/core/ext/filters/client_channel/client_channel_channelz.h" -#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/orphanable.h" @@ -193,10 +192,9 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual Subchannel* CreateSubchannel(const grpc_channel_args& args) GRPC_ABSTRACT; - /// Creates a channel with the specified target, type, and channel args. + /// Creates a channel with the specified target and channel args. virtual grpc_channel* CreateChannel( - const char* target, grpc_client_channel_type type, - const grpc_channel_args& args) GRPC_ABSTRACT; + const char* target, const grpc_channel_args& args) GRPC_ABSTRACT; /// Sets the connectivity state and returns a new picker to be used /// by the client channel. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 90398aac7f4..4cd4a51b9c5 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -273,7 +273,6 @@ class GrpcLb : public LoadBalancingPolicy { Subchannel* CreateSubchannel(const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, - grpc_client_channel_type type, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, grpc_error* state_error, UniquePtr picker) override; @@ -581,10 +580,9 @@ Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { } grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, - grpc_client_channel_type type, const grpc_channel_args& args) { if (parent_->shutting_down_) return nullptr; - return parent_->channel_control_helper()->CreateChannel(target, type, args); + return parent_->channel_control_helper()->CreateChannel(target, args); } void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, @@ -1305,8 +1303,8 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { if (lb_channel_ == nullptr) { char* uri_str; gpr_asprintf(&uri_str, "fake:///%s", server_name_); - lb_channel_ = channel_control_helper()->CreateChannel( - uri_str, GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, *lb_channel_args); + lb_channel_ = + channel_control_helper()->CreateChannel(uri_str, *lb_channel_args); GPR_ASSERT(lb_channel_ != nullptr); grpc_core::channelz::ChannelNode* channel_node = grpc_channel_get_channelz_node(lb_channel_); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index e1291da50af..078aebc133e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -223,7 +223,6 @@ class XdsLb : public LoadBalancingPolicy { Subchannel* CreateSubchannel(const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, - grpc_client_channel_type type, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, grpc_error* state_error, UniquePtr picker) override; @@ -354,10 +353,9 @@ Subchannel* XdsLb::Helper::CreateSubchannel(const grpc_channel_args& args) { } grpc_channel* XdsLb::Helper::CreateChannel(const char* target, - grpc_client_channel_type type, const grpc_channel_args& args) { if (parent_->shutting_down_) return nullptr; - return parent_->channel_control_helper()->CreateChannel(target, type, args); + return parent_->channel_control_helper()->CreateChannel(target, args); } void XdsLb::Helper::UpdateState(grpc_connectivity_state state, @@ -1076,8 +1074,8 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { char* uri_str; gpr_asprintf(&uri_str, "fake:///%s", server_name_); gpr_mu_lock(&lb_channel_mu_); - lb_channel_ = channel_control_helper()->CreateChannel( - uri_str, GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, *lb_channel_args); + lb_channel_ = + channel_control_helper()->CreateChannel(uri_str, *lb_channel_args); gpr_mu_unlock(&lb_channel_mu_); GPR_ASSERT(lb_channel_ != nullptr); gpr_free(uri_str); diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 02a7af54588..a02a7e8acdb 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -80,10 +80,10 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper return parent_->channel_control_helper()->CreateSubchannel(args); } - grpc_channel* CreateChannel(const char* target, grpc_client_channel_type type, + grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override { if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. - return parent_->channel_control_helper()->CreateChannel(target, type, args); + return parent_->channel_control_helper()->CreateChannel(target, args); } void UpdateState(grpc_connectivity_state state, grpc_error* state_error, diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc index 8aabcfa2000..d77799cef70 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -33,50 +33,53 @@ #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/channel.h" -static void client_channel_factory_ref( - grpc_client_channel_factory* cc_factory) {} +namespace grpc_core { -static void client_channel_factory_unref( - grpc_client_channel_factory* cc_factory) {} - -static grpc_core::Subchannel* client_channel_factory_create_subchannel( - grpc_client_channel_factory* cc_factory, const grpc_channel_args* args) { - grpc_channel_args* new_args = grpc_default_authority_add_if_not_present(args); - grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_core::Subchannel* s = grpc_core::Subchannel::Create(connector, new_args); - grpc_connector_unref(connector); - grpc_channel_args_destroy(new_args); - return s; -} - -static grpc_channel* client_channel_factory_create_channel( - grpc_client_channel_factory* cc_factory, const char* target, - grpc_client_channel_type type, const grpc_channel_args* args) { - if (target == nullptr) { - gpr_log(GPR_ERROR, "cannot create channel with NULL target name"); - return nullptr; +class Chttp2InsecureClientChannelFactory : public ClientChannelFactory { + public: + Subchannel* CreateSubchannel(const grpc_channel_args* args) override { + grpc_channel_args* new_args = + grpc_default_authority_add_if_not_present(args); + grpc_connector* connector = grpc_chttp2_connector_create(); + Subchannel* s = Subchannel::Create(connector, new_args); + grpc_connector_unref(connector); + grpc_channel_args_destroy(new_args); + return s; } - // Add channel arg containing the server URI. - grpc_core::UniquePtr canonical_target = - grpc_core::ResolverRegistry::AddDefaultPrefixIfNeeded(target); - grpc_arg arg = grpc_channel_arg_string_create( - const_cast(GRPC_ARG_SERVER_URI), canonical_target.get()); - const char* to_remove[] = {GRPC_ARG_SERVER_URI}; - grpc_channel_args* new_args = - grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1); - grpc_channel* channel = - grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr); - grpc_channel_args_destroy(new_args); - return channel; + + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args* args) override { + if (target == nullptr) { + gpr_log(GPR_ERROR, "cannot create channel with NULL target name"); + return nullptr; + } + // Add channel arg containing the server URI. + UniquePtr canonical_target = + ResolverRegistry::AddDefaultPrefixIfNeeded(target); + grpc_arg arg = grpc_channel_arg_string_create( + const_cast(GRPC_ARG_SERVER_URI), canonical_target.get()); + const char* to_remove[] = {GRPC_ARG_SERVER_URI}; + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1); + grpc_channel* channel = + grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr); + grpc_channel_args_destroy(new_args); + return channel; + } +}; + +} // namespace grpc_core + +namespace { + +grpc_core::Chttp2InsecureClientChannelFactory* g_factory; +gpr_once g_factory_once; + +void FactoryInit() { + g_factory = grpc_core::New(); } -static const grpc_client_channel_factory_vtable client_channel_factory_vtable = - {client_channel_factory_ref, client_channel_factory_unref, - client_channel_factory_create_subchannel, - client_channel_factory_create_channel}; - -static grpc_client_channel_factory client_channel_factory = { - &client_channel_factory_vtable}; +} // namespace /* Create a client channel: Asynchronously: - resolve target @@ -91,16 +94,13 @@ grpc_channel* grpc_insecure_channel_create(const char* target, (target, args, reserved)); GPR_ASSERT(reserved == nullptr); // Add channel arg containing the client channel factory. - grpc_arg arg = - grpc_client_channel_factory_create_channel_arg(&client_channel_factory); + gpr_once_init(&g_factory_once, FactoryInit); + grpc_arg arg = grpc_core::ClientChannelFactory::CreateChannelArg(g_factory); grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &arg, 1); // Create channel. - grpc_channel* channel = client_channel_factory_create_channel( - &client_channel_factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, - new_args); + grpc_channel* channel = g_factory->CreateChannel(target, new_args); // Clean up. grpc_channel_args_destroy(new_args); - return channel != nullptr ? channel : grpc_lame_client_channel_create( target, GRPC_STATUS_INTERNAL, diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index eb2fee2af91..6277859c59c 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -40,148 +40,148 @@ #include "src/core/lib/surface/channel.h" #include "src/core/lib/uri/uri_parser.h" -static void client_channel_factory_ref( - grpc_client_channel_factory* cc_factory) {} +namespace grpc_core { -static void client_channel_factory_unref( - grpc_client_channel_factory* cc_factory) {} - -static grpc_channel_args* get_secure_naming_channel_args( - const grpc_channel_args* args) { - grpc_channel_credentials* channel_credentials = - grpc_channel_credentials_find_in_args(args); - if (channel_credentials == nullptr) { - gpr_log(GPR_ERROR, - "Can't create subchannel: channel credentials missing for secure " - "channel."); - return nullptr; - } - // Make sure security connector does not already exist in args. - if (grpc_security_connector_find_in_args(args) != nullptr) { - gpr_log(GPR_ERROR, - "Can't create subchannel: security connector already present in " - "channel args."); - return nullptr; - } - // To which address are we connecting? By default, use the server URI. - const grpc_arg* server_uri_arg = - grpc_channel_args_find(args, GRPC_ARG_SERVER_URI); - const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg); - GPR_ASSERT(server_uri_str != nullptr); - grpc_uri* server_uri = - grpc_uri_parse(server_uri_str, true /* supress errors */); - GPR_ASSERT(server_uri != nullptr); - const grpc_core::TargetAuthorityTable* target_authority_table = - grpc_core::FindTargetAuthorityTableInArgs(args); - grpc_core::UniquePtr authority; - if (target_authority_table != nullptr) { - // Find the authority for the target. - const char* target_uri_str = - grpc_core::Subchannel::GetUriFromSubchannelAddressArg(args); - grpc_uri* target_uri = - grpc_uri_parse(target_uri_str, false /* suppress errors */); - GPR_ASSERT(target_uri != nullptr); - if (target_uri->path[0] != '\0') { // "path" may be empty - const grpc_slice key = grpc_slice_from_static_string( - target_uri->path[0] == '/' ? target_uri->path + 1 : target_uri->path); - const grpc_core::UniquePtr* value = - target_authority_table->Get(key); - if (value != nullptr) authority.reset(gpr_strdup(value->get())); - grpc_slice_unref_internal(key); +class Chttp2SecureClientChannelFactory : public ClientChannelFactory { + public: + Subchannel* CreateSubchannel(const grpc_channel_args* args) override { + grpc_channel_args* new_args = GetSecureNamingChannelArgs(args); + if (new_args == nullptr) { + gpr_log(GPR_ERROR, + "Failed to create channel args during subchannel creation."); + return nullptr; } - grpc_uri_destroy(target_uri); + grpc_connector* connector = grpc_chttp2_connector_create(); + Subchannel* s = Subchannel::Create(connector, new_args); + grpc_connector_unref(connector); + grpc_channel_args_destroy(new_args); + return s; } - // If the authority hasn't already been set (either because no target - // authority table was present or because the target was not present - // in the table), fall back to using the original server URI. - if (authority == nullptr) { - authority = - grpc_core::ResolverRegistry::GetDefaultAuthority(server_uri_str); + + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args* args) override { + if (target == nullptr) { + gpr_log(GPR_ERROR, "cannot create channel with NULL target name"); + return nullptr; + } + // Add channel arg containing the server URI. + UniquePtr canonical_target = + ResolverRegistry::AddDefaultPrefixIfNeeded(target); + grpc_arg arg = grpc_channel_arg_string_create( + const_cast(GRPC_ARG_SERVER_URI), canonical_target.get()); + const char* to_remove[] = {GRPC_ARG_SERVER_URI}; + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1); + grpc_channel* channel = + grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr); + grpc_channel_args_destroy(new_args); + return channel; } - grpc_arg args_to_add[2]; - size_t num_args_to_add = 0; - if (grpc_channel_args_find(args, GRPC_ARG_DEFAULT_AUTHORITY) == nullptr) { - // If the channel args don't already contain GRPC_ARG_DEFAULT_AUTHORITY, add - // the arg, setting it to the value just obtained. - args_to_add[num_args_to_add++] = grpc_channel_arg_string_create( - const_cast(GRPC_ARG_DEFAULT_AUTHORITY), authority.get()); - } - grpc_channel_args* args_with_authority = - grpc_channel_args_copy_and_add(args, args_to_add, num_args_to_add); - grpc_uri_destroy(server_uri); - // Create the security connector using the credentials and target name. - grpc_channel_args* new_args_from_connector = nullptr; - grpc_core::RefCountedPtr - subchannel_security_connector = - channel_credentials->create_security_connector( - /*call_creds=*/nullptr, authority.get(), args_with_authority, - &new_args_from_connector); - if (subchannel_security_connector == nullptr) { - gpr_log(GPR_ERROR, - "Failed to create secure subchannel for secure name '%s'", - authority.get()); + + private: + static grpc_channel_args* GetSecureNamingChannelArgs( + const grpc_channel_args* args) { + grpc_channel_credentials* channel_credentials = + grpc_channel_credentials_find_in_args(args); + if (channel_credentials == nullptr) { + gpr_log(GPR_ERROR, + "Can't create subchannel: channel credentials missing for secure " + "channel."); + return nullptr; + } + // Make sure security connector does not already exist in args. + if (grpc_security_connector_find_in_args(args) != nullptr) { + gpr_log(GPR_ERROR, + "Can't create subchannel: security connector already present in " + "channel args."); + return nullptr; + } + // To which address are we connecting? By default, use the server URI. + const grpc_arg* server_uri_arg = + grpc_channel_args_find(args, GRPC_ARG_SERVER_URI); + const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg); + GPR_ASSERT(server_uri_str != nullptr); + grpc_uri* server_uri = + grpc_uri_parse(server_uri_str, true /* suppress errors */); + GPR_ASSERT(server_uri != nullptr); + const TargetAuthorityTable* target_authority_table = + FindTargetAuthorityTableInArgs(args); + UniquePtr authority; + if (target_authority_table != nullptr) { + // Find the authority for the target. + const char* target_uri_str = + Subchannel::GetUriFromSubchannelAddressArg(args); + grpc_uri* target_uri = + grpc_uri_parse(target_uri_str, false /* suppress errors */); + GPR_ASSERT(target_uri != nullptr); + if (target_uri->path[0] != '\0') { // "path" may be empty + const grpc_slice key = grpc_slice_from_static_string( + target_uri->path[0] == '/' ? target_uri->path + 1 + : target_uri->path); + const UniquePtr* value = target_authority_table->Get(key); + if (value != nullptr) authority.reset(gpr_strdup(value->get())); + grpc_slice_unref_internal(key); + } + grpc_uri_destroy(target_uri); + } + // If the authority hasn't already been set (either because no target + // authority table was present or because the target was not present + // in the table), fall back to using the original server URI. + if (authority == nullptr) { + authority = ResolverRegistry::GetDefaultAuthority(server_uri_str); + } + grpc_arg args_to_add[2]; + size_t num_args_to_add = 0; + if (grpc_channel_args_find(args, GRPC_ARG_DEFAULT_AUTHORITY) == nullptr) { + // If the channel args don't already contain GRPC_ARG_DEFAULT_AUTHORITY, + // add the arg, setting it to the value just obtained. + args_to_add[num_args_to_add++] = grpc_channel_arg_string_create( + const_cast(GRPC_ARG_DEFAULT_AUTHORITY), authority.get()); + } + grpc_channel_args* args_with_authority = + grpc_channel_args_copy_and_add(args, args_to_add, num_args_to_add); + grpc_uri_destroy(server_uri); + // Create the security connector using the credentials and target name. + grpc_channel_args* new_args_from_connector = nullptr; + RefCountedPtr + subchannel_security_connector = + channel_credentials->create_security_connector( + /*call_creds=*/nullptr, authority.get(), args_with_authority, + &new_args_from_connector); + if (subchannel_security_connector == nullptr) { + gpr_log(GPR_ERROR, + "Failed to create secure subchannel for secure name '%s'", + authority.get()); + grpc_channel_args_destroy(args_with_authority); + return nullptr; + } + grpc_arg new_security_connector_arg = + grpc_security_connector_to_arg(subchannel_security_connector.get()); + grpc_channel_args* new_args = grpc_channel_args_copy_and_add( + new_args_from_connector != nullptr ? new_args_from_connector + : args_with_authority, + &new_security_connector_arg, 1); + subchannel_security_connector.reset(DEBUG_LOCATION, "lb_channel_create"); + if (new_args_from_connector != nullptr) { + grpc_channel_args_destroy(new_args_from_connector); + } grpc_channel_args_destroy(args_with_authority); - return nullptr; + return new_args; } - grpc_arg new_security_connector_arg = - grpc_security_connector_to_arg(subchannel_security_connector.get()); +}; - grpc_channel_args* new_args = grpc_channel_args_copy_and_add( - new_args_from_connector != nullptr ? new_args_from_connector - : args_with_authority, - &new_security_connector_arg, 1); +} // namespace grpc_core - subchannel_security_connector.reset(DEBUG_LOCATION, "lb_channel_create"); - if (new_args_from_connector != nullptr) { - grpc_channel_args_destroy(new_args_from_connector); - } - grpc_channel_args_destroy(args_with_authority); - return new_args; +namespace { + +grpc_core::Chttp2SecureClientChannelFactory* g_factory; +gpr_once g_factory_once; + +void FactoryInit() { + g_factory = grpc_core::New(); } -static grpc_core::Subchannel* client_channel_factory_create_subchannel( - grpc_client_channel_factory* cc_factory, const grpc_channel_args* args) { - grpc_channel_args* new_args = get_secure_naming_channel_args(args); - if (new_args == nullptr) { - gpr_log(GPR_ERROR, - "Failed to create channel args during subchannel creation."); - return nullptr; - } - grpc_connector* connector = grpc_chttp2_connector_create(); - grpc_core::Subchannel* s = grpc_core::Subchannel::Create(connector, new_args); - grpc_connector_unref(connector); - grpc_channel_args_destroy(new_args); - return s; -} - -static grpc_channel* client_channel_factory_create_channel( - grpc_client_channel_factory* cc_factory, const char* target, - grpc_client_channel_type type, const grpc_channel_args* args) { - if (target == nullptr) { - gpr_log(GPR_ERROR, "cannot create channel with NULL target name"); - return nullptr; - } - // Add channel arg containing the server URI. - grpc_core::UniquePtr canonical_target = - grpc_core::ResolverRegistry::AddDefaultPrefixIfNeeded(target); - grpc_arg arg = grpc_channel_arg_string_create((char*)GRPC_ARG_SERVER_URI, - canonical_target.get()); - const char* to_remove[] = {GRPC_ARG_SERVER_URI}; - grpc_channel_args* new_args = - grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1); - grpc_channel* channel = - grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr); - grpc_channel_args_destroy(new_args); - return channel; -} - -static const grpc_client_channel_factory_vtable client_channel_factory_vtable = - {client_channel_factory_ref, client_channel_factory_unref, - client_channel_factory_create_subchannel, - client_channel_factory_create_channel}; - -static grpc_client_channel_factory client_channel_factory = { - &client_channel_factory_vtable}; +} // namespace // Create a secure client channel: // Asynchronously: - resolve target @@ -201,16 +201,15 @@ grpc_channel* grpc_secure_channel_create(grpc_channel_credentials* creds, if (creds != nullptr) { // Add channel args containing the client channel factory and channel // credentials. + gpr_once_init(&g_factory_once, FactoryInit); grpc_arg args_to_add[] = { - grpc_client_channel_factory_create_channel_arg(&client_channel_factory), + grpc_core::ClientChannelFactory::CreateChannelArg(g_factory), grpc_channel_credentials_to_arg(creds)}; grpc_channel_args* new_args = grpc_channel_args_copy_and_add( args, args_to_add, GPR_ARRAY_SIZE(args_to_add)); new_args = creds->update_arguments(new_args); // Create channel. - channel = client_channel_factory_create_channel( - &client_channel_factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, - new_args); + channel = g_factory->CreateChannel(target, new_args); // Clean up. grpc_channel_args_destroy(new_args); } diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 0a01e483f13..745162f637f 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -147,10 +147,8 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy } grpc_channel* CreateChannel(const char* target, - grpc_client_channel_type type, const grpc_channel_args& args) override { - return parent_->channel_control_helper()->CreateChannel(target, type, - args); + return parent_->channel_control_helper()->CreateChannel(target, args); } void UpdateState(grpc_connectivity_state state, grpc_error* state_error, diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index e57650fe5b7..c1c8651ba43 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -318,30 +318,18 @@ static void FilterDestroy(void* arg, grpc_error* error) { gpr_free(arg); } static void DoNothing(void* arg, grpc_error* error) {} -class FakeClientChannelFactory : public grpc_client_channel_factory { +class FakeClientChannelFactory : public grpc_core::ClientChannelFactory { public: - FakeClientChannelFactory() { vtable = &vtable_; } - - private: - static void NoRef(grpc_client_channel_factory* factory) {} - static void NoUnref(grpc_client_channel_factory* factory) {} - static grpc_core::Subchannel* CreateSubchannel( - grpc_client_channel_factory* factory, const grpc_channel_args* args) { + grpc_core::Subchannel* CreateSubchannel( + const grpc_channel_args* args) override { return nullptr; } - static grpc_channel* CreateClientChannel(grpc_client_channel_factory* factory, - const char* target, - grpc_client_channel_type type, - const grpc_channel_args* args) { + grpc_channel* CreateChannel(const char* target, + const grpc_channel_args* args) override { return nullptr; } - - static const grpc_client_channel_factory_vtable vtable_; }; -const grpc_client_channel_factory_vtable FakeClientChannelFactory::vtable_ = { - NoRef, NoUnref, CreateSubchannel, CreateClientChannel}; - static grpc_arg StringArg(const char* key, const char* value) { grpc_arg a; a.type = GRPC_ARG_STRING; @@ -506,13 +494,13 @@ static void BM_IsolatedFilter(benchmark::State& state) { TrackCounters track_counters; Fixture fixture; std::ostringstream label; - - std::vector args; FakeClientChannelFactory fake_client_channel_factory; - args.push_back(grpc_client_channel_factory_create_channel_arg( - &fake_client_channel_factory)); - args.push_back(StringArg(GRPC_ARG_SERVER_URI, "localhost")); + std::vector args = { + grpc_core::ClientChannelFactory::CreateChannelArg( + &fake_client_channel_factory), + StringArg(GRPC_ARG_SERVER_URI, "localhost"), + }; grpc_channel_args channel_args = {args.size(), &args[0]}; std::vector filters; From ef42aff69934369ef57ef938472eecd2436009e1 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 1 Mar 2019 10:00:04 -0800 Subject: [PATCH 556/814] Simplify batch operations event interpretation --- src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi index be5013c8f7b..e80dc88767e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi @@ -56,18 +56,19 @@ cdef class _BatchOperationTag: self._retained_call = call cdef void prepare(self) except *: + cdef Operation operation self.c_nops = 0 if self._operations is None else len(self._operations) if 0 < self.c_nops: self.c_ops = gpr_malloc(sizeof(grpc_op) * self.c_nops) for index, operation in enumerate(self._operations): - (operation).c() - self.c_ops[index] = (operation).c_op + operation.c() + self.c_ops[index] = operation.c_op cdef BatchOperationEvent event(self, grpc_event c_event): + cdef Operation operation if 0 < self.c_nops: - for index, operation in enumerate(self._operations): - (operation).c_op = self.c_ops[index] - (operation).un_c() + for operation in self._operations: + operation.un_c() gpr_free(self.c_ops) return BatchOperationEvent( c_event.type, c_event.success, self._user_tag, self._operations) @@ -84,4 +85,4 @@ cdef class _ServerShutdownTag(_Tag): cdef ServerShutdownEvent event(self, grpc_event c_event): self._shutting_down_server.notify_shutdown_complete() - return ServerShutdownEvent(c_event.type, c_event.success, self._user_tag) \ No newline at end of file + return ServerShutdownEvent(c_event.type, c_event.success, self._user_tag) From 4a8a2e286ed10317673e46d0505311dc9f12d1ef Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 1 Mar 2019 11:14:40 -0800 Subject: [PATCH 557/814] Add basic multiprocessing-based server --- examples/python/multiprocessing/BUILD | 0 examples/python/multiprocessing/README.md | 0 examples/python/multiprocessing/client.py | 9 ++ examples/python/multiprocessing/prime.proto | 35 +++++ examples/python/multiprocessing/prime_pb2.py | 132 ++++++++++++++++++ .../python/multiprocessing/prime_pb2_grpc.py | 46 ++++++ examples/python/multiprocessing/server.py | 98 +++++++++++++ .../test/_multiprocessing_test.py | 0 8 files changed, 320 insertions(+) create mode 100644 examples/python/multiprocessing/BUILD create mode 100644 examples/python/multiprocessing/README.md create mode 100644 examples/python/multiprocessing/client.py create mode 100644 examples/python/multiprocessing/prime.proto create mode 100644 examples/python/multiprocessing/prime_pb2.py create mode 100644 examples/python/multiprocessing/prime_pb2_grpc.py create mode 100644 examples/python/multiprocessing/server.py create mode 100644 examples/python/multiprocessing/test/_multiprocessing_test.py diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/python/multiprocessing/README.md b/examples/python/multiprocessing/README.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/python/multiprocessing/client.py b/examples/python/multiprocessing/client.py new file mode 100644 index 00000000000..4ab33374ce2 --- /dev/null +++ b/examples/python/multiprocessing/client.py @@ -0,0 +1,9 @@ +# spin up multiple concurrent clients + +import logging +import multiprocessing +import os +import time + +import prime_pb2 +import prime_pb2_grpc diff --git a/examples/python/multiprocessing/prime.proto b/examples/python/multiprocessing/prime.proto new file mode 100644 index 00000000000..4ef232f86cb --- /dev/null +++ b/examples/python/multiprocessing/prime.proto @@ -0,0 +1,35 @@ +// Copyright 2019 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package prime; + +// A candidate integer for primality testing. +message PrimeCandidate { + // The candidate. + int64 candidate = 1; +} + +// The primality of the requested integer candidate. +message Primality { + // Is the candidate prime? + bool isPrime = 1; +} + +// Service to check primality. +service PrimeChecker { + // Determines the primality of an integer. + rpc check (PrimeCandidate) returns (Primality) {} +} diff --git a/examples/python/multiprocessing/prime_pb2.py b/examples/python/multiprocessing/prime_pb2.py new file mode 100644 index 00000000000..58e6e6a023a --- /dev/null +++ b/examples/python/multiprocessing/prime_pb2.py @@ -0,0 +1,132 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: prime.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='prime.proto', + package='prime', + syntax='proto3', + serialized_options=None, + serialized_pb=_b('\n\x0bprime.proto\x12\x05prime\"#\n\x0ePrimeCandidate\x12\x11\n\tcandidate\x18\x01 \x01(\x03\"\x1c\n\tPrimality\x12\x0f\n\x07isPrime\x18\x01 \x01(\x08\x32\x42\n\x0cPrimeChecker\x12\x32\n\x05\x63heck\x12\x15.prime.PrimeCandidate\x1a\x10.prime.Primality\"\x00\x62\x06proto3') +) + + + + +_PRIMECANDIDATE = _descriptor.Descriptor( + name='PrimeCandidate', + full_name='prime.PrimeCandidate', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='candidate', full_name='prime.PrimeCandidate.candidate', index=0, + number=1, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=22, + serialized_end=57, +) + + +_PRIMALITY = _descriptor.Descriptor( + name='Primality', + full_name='prime.Primality', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='isPrime', full_name='prime.Primality.isPrime', index=0, + number=1, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=59, + serialized_end=87, +) + +DESCRIPTOR.message_types_by_name['PrimeCandidate'] = _PRIMECANDIDATE +DESCRIPTOR.message_types_by_name['Primality'] = _PRIMALITY +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +PrimeCandidate = _reflection.GeneratedProtocolMessageType('PrimeCandidate', (_message.Message,), dict( + DESCRIPTOR = _PRIMECANDIDATE, + __module__ = 'prime_pb2' + # @@protoc_insertion_point(class_scope:prime.PrimeCandidate) + )) +_sym_db.RegisterMessage(PrimeCandidate) + +Primality = _reflection.GeneratedProtocolMessageType('Primality', (_message.Message,), dict( + DESCRIPTOR = _PRIMALITY, + __module__ = 'prime_pb2' + # @@protoc_insertion_point(class_scope:prime.Primality) + )) +_sym_db.RegisterMessage(Primality) + + + +_PRIMECHECKER = _descriptor.ServiceDescriptor( + name='PrimeChecker', + full_name='prime.PrimeChecker', + file=DESCRIPTOR, + index=0, + serialized_options=None, + serialized_start=89, + serialized_end=155, + methods=[ + _descriptor.MethodDescriptor( + name='check', + full_name='prime.PrimeChecker.check', + index=0, + containing_service=None, + input_type=_PRIMECANDIDATE, + output_type=_PRIMALITY, + serialized_options=None, + ), +]) +_sym_db.RegisterServiceDescriptor(_PRIMECHECKER) + +DESCRIPTOR.services_by_name['PrimeChecker'] = _PRIMECHECKER + +# @@protoc_insertion_point(module_scope) diff --git a/examples/python/multiprocessing/prime_pb2_grpc.py b/examples/python/multiprocessing/prime_pb2_grpc.py new file mode 100644 index 00000000000..dcc3a35706d --- /dev/null +++ b/examples/python/multiprocessing/prime_pb2_grpc.py @@ -0,0 +1,46 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +import grpc + +import prime_pb2 as prime__pb2 + + +class PrimeCheckerStub(object): + """Service to check primality. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.check = channel.unary_unary( + '/prime.PrimeChecker/check', + request_serializer=prime__pb2.PrimeCandidate.SerializeToString, + response_deserializer=prime__pb2.Primality.FromString, + ) + + +class PrimeCheckerServicer(object): + """Service to check primality. + """ + + def check(self, request, context): + """Determines the primality of an integer. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_PrimeCheckerServicer_to_server(servicer, server): + rpc_method_handlers = { + 'check': grpc.unary_unary_rpc_method_handler( + servicer.check, + request_deserializer=prime__pb2.PrimeCandidate.FromString, + response_serializer=prime__pb2.Primality.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'prime.PrimeChecker', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py new file mode 100644 index 00000000000..d30f3b6734d --- /dev/null +++ b/examples/python/multiprocessing/server.py @@ -0,0 +1,98 @@ +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""An example of multiprocess concurrency with gRPC.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from concurrent import futures +import datetime +import grpc +import logging +import math +import multiprocessing +import os +import time + +import prime_pb2 +import prime_pb2_grpc + +_ONE_DAY = datetime.timedelta(days=1) +_NUM_PROCESSES = 8 +_THREAD_CONCURRENCY = 10 +_BIND_ADDRESS = '[::]:50051' + + +def is_prime(n): + for i in range(2, math.ceil(math.sqrt(n))): + if i % n == 0: + return False + else: + return True + + +class PrimeChecker(prime_pb2_grpc.PrimeCheckerServicer): + + def check(self, request, context): + logging.info( + '[PID {}] Determining primality of {}'.format( + os.getpid(), request.candidate)) + return is_prime(request.candidate) + + +def _wait_forever(server): + try: + while True: + time.sleep(_ONE_DAY.total_seconds()) + except KeyboardInterrupt: + server.stop(None) + + +def _run_server(bind_address): + logging.warning( '[PID {}] Starting new server.'.format( os.getpid())) + options = (('grpc.so_reuseport', 1),) + + # WARNING: This example takes advantage of SO_REUSEPORT. Due to the + # limitations of manylinux1, none of our precompiled Linux wheels currently + # support this option. (https://github.com/grpc/grpc/issues/18210). To take + # advantage of this feature, install from source with + # `pip install grpcio --no-binary grpcio`. + + server = grpc.server( + futures.ThreadPoolExecutor( + max_workers=_THREAD_CONCURRENCY,), + options=options) + prime_pb2_grpc.add_PrimeCheckerServicer_to_server(PrimeChecker(), server) + server.add_insecure_port(bind_address) + server.start() + _wait_forever(server) + + +def main(): + workers = [] + for _ in range(_NUM_PROCESSES): + # NOTE: It is imperative that the worker subprocesses be forked before + # any gRPC servers start up. See + # https://github.com/grpc/grpc/issues/16001 for more details. + worker = multiprocessing.Process(target=_run_server, args=(_BIND_ADDRESS,)) + worker.start() + workers.append(worker) + for worker in workers: + worker.join() + + +if __name__ == "__main__": + logging.basicConfig() + main() diff --git a/examples/python/multiprocessing/test/_multiprocessing_test.py b/examples/python/multiprocessing/test/_multiprocessing_test.py new file mode 100644 index 00000000000..e69de29bb2d From f2c7ffc9fb35b112a3c097df324a94727f1b95fe Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 1 Mar 2019 13:27:16 -0800 Subject: [PATCH 558/814] Add multiprocessed client --- examples/python/multiprocessing/client.py | 69 ++++++++++++++++++++++- examples/python/multiprocessing/server.py | 14 ++--- 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/examples/python/multiprocessing/client.py b/examples/python/multiprocessing/client.py index 4ab33374ce2..788820916ea 100644 --- a/examples/python/multiprocessing/client.py +++ b/examples/python/multiprocessing/client.py @@ -1,9 +1,76 @@ -# spin up multiple concurrent clients +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""An example of multiprocessing concurrency with gRPC.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import atexit +import grpc import logging import multiprocessing +import operator import os import time import prime_pb2 import prime_pb2_grpc + +_PROCESS_COUNT = 8 +_SERVER_ADDRESS = 'localhost:50051' +_MAXIMUM_CANDIDATE = 10000 + +# Each worker process initializes a single channel after forking. +_worker_channel_singleton = None +_worker_stub_singleton = None + + +def _initialize_worker(server_address): + global _worker_channel_singleton + global _worker_stub_singleton + logging.warning('[PID {}] Initializing worker process.'.format( + os.getpid())) + _worker_channel_singleton = grpc.insecure_channel(server_address) + _worker_stub_singleton = prime_pb2_grpc.PrimeCheckerStub( + _worker_channel_singleton) + atexit.register(_shutdown_worker) + + +def _shutdown_worker(): + logging.warning('[PID {}] Shutting worker process down.'.format( + os.getpid())) + if _worker_channel_singleton is not None: + _worker_channel_singleton.stop() + + +def _run_worker_query(primality_candidate): + logging.warning('[PID {}] Checking primality of {}.'.format( + os.getpid(), primality_candidate)) + return _worker_stub_singleton.check( + prime_pb2.PrimeCandidate(candidate=primality_candidate)) + + +def main(): + worker_pool = multiprocessing.Pool(processes=_PROCESS_COUNT, + initializer=_initialize_worker, initargs=(_SERVER_ADDRESS,)) + check_range = range(2, _MAXIMUM_CANDIDATE) + primality = worker_pool.map(_run_worker_query, check_range) + primes = zip(check_range, map(operator.attrgetter('isPrime'), primality)) + logging.warning(tuple(primes)) + + +if __name__ == '__main__': + logging.basicConfig() + main() diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index d30f3b6734d..d0ca6a0cdfb 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -30,14 +30,14 @@ import prime_pb2 import prime_pb2_grpc _ONE_DAY = datetime.timedelta(days=1) -_NUM_PROCESSES = 8 +_PROCESS_COUNT = 8 _THREAD_CONCURRENCY = 10 _BIND_ADDRESS = '[::]:50051' def is_prime(n): - for i in range(2, math.ceil(math.sqrt(n))): - if i % n == 0: + for i in range(2, int(math.ceil(math.sqrt(n)))): + if n % i == 0: return False else: return True @@ -46,10 +46,10 @@ def is_prime(n): class PrimeChecker(prime_pb2_grpc.PrimeCheckerServicer): def check(self, request, context): - logging.info( + logging.warning( '[PID {}] Determining primality of {}'.format( os.getpid(), request.candidate)) - return is_prime(request.candidate) + return prime_pb2.Primality(isPrime=is_prime(request.candidate)) def _wait_forever(server): @@ -82,7 +82,7 @@ def _run_server(bind_address): def main(): workers = [] - for _ in range(_NUM_PROCESSES): + for _ in range(_PROCESS_COUNT): # NOTE: It is imperative that the worker subprocesses be forked before # any gRPC servers start up. See # https://github.com/grpc/grpc/issues/16001 for more details. @@ -93,6 +93,6 @@ def main(): worker.join() -if __name__ == "__main__": +if __name__ == '__main__': logging.basicConfig() main() From 8d9982c1f858a14bf187f02a8e54fde4b7795e8b Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 1 Mar 2019 14:41:25 -0800 Subject: [PATCH 559/814] Fix gpr_once initialization. --- src/core/ext/transport/chttp2/client/insecure/channel_create.cc | 2 +- .../ext/transport/chttp2/client/secure/secure_channel_create.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc index d77799cef70..0d61abd2a01 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -73,7 +73,7 @@ class Chttp2InsecureClientChannelFactory : public ClientChannelFactory { namespace { grpc_core::Chttp2InsecureClientChannelFactory* g_factory; -gpr_once g_factory_once; +gpr_once g_factory_once = GPR_ONCE_INIT; void FactoryInit() { g_factory = grpc_core::New(); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index 6277859c59c..bc38ff25c79 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -175,7 +175,7 @@ class Chttp2SecureClientChannelFactory : public ClientChannelFactory { namespace { grpc_core::Chttp2SecureClientChannelFactory* g_factory; -gpr_once g_factory_once; +gpr_once g_factory_once = GPR_ONCE_INIT; void FactoryInit() { g_factory = grpc_core::New(); From e1f5ce30ea9fd53df9292b84b0621727d8f195b9 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 1 Mar 2019 16:40:00 -0800 Subject: [PATCH 560/814] Correct grpc_call_cancel and grpc_call_cancel_with_status comments --- include/grpc/grpc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index fec7f5269e1..c2da4d8faf1 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -318,14 +318,14 @@ GRPCAPI void grpc_channel_destroy(grpc_channel* channel); If a grpc_call fails, it's guaranteed that no change to the call state has been made. */ -/** Called by clients to cancel an RPC on the server. +/** Cancel an RPC. Can be called multiple times, from any thread. THREAD-SAFETY grpc_call_cancel and grpc_call_cancel_with_status are thread-safe, and can be called at any point before grpc_call_unref is called.*/ GRPCAPI grpc_call_error grpc_call_cancel(grpc_call* call, void* reserved); -/** Called by clients to cancel an RPC on the server. +/** Cancel an RPC. Can be called multiple times, from any thread. If a status has not been received for the call, set it to the status code and description passed in. From a6c33d351667bec864cc8c860ac94385f60d76cb Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 1 Mar 2019 17:35:35 -0800 Subject: [PATCH 561/814] Dynamically allocate port --- examples/python/multiprocessing/server.py | 38 +++++++++++++++++------ 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index d0ca6a0cdfb..f2a2544b827 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -18,6 +18,7 @@ from __future__ import division from __future__ import print_function from concurrent import futures +import contextlib import datetime import grpc import logging @@ -25,6 +26,7 @@ import math import multiprocessing import os import time +import socket import prime_pb2 import prime_pb2_grpc @@ -61,6 +63,7 @@ def _wait_forever(server): def _run_server(bind_address): + """Start a server in a subprocess.""" logging.warning( '[PID {}] Starting new server.'.format( os.getpid())) options = (('grpc.so_reuseport', 1),) @@ -80,17 +83,32 @@ def _run_server(bind_address): _wait_forever(server) +@contextlib.contextmanager +def _reserve_port(): + """Find and reserve a port for all subprocesses to use.""" + sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + sock.bind(('', 0)) + try: + yield sock.getsockname()[1] + finally: + sock.close() + + def main(): - workers = [] - for _ in range(_PROCESS_COUNT): - # NOTE: It is imperative that the worker subprocesses be forked before - # any gRPC servers start up. See - # https://github.com/grpc/grpc/issues/16001 for more details. - worker = multiprocessing.Process(target=_run_server, args=(_BIND_ADDRESS,)) - worker.start() - workers.append(worker) - for worker in workers: - worker.join() + with _reserve_port() as port: + bind_address = '[::]:{}'.format(port) + logging.warning("Binding to {}".format(bind_address)) + workers = [] + for _ in range(_PROCESS_COUNT): + # NOTE: It is imperative that the worker subprocesses be forked before + # any gRPC servers start up. See + # https://github.com/grpc/grpc/issues/16001 for more details. + worker = multiprocessing.Process(target=_run_server, args=(bind_address,)) + worker.start() + workers.append(worker) + for worker in workers: + worker.join() if __name__ == '__main__': From 510beaaede6faf2aa1c18c9ec9c77bcbee6c2f4c Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 1 Mar 2019 17:41:56 -0800 Subject: [PATCH 562/814] Add a CLI parser to the client --- examples/python/multiprocessing/client.py | 15 +++++++++++---- examples/python/multiprocessing/server.py | 1 - 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/examples/python/multiprocessing/client.py b/examples/python/multiprocessing/client.py index 788820916ea..920b5285475 100644 --- a/examples/python/multiprocessing/client.py +++ b/examples/python/multiprocessing/client.py @@ -17,6 +17,7 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function +import argparse import atexit import grpc import logging @@ -29,7 +30,6 @@ import prime_pb2 import prime_pb2_grpc _PROCESS_COUNT = 8 -_SERVER_ADDRESS = 'localhost:50051' _MAXIMUM_CANDIDATE = 10000 # Each worker process initializes a single channel after forking. @@ -61,16 +61,23 @@ def _run_worker_query(primality_candidate): return _worker_stub_singleton.check( prime_pb2.PrimeCandidate(candidate=primality_candidate)) - -def main(): +def _calculate_primes(server_address): worker_pool = multiprocessing.Pool(processes=_PROCESS_COUNT, - initializer=_initialize_worker, initargs=(_SERVER_ADDRESS,)) + initializer=_initialize_worker, initargs=(server_address,)) check_range = range(2, _MAXIMUM_CANDIDATE) primality = worker_pool.map(_run_worker_query, check_range) primes = zip(check_range, map(operator.attrgetter('isPrime'), primality)) logging.warning(tuple(primes)) +def main(): + msg = 'Determine the primality of the first {} integers.'.format( + _MAXIMUM_CANDIDATE) + parser = argparse.ArgumentParser(description=msg) + parser.add_argument('server_address', help='The address of the server (e.g. localhost:50051)') + args = parser.parse_args() + _calculate_primes(args.server_address) + if __name__ == '__main__': logging.basicConfig() main() diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index f2a2544b827..6801f806126 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -34,7 +34,6 @@ import prime_pb2_grpc _ONE_DAY = datetime.timedelta(days=1) _PROCESS_COUNT = 8 _THREAD_CONCURRENCY = 10 -_BIND_ADDRESS = '[::]:50051' def is_prime(n): From 394afb3a0cb0beb8018daa9db57e9352e887fdde Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 1 Mar 2019 18:00:28 -0800 Subject: [PATCH 563/814] Update validation rules for service config --- doc/service_config.md | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/doc/service_config.md b/doc/service_config.md index dd1cbc56300..4cef4567d19 100644 --- a/doc/service_config.md +++ b/doc/service_config.md @@ -12,11 +12,13 @@ The service config is a JSON string of the following form: ``` { - // Load balancing policy name (case insensitive). + // [deprecated] Load balancing policy name (case insensitive). // Currently, the only selectable client-side policy provided with gRPC // is 'round_robin', but third parties may add their own policies. // This field is optional; if unset, the default behavior is to pick - // the first available backend. + // the first available backend. If set, the load balancing policy should be + // supported by the client, otherwise the service config is considered + // invalid. // If the policy name is set via the client API, that value overrides // the value specified here. // @@ -61,10 +63,11 @@ The service config is a JSON string of the following form: } ], - // Whether RPCs sent to this method should wait until the connection is - // ready by default. If false, the RPC will abort immediately if there - // is a transient failure connecting to the server. Otherwise, gRPC will - // attempt to connect until the deadline is exceeded. + // Optional. Whether RPCs sent to this method should wait until the + // connection is ready by default. If false, the RPC will abort + // immediately if there is a transient failure connecting to the server. + // Otherwise, gRPC will attempt to connect until the deadline is + // exceeded. // // The value specified via the gRPC client API will override the value // set here. However, note that setting the value in the client API will @@ -73,10 +76,10 @@ The service config is a JSON string of the following form: // is obtained by the gRPC client via name resolution. 'waitForReady': bool, - // The default timeout in seconds for RPCs sent to this method. This can - // be overridden in code. If no reply is received in the specified amount - // of time, the request is aborted and a deadline-exceeded error status - // is returned to the caller. + // Optional. The default timeout in seconds for RPCs sent to this method. + // This can be overridden in code. If no reply is received in the + // specified amount of time, the request is aborted and a + // deadline-exceeded error status is returned to the caller. // // The actual deadline used will be the minimum of the value specified // here and the value set by the application via the gRPC client API. @@ -87,10 +90,10 @@ The service config is a JSON string of the following form: // https://developers.google.com/protocol-buffers/docs/proto3#json 'timeout': string, - // The maximum allowed payload size for an individual request or object - // in a stream (client->server) in bytes. The size which is measured is - // the serialized, uncompressed payload in bytes. This applies both - // to streaming and non-streaming requests. + // Optional. The maximum allowed payload size for an individual request + // or object in a stream (client->server) in bytes. The size which is + // measured is the serialized, uncompressed payload in bytes. This + // applies both to streaming and non-streaming requests. // // The actual value used is the minimum of the value specified here and // the value set by the application via the gRPC client API. @@ -103,10 +106,10 @@ The service config is a JSON string of the following form: // be empty. 'maxRequestMessageBytes': number, - // The maximum allowed payload size for an individual response or object - // in a stream (server->client) in bytes. The size which is measured is - // the serialized, uncompressed payload in bytes. This applies both - // to streaming and non-streaming requests. + // Optional. The maximum allowed payload size for an individual response + // or object in a stream (server->client) in bytes. The size which is + // measured is the serialized, uncompressed payload in bytes. This + // applies both to streaming and non-streaming requests. // // The actual value used is the minimum of the value specified here and // the value set by the application via the gRPC client API. From 8898f482777fb511bb4fae485fb012f4f05cc18f Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sat, 2 Mar 2019 21:39:16 -0500 Subject: [PATCH 564/814] Avoid copying grpc_slice as much as possible. Passing grpc_slice by value and/or returning it can be very costly, introducing many extra instructions to push the structure to the stack and poping it. This CL, wherever possible, changes grpc_slice to be passed by value. On a local benchmark, I obserse 4-7% improvements in latency and QPS. There are still copies to the slice_ref vtable which @arjunroy is fixing as part of his major effort to use grpc_core::RefCount for slices and devirtualizing them. --- .../client_channel/client_channel_channelz.h | 4 ++-- .../lb_policy/grpclb/load_balancer_api.cc | 16 ++++++++-------- .../lb_policy/grpclb/load_balancer_api.h | 4 ++-- .../lb_policy/xds/xds_load_balancer_api.cc | 16 ++++++++-------- .../lb_policy/xds/xds_load_balancer_api.h | 4 ++-- .../transport/chttp2/transport/bin_decoder.cc | 8 ++++---- .../transport/chttp2/transport/bin_decoder.h | 8 ++++---- .../transport/chttp2/transport/bin_encoder.cc | 13 +++++++------ .../transport/chttp2/transport/bin_encoder.h | 7 ++++--- .../chttp2/transport/chttp2_transport.cc | 4 ++-- .../transport/chttp2/transport/frame_data.cc | 3 ++- .../transport/chttp2/transport/frame_data.h | 2 +- .../transport/chttp2/transport/frame_goaway.cc | 11 ++++++----- .../transport/chttp2/transport/frame_goaway.h | 5 +++-- .../transport/chttp2/transport/frame_ping.cc | 9 +++++---- .../transport/chttp2/transport/frame_ping.h | 2 +- .../chttp2/transport/frame_rst_stream.cc | 9 +++++---- .../chttp2/transport/frame_rst_stream.h | 3 ++- .../chttp2/transport/frame_settings.cc | 3 ++- .../chttp2/transport/frame_settings.h | 3 ++- .../chttp2/transport/frame_window_update.cc | 8 ++++---- .../chttp2/transport/frame_window_update.h | 2 +- .../transport/chttp2/transport/hpack_parser.cc | 11 ++++++----- .../transport/chttp2/transport/hpack_parser.h | 5 +++-- .../ext/transport/chttp2/transport/internal.h | 9 +++++---- .../ext/transport/chttp2/transport/parsing.cc | 18 +++++++++--------- src/core/lib/channel/channel_trace.cc | 8 ++++---- src/core/lib/channel/channel_trace.h | 8 ++++---- src/core/lib/channel/channelz.h | 8 ++++---- src/core/lib/compression/algorithm_metadata.h | 6 +++--- src/core/lib/compression/compression.cc | 2 +- .../lib/compression/compression_internal.cc | 4 ++-- src/core/lib/http/httpcli.cc | 3 ++- src/core/lib/http/parser.cc | 3 ++- src/core/lib/http/parser.h | 3 ++- src/core/lib/iomgr/error.cc | 18 +++++++++--------- src/core/lib/iomgr/error.h | 7 ++++--- .../security/credentials/jwt/jwt_verifier.cc | 11 +++++++---- .../security/credentials/jwt/jwt_verifier.h | 3 ++- src/core/lib/security/transport/auth_filters.h | 4 ++-- .../security/transport/client_auth_filter.cc | 4 ++-- src/core/lib/slice/percent_encoding.cc | 6 +++--- src/core/lib/slice/percent_encoding.h | 6 +++--- src/core/lib/slice/slice.cc | 13 ------------- src/core/lib/slice/slice_hash_table.h | 4 ++-- src/core/lib/slice/slice_intern.cc | 2 +- src/core/lib/slice/slice_internal.h | 17 ++++++++++++++--- src/core/lib/slice/slice_traits.h | 6 +++--- src/core/lib/slice/slice_weak_hash_table.h | 8 ++++---- src/core/lib/transport/metadata_batch.cc | 2 +- src/core/lib/transport/metadata_batch.h | 2 +- src/core/lib/transport/service_config.h | 4 ++-- src/core/lib/transport/timeout_encoding.cc | 2 +- src/core/lib/transport/timeout_encoding.h | 2 +- .../alts/handshaker/alts_handshaker_client.cc | 6 +++--- .../alts/handshaker/alts_handshaker_client.h | 2 +- .../transport_security_common_api.cc | 7 ++++--- .../handshaker/transport_security_common_api.h | 2 +- 58 files changed, 195 insertions(+), 175 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 1dc1bf595be..9272116882e 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -71,11 +71,11 @@ class SubchannelNode : public BaseNode { grpc_json* RenderJson() override; // proxy methods to composed classes. - void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { + void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) { trace_.AddTraceEvent(severity, data); } void AddTraceEventWithReference(ChannelTrace::Severity severity, - grpc_slice data, + const grpc_slice& data, RefCountedPtr referenced_channel) { trace_.AddTraceEventWithReference(severity, data, std::move(referenced_channel)); diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc index f24281a5bfb..594c8cf6e94 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc @@ -161,10 +161,10 @@ void grpc_grpclb_request_destroy(grpc_grpclb_request* request) { typedef grpc_lb_v1_LoadBalanceResponse grpc_grpclb_response; grpc_grpclb_initial_response* grpc_grpclb_initial_response_parse( - grpc_slice encoded_grpc_grpclb_response) { - pb_istream_t stream = - pb_istream_from_buffer(GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response), - GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response)); + const grpc_slice& encoded_grpc_grpclb_response) { + pb_istream_t stream = pb_istream_from_buffer( + const_cast(GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response)), + GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response)); grpc_grpclb_response res; memset(&res, 0, sizeof(grpc_grpclb_response)); if (GPR_UNLIKELY( @@ -185,10 +185,10 @@ grpc_grpclb_initial_response* grpc_grpclb_initial_response_parse( } grpc_grpclb_serverlist* grpc_grpclb_response_parse_serverlist( - grpc_slice encoded_grpc_grpclb_response) { - pb_istream_t stream = - pb_istream_from_buffer(GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response), - GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response)); + const grpc_slice& encoded_grpc_grpclb_response) { + pb_istream_t stream = pb_istream_from_buffer( + const_cast(GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response)), + GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response)); pb_istream_t stream_at_start = stream; grpc_grpclb_serverlist* sl = static_cast( gpr_zalloc(sizeof(grpc_grpclb_serverlist))); diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h index 71d371c880a..3c1d41a01b1 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h @@ -55,11 +55,11 @@ void grpc_grpclb_request_destroy(grpc_grpclb_request* request); /** Parse (ie, decode) the bytes in \a encoded_grpc_grpclb_response as a \a * grpc_grpclb_initial_response */ grpc_grpclb_initial_response* grpc_grpclb_initial_response_parse( - grpc_slice encoded_grpc_grpclb_response); + const grpc_slice& encoded_grpc_grpclb_response); /** Parse the list of servers from an encoded \a grpc_grpclb_response */ grpc_grpclb_serverlist* grpc_grpclb_response_parse_serverlist( - grpc_slice encoded_grpc_grpclb_response); + const grpc_slice& encoded_grpc_grpclb_response); /** Return a copy of \a sl. The caller is responsible for calling \a * grpc_grpclb_destroy_serverlist on the returned copy. */ diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc index 79b7bdbe338..90094974a14 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc @@ -161,10 +161,10 @@ void xds_grpclb_request_destroy(xds_grpclb_request* request) { typedef grpc_lb_v1_LoadBalanceResponse xds_grpclb_response; xds_grpclb_initial_response* xds_grpclb_initial_response_parse( - grpc_slice encoded_xds_grpclb_response) { - pb_istream_t stream = - pb_istream_from_buffer(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response), - GRPC_SLICE_LENGTH(encoded_xds_grpclb_response)); + const grpc_slice& encoded_xds_grpclb_response) { + pb_istream_t stream = pb_istream_from_buffer( + const_cast(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response)), + GRPC_SLICE_LENGTH(encoded_xds_grpclb_response)); xds_grpclb_response res; memset(&res, 0, sizeof(xds_grpclb_response)); if (GPR_UNLIKELY( @@ -185,10 +185,10 @@ xds_grpclb_initial_response* xds_grpclb_initial_response_parse( } xds_grpclb_serverlist* xds_grpclb_response_parse_serverlist( - grpc_slice encoded_xds_grpclb_response) { - pb_istream_t stream = - pb_istream_from_buffer(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response), - GRPC_SLICE_LENGTH(encoded_xds_grpclb_response)); + const grpc_slice& encoded_xds_grpclb_response) { + pb_istream_t stream = pb_istream_from_buffer( + const_cast(GRPC_SLICE_START_PTR(encoded_xds_grpclb_response)), + GRPC_SLICE_LENGTH(encoded_xds_grpclb_response)); pb_istream_t stream_at_start = stream; xds_grpclb_serverlist* sl = static_cast( gpr_zalloc(sizeof(xds_grpclb_serverlist))); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h index 67049956417..e52d20f8658 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h @@ -55,11 +55,11 @@ void xds_grpclb_request_destroy(xds_grpclb_request* request); /** Parse (ie, decode) the bytes in \a encoded_xds_grpclb_response as a \a * xds_grpclb_initial_response */ xds_grpclb_initial_response* xds_grpclb_initial_response_parse( - grpc_slice encoded_xds_grpclb_response); + const grpc_slice& encoded_xds_grpclb_response); /** Parse the list of servers from an encoded \a xds_grpclb_response */ xds_grpclb_serverlist* xds_grpclb_response_parse_serverlist( - grpc_slice encoded_xds_grpclb_response); + const grpc_slice& encoded_xds_grpclb_response); /** Return a copy of \a sl. The caller is responsible for calling \a * xds_grpclb_destroy_serverlist on the returned copy. */ diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.cc b/src/core/ext/transport/chttp2/transport/bin_decoder.cc index b660a456521..249035d7e89 100644 --- a/src/core/ext/transport/chttp2/transport/bin_decoder.cc +++ b/src/core/ext/transport/chttp2/transport/bin_decoder.cc @@ -51,7 +51,7 @@ static uint8_t decode_table[] = { static const uint8_t tail_xtra[4] = {0, 0, 1, 2}; -static bool input_is_valid(uint8_t* input_ptr, size_t length) { +static bool input_is_valid(const uint8_t* input_ptr, size_t length) { size_t i; for (i = 0; i < length; ++i) { @@ -158,7 +158,7 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context* ctx) { return true; } -grpc_slice grpc_chttp2_base64_decode(grpc_slice input) { +grpc_slice grpc_chttp2_base64_decode(const grpc_slice& input) { size_t input_length = GRPC_SLICE_LENGTH(input); size_t output_length = input_length / 4 * 3; struct grpc_base64_decode_context ctx; @@ -174,7 +174,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input) { } if (input_length > 0) { - uint8_t* input_end = GRPC_SLICE_END_PTR(input); + const uint8_t* input_end = GRPC_SLICE_END_PTR(input); if (*(--input_end) == '=') { output_length--; if (*(--input_end) == '=') { @@ -202,7 +202,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input) { return output; } -grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input, +grpc_slice grpc_chttp2_base64_decode_with_length(const grpc_slice& input, size_t output_length) { size_t input_length = GRPC_SLICE_LENGTH(input); grpc_slice output = GRPC_SLICE_MALLOC(output_length); diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.h b/src/core/ext/transport/chttp2/transport/bin_decoder.h index 8a4d4a71790..1cbca033a1f 100644 --- a/src/core/ext/transport/chttp2/transport/bin_decoder.h +++ b/src/core/ext/transport/chttp2/transport/bin_decoder.h @@ -26,8 +26,8 @@ struct grpc_base64_decode_context { /* input/output: */ - uint8_t* input_cur; - uint8_t* input_end; + const uint8_t* input_cur; + const uint8_t* input_end; uint8_t* output_cur; uint8_t* output_end; /* Indicate if the decoder should handle the tail of input data*/ @@ -42,12 +42,12 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context* ctx); /* base64 decode a slice with pad chars. Returns a new slice, does not take ownership of the input. Returns an empty slice if decoding is failed. */ -grpc_slice grpc_chttp2_base64_decode(grpc_slice input); +grpc_slice grpc_chttp2_base64_decode(const grpc_slice& input); /* base64 decode a slice without pad chars, data length is needed. Returns a new slice, does not take ownership of the input. Returns an empty slice if decoding is failed. */ -grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input, +grpc_slice grpc_chttp2_base64_decode_with_length(const grpc_slice& input, size_t output_length); /* Infer the length of decoded data from encoded data. */ diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.cc b/src/core/ext/transport/chttp2/transport/bin_encoder.cc index bad29e3421c..c816aba991f 100644 --- a/src/core/ext/transport/chttp2/transport/bin_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/bin_encoder.cc @@ -48,13 +48,13 @@ static const b64_huff_sym huff_alphabet[64] = { static const uint8_t tail_xtra[3] = {0, 2, 3}; -grpc_slice grpc_chttp2_base64_encode(grpc_slice input) { +grpc_slice grpc_chttp2_base64_encode(const grpc_slice& input) { size_t input_length = GRPC_SLICE_LENGTH(input); size_t input_triplets = input_length / 3; size_t tail_case = input_length % 3; size_t output_length = input_triplets * 4 + tail_xtra[tail_case]; grpc_slice output = GRPC_SLICE_MALLOC(output_length); - uint8_t* in = GRPC_SLICE_START_PTR(input); + const uint8_t* in = GRPC_SLICE_START_PTR(input); char* out = reinterpret_cast GRPC_SLICE_START_PTR(output); size_t i; @@ -92,9 +92,9 @@ grpc_slice grpc_chttp2_base64_encode(grpc_slice input) { return output; } -grpc_slice grpc_chttp2_huffman_compress(grpc_slice input) { +grpc_slice grpc_chttp2_huffman_compress(const grpc_slice& input) { size_t nbits; - uint8_t* in; + const uint8_t* in; uint8_t* out; grpc_slice output; uint32_t temp = 0; @@ -166,7 +166,8 @@ static void enc_add1(huff_out* out, uint8_t a) { enc_flush_some(out); } -grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input) { +grpc_slice grpc_chttp2_base64_encode_and_huffman_compress( + const grpc_slice& input) { size_t input_length = GRPC_SLICE_LENGTH(input); size_t input_triplets = input_length / 3; size_t tail_case = input_length % 3; @@ -174,7 +175,7 @@ grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input) { size_t max_output_bits = 11 * output_syms; size_t max_output_length = max_output_bits / 8 + (max_output_bits % 8 != 0); grpc_slice output = GRPC_SLICE_MALLOC(max_output_length); - uint8_t* in = GRPC_SLICE_START_PTR(input); + const uint8_t* in = GRPC_SLICE_START_PTR(input); uint8_t* start_out = GRPC_SLICE_START_PTR(output); huff_out out; size_t i; diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.h b/src/core/ext/transport/chttp2/transport/bin_encoder.h index 1b7bb1574af..4f7ee67bd31 100644 --- a/src/core/ext/transport/chttp2/transport/bin_encoder.h +++ b/src/core/ext/transport/chttp2/transport/bin_encoder.h @@ -25,17 +25,18 @@ /* base64 encode a slice. Returns a new slice, does not take ownership of the input */ -grpc_slice grpc_chttp2_base64_encode(grpc_slice input); +grpc_slice grpc_chttp2_base64_encode(const grpc_slice& input); /* Compress a slice with the static huffman encoder detailed in the hpack standard. Returns a new slice, does not take ownership of the input */ -grpc_slice grpc_chttp2_huffman_compress(grpc_slice input); +grpc_slice grpc_chttp2_huffman_compress(const grpc_slice& input); /* equivalent to: grpc_slice x = grpc_chttp2_base64_encode(input); grpc_slice y = grpc_chttp2_huffman_compress(x); grpc_slice_unref_internal( x); return y; */ -grpc_slice grpc_chttp2_base64_encode_and_huffman_compress(grpc_slice input); +grpc_slice grpc_chttp2_base64_encode_and_huffman_compress( + const grpc_slice& input); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_ENCODER_H */ diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index aa0aac7b986..306349b7910 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1129,7 +1129,7 @@ static void queue_setting_update(grpc_chttp2_transport* t, void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, uint32_t goaway_error, - grpc_slice goaway_text) { + const grpc_slice& goaway_text) { // Discard the error from a previous goaway frame (if any) if (t->goaway_error != GRPC_ERROR_NONE) { GRPC_ERROR_UNREF(t->goaway_error); @@ -2996,7 +2996,7 @@ void Chttp2IncomingByteStream::PublishError(grpc_error* error) { grpc_chttp2_cancel_stream(transport_, stream_, GRPC_ERROR_REF(error)); } -grpc_error* Chttp2IncomingByteStream::Push(grpc_slice slice, +grpc_error* Chttp2IncomingByteStream::Push(const grpc_slice& slice, grpc_slice* slice_out) { if (remaining_bytes_ < GRPC_SLICE_LENGTH(slice)) { grpc_error* error = diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index 1de00735cf3..6080a4bd1c4 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -287,7 +287,8 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( grpc_error* grpc_chttp2_data_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { + const grpc_slice& slice, + int is_last) { if (!s->pending_byte_stream) { grpc_slice_ref_internal(slice); grpc_slice_buffer_add(&s->frame_storage, slice); diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h index 2c5da99fa68..ec3890098ec 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.h +++ b/src/core/ext/transport/chttp2/transport/frame_data.h @@ -67,7 +67,7 @@ grpc_error* grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser* parser, grpc_error* grpc_chttp2_data_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, int is_last); void grpc_chttp2_encode_data(uint32_t id, grpc_slice_buffer* inbuf, uint32_t write_bytes, int is_eof, diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.cc b/src/core/ext/transport/chttp2/transport/frame_goaway.cc index 2a1dd3c3163..e901a6bdc76 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.cc +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.cc @@ -57,10 +57,11 @@ grpc_error* grpc_chttp2_goaway_parser_begin_frame(grpc_chttp2_goaway_parser* p, grpc_error* grpc_chttp2_goaway_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { - uint8_t* const beg = GRPC_SLICE_START_PTR(slice); - uint8_t* const end = GRPC_SLICE_END_PTR(slice); - uint8_t* cur = beg; + const grpc_slice& slice, + int is_last) { + const uint8_t* const beg = GRPC_SLICE_START_PTR(slice); + const uint8_t* const end = GRPC_SLICE_END_PTR(slice); + const uint8_t* cur = beg; grpc_chttp2_goaway_parser* p = static_cast(parser); @@ -149,7 +150,7 @@ grpc_error* grpc_chttp2_goaway_parser_parse(void* parser, } void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, - grpc_slice debug_data, + const grpc_slice& debug_data, grpc_slice_buffer* slice_buffer) { grpc_slice header = GRPC_SLICE_MALLOC(9 + 4 + 4); uint8_t* p = GRPC_SLICE_START_PTR(header); diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.h b/src/core/ext/transport/chttp2/transport/frame_goaway.h index 66c7a68befe..6f65bb2d604 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.h +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.h @@ -53,10 +53,11 @@ grpc_error* grpc_chttp2_goaway_parser_begin_frame( grpc_error* grpc_chttp2_goaway_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, + int is_last); void grpc_chttp2_goaway_append(uint32_t last_stream_id, uint32_t error_code, - grpc_slice debug_data, + const grpc_slice& debug_data, grpc_slice_buffer* slice_buffer); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_GOAWAY_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.cc b/src/core/ext/transport/chttp2/transport/frame_ping.cc index 205826b779a..9a56bf093f4 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.cc +++ b/src/core/ext/transport/chttp2/transport/frame_ping.cc @@ -73,10 +73,11 @@ grpc_error* grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser* parser, grpc_error* grpc_chttp2_ping_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { - uint8_t* const beg = GRPC_SLICE_START_PTR(slice); - uint8_t* const end = GRPC_SLICE_END_PTR(slice); - uint8_t* cur = beg; + const grpc_slice& slice, + int is_last) { + const uint8_t* const beg = GRPC_SLICE_START_PTR(slice); + const uint8_t* const end = GRPC_SLICE_END_PTR(slice); + const uint8_t* cur = beg; grpc_chttp2_ping_parser* p = static_cast(parser); while (p->byte != 8 && cur != end) { diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.h b/src/core/ext/transport/chttp2/transport/frame_ping.h index 55a4499ad59..915d023a34c 100644 --- a/src/core/ext/transport/chttp2/transport/frame_ping.h +++ b/src/core/ext/transport/chttp2/transport/frame_ping.h @@ -37,7 +37,7 @@ grpc_error* grpc_chttp2_ping_parser_begin_frame(grpc_chttp2_ping_parser* parser, grpc_error* grpc_chttp2_ping_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, int is_last); /* Test-only function for disabling ping ack */ void grpc_set_disable_ping_ack(bool disable_ping_ack); diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc index a0a75345947..ccde36cbc48 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc @@ -74,10 +74,11 @@ grpc_error* grpc_chttp2_rst_stream_parser_begin_frame( grpc_error* grpc_chttp2_rst_stream_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { - uint8_t* const beg = GRPC_SLICE_START_PTR(slice); - uint8_t* const end = GRPC_SLICE_END_PTR(slice); - uint8_t* cur = beg; + const grpc_slice& slice, + int is_last) { + const uint8_t* const beg = GRPC_SLICE_START_PTR(slice); + const uint8_t* const end = GRPC_SLICE_END_PTR(slice); + const uint8_t* cur = beg; grpc_chttp2_rst_stream_parser* p = static_cast(parser); diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h index 6bcf9c44797..64707666181 100644 --- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h @@ -38,6 +38,7 @@ grpc_error* grpc_chttp2_rst_stream_parser_begin_frame( grpc_error* grpc_chttp2_rst_stream_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, + int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_RST_STREAM_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.cc b/src/core/ext/transport/chttp2/transport/frame_settings.cc index 987ac0e79d0..ed1554e2fef 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.cc +++ b/src/core/ext/transport/chttp2/transport/frame_settings.cc @@ -111,7 +111,8 @@ grpc_error* grpc_chttp2_settings_parser_begin_frame( grpc_error* grpc_chttp2_settings_parser_parse(void* p, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { + const grpc_slice& slice, + int is_last) { grpc_chttp2_settings_parser* parser = static_cast(p); const uint8_t* cur = GRPC_SLICE_START_PTR(slice); diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.h b/src/core/ext/transport/chttp2/transport/frame_settings.h index 8d8d9b1a914..8a3ff0426b3 100644 --- a/src/core/ext/transport/chttp2/transport/frame_settings.h +++ b/src/core/ext/transport/chttp2/transport/frame_settings.h @@ -55,6 +55,7 @@ grpc_error* grpc_chttp2_settings_parser_begin_frame( grpc_error* grpc_chttp2_settings_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, + int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_SETTINGS_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.cc b/src/core/ext/transport/chttp2/transport/frame_window_update.cc index b8738ea7ea0..80e799f17f1 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.cc +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.cc @@ -69,11 +69,11 @@ grpc_error* grpc_chttp2_window_update_parser_begin_frame( grpc_error* grpc_chttp2_window_update_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, + const grpc_slice& slice, int is_last) { - uint8_t* const beg = GRPC_SLICE_START_PTR(slice); - uint8_t* const end = GRPC_SLICE_END_PTR(slice); - uint8_t* cur = beg; + const uint8_t* const beg = GRPC_SLICE_START_PTR(slice); + const uint8_t* const end = GRPC_SLICE_END_PTR(slice); + const uint8_t* cur = beg; grpc_chttp2_window_update_parser* p = static_cast(parser); diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.h b/src/core/ext/transport/chttp2/transport/frame_window_update.h index 3d2391f637d..f6721a5bc5d 100644 --- a/src/core/ext/transport/chttp2/transport/frame_window_update.h +++ b/src/core/ext/transport/chttp2/transport/frame_window_update.h @@ -39,7 +39,7 @@ grpc_error* grpc_chttp2_window_update_parser_begin_frame( grpc_error* grpc_chttp2_window_update_parser_parse(void* parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, + const grpc_slice& slice, int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_WINDOW_UPDATE_H */ diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc index 7b47c9bc18e..5bcdb4e2326 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc @@ -1570,16 +1570,16 @@ void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser* p) { } grpc_error* grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser* p, - grpc_slice slice) { + const grpc_slice& slice) { /* max number of bytes to parse at a time... limits call stack depth on * compilers without TCO */ #define MAX_PARSE_LENGTH 1024 p->current_slice_refcount = slice.refcount; - uint8_t* start = GRPC_SLICE_START_PTR(slice); - uint8_t* end = GRPC_SLICE_END_PTR(slice); + const uint8_t* start = GRPC_SLICE_START_PTR(slice); + const uint8_t* end = GRPC_SLICE_END_PTR(slice); grpc_error* error = GRPC_ERROR_NONE; while (start != end && error == GRPC_ERROR_NONE) { - uint8_t* target = start + GPR_MIN(MAX_PARSE_LENGTH, end - start); + const uint8_t* target = start + GPR_MIN(MAX_PARSE_LENGTH, end - start); error = p->state(p, start, target); start = target; } @@ -1621,7 +1621,8 @@ static void parse_stream_compression_md(grpc_chttp2_transport* t, grpc_error* grpc_chttp2_header_parser_parse(void* hpack_parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last) { + const grpc_slice& slice, + int is_last) { GPR_TIMER_SCOPE("grpc_chttp2_header_parser_parse", 0); grpc_chttp2_hpack_parser* parser = static_cast(hpack_parser); diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h index 3e05de4b925..3dc8e13bea2 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.h +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h @@ -97,13 +97,14 @@ void grpc_chttp2_hpack_parser_destroy(grpc_chttp2_hpack_parser* p); void grpc_chttp2_hpack_parser_set_has_priority(grpc_chttp2_hpack_parser* p); grpc_error* grpc_chttp2_hpack_parser_parse(grpc_chttp2_hpack_parser* p, - grpc_slice slice); + const grpc_slice& slice); /* wraps grpc_chttp2_hpack_parser_parse to provide a frame level parser for the transport */ grpc_error* grpc_chttp2_header_parser_parse(void* hpack_parser, grpc_chttp2_transport* t, grpc_chttp2_stream* s, - grpc_slice slice, int is_last); + const grpc_slice& slice, + int is_last); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_PARSER_H */ diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 341f5b3977f..760324c0c95 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -245,7 +245,7 @@ class Chttp2IncomingByteStream : public ByteStream { void PublishError(grpc_error* error); - grpc_error* Push(grpc_slice slice, grpc_slice* slice_out); + grpc_error* Push(const grpc_slice& slice, grpc_slice* slice_out); grpc_error* Finished(grpc_error* error, bool reset_on_error); @@ -438,7 +438,8 @@ struct grpc_chttp2_transport { void* parser_data = nullptr; grpc_chttp2_stream* incoming_stream = nullptr; grpc_error* (*parser)(void* parser_user_data, grpc_chttp2_transport* t, - grpc_chttp2_stream* s, grpc_slice slice, int is_last); + grpc_chttp2_stream* s, const grpc_slice& slice, + int is_last); grpc_chttp2_write_cb* write_cb_pool = nullptr; @@ -681,7 +682,7 @@ void grpc_chttp2_end_write(grpc_chttp2_transport* t, grpc_error* error); /** Process one slice of incoming data; return 1 if the connection is still viable after reading, or 0 if the connection should be torn down */ grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t, - grpc_slice slice); + const grpc_slice& slice); bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport* t, grpc_chttp2_stream* s); @@ -740,7 +741,7 @@ grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t, void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, uint32_t goaway_error, - grpc_slice goaway_text); + const grpc_slice& goaway_text); void grpc_chttp2_parsing_become_skip_parser(grpc_chttp2_transport* t); diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index 1ff96d3cd36..84b2275ebc4 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -45,14 +45,14 @@ static grpc_error* init_goaway_parser(grpc_chttp2_transport* t); static grpc_error* init_skip_frame_parser(grpc_chttp2_transport* t, int is_header); -static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, grpc_slice slice, - int is_last); +static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, + const grpc_slice& slice, int is_last); grpc_error* grpc_chttp2_perform_read(grpc_chttp2_transport* t, - grpc_slice slice) { - uint8_t* beg = GRPC_SLICE_START_PTR(slice); - uint8_t* end = GRPC_SLICE_END_PTR(slice); - uint8_t* cur = beg; + const grpc_slice& slice) { + const uint8_t* beg = GRPC_SLICE_START_PTR(slice); + const uint8_t* end = GRPC_SLICE_END_PTR(slice); + const uint8_t* cur = beg; grpc_error* err; if (cur == end) return GRPC_ERROR_NONE; @@ -312,7 +312,7 @@ static grpc_error* init_frame_parser(grpc_chttp2_transport* t) { } static grpc_error* skip_parser(void* parser, grpc_chttp2_transport* t, - grpc_chttp2_stream* s, grpc_slice slice, + grpc_chttp2_stream* s, const grpc_slice& slice, int is_last) { return GRPC_ERROR_NONE; } @@ -753,8 +753,8 @@ static grpc_error* init_settings_frame_parser(grpc_chttp2_transport* t) { return GRPC_ERROR_NONE; } -static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, grpc_slice slice, - int is_last) { +static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, + const grpc_slice& slice, int is_last) { grpc_chttp2_stream* s = t->incoming_stream; grpc_error* err = t->parser(t->parser_data, t, s, slice, is_last); intptr_t unused; diff --git a/src/core/lib/channel/channel_trace.cc b/src/core/lib/channel/channel_trace.cc index f0d21db32a8..d329ccc98de 100644 --- a/src/core/lib/channel/channel_trace.cc +++ b/src/core/lib/channel/channel_trace.cc @@ -41,7 +41,7 @@ namespace grpc_core { namespace channelz { -ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data, +ChannelTrace::TraceEvent::TraceEvent(Severity severity, const grpc_slice& data, RefCountedPtr referenced_entity) : severity_(severity), data_(data), @@ -51,7 +51,7 @@ ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data, referenced_entity_(std::move(referenced_entity)), memory_usage_(sizeof(TraceEvent) + grpc_slice_memory_usage(data)) {} -ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data) +ChannelTrace::TraceEvent::TraceEvent(Severity severity, const grpc_slice& data) : severity_(severity), data_(data), timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), @@ -107,7 +107,7 @@ void ChannelTrace::AddTraceEventHelper(TraceEvent* new_trace_event) { } } -void ChannelTrace::AddTraceEvent(Severity severity, grpc_slice data) { +void ChannelTrace::AddTraceEvent(Severity severity, const grpc_slice& data) { if (max_event_memory_ == 0) { grpc_slice_unref_internal(data); return; // tracing is disabled if max_event_memory_ == 0 @@ -116,7 +116,7 @@ void ChannelTrace::AddTraceEvent(Severity severity, grpc_slice data) { } void ChannelTrace::AddTraceEventWithReference( - Severity severity, grpc_slice data, + Severity severity, const grpc_slice& data, RefCountedPtr referenced_entity) { if (max_event_memory_ == 0) { grpc_slice_unref_internal(data); diff --git a/src/core/lib/channel/channel_trace.h b/src/core/lib/channel/channel_trace.h index 8ff91ee8c81..f088185a423 100644 --- a/src/core/lib/channel/channel_trace.h +++ b/src/core/lib/channel/channel_trace.h @@ -62,7 +62,7 @@ class ChannelTrace { // TODO(ncteisen): as this call is used more and more throughout the gRPC // stack, determine if it makes more sense to accept a char* instead of a // slice. - void AddTraceEvent(Severity severity, grpc_slice data); + void AddTraceEvent(Severity severity, const grpc_slice& data); // Adds a new trace event to the tracing object. This trace event refers to a // an event that concerns a different channelz entity. For example, if this @@ -72,7 +72,7 @@ class ChannelTrace { // NOTE: see the note in the method above. // // TODO(ncteisen): see the todo in the method above. - void AddTraceEventWithReference(Severity severity, grpc_slice data, + void AddTraceEventWithReference(Severity severity, const grpc_slice& data, RefCountedPtr referenced_entity); // Creates and returns the raw grpc_json object, so a parent channelz @@ -87,12 +87,12 @@ class ChannelTrace { class TraceEvent { public: // Constructor for a TraceEvent that references a channel. - TraceEvent(Severity severity, grpc_slice data, + TraceEvent(Severity severity, const grpc_slice& data, RefCountedPtr referenced_entity_); // Constructor for a TraceEvent that does not reverence a different // channel. - TraceEvent(Severity severity, grpc_slice data); + TraceEvent(Severity severity, const grpc_slice& data); ~TraceEvent(); diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index e43792126f0..e543cda1c2b 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -180,11 +180,11 @@ class ChannelNode : public BaseNode { bool ChannelIsDestroyed() { return channel_ == nullptr; } // proxy methods to composed classes. - void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { + void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) { trace_.AddTraceEvent(severity, data); } void AddTraceEventWithReference(ChannelTrace::Severity severity, - grpc_slice data, + const grpc_slice& data, RefCountedPtr referenced_channel) { trace_.AddTraceEventWithReference(severity, data, std::move(referenced_channel)); @@ -214,11 +214,11 @@ class ServerNode : public BaseNode { intptr_t pagination_limit); // proxy methods to composed classes. - void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { + void AddTraceEvent(ChannelTrace::Severity severity, const grpc_slice& data) { trace_.AddTraceEvent(severity, data); } void AddTraceEventWithReference(ChannelTrace::Severity severity, - grpc_slice data, + const grpc_slice& data, RefCountedPtr referenced_channel) { trace_.AddTraceEventWithReference(severity, data, std::move(referenced_channel)); diff --git a/src/core/lib/compression/algorithm_metadata.h b/src/core/lib/compression/algorithm_metadata.h index 1be79e59c00..d58d2f541a0 100644 --- a/src/core/lib/compression/algorithm_metadata.h +++ b/src/core/lib/compression/algorithm_metadata.h @@ -32,7 +32,7 @@ grpc_slice grpc_compression_algorithm_slice( /** Find compression algorithm based on passed in mdstr - returns * GRPC_COMPRESS_ALGORITHM_COUNT on failure */ grpc_compression_algorithm grpc_compression_algorithm_from_slice( - grpc_slice str); + const grpc_slice& str); /** Return compression algorithm based metadata element */ grpc_mdelem grpc_compression_encoding_mdelem( @@ -51,11 +51,11 @@ grpc_mdelem grpc_stream_compression_encoding_mdelem( /** Find compression algorithm based on passed in mdstr - returns * GRPC_COMPRESS_ALGORITHM_COUNT on failure */ grpc_message_compression_algorithm -grpc_message_compression_algorithm_from_slice(grpc_slice str); +grpc_message_compression_algorithm_from_slice(const grpc_slice& str); /** Find stream compression algorithm based on passed in mdstr - returns * GRPC_STREAM_COMPRESS_ALGORITHM_COUNT on failure */ grpc_stream_compression_algorithm grpc_stream_compression_algorithm_from_slice( - grpc_slice str); + const grpc_slice& str); #endif /* GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H */ diff --git a/src/core/lib/compression/compression.cc b/src/core/lib/compression/compression.cc index 48717541a76..9139fa04ee5 100644 --- a/src/core/lib/compression/compression.cc +++ b/src/core/lib/compression/compression.cc @@ -147,7 +147,7 @@ grpc_slice grpc_compression_algorithm_slice( } grpc_compression_algorithm grpc_compression_algorithm_from_slice( - grpc_slice str) { + const grpc_slice& str) { if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_COMPRESS_NONE; if (grpc_slice_eq(str, GRPC_MDSTR_DEFLATE)) return GRPC_COMPRESS_DEFLATE; if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_COMPRESS_GZIP; diff --git a/src/core/lib/compression/compression_internal.cc b/src/core/lib/compression/compression_internal.cc index 538514caf37..65a36de4290 100644 --- a/src/core/lib/compression/compression_internal.cc +++ b/src/core/lib/compression/compression_internal.cc @@ -32,7 +32,7 @@ /* Interfaces related to MD */ grpc_message_compression_algorithm -grpc_message_compression_algorithm_from_slice(grpc_slice str) { +grpc_message_compression_algorithm_from_slice(const grpc_slice& str) { if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_MESSAGE_COMPRESS_NONE; if (grpc_slice_eq(str, GRPC_MDSTR_DEFLATE)) @@ -42,7 +42,7 @@ grpc_message_compression_algorithm_from_slice(grpc_slice str) { } grpc_stream_compression_algorithm grpc_stream_compression_algorithm_from_slice( - grpc_slice str) { + const grpc_slice& str) { if (grpc_slice_eq(str, GRPC_MDSTR_IDENTITY)) return GRPC_STREAM_COMPRESS_NONE; if (grpc_slice_eq(str, GRPC_MDSTR_GZIP)) return GRPC_STREAM_COMPRESS_GZIP; return GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT; diff --git a/src/core/lib/http/httpcli.cc b/src/core/lib/http/httpcli.cc index 3bd7a2ce590..8c9ce4da0d3 100644 --- a/src/core/lib/http/httpcli.cc +++ b/src/core/lib/http/httpcli.cc @@ -229,7 +229,8 @@ static void internal_request_begin(grpc_httpcli_context* context, const grpc_httpcli_request* request, grpc_millis deadline, grpc_closure* on_done, grpc_httpcli_response* response, - const char* name, grpc_slice request_text) { + const char* name, + const grpc_slice& request_text) { internal_request* req = static_cast(gpr_malloc(sizeof(internal_request))); memset(req, 0, sizeof(*req)); diff --git a/src/core/lib/http/parser.cc b/src/core/lib/http/parser.cc index a37fdda8ea7..7ca1cc9db5f 100644 --- a/src/core/lib/http/parser.cc +++ b/src/core/lib/http/parser.cc @@ -351,7 +351,8 @@ void grpc_http_response_destroy(grpc_http_response* response) { gpr_free(response->hdrs); } -grpc_error* grpc_http_parser_parse(grpc_http_parser* parser, grpc_slice slice, +grpc_error* grpc_http_parser_parse(grpc_http_parser* parser, + const grpc_slice& slice, size_t* start_of_body) { for (size_t i = 0; i < GRPC_SLICE_LENGTH(slice); i++) { bool found_body_start = false; diff --git a/src/core/lib/http/parser.h b/src/core/lib/http/parser.h index a8f47c96c85..b51fd5af09f 100644 --- a/src/core/lib/http/parser.h +++ b/src/core/lib/http/parser.h @@ -101,7 +101,8 @@ void grpc_http_parser_init(grpc_http_parser* parser, grpc_http_type type, void grpc_http_parser_destroy(grpc_http_parser* parser); /* Sets \a start_of_body to the offset in \a slice of the start of the body. */ -grpc_error* grpc_http_parser_parse(grpc_http_parser* parser, grpc_slice slice, +grpc_error* grpc_http_parser_parse(grpc_http_parser* parser, + const grpc_slice& slice, size_t* start_of_body); grpc_error* grpc_http_parser_eof(grpc_http_parser* parser); diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index f4abad9b288..f194eb62d48 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -150,13 +150,12 @@ static void unref_errs(grpc_error* err) { } } -static void unref_slice(grpc_slice slice) { grpc_slice_unref_internal(slice); } - static void unref_strs(grpc_error* err) { for (size_t which = 0; which < GRPC_ERROR_STR_MAX; ++which) { uint8_t slot = err->strs[which]; if (slot != UINT8_MAX) { - unref_slice(*reinterpret_cast(err->arena + slot)); + grpc_slice_unref_internal( + *reinterpret_cast(err->arena + slot)); } } } @@ -231,7 +230,7 @@ static void internal_set_int(grpc_error** err, grpc_error_ints which, } static void internal_set_str(grpc_error** err, grpc_error_strs which, - grpc_slice value) { + const grpc_slice& value) { uint8_t slot = (*err)->strs[which]; if (slot == UINT8_MAX) { slot = get_placement(err, sizeof(value)); @@ -243,7 +242,8 @@ static void internal_set_str(grpc_error** err, grpc_error_strs which, return; } } else { - unref_slice(*reinterpret_cast((*err)->arena + slot)); + grpc_slice_unref_internal( + *reinterpret_cast((*err)->arena + slot)); } (*err)->strs[which] = slot; memcpy((*err)->arena + slot, &value, sizeof(value)); @@ -313,8 +313,8 @@ void grpc_enable_error_creation() { gpr_atm_no_barrier_store(&g_error_creation_allowed, true); } -grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc, - grpc_error** referencing, +grpc_error* grpc_error_create(const char* file, int line, + const grpc_slice& desc, grpc_error** referencing, size_t num_referencing) { GPR_TIMER_SCOPE("grpc_error_create", 0); uint8_t initial_arena_capacity = static_cast( @@ -472,7 +472,7 @@ bool grpc_error_get_int(grpc_error* err, grpc_error_ints which, intptr_t* p) { } grpc_error* grpc_error_set_str(grpc_error* src, grpc_error_strs which, - grpc_slice str) { + const grpc_slice& str) { GPR_TIMER_SCOPE("grpc_error_set_str", 0); grpc_error* new_err = copy_error_and_unref(src); internal_set_str(&new_err, which, str); @@ -620,7 +620,7 @@ static char* key_str(grpc_error_strs which) { return gpr_strdup(error_str_name(which)); } -static char* fmt_str(grpc_slice slice) { +static char* fmt_str(const grpc_slice& slice) { char* s = nullptr; size_t sz = 0; size_t cap = 0; diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index cb740d5b01c..fcc6f0761b3 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -138,8 +138,9 @@ void grpc_enable_error_creation(); const char* grpc_error_string(grpc_error* error); /// Create an error - but use GRPC_ERROR_CREATE instead -grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc, - grpc_error** referencing, size_t num_referencing); +grpc_error* grpc_error_create(const char* file, int line, + const grpc_slice& desc, grpc_error** referencing, + size_t num_referencing); /// Create an error (this is the preferred way of generating an error that is /// not due to a system call - for system calls, use GRPC_OS_ERROR or /// GRPC_WSA_ERROR as appropriate) @@ -200,7 +201,7 @@ bool grpc_error_get_int(grpc_error* error, grpc_error_ints which, intptr_t* p); /// This call takes ownership of the slice; the error is responsible for /// eventually unref-ing it. grpc_error* grpc_error_set_str(grpc_error* src, grpc_error_strs which, - grpc_slice str) GRPC_MUST_USE_RESULT; + const grpc_slice& str) GRPC_MUST_USE_RESULT; /// Returns false if the specified string is not set. /// Caller does NOT own the slice. bool grpc_error_get_str(grpc_error* error, grpc_error_strs which, diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc index 303f13300d9..5b120eddb43 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc @@ -134,7 +134,8 @@ static void jose_header_destroy(jose_header* h) { } /* Takes ownership of json and buffer. */ -static jose_header* jose_header_from_json(grpc_json* json, grpc_slice buffer) { +static jose_header* jose_header_from_json(grpc_json* json, + const grpc_slice& buffer) { grpc_json* cur; jose_header* h = static_cast(gpr_zalloc(sizeof(jose_header))); h->buffer = buffer; @@ -235,7 +236,8 @@ gpr_timespec grpc_jwt_claims_not_before(const grpc_jwt_claims* claims) { } /* Takes ownership of json and buffer even in case of failure. */ -grpc_jwt_claims* grpc_jwt_claims_from_json(grpc_json* json, grpc_slice buffer) { +grpc_jwt_claims* grpc_jwt_claims_from_json(grpc_json* json, + const grpc_slice& buffer) { grpc_json* cur; grpc_jwt_claims* claims = static_cast(gpr_malloc(sizeof(grpc_jwt_claims))); @@ -350,7 +352,7 @@ typedef struct { /* Takes ownership of the header, claims and signature. */ static verifier_cb_ctx* verifier_cb_ctx_create( grpc_jwt_verifier* verifier, grpc_pollset* pollset, jose_header* header, - grpc_jwt_claims* claims, const char* audience, grpc_slice signature, + grpc_jwt_claims* claims, const char* audience, const grpc_slice& signature, const char* signed_jwt, size_t signed_jwt_len, void* user_data, grpc_jwt_verification_done_cb cb) { grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; @@ -602,7 +604,8 @@ static EVP_PKEY* find_verification_key(const grpc_json* json, } static int verify_jwt_signature(EVP_PKEY* key, const char* alg, - grpc_slice signature, grpc_slice signed_data) { + const grpc_slice& signature, + const grpc_slice& signed_data) { EVP_MD_CTX* md_ctx = EVP_MD_CTX_create(); const EVP_MD* md = evp_md_from_alg(alg); int result = 0; diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.h b/src/core/lib/security/credentials/jwt/jwt_verifier.h index cdb09870bd5..3f69ada98d5 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.h +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.h @@ -115,7 +115,8 @@ void grpc_jwt_verifier_verify(grpc_jwt_verifier* verifier, /* --- TESTING ONLY exposed functions. --- */ -grpc_jwt_claims* grpc_jwt_claims_from_json(grpc_json* json, grpc_slice buffer); +grpc_jwt_claims* grpc_jwt_claims_from_json(grpc_json* json, + const grpc_slice& buffer); grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims* claims, const char* audience); const char* grpc_jwt_issuer_email_domain(const char* issuer); diff --git a/src/core/lib/security/transport/auth_filters.h b/src/core/lib/security/transport/auth_filters.h index af2104cfbcd..16a8e58ed9a 100644 --- a/src/core/lib/security/transport/auth_filters.h +++ b/src/core/lib/security/transport/auth_filters.h @@ -28,8 +28,8 @@ extern const grpc_channel_filter grpc_client_auth_filter; extern const grpc_channel_filter grpc_server_auth_filter; void grpc_auth_metadata_context_build( - const char* url_scheme, grpc_slice call_host, grpc_slice call_method, - grpc_auth_context* auth_context, + const char* url_scheme, const grpc_slice& call_host, + const grpc_slice& call_method, grpc_auth_context* auth_context, grpc_auth_metadata_context* auth_md_context); void grpc_auth_metadata_context_reset(grpc_auth_metadata_context* context); diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 66f86b8bc52..5fe750edbf3 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -155,8 +155,8 @@ static void on_credentials_metadata(void* arg, grpc_error* input_error) { } void grpc_auth_metadata_context_build( - const char* url_scheme, grpc_slice call_host, grpc_slice call_method, - grpc_auth_context* auth_context, + const char* url_scheme, const grpc_slice& call_host, + const grpc_slice& call_method, grpc_auth_context* auth_context, grpc_auth_metadata_context* auth_md_context) { char* service = grpc_slice_to_c_string(call_method); char* last_slash = strrchr(service, '/'); diff --git a/src/core/lib/slice/percent_encoding.cc b/src/core/lib/slice/percent_encoding.cc index 45cd2cc47f4..79a4805bc91 100644 --- a/src/core/lib/slice/percent_encoding.cc +++ b/src/core/lib/slice/percent_encoding.cc @@ -38,7 +38,7 @@ static bool is_unreserved_character(uint8_t c, return ((unreserved_bytes[c / 8] >> (c % 8)) & 1) != 0; } -grpc_slice grpc_percent_encode_slice(grpc_slice slice, +grpc_slice grpc_percent_encode_slice(const grpc_slice& slice, const uint8_t* unreserved_bytes) { static const uint8_t hex[] = "0123456789ABCDEF"; @@ -86,7 +86,7 @@ static uint8_t dehex(uint8_t c) { GPR_UNREACHABLE_CODE(return 255); } -bool grpc_strict_percent_decode_slice(grpc_slice slice_in, +bool grpc_strict_percent_decode_slice(const grpc_slice& slice_in, const uint8_t* unreserved_bytes, grpc_slice* slice_out) { const uint8_t* p = GRPC_SLICE_START_PTR(slice_in); @@ -126,7 +126,7 @@ bool grpc_strict_percent_decode_slice(grpc_slice slice_in, return true; } -grpc_slice grpc_permissive_percent_decode_slice(grpc_slice slice_in) { +grpc_slice grpc_permissive_percent_decode_slice(const grpc_slice& slice_in) { const uint8_t* p = GRPC_SLICE_START_PTR(slice_in); const uint8_t* in_end = GRPC_SLICE_END_PTR(slice_in); size_t out_length = 0; diff --git a/src/core/lib/slice/percent_encoding.h b/src/core/lib/slice/percent_encoding.h index 6b13ffc3fee..43b20f090f0 100644 --- a/src/core/lib/slice/percent_encoding.h +++ b/src/core/lib/slice/percent_encoding.h @@ -46,7 +46,7 @@ extern const uint8_t grpc_compatible_percent_encoding_unreserved_bytes[256 / 8]; /* Percent-encode a slice, returning the new slice (this cannot fail): unreserved_bytes is a bitfield indicating which bytes are considered unreserved and thus do not need percent encoding */ -grpc_slice grpc_percent_encode_slice(grpc_slice slice, +grpc_slice grpc_percent_encode_slice(const grpc_slice& slice, const uint8_t* unreserved_bytes); /* Percent-decode a slice, strictly. If the input is legal (contains no unreserved bytes, and legal % encodings), @@ -54,12 +54,12 @@ grpc_slice grpc_percent_encode_slice(grpc_slice slice, If the input is not legal, returns false and leaves *slice_out untouched. unreserved_bytes is a bitfield indicating which bytes are considered unreserved and thus do not need percent encoding */ -bool grpc_strict_percent_decode_slice(grpc_slice slice_in, +bool grpc_strict_percent_decode_slice(const grpc_slice& slice_in, const uint8_t* unreserved_bytes, grpc_slice* slice_out); /* Percent-decode a slice, permissively. If a % triplet can not be decoded, pass it through verbatim. This cannot fail. */ -grpc_slice grpc_permissive_percent_decode_slice(grpc_slice slice_in); +grpc_slice grpc_permissive_percent_decode_slice(const grpc_slice& slice_in); #endif /* GRPC_CORE_LIB_SLICE_PERCENT_ENCODING_H */ diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index 31437aa4600..ac935f13e28 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -50,19 +50,6 @@ grpc_slice grpc_slice_copy(grpc_slice s) { return out; } -grpc_slice grpc_slice_ref_internal(grpc_slice slice) { - if (slice.refcount) { - slice.refcount->vtable->ref(slice.refcount); - } - return slice; -} - -void grpc_slice_unref_internal(grpc_slice slice) { - if (slice.refcount) { - slice.refcount->vtable->unref(slice.refcount); - } -} - /* Public API */ grpc_slice grpc_slice_ref(grpc_slice slice) { return grpc_slice_ref_internal(slice); diff --git a/src/core/lib/slice/slice_hash_table.h b/src/core/lib/slice/slice_hash_table.h index 4bbcf88e895..942830a3e9c 100644 --- a/src/core/lib/slice/slice_hash_table.h +++ b/src/core/lib/slice/slice_hash_table.h @@ -88,7 +88,7 @@ class SliceHashTable : public RefCounted> { SliceHashTable(size_t num_entries, Entry* entries, ValueCmp value_cmp); virtual ~SliceHashTable(); - void Add(grpc_slice key, T& value); + void Add(const grpc_slice& key, T& value); // Default value comparison function, if none specified by caller. static int DefaultValueCmp(const T& a, const T& b) { return GPR_ICMP(a, b); } @@ -137,7 +137,7 @@ SliceHashTable::~SliceHashTable() { } template -void SliceHashTable::Add(grpc_slice key, T& value) { +void SliceHashTable::Add(const grpc_slice& key, T& value) { const size_t hash = grpc_slice_hash(key); for (size_t offset = 0; offset < size_; ++offset) { const size_t idx = (hash + offset) % size_; diff --git a/src/core/lib/slice/slice_intern.cc b/src/core/lib/slice/slice_intern.cc index e53c040e1aa..0eef38d3f35 100644 --- a/src/core/lib/slice/slice_intern.cc +++ b/src/core/lib/slice/slice_intern.cc @@ -196,7 +196,7 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice, return slice; } -bool grpc_slice_is_interned(grpc_slice slice) { +bool grpc_slice_is_interned(const grpc_slice& slice) { return (slice.refcount && slice.refcount->vtable == &interned_slice_vtable) || GRPC_IS_STATIC_METADATA_STRING(slice); } diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index 5b05951522f..0e50866b70e 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -24,15 +24,26 @@ #include #include -grpc_slice grpc_slice_ref_internal(grpc_slice slice); -void grpc_slice_unref_internal(grpc_slice slice); +inline const grpc_slice& grpc_slice_ref_internal(const grpc_slice& slice) { + if (slice.refcount) { + slice.refcount->vtable->ref(slice.refcount); + } + return slice; +} + +inline void grpc_slice_unref_internal(const grpc_slice& slice) { + if (slice.refcount) { + slice.refcount->vtable->unref(slice.refcount); + } +} + void grpc_slice_buffer_reset_and_unref_internal(grpc_slice_buffer* sb); void grpc_slice_buffer_partial_unref_internal(grpc_slice_buffer* sb, size_t idx); void grpc_slice_buffer_destroy_internal(grpc_slice_buffer* sb); /* Check if a slice is interned */ -bool grpc_slice_is_interned(grpc_slice slice); +bool grpc_slice_is_interned(const grpc_slice& slice); void grpc_slice_intern_init(void); void grpc_slice_intern_shutdown(void); diff --git a/src/core/lib/slice/slice_traits.h b/src/core/lib/slice/slice_traits.h index ee01916525e..07d13cd8b54 100644 --- a/src/core/lib/slice/slice_traits.h +++ b/src/core/lib/slice/slice_traits.h @@ -24,8 +24,8 @@ #include #include -bool grpc_slice_is_legal_header(grpc_slice s); -bool grpc_slice_is_legal_nonbin_header(grpc_slice s); -bool grpc_slice_is_bin_suffixed(grpc_slice s); +bool grpc_slice_is_legal_header(const grpc_slice& s); +bool grpc_slice_is_legal_nonbin_header(const grpc_slice& s); +bool grpc_slice_is_bin_suffixed(const grpc_slice& s); #endif /* GRPC_CORE_LIB_SLICE_SLICE_TRAITS_H */ diff --git a/src/core/lib/slice/slice_weak_hash_table.h b/src/core/lib/slice/slice_weak_hash_table.h index dc3ccc5dadd..1335c817a39 100644 --- a/src/core/lib/slice/slice_weak_hash_table.h +++ b/src/core/lib/slice/slice_weak_hash_table.h @@ -46,7 +46,7 @@ class SliceWeakHashTable : public RefCounted> { /// Add a mapping from \a key to \a value, taking ownership of \a key. This /// operation will always succeed. It may discard older entries. - void Add(grpc_slice key, T value) { + void Add(const grpc_slice& key, T value) { const size_t idx = grpc_slice_hash(key) % Size; entries_[idx].Set(key, std::move(value)); return; @@ -54,7 +54,7 @@ class SliceWeakHashTable : public RefCounted> { /// Returns the value from the table associated with / \a key or null if not /// found. - const T* Get(const grpc_slice key) const { + const T* Get(const grpc_slice& key) const { const size_t idx = grpc_slice_hash(key) % Size; const auto& entry = entries_[idx]; return grpc_slice_eq(entry.key(), key) ? entry.value() : nullptr; @@ -79,7 +79,7 @@ class SliceWeakHashTable : public RefCounted> { ~Entry() { if (is_set_) grpc_slice_unref_internal(key_); } - grpc_slice key() const { return key_; } + const grpc_slice& key() const { return key_; } /// Return the entry's value, or null if unset. const T* value() const { @@ -88,7 +88,7 @@ class SliceWeakHashTable : public RefCounted> { } /// Set the \a key and \a value (which is moved) for the entry. - void Set(grpc_slice key, T&& value) { + void Set(const grpc_slice& key, T&& value) { if (is_set_) grpc_slice_unref_internal(key_); key_ = key; value_ = std::move(value); diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index 928ed73cdad..49a56e709d5 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -227,7 +227,7 @@ void grpc_metadata_batch_remove(grpc_metadata_batch* batch, } void grpc_metadata_batch_set_value(grpc_linked_mdelem* storage, - grpc_slice value) { + const grpc_slice& value) { grpc_mdelem old_mdelem = storage->md; grpc_mdelem new_mdelem = grpc_mdelem_from_slices( grpc_slice_ref_internal(GRPC_MDKEY(old_mdelem)), value); diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index f6e8bbf2052..d87a8b0886d 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -74,7 +74,7 @@ grpc_error* grpc_metadata_batch_substitute(grpc_metadata_batch* batch, grpc_mdelem new_value); void grpc_metadata_batch_set_value(grpc_linked_mdelem* storage, - grpc_slice value); + const grpc_slice& value); /** Add \a storage to the beginning of \a batch. storage->md is assumed to be valid. diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h index af24501e3df..224c6dd576c 100644 --- a/src/core/lib/transport/service_config.h +++ b/src/core/lib/transport/service_config.h @@ -92,7 +92,7 @@ class ServiceConfig : public RefCounted { /// Caller does NOT own a reference to the result. template static RefCountedPtr MethodConfigTableLookup( - const SliceHashTable>& table, grpc_slice path); + const SliceHashTable>& table, const grpc_slice& path); private: // So New() can call our private ctor. @@ -223,7 +223,7 @@ ServiceConfig::CreateMethodConfigTable(CreateValue create_value) { template RefCountedPtr ServiceConfig::MethodConfigTableLookup( - const SliceHashTable>& table, grpc_slice path) { + const SliceHashTable>& table, const grpc_slice& path) { const RefCountedPtr* value = table.Get(path); // If we didn't find a match for the path, try looking for a wildcard // entry (i.e., change "/service/method" to "/service/*"). diff --git a/src/core/lib/transport/timeout_encoding.cc b/src/core/lib/transport/timeout_encoding.cc index c37249920bd..fe22c15fa6d 100644 --- a/src/core/lib/transport/timeout_encoding.cc +++ b/src/core/lib/transport/timeout_encoding.cc @@ -89,7 +89,7 @@ static int is_all_whitespace(const char* p, const char* end) { return p == end; } -int grpc_http2_decode_timeout(grpc_slice text, grpc_millis* timeout) { +int grpc_http2_decode_timeout(const grpc_slice& text, grpc_millis* timeout) { grpc_millis x = 0; const uint8_t* p = GRPC_SLICE_START_PTR(text); const uint8_t* end = GRPC_SLICE_END_PTR(text); diff --git a/src/core/lib/transport/timeout_encoding.h b/src/core/lib/transport/timeout_encoding.h index 8505e32ff09..cc0d37452fd 100644 --- a/src/core/lib/transport/timeout_encoding.h +++ b/src/core/lib/transport/timeout_encoding.h @@ -32,6 +32,6 @@ /* Encode/decode timeouts to the GRPC over HTTP/2 format; encoding may round up arbitrarily */ void grpc_http2_encode_timeout(grpc_millis timeout, char* buffer); -int grpc_http2_decode_timeout(grpc_slice text, grpc_millis* timeout); +int grpc_http2_decode_timeout(const grpc_slice& text, grpc_millis* timeout); #endif /* GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H */ diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc index 43d0979f4b9..464de9e00d0 100644 --- a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +++ b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc @@ -363,7 +363,7 @@ static tsi_result handshaker_client_next(alts_handshaker_client* c, alts_grpc_handshaker_client* client = reinterpret_cast(c); grpc_slice_unref_internal(client->recv_bytes); - client->recv_bytes = grpc_slice_ref(*bytes_received); + client->recv_bytes = grpc_slice_ref_internal(*bytes_received); grpc_byte_buffer* buffer = get_serialized_next(bytes_received); if (buffer == nullptr) { gpr_log(GPR_ERROR, "get_serialized_next() failed"); @@ -406,7 +406,7 @@ static const alts_handshaker_client_vtable vtable = { alts_handshaker_client* alts_grpc_handshaker_client_create( alts_tsi_handshaker* handshaker, grpc_channel* channel, const char* handshaker_service_url, grpc_pollset_set* interested_parties, - grpc_alts_credentials_options* options, grpc_slice target_name, + grpc_alts_credentials_options* options, const grpc_slice& target_name, grpc_iomgr_cb_func grpc_cb, tsi_handshaker_on_next_done_cb cb, void* user_data, alts_handshaker_client_vtable* vtable_for_testing, bool is_client) { @@ -487,7 +487,7 @@ void alts_handshaker_client_set_recv_bytes_for_testing( GPR_ASSERT(c != nullptr); alts_grpc_handshaker_client* client = reinterpret_cast(c); - client->recv_bytes = grpc_slice_ref(*recv_bytes); + client->recv_bytes = grpc_slice_ref_internal(*recv_bytes); } void alts_handshaker_client_set_fields_for_testing( diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_client.h b/src/core/tsi/alts/handshaker/alts_handshaker_client.h index 4b489875f3c..319a23c88c7 100644 --- a/src/core/tsi/alts/handshaker/alts_handshaker_client.h +++ b/src/core/tsi/alts/handshaker/alts_handshaker_client.h @@ -138,7 +138,7 @@ void alts_handshaker_client_destroy(alts_handshaker_client* client); alts_handshaker_client* alts_grpc_handshaker_client_create( alts_tsi_handshaker* handshaker, grpc_channel* channel, const char* handshaker_service_url, grpc_pollset_set* interested_parties, - grpc_alts_credentials_options* options, grpc_slice target_name, + grpc_alts_credentials_options* options, const grpc_slice& target_name, grpc_iomgr_cb_func grpc_cb, tsi_handshaker_on_next_done_cb cb, void* user_data, alts_handshaker_client_vtable* vtable_for_testing, bool is_client); diff --git a/src/core/tsi/alts/handshaker/transport_security_common_api.cc b/src/core/tsi/alts/handshaker/transport_security_common_api.cc index 8a7edb53d4f..6c518c1ff31 100644 --- a/src/core/tsi/alts/handshaker/transport_security_common_api.cc +++ b/src/core/tsi/alts/handshaker/transport_security_common_api.cc @@ -106,15 +106,16 @@ bool grpc_gcp_rpc_protocol_versions_encode( } bool grpc_gcp_rpc_protocol_versions_decode( - grpc_slice slice, grpc_gcp_rpc_protocol_versions* versions) { + const grpc_slice& slice, grpc_gcp_rpc_protocol_versions* versions) { if (versions == nullptr) { gpr_log(GPR_ERROR, "version is nullptr in " "grpc_gcp_rpc_protocol_versions_decode()."); return false; } - pb_istream_t stream = pb_istream_from_buffer(GRPC_SLICE_START_PTR(slice), - GRPC_SLICE_LENGTH(slice)); + pb_istream_t stream = + pb_istream_from_buffer(const_cast(GRPC_SLICE_START_PTR(slice)), + GRPC_SLICE_LENGTH(slice)); if (!pb_decode(&stream, grpc_gcp_RpcProtocolVersions_fields, versions)) { gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream)); return false; diff --git a/src/core/tsi/alts/handshaker/transport_security_common_api.h b/src/core/tsi/alts/handshaker/transport_security_common_api.h index ec2a0b4b5e3..27942c8ae4c 100644 --- a/src/core/tsi/alts/handshaker/transport_security_common_api.h +++ b/src/core/tsi/alts/handshaker/transport_security_common_api.h @@ -112,7 +112,7 @@ bool grpc_gcp_rpc_protocol_versions_encode( * The method returns true on success and false otherwise. */ bool grpc_gcp_rpc_protocol_versions_decode( - grpc_slice slice, grpc_gcp_rpc_protocol_versions* versions); + const grpc_slice& slice, grpc_gcp_rpc_protocol_versions* versions); /** * This method performs a deep copy operation on rpc protocol versions From 059e10447534eeb2e43b5d4cb1f1d29afdb591ee Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sat, 2 Mar 2019 23:25:18 -0500 Subject: [PATCH 565/814] Use grpc_core::RefCount for ServerContext. --- src/cpp/server/server_context.cc | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index e116cf6e7d2..d38b46822ae 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -32,6 +32,7 @@ #include #include +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/surface/call.h" namespace grpc { @@ -116,13 +117,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { done_intercepting_ = true; if (!has_tag_) { /* We don't have a tag to return. */ - std::unique_lock lock(mu_); - if (--refs_ == 0) { - lock.unlock(); - grpc_call* call = call_.call(); - delete this; - grpc_call_unref(call); - } + Unref(); return; } /* Start a dummy op so that we can return the tag */ @@ -142,8 +137,8 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { bool has_tag_; void* tag_; void* core_cq_tag_; + grpc_core::RefCount refs_; std::mutex mu_; - int refs_; bool finalized_; int cancelled_; // This is an int (not bool) because it is passed to core bool done_intercepting_; @@ -151,9 +146,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { }; void ServerContext::CompletionOp::Unref() { - std::unique_lock lock(mu_); - if (--refs_ == 0) { - lock.unlock(); + if (refs_.Unref()) { grpc_call* call = call_.call(); delete this; grpc_call_unref(call); @@ -183,12 +176,7 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { *tag = tag_; ret = true; } - if (--refs_ == 0) { - lock.unlock(); - grpc_call* call = call_.call(); - delete this; - grpc_call_unref(call); - } + Unref(); return ret; } finalized_ = true; @@ -220,13 +208,7 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { *tag = tag_; ret = true; } - lock.lock(); - if (--refs_ == 0) { - lock.unlock(); - grpc_call* call = call_.call(); - delete this; - grpc_call_unref(call); - } + Unref(); return ret; } /* There are interceptors to be run. Return false for now */ From dcc5728ddfb79a8c3faad2071fa63e651fe58ab8 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Mon, 4 Mar 2019 12:26:13 -0500 Subject: [PATCH 566/814] Initialize tcp->read_done_closure only once We are initializing the closure every time in tcp_notify_on_read() wasting cycles. --- src/core/lib/iomgr/tcp_posix.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 68cce8a4655..525288a77ae 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -250,8 +250,6 @@ static void notify_on_read(grpc_tcp* tcp) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p notify_on_read", tcp); } - GRPC_CLOSURE_INIT(&tcp->read_done_closure, tcp_handle_read, tcp, - grpc_schedule_on_exec_ctx); grpc_fd_notify_on_read(tcp->em_fd, &tcp->read_done_closure); } @@ -1157,6 +1155,8 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, grpc_resource_quota_unref_internal(resource_quota); gpr_mu_init(&tcp->tb_mu); tcp->tb_head = nullptr; + GRPC_CLOSURE_INIT(&tcp->read_done_closure, tcp_handle_read, tcp, + grpc_schedule_on_exec_ctx); /* Start being notified on errors if event engine can track errors. */ if (grpc_event_engine_can_track_errors()) { /* Grab a ref to tcp so that we can safely access the tcp struct when From 509e77a5a3238e63dd2b262c87c675f8c6526c0f Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 27 Feb 2019 23:41:18 -0500 Subject: [PATCH 567/814] Introduce grpc_byte_buffer_reader_peek and use it for Protobuf parsing. grpc_byte_buffer_reader_next() copies and references the slice. This is not always necessary since the caller will not use the slice after destroying the byte buffer. A prominent example is the protobuf parser, which calls grpc_byte_buffer_reader_next() and immediately unrefs the slice after the call. This ref() and unref() calls can be very expensive in the hot path. This commit introduces grpc_byte_buffer_reader_peek() which essentialy return a pointer to the slice in the buffer, i.e., no copies, and no refs. QPS of 1MiB 1 Channel callback benchmark increases by 5%. More importantly insructions per cycle is increased by 10%. Also add tests and benchmarks for byte_buffer_reader_peek() --- grpc.def | 1 + include/grpc/impl/codegen/byte_buffer.h | 13 ++++ include/grpcpp/impl/codegen/core_codegen.h | 2 + .../impl/codegen/core_codegen_interface.h | 2 + .../grpcpp/impl/codegen/proto_buffer_reader.h | 18 ++--- src/core/lib/surface/byte_buffer_reader.cc | 17 +++++ src/cpp/common/core_codegen.cc | 5 ++ src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 + src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 + test/core/surface/byte_buffer_reader_test.cc | 70 ++++++++++++++++++ .../core/surface/public_headers_must_be_c89.c | 1 + test/cpp/microbenchmarks/bm_byte_buffer.cc | 71 ++++++++++++++++++- 12 files changed, 194 insertions(+), 11 deletions(-) diff --git a/grpc.def b/grpc.def index e0a08d22c19..922f95383a3 100644 --- a/grpc.def +++ b/grpc.def @@ -149,6 +149,7 @@ EXPORTS grpc_byte_buffer_reader_init grpc_byte_buffer_reader_destroy grpc_byte_buffer_reader_next + grpc_byte_buffer_reader_peek grpc_byte_buffer_reader_readall grpc_raw_byte_buffer_from_reader gpr_log_severity_string diff --git a/include/grpc/impl/codegen/byte_buffer.h b/include/grpc/impl/codegen/byte_buffer.h index 774655ed66f..12479068155 100644 --- a/include/grpc/impl/codegen/byte_buffer.h +++ b/include/grpc/impl/codegen/byte_buffer.h @@ -73,6 +73,19 @@ GRPCAPI void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader); GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice); +/** EXPERIMENTAL API - This function may be removed and changed, in the future. + * + * Updates \a slice with the next piece of data from from \a reader and returns + * 1. Returns 0 at the end of the stream. Caller is responsible for making sure + * the slice pointer remains valid when accessed. + * + * NOTE: Do not use this function unless the caller can guarantee that the + * underlying grpc_byte_buffer outlasts the use of the slice. This is only + * safe when the underlying grpc_byte_buffer remains immutable while slice + * is being accessed. */ +GRPCAPI int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice); + /** Merge all data from \a reader into single slice */ GRPCAPI grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader* reader); diff --git a/include/grpcpp/impl/codegen/core_codegen.h b/include/grpcpp/impl/codegen/core_codegen.h index b7ddb0c791c..27729e0d5db 100644 --- a/include/grpcpp/impl/codegen/core_codegen.h +++ b/include/grpcpp/impl/codegen/core_codegen.h @@ -85,6 +85,8 @@ class CoreCodegen final : public CoreCodegenInterface { grpc_byte_buffer_reader* reader) override; int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) override; + int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) override; grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) override; diff --git a/include/grpcpp/impl/codegen/core_codegen_interface.h b/include/grpcpp/impl/codegen/core_codegen_interface.h index 1d92b4f0dff..3792c3d4693 100644 --- a/include/grpcpp/impl/codegen/core_codegen_interface.h +++ b/include/grpcpp/impl/codegen/core_codegen_interface.h @@ -92,6 +92,8 @@ class CoreCodegenInterface { grpc_byte_buffer_reader* reader) = 0; virtual int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) = 0; + virtual int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) = 0; virtual grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) = 0; diff --git a/include/grpcpp/impl/codegen/proto_buffer_reader.h b/include/grpcpp/impl/codegen/proto_buffer_reader.h index 9acae476b11..734da366f3a 100644 --- a/include/grpcpp/impl/codegen/proto_buffer_reader.h +++ b/include/grpcpp/impl/codegen/proto_buffer_reader.h @@ -73,7 +73,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { } /// If we have backed up previously, we need to return the backed-up slice if (backup_count_ > 0) { - *data = GRPC_SLICE_START_PTR(slice_) + GRPC_SLICE_LENGTH(slice_) - + *data = GRPC_SLICE_START_PTR(*slice_) + GRPC_SLICE_LENGTH(*slice_) - backup_count_; GPR_CODEGEN_ASSERT(backup_count_ <= INT_MAX); *size = (int)backup_count_; @@ -81,15 +81,14 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { return true; } /// Otherwise get the next slice from the byte buffer reader - if (!g_core_codegen_interface->grpc_byte_buffer_reader_next(&reader_, + if (!g_core_codegen_interface->grpc_byte_buffer_reader_peek(&reader_, &slice_)) { return false; } - g_core_codegen_interface->grpc_slice_unref(slice_); - *data = GRPC_SLICE_START_PTR(slice_); + *data = GRPC_SLICE_START_PTR(*slice_); // On win x64, int is only 32bit - GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX); - byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_); + GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(*slice_) <= INT_MAX); + byte_count_ += * size = (int)GRPC_SLICE_LENGTH(*slice_); return true; } @@ -100,7 +99,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { /// bytes that have already been returned by the last call of Next. /// So do the backup and have that ready for a later Next. void BackUp(int count) override { - GPR_CODEGEN_ASSERT(count <= static_cast(GRPC_SLICE_LENGTH(slice_))); + GPR_CODEGEN_ASSERT(count <= static_cast(GRPC_SLICE_LENGTH(*slice_))); backup_count_ = count; } @@ -135,14 +134,15 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { int64_t backup_count() { return backup_count_; } void set_backup_count(int64_t backup_count) { backup_count_ = backup_count; } grpc_byte_buffer_reader* reader() { return &reader_; } - grpc_slice* slice() { return &slice_; } + grpc_slice* slice() { return slice_; } + grpc_slice** mutable_slice_ptr() { return &slice_; } private: int64_t byte_count_; ///< total bytes read since object creation int64_t backup_count_; ///< how far backed up in the stream we are grpc_byte_buffer_reader reader_; ///< internal object to read \a grpc_slice ///< from the \a grpc_byte_buffer - grpc_slice slice_; ///< current slice passed back to the caller + grpc_slice* slice_; ///< current slice passed back to the caller Status status_; ///< status of the entire object }; diff --git a/src/core/lib/surface/byte_buffer_reader.cc b/src/core/lib/surface/byte_buffer_reader.cc index 1debc98ea0c..ed8ecc49590 100644 --- a/src/core/lib/surface/byte_buffer_reader.cc +++ b/src/core/lib/surface/byte_buffer_reader.cc @@ -91,6 +91,23 @@ void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader) { } } +int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) { + switch (reader->buffer_in->type) { + case GRPC_BB_RAW: { + grpc_slice_buffer* slice_buffer; + slice_buffer = &reader->buffer_out->data.raw.slice_buffer; + if (reader->current.index < slice_buffer->count) { + *slice = &slice_buffer->slices[reader->current.index]; + reader->current.index += 1; + return 1; + } + break; + } + } + return 0; +} + int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) { switch (reader->buffer_in->type) { diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc index ab5f601fdd4..665305ca0a5 100644 --- a/src/cpp/common/core_codegen.cc +++ b/src/cpp/common/core_codegen.cc @@ -139,6 +139,11 @@ int CoreCodegen::grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, return ::grpc_byte_buffer_reader_next(reader, slice); } +int CoreCodegen::grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) { + return ::grpc_byte_buffer_reader_peek(reader, slice); +} + grpc_byte_buffer* CoreCodegen::grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) { return ::grpc_raw_byte_buffer_create(slice, nslices); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index fdbe0df4e52..f8a31286115 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -172,6 +172,7 @@ grpc_byte_buffer_destroy_type grpc_byte_buffer_destroy_import; grpc_byte_buffer_reader_init_type grpc_byte_buffer_reader_init_import; grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_import; grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import; +grpc_byte_buffer_reader_peek_type grpc_byte_buffer_reader_peek_import; grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import; grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import; gpr_log_severity_string_type gpr_log_severity_string_import; @@ -440,6 +441,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_byte_buffer_reader_init_import = (grpc_byte_buffer_reader_init_type) GetProcAddress(library, "grpc_byte_buffer_reader_init"); grpc_byte_buffer_reader_destroy_import = (grpc_byte_buffer_reader_destroy_type) GetProcAddress(library, "grpc_byte_buffer_reader_destroy"); grpc_byte_buffer_reader_next_import = (grpc_byte_buffer_reader_next_type) GetProcAddress(library, "grpc_byte_buffer_reader_next"); + grpc_byte_buffer_reader_peek_import = (grpc_byte_buffer_reader_peek_type) GetProcAddress(library, "grpc_byte_buffer_reader_peek"); grpc_byte_buffer_reader_readall_import = (grpc_byte_buffer_reader_readall_type) GetProcAddress(library, "grpc_byte_buffer_reader_readall"); grpc_raw_byte_buffer_from_reader_import = (grpc_raw_byte_buffer_from_reader_type) GetProcAddress(library, "grpc_raw_byte_buffer_from_reader"); gpr_log_severity_string_import = (gpr_log_severity_string_type) GetProcAddress(library, "gpr_log_severity_string"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index cf16f0ca33b..275ca6e9cbf 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -491,6 +491,9 @@ extern grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_impo typedef int(*grpc_byte_buffer_reader_next_type)(grpc_byte_buffer_reader* reader, grpc_slice* slice); extern grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import; #define grpc_byte_buffer_reader_next grpc_byte_buffer_reader_next_import +typedef int(*grpc_byte_buffer_reader_peek_type)(grpc_byte_buffer_reader* reader, grpc_slice** slice); +extern grpc_byte_buffer_reader_peek_type grpc_byte_buffer_reader_peek_import; +#define grpc_byte_buffer_reader_peek grpc_byte_buffer_reader_peek_import typedef grpc_slice(*grpc_byte_buffer_reader_readall_type)(grpc_byte_buffer_reader* reader); extern grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import; #define grpc_byte_buffer_reader_readall grpc_byte_buffer_reader_readall_import diff --git a/test/core/surface/byte_buffer_reader_test.cc b/test/core/surface/byte_buffer_reader_test.cc index 301a1e283ba..bc368c49657 100644 --- a/test/core/surface/byte_buffer_reader_test.cc +++ b/test/core/surface/byte_buffer_reader_test.cc @@ -101,6 +101,73 @@ static void test_read_none_compressed_slice(void) { grpc_byte_buffer_destroy(buffer); } +static void test_peek_one_slice(void) { + grpc_slice slice; + grpc_byte_buffer* buffer; + grpc_byte_buffer_reader reader; + grpc_slice* first_slice; + grpc_slice* second_slice; + int first_code, second_code; + + LOG_TEST("test_peek_one_slice"); + slice = grpc_slice_from_copied_string("test"); + buffer = grpc_raw_byte_buffer_create(&slice, 1); + grpc_slice_unref(slice); + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && + "Couldn't init byte buffer reader"); + first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); + GPR_ASSERT(first_code != 0); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); + second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); + GPR_ASSERT(second_code == 0); + grpc_byte_buffer_destroy(buffer); +} + +static void test_peek_one_slice_malloc(void) { + grpc_slice slice; + grpc_byte_buffer* buffer; + grpc_byte_buffer_reader reader; + grpc_slice* first_slice; + grpc_slice* second_slice; + int first_code, second_code; + + LOG_TEST("test_peek_one_slice_malloc"); + slice = grpc_slice_malloc(4); + memcpy(GRPC_SLICE_START_PTR(slice), "test", 4); + buffer = grpc_raw_byte_buffer_create(&slice, 1); + grpc_slice_unref(slice); + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && + "Couldn't init byte buffer reader"); + first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); + GPR_ASSERT(first_code != 0); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); + second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); + GPR_ASSERT(second_code == 0); + grpc_byte_buffer_destroy(buffer); +} + +static void test_peek_none_compressed_slice(void) { + grpc_slice slice; + grpc_byte_buffer* buffer; + grpc_byte_buffer_reader reader; + grpc_slice* first_slice; + grpc_slice* second_slice; + int first_code, second_code; + + LOG_TEST("test_peek_none_compressed_slice"); + slice = grpc_slice_from_copied_string("test"); + buffer = grpc_raw_byte_buffer_create(&slice, 1); + grpc_slice_unref(slice); + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && + "Couldn't init byte buffer reader"); + first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); + GPR_ASSERT(first_code != 0); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); + second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); + GPR_ASSERT(second_code == 0); + grpc_byte_buffer_destroy(buffer); +} + static void test_read_corrupted_slice(void) { grpc_slice slice; grpc_byte_buffer* buffer; @@ -271,6 +338,9 @@ int main(int argc, char** argv) { test_read_one_slice(); test_read_one_slice_malloc(); test_read_none_compressed_slice(); + test_peek_one_slice(); + test_peek_one_slice_malloc(); + test_peek_none_compressed_slice(); test_read_gzip_compressed_slice(); test_read_deflate_compressed_slice(); test_read_corrupted_slice(); diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 04d0506b3c2..fa02e76ec92 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -209,6 +209,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_byte_buffer_reader_init); printf("%lx", (unsigned long) grpc_byte_buffer_reader_destroy); printf("%lx", (unsigned long) grpc_byte_buffer_reader_next); + printf("%lx", (unsigned long) grpc_byte_buffer_reader_peek); printf("%lx", (unsigned long) grpc_byte_buffer_reader_readall); printf("%lx", (unsigned long) grpc_raw_byte_buffer_from_reader); printf("%lx", (unsigned long) gpr_log_severity_string); diff --git a/test/cpp/microbenchmarks/bm_byte_buffer.cc b/test/cpp/microbenchmarks/bm_byte_buffer.cc index a359e6f6212..644c27c4873 100644 --- a/test/cpp/microbenchmarks/bm_byte_buffer.cc +++ b/test/cpp/microbenchmarks/bm_byte_buffer.cc @@ -29,9 +29,8 @@ namespace grpc { namespace testing { -auto& force_library_initialization = Library::get(); - static void BM_ByteBuffer_Copy(benchmark::State& state) { + Library::get(); int num_slices = state.range(0); size_t slice_size = state.range(1); std::vector slices; @@ -48,6 +47,74 @@ static void BM_ByteBuffer_Copy(benchmark::State& state) { } BENCHMARK(BM_ByteBuffer_Copy)->Ranges({{1, 64}, {1, 1024 * 1024}}); +static void BM_ByteBufferReader_Next(benchmark::State& state) { + Library::get(); + const int num_slices = state.range(0); + constexpr size_t kSliceSize = 16; + std::vector slices; + for (int i = 0; i < num_slices; ++i) { + std::unique_ptr buf(new char[kSliceSize]); + slices.emplace_back(g_core_codegen_interface->grpc_slice_from_copied_buffer( + buf.get(), kSliceSize)); + } + grpc_byte_buffer* bb = g_core_codegen_interface->grpc_raw_byte_buffer_create( + slices.data(), num_slices); + grpc_byte_buffer_reader reader; + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + while (state.KeepRunning()) { + grpc_slice* slice; + if (GPR_UNLIKELY(!g_core_codegen_interface->grpc_byte_buffer_reader_peek( + &reader, &slice))) { + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + continue; + } + } + + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + g_core_codegen_interface->grpc_byte_buffer_destroy(bb); + for (auto& slice : slices) { + g_core_codegen_interface->grpc_slice_unref(slice); + } +} +BENCHMARK(BM_ByteBufferReader_Next)->Ranges({{64 * 1024, 1024 * 1024}}); + +static void BM_ByteBufferReader_Peek(benchmark::State& state) { + Library::get(); + const int num_slices = state.range(0); + constexpr size_t kSliceSize = 16; + std::vector slices; + for (int i = 0; i < num_slices; ++i) { + std::unique_ptr buf(new char[kSliceSize]); + slices.emplace_back(g_core_codegen_interface->grpc_slice_from_copied_buffer( + buf.get(), kSliceSize)); + } + grpc_byte_buffer* bb = g_core_codegen_interface->grpc_raw_byte_buffer_create( + slices.data(), num_slices); + grpc_byte_buffer_reader reader; + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + while (state.KeepRunning()) { + grpc_slice* slice; + if (GPR_UNLIKELY(!g_core_codegen_interface->grpc_byte_buffer_reader_peek( + &reader, &slice))) { + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + continue; + } + } + + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + g_core_codegen_interface->grpc_byte_buffer_destroy(bb); + for (auto& slice : slices) { + g_core_codegen_interface->grpc_slice_unref(slice); + } +} +BENCHMARK(BM_ByteBufferReader_Peek)->Ranges({{64 * 1024, 1024 * 1024}}); + } // namespace testing } // namespace grpc From 05d8ddfc6e106e8a960e0a9fa54874d9e9298835 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 26 Feb 2019 22:29:21 -0800 Subject: [PATCH 568/814] Support callback-based generic service --- .../impl/codegen/async_generic_service.h | 51 ++++++ include/grpcpp/impl/codegen/server_context.h | 10 +- .../grpcpp/impl/codegen/server_interface.h | 23 +++ include/grpcpp/server.h | 42 ++++- include/grpcpp/server_builder.h | 10 +- src/cpp/server/server_builder.cc | 24 ++- src/cpp/server/server_cc.cc | 160 +++++++++++++----- test/cpp/end2end/hybrid_end2end_test.cc | 122 ++++++++++--- 8 files changed, 357 insertions(+), 85 deletions(-) diff --git a/include/grpcpp/impl/codegen/async_generic_service.h b/include/grpcpp/impl/codegen/async_generic_service.h index 2a0e1b40881..46489b135d7 100644 --- a/include/grpcpp/impl/codegen/async_generic_service.h +++ b/include/grpcpp/impl/codegen/async_generic_service.h @@ -21,6 +21,7 @@ #include #include +#include struct grpc_server; @@ -41,6 +42,12 @@ class GenericServerContext final : public ServerContext { friend class Server; friend class ServerInterface; + void Clear() { + method_.clear(); + host_.clear(); + ServerContext::Clear(); + } + grpc::string method_; grpc::string host_; }; @@ -76,6 +83,50 @@ class AsyncGenericService final { Server* server_; }; +namespace experimental { + +class ServerGenericBidiReactor + : public ServerBidiReactor { + public: + void OnStarted(ServerContext* ctx) final { + OnStarted(static_cast(ctx)); + } + virtual void OnStarted(GenericServerContext* ctx) {} +}; + +} // namespace experimental + +namespace internal { +class UnimplementedGenericBidiReactor + : public experimental::ServerGenericBidiReactor { + public: + void OnDone() override { delete this; } + void OnStarted(GenericServerContext*) override { + this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); + } +}; +} // namespace internal + +namespace experimental { +class CallbackGenericService { + public: + CallbackGenericService() {} + virtual ~CallbackGenericService() {} + virtual ServerGenericBidiReactor* CreateReactor() { + return new internal::UnimplementedGenericBidiReactor; + } + + private: + friend class ::grpc::Server; + + internal::CallbackBidiHandler* Handler() { + return new internal::CallbackBidiHandler( + [this] { return CreateReactor(); }); + } + + Server* server_{nullptr}; +}; +} // namespace experimental } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index affe61b547b..fb82186d69e 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -43,6 +43,10 @@ struct census_context; namespace grpc { class ClientContext; +class GenericServerContext; +class CompletionQueue; +class Server; +class ServerInterface; template class ServerAsyncReader; template @@ -55,6 +59,7 @@ template class ServerReader; template class ServerWriter; + namespace internal { template class ServerReaderWriterBody; @@ -82,10 +87,6 @@ class Call; class ServerReactor; } // namespace internal -class CompletionQueue; -class Server; -class ServerInterface; - namespace testing { class InteropServerContextInspector; class ServerContextTestSpouse; @@ -302,6 +303,7 @@ class ServerContext { template friend class internal::ErrorMethodHandler; friend class ::grpc::ClientContext; + friend class ::grpc::GenericServerContext; /// Prevent copying. ServerContext(const ServerContext&); diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h index 890a5650d02..f599e037fd5 100644 --- a/include/grpcpp/impl/codegen/server_interface.h +++ b/include/grpcpp/impl/codegen/server_interface.h @@ -47,6 +47,10 @@ namespace internal { class ServerAsyncStreamingInterface; } // namespace internal +namespace experimental { +class CallbackGenericService; +} // namespace experimental + class ServerInterface : public internal::CallHook { public: virtual ~ServerInterface() {} @@ -115,6 +119,25 @@ class ServerInterface : public internal::CallHook { /// service. The service must exist for the lifetime of the Server instance. virtual void RegisterAsyncGenericService(AsyncGenericService* service) = 0; + /// NOTE: class experimental_registration_interface is not part of the public + /// API of this class + /// TODO(vjpai): Move these contents to public API when no longer experimental + class experimental_registration_interface { + public: + virtual ~experimental_registration_interface() {} + /// May not be abstract since this is a post-1.0 API addition + virtual void RegisterCallbackGenericService( + experimental::CallbackGenericService* service) {} + }; + + /// NOTE: The function experimental_registration() is not stable public API. + /// It is a view to the experimental components of this class. It may be + /// changed or removed at any time. May not be abstract since this is a + /// post-1.0 API addition + virtual experimental_registration_interface* experimental_registration() { + return nullptr; + } + /// Tries to bind \a server to the given \a addr. /// /// It can be invoked multiple times. diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 248f20452a5..21c908aebdb 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -202,6 +202,8 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { friend class ServerInitializer; class SyncRequest; + class CallbackRequestBase; + template class CallbackRequest; class UnimplementedAsyncRequest; class UnimplementedAsyncResponse; @@ -216,6 +218,34 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { /// service. The service must exist for the lifetime of the Server instance. void RegisterAsyncGenericService(AsyncGenericService* service) override; + /// NOTE: class experimental_registration_type is not part of the public API + /// of this class + /// TODO(vjpai): Move these contents to the public API of Server when + /// they are no longer experimental + class experimental_registration_type final + : public experimental_registration_interface { + public: + explicit experimental_registration_type(Server* server) : server_(server) {} + void RegisterCallbackGenericService( + experimental::CallbackGenericService* service) override { + server_->RegisterCallbackGenericService(service); + } + + private: + Server* server_; + }; + + /// TODO(vjpai): Mark this override when experimental type above is deleted + void RegisterCallbackGenericService( + experimental::CallbackGenericService* service); + + /// NOTE: The function experimental_registration() is not stable public API. + /// It is a view to the experimental components of this class. It may be + /// changed or removed at any time. + experimental_registration_interface* experimental_registration() override { + return &experimental_registration_; + } + void PerformOpsOnCall(internal::CallOpSetInterface* ops, internal::Call* call) override; @@ -257,7 +287,11 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { std::vector callback_unmatched_reqs_count_; // List of callback requests to start when server actually starts. - std::list callback_reqs_to_start_; + std::list callback_reqs_to_start_; + + // For registering experimental callback generic service; remove when that + // method longer experimental + experimental_registration_type experimental_registration_{this}; // Server status std::mutex mu_; @@ -281,7 +315,8 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { std::shared_ptr global_callbacks_; std::vector services_; - bool has_generic_service_; + bool has_async_generic_service_{false}; + bool has_callback_generic_service_{false}; // Pointer to the wrapped grpc_server. grpc_server* server_; @@ -294,6 +329,9 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { // A special handler for resource exhausted in sync case std::unique_ptr resource_exhausted_handler_; + // Handler for callback generic service, if any + std::unique_ptr generic_handler_; + // callback_cq_ references the callbackable completion queue associated // with this server (if any). It is set on the first call to CallbackCQ(). // It is _not owned_ by the server; ownership belongs with its internal diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 028b8cffaa7..498e5b7bb31 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -49,6 +49,10 @@ namespace testing { class ServerBuilderPluginTest; } // namespace testing +namespace experimental { +class CallbackGenericService; +} // namespace experimental + /// A builder class for the creation and startup of \a grpc::Server instances. class ServerBuilder { public: @@ -227,6 +231,9 @@ class ServerBuilder { builder_->interceptor_creators_ = std::move(interceptor_creators); } + ServerBuilder& RegisterCallbackGenericService( + experimental::CallbackGenericService* service); + private: ServerBuilder* builder_; }; @@ -311,7 +318,8 @@ class ServerBuilder { std::shared_ptr creds_; std::vector> plugins_; grpc_resource_quota* resource_quota_; - AsyncGenericService* generic_service_; + AsyncGenericService* generic_service_{nullptr}; + experimental::CallbackGenericService* callback_generic_service_{nullptr}; struct { bool is_set; grpc_compression_level level; diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index b7fad558abb..cd0e516d9a3 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -44,8 +44,7 @@ ServerBuilder::ServerBuilder() : max_receive_message_size_(INT_MIN), max_send_message_size_(INT_MIN), sync_server_settings_(SyncServerSettings()), - resource_quota_(nullptr), - generic_service_(nullptr) { + resource_quota_(nullptr) { gpr_once_init(&once_init_plugin_list, do_plugin_list_init); for (auto it = g_plugin_factory_list->begin(); it != g_plugin_factory_list->end(); it++) { @@ -91,9 +90,9 @@ ServerBuilder& ServerBuilder::RegisterService(const grpc::string& addr, ServerBuilder& ServerBuilder::RegisterAsyncGenericService( AsyncGenericService* service) { - if (generic_service_) { + if (generic_service_ || callback_generic_service_) { gpr_log(GPR_ERROR, - "Adding multiple AsyncGenericService is unsupported for now. " + "Adding multiple generic services is unsupported for now. " "Dropping the service %p", (void*)service); } else { @@ -102,6 +101,19 @@ ServerBuilder& ServerBuilder::RegisterAsyncGenericService( return *this; } +ServerBuilder& ServerBuilder::experimental_type::RegisterCallbackGenericService( + experimental::CallbackGenericService* service) { + if (builder_->generic_service_ || builder_->callback_generic_service_) { + gpr_log(GPR_ERROR, + "Adding multiple generic services is unsupported for now. " + "Dropping the service %p", + (void*)service); + } else { + builder_->callback_generic_service_ = service; + } + return *builder_; +} + ServerBuilder& ServerBuilder::SetOption( std::unique_ptr option) { options_.push_back(std::move(option)); @@ -310,7 +322,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { has_frequently_polled_cqs = true; } - if (has_callback_methods) { + if (has_callback_methods || callback_generic_service_ != nullptr) { auto* cq = server->CallbackCQ(); grpc_server_register_completion_queue(server->server_, cq->cq(), nullptr); } @@ -344,6 +356,8 @@ std::unique_ptr ServerBuilder::BuildAndStart() { if (generic_service_) { server->RegisterAsyncGenericService(generic_service_); + } else if (callback_generic_service_) { + server->RegisterCallbackGenericService(callback_generic_service_); } else { for (auto it = services_.begin(); it != services_.end(); ++it) { if ((*it)->service->has_generic_methods()) { diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 7eb0f2372b6..4d5c8179fce 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -348,8 +349,18 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { grpc_completion_queue* cq_; }; -class Server::CallbackRequest final : public internal::CompletionQueueTag { +class Server::CallbackRequestBase : public internal::CompletionQueueTag { public: + virtual ~CallbackRequestBase() {} + virtual bool Request() = 0; +}; + +template +class Server::CallbackRequest final : public Server::CallbackRequestBase { + public: + static_assert(std::is_base_of::value, + "ServerContextType must be derived from ServerContext"); + CallbackRequest(Server* server, size_t method_idx, internal::RpcServiceMethod* method, void* method_tag) : server_(server), @@ -357,8 +368,9 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { method_(method), method_tag_(method_tag), has_request_payload_( - method->method_type() == internal::RpcMethod::NORMAL_RPC || - method->method_type() == internal::RpcMethod::SERVER_STREAMING), + method_ != nullptr && + (method->method_type() == internal::RpcMethod::NORMAL_RPC || + method->method_type() == internal::RpcMethod::SERVER_STREAMING)), cq_(server->CallbackCQ()), tag_(this) { server_->callback_reqs_outstanding_++; @@ -376,7 +388,7 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { } } - bool Request() { + bool Request() override { if (method_tag_) { if (GRPC_CALL_OK != grpc_server_request_registered_call( @@ -400,12 +412,18 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { return true; } - bool FinalizeResult(void** tag, bool* status) override { return false; } + // Needs specialization to account for different processing of metadata + // in generic API + bool FinalizeResult(void** tag, bool* status) override; private: + // method_name needs to be specialized between named method and generic + const char* method_name() const; + class CallbackCallTag : public grpc_experimental_completion_queue_functor { public: - CallbackCallTag(Server::CallbackRequest* req) : req_(req) { + CallbackCallTag(Server::CallbackRequest* req) + : req_(req) { functor_run = &CallbackCallTag::StaticRun; } @@ -415,7 +433,7 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { void force_run(bool ok) { Run(ok); } private: - Server::CallbackRequest* req_; + Server::CallbackRequest* req_; internal::Call* call_; static void StaticRun(grpc_experimental_completion_queue_functor* cb, @@ -446,8 +464,9 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { if (count == 0 || (count < SOFT_MINIMUM_SPARE_CALLBACK_REQS_PER_METHOD && req_->server_->callback_reqs_outstanding_ < SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING)) { - auto* new_req = new CallbackRequest(req_->server_, req_->method_index_, - req_->method_, req_->method_tag_); + auto* new_req = new CallbackRequest( + req_->server_, req_->method_index_, req_->method_, + req_->method_tag_); if (!new_req->Request()) { // The server must have just decided to shutdown. gpr_atm_no_barrier_fetch_add( @@ -467,12 +486,14 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { // Create a C++ Call to control the underlying core call call_ = new (grpc_call_arena_alloc(req_->call_, sizeof(internal::Call))) - internal::Call( - req_->call_, req_->server_, req_->cq_, - req_->server_->max_receive_message_size(), - req_->ctx_.set_server_rpc_info( - req_->method_->name(), req_->method_->method_type(), - req_->server_->interceptor_creators_)); + internal::Call(req_->call_, req_->server_, req_->cq_, + req_->server_->max_receive_message_size(), + req_->ctx_.set_server_rpc_info( + req_->method_name(), + (req_->method_ != nullptr) + ? req_->method_->method_type() + : internal::RpcMethod::BIDI_STREAMING, + req_->server_->interceptor_creators_)); req_->interceptor_methods_.SetCall(call_); req_->interceptor_methods_.SetReverse(); @@ -501,31 +522,32 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { } } void ContinueRunAfterInterception() { - req_->method_->handler()->RunHandler( - internal::MethodHandler::HandlerParameter( - call_, &req_->ctx_, req_->request_, req_->request_status_, - [this] { - // Recycle this request if there aren't too many outstanding. - // Note that we don't have to worry about a case where there - // are no requests waiting to match for this method since that - // is already taken care of when binding a request to a call. - // TODO(vjpai): Also don't recycle this request if the dynamic - // load no longer justifies it. Consider measuring - // dynamic load and setting a target accordingly. - if (req_->server_->callback_reqs_outstanding_ < - SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING) { - req_->Clear(); - req_->Setup(); - } else { - // We can free up this request because there are too many - delete req_; - return; - } - if (!req_->Request()) { - // The server must have just decided to shutdown. - delete req_; - } - })); + auto* handler = (req_->method_ != nullptr) + ? req_->method_->handler() + : req_->server_->generic_handler_.get(); + handler->RunHandler(internal::MethodHandler::HandlerParameter( + call_, &req_->ctx_, req_->request_, req_->request_status_, [this] { + // Recycle this request if there aren't too many outstanding. + // Note that we don't have to worry about a case where there + // are no requests waiting to match for this method since that + // is already taken care of when binding a request to a call. + // TODO(vjpai): Also don't recycle this request if the dynamic + // load no longer justifies it. Consider measuring + // dynamic load and setting a target accordingly. + if (req_->server_->callback_reqs_outstanding_ < + SOFT_MAXIMUM_CALLBACK_REQS_OUTSTANDING) { + req_->Clear(); + req_->Setup(); + } else { + // We can free up this request because there are too many + delete req_; + return; + } + if (!req_->Request()) { + // The server must have just decided to shutdown. + delete req_; + } + })); } }; @@ -553,7 +575,7 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { } Server* const server_; - size_t method_index_; + const size_t method_index_; internal::RpcServiceMethod* const method_; void* const method_tag_; const bool has_request_payload_; @@ -566,10 +588,39 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag { grpc_metadata_array request_metadata_; CompletionQueue* cq_; CallbackCallTag tag_; - ServerContext ctx_; + ServerContextType ctx_; internal::InterceptorBatchMethodsImpl interceptor_methods_; }; +template <> +bool Server::CallbackRequest::FinalizeResult(void** tag, + bool* status) { + return false; +} + +template <> +bool Server::CallbackRequest::FinalizeResult( + void** tag, bool* status) { + if (*status) { + // TODO(yangg) remove the copy here + ctx_.method_ = StringFromCopiedSlice(call_details_->method); + ctx_.host_ = StringFromCopiedSlice(call_details_->host); + } + grpc_slice_unref(call_details_->method); + grpc_slice_unref(call_details_->host); + return false; +} + +template <> +const char* Server::CallbackRequest::method_name() const { + return method_->name(); +} + +template <> +const char* Server::CallbackRequest::method_name() const { + return ctx_.method().c_str(); +} + // Implementation of ThreadManager. Each instance of SyncRequestThreadManager // manages a pool of threads that poll for incoming Sync RPCs and call the // appropriate RPC handlers @@ -708,7 +759,6 @@ Server::Server( started_(false), shutdown_(false), shutdown_notified_(false), - has_generic_service_(false), server_(nullptr), server_initializer_(new ServerInitializer(this)), health_check_service_disabled_(false) { @@ -865,7 +915,7 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { auto method_index = callback_unmatched_reqs_count_.size() - 1; // TODO(vjpai): Register these dynamically based on need for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) { - callback_reqs_to_start_.push_back(new CallbackRequest( + callback_reqs_to_start_.push_back(new CallbackRequest( this, method_index, method, method_registration_tag)); } // Enqueue it so that it will be Request'ed later after all request @@ -891,7 +941,25 @@ void Server::RegisterAsyncGenericService(AsyncGenericService* service) { GPR_ASSERT(service->server_ == nullptr && "Can only register an async generic service against one server."); service->server_ = this; - has_generic_service_ = true; + has_async_generic_service_ = true; +} + +void Server::RegisterCallbackGenericService( + experimental::CallbackGenericService* service) { + GPR_ASSERT( + service->server_ == nullptr && + "Can only register a callback generic service against one server."); + service->server_ = this; + has_callback_generic_service_ = true; + generic_handler_.reset(service->Handler()); + + callback_unmatched_reqs_count_.push_back(0); + auto method_index = callback_unmatched_reqs_count_.size() - 1; + // TODO(vjpai): Register these dynamically based on need + for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) { + callback_reqs_to_start_.push_back(new CallbackRequest( + this, method_index, nullptr, nullptr)); + } } int Server::AddListeningPort(const grpc::string& addr, @@ -932,7 +1000,7 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { grpc_server_start(server_); - if (!has_generic_service_) { + if (!has_async_generic_service_ && !has_callback_generic_service_) { for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { (*it)->AddUnknownSyncMethod(); } diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index 18bb1ff4b96..b0dd901cf11 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -28,6 +28,7 @@ #include #include +#include "src/core/lib/iomgr/iomgr.h" #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" @@ -39,7 +40,6 @@ namespace grpc { namespace testing { - namespace { void* tag(int i) { return (void*)static_cast(i); } @@ -225,13 +225,23 @@ class TestServiceImplDupPkg } }; -class HybridEnd2endTest : public ::testing::Test { +class HybridEnd2endTest : public ::testing::TestWithParam { protected: HybridEnd2endTest() {} - void SetUpServer(::grpc::Service* service1, ::grpc::Service* service2, - AsyncGenericService* generic_service, - int max_message_size = 0) { + void SetUp() override { + inproc_ = (::testing::UnitTest::GetInstance() + ->current_test_info() + ->value_param() != nullptr) + ? GetParam() + : false; + } + + bool SetUpServer( + ::grpc::Service* service1, ::grpc::Service* service2, + AsyncGenericService* generic_service, + experimental::CallbackGenericService* callback_generic_service, + int max_message_size = 0) { int port = grpc_pick_unused_port_or_die(); server_address_ << "localhost:" << port; @@ -249,6 +259,10 @@ class HybridEnd2endTest : public ::testing::Test { if (generic_service) { builder.RegisterAsyncGenericService(generic_service); } + if (callback_generic_service) { + builder.experimental().RegisterCallbackGenericService( + callback_generic_service); + } if (max_message_size != 0) { builder.SetMaxMessageSize(max_message_size); @@ -259,6 +273,11 @@ class HybridEnd2endTest : public ::testing::Test { cqs_.push_back(builder.AddCompletionQueue(false)); } server_ = builder.BuildAndStart(); + + // If there is a generic callback service, this setup is only successful if + // we have an iomgr that can run in the background or are inprocess + return !callback_generic_service || grpc_iomgr_run_in_background() || + inproc_; } void TearDown() override { @@ -276,7 +295,9 @@ class HybridEnd2endTest : public ::testing::Test { void ResetStub() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + inproc_ ? server_->InProcessChannel(ChannelArguments()) + : CreateChannel(server_address_.str(), + InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -411,12 +432,13 @@ class HybridEnd2endTest : public ::testing::Test { std::unique_ptr stub_; std::unique_ptr server_; std::ostringstream server_address_; + bool inproc_; }; TEST_F(HybridEnd2endTest, AsyncEcho) { typedef EchoTestService::WithAsyncMethod_Echo SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread echo_handler_thread(HandleEcho, &service, cqs_[0].get(), false); @@ -427,7 +449,7 @@ TEST_F(HybridEnd2endTest, AsyncEcho) { TEST_F(HybridEnd2endTest, RawEcho) { typedef EchoTestService::WithRawMethod_Echo SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread echo_handler_thread(HandleRawEcho, &service, cqs_[0].get(), false); @@ -438,7 +460,7 @@ TEST_F(HybridEnd2endTest, RawEcho) { TEST_F(HybridEnd2endTest, RawRequestStream) { typedef EchoTestService::WithRawMethod_RequestStream SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread request_stream_handler_thread(HandleRawClientStreaming, &service, cqs_[0].get()); @@ -451,7 +473,7 @@ TEST_F(HybridEnd2endTest, AsyncEchoRawRequestStream) { EchoTestService::WithAsyncMethod_Echo> SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread echo_handler_thread(HandleEcho, &service, cqs_[0].get(), false); @@ -468,7 +490,7 @@ TEST_F(HybridEnd2endTest, GenericEchoRawRequestStream) { SType; SType service; AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service); + SetUpServer(&service, nullptr, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -484,7 +506,7 @@ TEST_F(HybridEnd2endTest, AsyncEchoRequestStream) { EchoTestService::WithAsyncMethod_Echo> SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread echo_handler_thread(HandleEcho, &service, cqs_[0].get(), false); @@ -500,7 +522,7 @@ TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream) { EchoTestService::WithAsyncMethod_ResponseStream> SType; SType service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -518,7 +540,7 @@ TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_SyncDupService) { SType; SType service; TestServiceImplDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr); + SetUpServer(&service, &dup_service, nullptr, nullptr); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -557,7 +579,7 @@ TEST_F(HybridEnd2endTest, SType; SType service; StreamedUnaryDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, 8192); + SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -595,7 +617,7 @@ TEST_F(HybridEnd2endTest, SType; SType service; FullyStreamedUnaryDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, 8192); + SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -636,7 +658,7 @@ TEST_F(HybridEnd2endTest, SType; SType service; SplitResponseStreamDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, 8192); + SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -676,7 +698,7 @@ TEST_F(HybridEnd2endTest, SType; SType service; FullySplitStreamedDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, 8192); + SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -728,7 +750,7 @@ TEST_F(HybridEnd2endTest, SType; SType service; FullyStreamedDupPkg dup_service; - SetUpServer(&service, &dup_service, nullptr, 8192); + SetUpServer(&service, &dup_service, nullptr, nullptr, 8192); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -748,7 +770,7 @@ TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_AsyncDupService) { SType; SType service; duplicate::EchoTestService::AsyncService dup_service; - SetUpServer(&service, &dup_service, nullptr); + SetUpServer(&service, &dup_service, nullptr, nullptr); ResetStub(); std::thread response_stream_handler_thread(HandleServerStreaming, &service, cqs_[0].get()); @@ -767,7 +789,7 @@ TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_AsyncDupService) { TEST_F(HybridEnd2endTest, GenericEcho) { EchoTestService::WithGenericMethod_Echo service; AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service); + SetUpServer(&service, nullptr, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -775,13 +797,56 @@ TEST_F(HybridEnd2endTest, GenericEcho) { generic_handler_thread.join(); } +TEST_P(HybridEnd2endTest, CallbackGenericEcho) { + EchoTestService::WithGenericMethod_Echo service; + class GenericEchoService : public experimental::CallbackGenericService { + private: + experimental::ServerGenericBidiReactor* CreateReactor() override { + class Reactor : public experimental::ServerGenericBidiReactor { + private: + void OnStarted(GenericServerContext* ctx) override { + ctx_ = ctx; + EXPECT_EQ(ctx->method(), "/grpc.testing.EchoTestService/Echo"); + StartRead(&request_); + } + void OnDone() override { delete this; } + void OnReadDone(bool ok) override { + if (!ok) { + EXPECT_EQ(reads_complete_, 1); + } else { + EXPECT_EQ(reads_complete_++, 0); + response_ = request_; + StartWrite(&response_); + StartRead(&request_); + } + } + void OnWriteDone(bool ok) override { + Finish(ok ? Status::OK + : Status(StatusCode::UNKNOWN, "Unexpected failure")); + } + GenericServerContext* ctx_; + ByteBuffer request_; + ByteBuffer response_; + std::atomic_int reads_complete_{0}; + }; + return new Reactor; + } + } generic_service; + + if (!SetUpServer(&service, nullptr, nullptr, &generic_service)) { + return; + } + ResetStub(); + TestAllMethods(); +} + TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream) { typedef EchoTestService::WithAsyncMethod_RequestStream< EchoTestService::WithGenericMethod_Echo> SType; SType service; AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service); + SetUpServer(&service, nullptr, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -800,7 +865,7 @@ TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_SyncDupService) { SType service; AsyncGenericService generic_service; TestServiceImplDupPkg dup_service; - SetUpServer(&service, &dup_service, &generic_service); + SetUpServer(&service, &dup_service, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -820,7 +885,7 @@ TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_AsyncDupService) { SType service; AsyncGenericService generic_service; duplicate::EchoTestService::AsyncService dup_service; - SetUpServer(&service, &dup_service, &generic_service); + SetUpServer(&service, &dup_service, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -843,7 +908,7 @@ TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStreamResponseStream) { SType; SType service; AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service); + SetUpServer(&service, nullptr, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -864,7 +929,7 @@ TEST_F(HybridEnd2endTest, GenericEchoRequestStreamAsyncResponseStream) { SType; SType service; AsyncGenericService generic_service; - SetUpServer(&service, nullptr, &generic_service); + SetUpServer(&service, nullptr, &generic_service, nullptr); ResetStub(); std::thread generic_handler_thread(HandleGenericCall, &generic_service, cqs_[0].get()); @@ -885,10 +950,13 @@ TEST_F(HybridEnd2endTest, GenericMethodWithoutGenericService) { EchoTestService::WithGenericMethod_Echo< EchoTestService::WithAsyncMethod_ResponseStream>> service; - SetUpServer(&service, nullptr, nullptr); + SetUpServer(&service, nullptr, nullptr, nullptr); EXPECT_EQ(nullptr, server_.get()); } +INSTANTIATE_TEST_CASE_P(HybridEnd2endTest, HybridEnd2endTest, + ::testing::Bool()); + } // namespace } // namespace testing } // namespace grpc From ede3e61acb419057259e740141ad3d2ac606553a Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Mon, 4 Mar 2019 13:25:31 -0800 Subject: [PATCH 569/814] Try to fix FlakyNetworkTest.ServerRestartKeepaliveDisabled flake Set channel arg for max connect time. --- test/cpp/end2end/flaky_network_test.cc | 8 +++++++- tools/internal_ci/linux/grpc_flaky_network_in_docker.sh | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/test/cpp/end2end/flaky_network_test.cc b/test/cpp/end2end/flaky_network_test.cc index d0c95740959..63a6897f931 100644 --- a/test/cpp/end2end/flaky_network_test.cc +++ b/test/cpp/end2end/flaky_network_test.cc @@ -345,9 +345,12 @@ TEST_F(FlakyNetworkTest, ServerUnreachableWithKeepalive) { args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); + // max time for a connection attempt + args.SetInt(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); + // max time between reconnect attempts args.SetInt(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); + gpr_log(GPR_DEBUG, "FlakyNetworkTest.ServerUnreachableWithKeepalive start"); auto channel = BuildChannel("pick_first", args); auto stub = BuildStub(channel); // Channel should be in READY state after we send an RPC @@ -366,15 +369,18 @@ TEST_F(FlakyNetworkTest, ServerUnreachableWithKeepalive) { }); // break network connectivity + gpr_log(GPR_DEBUG, "Adding iptables rule to drop packets"); DropPackets(); std::this_thread::sleep_for(std::chrono::milliseconds(10000)); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); // bring network interface back up RestoreNetwork(); + gpr_log(GPR_DEBUG, "Removed iptables rule to drop packets"); EXPECT_TRUE(WaitForChannelReady(channel.get())); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); shutdown.store(true); sender.join(); + gpr_log(GPR_DEBUG, "FlakyNetworkTest.ServerUnreachableWithKeepalive end"); } // diff --git a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh index eb6216c62c3..7fc8f146727 100755 --- a/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh +++ b/tools/internal_ci/linux/grpc_flaky_network_in_docker.sh @@ -28,4 +28,4 @@ cd /var/local/git/grpc/test/cpp/end2end # iptables is used to drop traffic between client and server apt-get install -y iptables -bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all :flaky_network_test --test_env=GRPC_VERBOSITY=debug --test_env=GRPC_TRACE=channel,client_channel,call_error,connectivity_state +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=all :flaky_network_test --test_env=GRPC_VERBOSITY=debug --test_env=GRPC_TRACE=channel,client_channel,call_error,connectivity_state,tcp From bc81010f10e31af51f2a790f1adf2500d4aba0ad Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 4 Mar 2019 12:12:37 -0800 Subject: [PATCH 570/814] Strip Python wheel binary --- .../artifacts/build_package_python.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh index 29801a5b867..193d75db62a 100755 --- a/tools/run_tests/artifacts/build_package_python.sh +++ b/tools/run_tests/artifacts/build_package_python.sh @@ -23,6 +23,24 @@ mkdir -p artifacts/ # and we only collect them here to deliver them to the distribtest phase. cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/python_*/* artifacts/ || true +strip_binary_wheel() { + WHEEL_PATH="$1" + TEMP_WHEEL_DIR=$(mktemp -d) + wheel unpack "$WHEEL_PATH" -d "$TEMP_WHEEL_DIR" + find "$TEMP_WHEEL_DIR" -name "_protoc_compiler*.so" -exec strip --strip-debug {} ";" + find "$TEMP_WHEEL_DIR" -name "cygrpc*.so" -exec strip --strip-debug {} ";" + + WHEEL_FILE=$(basename "$WHEEL_PATH") + DISTRIBUTION_NAME=$(basename "$WHEEL_PATH" | cut -d '-' -f 1) + VERSION=$(basename "$WHEEL_PATH" | cut -d '-' -f 2) + wheel pack "$TEMP_WHEEL_DIR/$DISTRIBUTION_NAME-$VERSION" -d "$TEMP_WHEEL_DIR" + mv "$TEMP_WHEEL_DIR/$WHEEL_FILE" "$WHEEL_PATH" +} + +for wheel in artifacts/*.whl; do + strip_binary_wheel "$wheel" +done + # TODO: all the artifact builder configurations generate a grpcio-VERSION.tar.gz # source distribution package, and only one of them will end up # in the artifacts/ directory. They should be all equivalent though. From 397bdd6b7bf96d0ecbb8642579df15c943b18fe0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 4 Mar 2019 13:55:12 -0800 Subject: [PATCH 571/814] Fix a bug that was exposed but unrelated... --- test/cpp/end2end/test_service_impl.cc | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index baebdbc8091..159ea33c2bc 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -125,6 +125,19 @@ void ServerTryCancelNonblocking(ServerContext* context) { gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); } +void LoopUntilCancelled(Alarm* alarm, ServerContext* context, + experimental::ServerCallbackRpcController* controller) { + if (!context->IsCancelled()) { + alarm->experimental().Set( + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_micros(1000, GPR_TIMESPAN)), + [alarm, context, controller](bool) { + LoopUntilCancelled(alarm, context, controller); + }); + } else { + controller->Finish(Status::CANCELLED); + } +} } // namespace Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, @@ -290,18 +303,7 @@ void CallbackTestServiceImpl::EchoNonDelayed( gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); // Now wait until it's really canceled - std::function recurrence = [this, context, controller, - &recurrence](bool) { - if (!context->IsCancelled()) { - alarm_.experimental().Set( - gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(1000, GPR_TIMESPAN)), - recurrence); - } else { - controller->Finish(Status::CANCELLED); - } - }; - recurrence(true); + LoopUntilCancelled(&alarm_, context, controller); return; } From a04b0646de2c80f76f52af443d31b369d26e1452 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 4 Mar 2019 14:38:02 -0800 Subject: [PATCH 572/814] Don't use a separate call context for subchannel calls. --- CMakeLists.txt | 2 + Makefile | 2 + gRPC-Core.podspec | 1 + grpc.gyp | 2 + .../filters/client_channel/client_channel.cc | 28 +- .../ext/filters/client_channel/lb_policy.h | 5 - .../grpclb/client_load_reporting_filter.cc | 61 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 47 +- .../lb_policy/grpclb/grpclb_client_stats.h | 6 + .../client_channel/lb_policy/xds/xds.cc | 10 +- src/core/lib/channel/context.h | 3 - .../security/transport/client_auth_filter.cc | 70 +- src/core/lib/transport/metadata.cc | 99 ++- test/core/end2end/end2end_nosec_tests.cc | 8 + test/core/end2end/end2end_tests.cc | 8 + test/core/end2end/gen_build_yaml.py | 1 + test/core/end2end/generate_tests.bzl | 1 + test/core/end2end/tests/filter_context.cc | 318 +++++++ test/core/transport/metadata_test.cc | 23 + test/cpp/end2end/grpclb_end2end_test.cc | 3 + .../generated/sources_and_headers.json | 2 + tools/run_tests/generated/tests.json | 789 ++++++++++++++++++ 22 files changed, 1327 insertions(+), 162 deletions(-) create mode 100644 test/core/end2end/tests/filter_context.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 1bab5e6cba2..939e83c481f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5616,6 +5616,7 @@ add_library(end2end_tests test/core/end2end/tests/empty_batch.cc test/core/end2end/tests/filter_call_init_fails.cc test/core/end2end/tests/filter_causes_close.cc + test/core/end2end/tests/filter_context.cc test/core/end2end/tests/filter_latency.cc test/core/end2end/tests/filter_status_code.cc test/core/end2end/tests/graceful_server_shutdown.cc @@ -5739,6 +5740,7 @@ add_library(end2end_nosec_tests test/core/end2end/tests/empty_batch.cc test/core/end2end/tests/filter_call_init_fails.cc test/core/end2end/tests/filter_causes_close.cc + test/core/end2end/tests/filter_context.cc test/core/end2end/tests/filter_latency.cc test/core/end2end/tests/filter_status_code.cc test/core/end2end/tests/graceful_server_shutdown.cc diff --git a/Makefile b/Makefile index a2789e40431..3c890797431 100644 --- a/Makefile +++ b/Makefile @@ -10410,6 +10410,7 @@ LIBEND2END_TESTS_SRC = \ test/core/end2end/tests/empty_batch.cc \ test/core/end2end/tests/filter_call_init_fails.cc \ test/core/end2end/tests/filter_causes_close.cc \ + test/core/end2end/tests/filter_context.cc \ test/core/end2end/tests/filter_latency.cc \ test/core/end2end/tests/filter_status_code.cc \ test/core/end2end/tests/graceful_server_shutdown.cc \ @@ -10526,6 +10527,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \ test/core/end2end/tests/empty_batch.cc \ test/core/end2end/tests/filter_call_init_fails.cc \ test/core/end2end/tests/filter_causes_close.cc \ + test/core/end2end/tests/filter_context.cc \ test/core/end2end/tests/filter_latency.cc \ test/core/end2end/tests/filter_status_code.cc \ test/core/end2end/tests/graceful_server_shutdown.cc \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 318092f758b..2e54b9d7847 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1293,6 +1293,7 @@ Pod::Spec.new do |s| 'test/core/end2end/tests/empty_batch.cc', 'test/core/end2end/tests/filter_call_init_fails.cc', 'test/core/end2end/tests/filter_causes_close.cc', + 'test/core/end2end/tests/filter_context.cc', 'test/core/end2end/tests/filter_latency.cc', 'test/core/end2end/tests/filter_status_code.cc', 'test/core/end2end/tests/graceful_server_shutdown.cc', diff --git a/grpc.gyp b/grpc.gyp index ca9d017dbbe..53e891b28dc 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -2710,6 +2710,7 @@ 'test/core/end2end/tests/empty_batch.cc', 'test/core/end2end/tests/filter_call_init_fails.cc', 'test/core/end2end/tests/filter_causes_close.cc', + 'test/core/end2end/tests/filter_context.cc', 'test/core/end2end/tests/filter_latency.cc', 'test/core/end2end/tests/filter_status_code.cc', 'test/core/end2end/tests/graceful_server_shutdown.cc', @@ -2799,6 +2800,7 @@ 'test/core/end2end/tests/empty_batch.cc', 'test/core/end2end/tests/filter_call_init_fails.cc', 'test/core/end2end/tests/filter_causes_close.cc', + 'test/core/end2end/tests/filter_context.cc', 'test/core/end2end/tests/filter_latency.cc', 'test/core/end2end/tests/filter_status_code.cc', 'test/core/end2end/tests/graceful_server_shutdown.cc', diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 3fb32f7e823..3f87438b13b 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -694,6 +694,7 @@ struct call_data { arena(args.arena), owning_call(args.call_stack), call_combiner(args.call_combiner), + call_context(args.context), pending_send_initial_metadata(false), pending_send_message(false), pending_send_trailing_metadata(false), @@ -707,12 +708,6 @@ struct call_data { for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches); ++i) { GPR_ASSERT(pending_batches[i].batch == nullptr); } - for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) { - if (pick.pick.subchannel_call_context[i].destroy != nullptr) { - pick.pick.subchannel_call_context[i].destroy( - pick.pick.subchannel_call_context[i].value); - } - } } // State for handling deadlines. @@ -729,6 +724,7 @@ struct call_data { gpr_arena* arena; grpc_call_stack* owning_call; grpc_call_combiner* call_combiner; + grpc_call_context_element* call_context; grpc_core::RefCountedPtr retry_throttle_data; grpc_core::RefCountedPtr method_params; @@ -2429,14 +2425,16 @@ static void create_subchannel_call(grpc_call_element* elem) { const size_t parent_data_size = calld->enable_retries ? sizeof(subchannel_call_retry_state) : 0; const grpc_core::ConnectedSubchannel::CallArgs call_args = { - calld->pollent, // pollent - calld->path, // path - calld->call_start_time, // start_time - calld->deadline, // deadline - calld->arena, // arena - calld->pick.pick.subchannel_call_context, // context - calld->call_combiner, // call_combiner - parent_data_size // parent_data_size + calld->pollent, // pollent + calld->path, // path + calld->call_start_time, // start_time + calld->deadline, // deadline + calld->arena, // arena + // TODO(roth): When we implement hedging support, we will probably + // need to use a separate call context for each subchannel call. + calld->call_context, // context + calld->call_combiner, // call_combiner + parent_data_size // parent_data_size }; grpc_error* error = GRPC_ERROR_NONE; calld->subchannel_call = @@ -2451,7 +2449,7 @@ static void create_subchannel_call(grpc_call_element* elem) { } else { if (parent_data_size > 0) { new (calld->subchannel_call->GetParentData()) - subchannel_call_retry_state(calld->pick.pick.subchannel_call_context); + subchannel_call_retry_state(calld->call_context); } pending_batches_resume(elem); } diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 1bb8c5e96c0..7a876966524 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -73,11 +73,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Will be set to the selected subchannel, or nullptr on failure or when /// the LB policy decides to drop the call. RefCountedPtr connected_subchannel; - /// Will be populated with context to pass to the subchannel call, if - /// needed. - // TODO(roth): Remove this from the API, especially since it's not - // working properly anyway (see https://github.com/grpc/grpc/issues/15927). - grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {}; }; /// A picker is the object used to actual perform picks. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc index 399bb452f45..3bb31fe3b08 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc @@ -37,17 +37,6 @@ static void destroy_channel_elem(grpc_channel_element* elem) {} namespace { struct call_data { - call_data(const grpc_call_element_args& args) { - if (args.context[GRPC_GRPCLB_CLIENT_STATS].value != nullptr) { - // Get stats object from context and take a ref. - client_stats = static_cast( - args.context[GRPC_GRPCLB_CLIENT_STATS].value) - ->Ref(); - // Record call started. - client_stats->AddCallStarted(); - } - } - // Stats object to update. grpc_core::RefCountedPtr client_stats; // State for intercepting send_initial_metadata. @@ -82,7 +71,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { static grpc_error* init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { GPR_ASSERT(args->context != nullptr); - new (elem->call_data) call_data(*args); + new (elem->call_data) call_data(); return GRPC_ERROR_NONE; } @@ -96,9 +85,6 @@ static void destroy_call_elem(grpc_call_element* elem, calld->client_stats->AddCallFinished( !calld->send_initial_metadata_succeeded /* client_failed_to_send */, calld->recv_initial_metadata_succeeded /* known_received */); - // All done, so unref the stats object. - // TODO(roth): Eliminate this once filter stack is converted to C++. - calld->client_stats.reset(); } calld->~call_data(); } @@ -107,25 +93,36 @@ static void start_transport_stream_op_batch( grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { call_data* calld = static_cast(elem->call_data); GPR_TIMER_SCOPE("clr_start_transport_stream_op_batch", 0); - if (calld->client_stats != nullptr) { - // Intercept send_initial_metadata. - if (batch->send_initial_metadata) { - calld->original_on_complete_for_send = batch->on_complete; - GRPC_CLOSURE_INIT(&calld->on_complete_for_send, on_complete_for_send, - calld, grpc_schedule_on_exec_ctx); - batch->on_complete = &calld->on_complete_for_send; - } - // Intercept recv_initial_metadata. - if (batch->recv_initial_metadata) { - calld->original_recv_initial_metadata_ready = - batch->payload->recv_initial_metadata.recv_initial_metadata_ready; - GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready, - recv_initial_metadata_ready, calld, - grpc_schedule_on_exec_ctx); - batch->payload->recv_initial_metadata.recv_initial_metadata_ready = - &calld->recv_initial_metadata_ready; + // Handle send_initial_metadata. + if (batch->send_initial_metadata) { + // Grab client stats object from user_data for LB token metadata. + grpc_linked_mdelem* lb_token = + batch->payload->send_initial_metadata.send_initial_metadata->idx.named + .lb_token; + if (lb_token != nullptr) { + grpc_core::GrpcLbClientStats* client_stats = + static_cast(grpc_mdelem_get_user_data( + lb_token->md, grpc_core::GrpcLbClientStats::Destroy)); + if (client_stats != nullptr) { + calld->client_stats = client_stats->Ref(); + // Intercept completion. + calld->original_on_complete_for_send = batch->on_complete; + GRPC_CLOSURE_INIT(&calld->on_complete_for_send, on_complete_for_send, + calld, grpc_schedule_on_exec_ctx); + batch->on_complete = &calld->on_complete_for_send; + } } } + // Intercept completion of recv_initial_metadata. + if (batch->recv_initial_metadata) { + calld->original_recv_initial_metadata_ready = + batch->payload->recv_initial_metadata.recv_initial_metadata_ready; + GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready, + recv_initial_metadata_ready, calld, + grpc_schedule_on_exec_ctx); + batch->payload->recv_initial_metadata.recv_initial_metadata_ready = + &calld->recv_initial_metadata_ready; + } // Chain to next filter. grpc_call_next_op(elem, batch); } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 9d6d5ad9f50..c5d1ff22a9d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -225,7 +225,8 @@ class GrpcLb : public LoadBalancingPolicy { UniquePtr AsText() const; // Extracts all non-drop entries into a ServerAddressList. - ServerAddressList GetServerAddressList() const; + ServerAddressList GetServerAddressList( + GrpcLbClientStats* client_stats) const; // Returns true if the serverlist contains at least one drop entry and // no backend address entries. @@ -446,7 +447,8 @@ bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) { } // Returns addresses extracted from the serverlist. -ServerAddressList GrpcLb::Serverlist::GetServerAddressList() const { +ServerAddressList GrpcLb::Serverlist::GetServerAddressList( + GrpcLbClientStats* client_stats) const { ServerAddressList addresses; for (size_t i = 0; i < serverlist_->num_servers; ++i) { const grpc_grpclb_server* server = serverlist_->servers[i]; @@ -464,6 +466,11 @@ ServerAddressList GrpcLb::Serverlist::GetServerAddressList() const { grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer( server->load_balance_token, lb_token_length); lb_token = grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr); + if (client_stats != nullptr) { + GPR_ASSERT(grpc_mdelem_set_user_data( + lb_token, GrpcLbClientStats::Destroy, + client_stats->Ref().release()) == client_stats); + } } else { char* uri = grpc_sockaddr_to_uri(&addr); gpr_log(GPR_INFO, @@ -504,22 +511,6 @@ const char* GrpcLb::Serverlist::ShouldDrop() { // GrpcLb::Picker // -// Adds lb_token of selected subchannel (address) to the call's initial -// metadata. -grpc_error* AddLbTokenToInitialMetadata( - grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage, - grpc_metadata_batch* initial_metadata) { - GPR_ASSERT(lb_token_mdelem_storage != nullptr); - GPR_ASSERT(!GRPC_MDISNULL(lb_token)); - return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage, - lb_token); -} - -// Destroy function used when embedding client stats in call context. -void DestroyClientStats(void* arg) { - static_cast(arg)->Unref(); -} - GrpcLb::Picker::PickResult GrpcLb::Picker::Pick(PickState* pick, grpc_error** error) { // Check if we should drop the call. @@ -550,15 +541,14 @@ GrpcLb::Picker::PickResult GrpcLb::Picker::Pick(PickState* pick, abort(); } grpc_mdelem lb_token = {reinterpret_cast(arg->value.pointer.p)}; - AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(lb_token), - &pick->lb_token_mdelem_storage, - pick->initial_metadata); - // Pass on client stats via context. Passes ownership of the reference. - if (client_stats_ != nullptr) { - pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = - client_stats_->Ref().release(); - pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = - DestroyClientStats; + GPR_ASSERT(!GRPC_MDISNULL(lb_token)); + GPR_ASSERT(grpc_metadata_batch_add_tail( + pick->initial_metadata, &pick->lb_token_mdelem_storage, + GRPC_MDELEM_REF(lb_token)) == GRPC_ERROR_NONE); + GrpcLbClientStats* client_stats = static_cast( + grpc_mdelem_get_user_data(lb_token, GrpcLbClientStats::Destroy)); + if (client_stats != nullptr) { + client_stats->AddCallStarted(); } } return result; @@ -1414,7 +1404,8 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { ServerAddressList* addresses = &tmp_addresses; bool is_backend_from_grpclb_load_balancer = false; if (serverlist_ != nullptr) { - tmp_addresses = serverlist_->GetServerAddressList(); + tmp_addresses = serverlist_->GetServerAddressList( + lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats()); is_backend_from_grpclb_load_balancer = true; } else { // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h index 45ca40942ca..cb261ee16c7 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h @@ -56,6 +56,12 @@ class GrpcLbClientStats : public RefCounted { int64_t* num_calls_finished_known_received, UniquePtr* drop_token_counts); + // A destruction function to use as the user_data key when attaching + // client stats to a grpc_mdelem. + static void Destroy(void* arg) { + static_cast(arg)->Unref(); + } + private: // This field must only be accessed via *_locked() methods. UniquePtr drop_token_counts_; diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 637c3b13aa5..6c10d876af7 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -322,11 +322,6 @@ class XdsLb : public LoadBalancingPolicy { // XdsLb::Picker // -// Destroy function used when embedding client stats in call context. -void DestroyClientStats(void* arg) { - static_cast(arg)->Unref(); -} - XdsLb::Picker::PickResult XdsLb::Picker::Pick(PickState* pick, grpc_error** error) { // TODO(roth): Add support for drop handling. @@ -335,10 +330,7 @@ XdsLb::Picker::PickResult XdsLb::Picker::Pick(PickState* pick, // If pick succeeded, add client stats. if (result == PickResult::PICK_COMPLETE && pick->connected_subchannel != nullptr && client_stats_ != nullptr) { - pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value = - client_stats_->Ref().release(); - pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy = - DestroyClientStats; + // TODO(roth): Add support for client stats. } return result; } diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index 763e4ffc9fe..81b84f1ca05 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -35,9 +35,6 @@ typedef enum { /// Reserved for traffic_class_context. GRPC_CONTEXT_TRAFFIC, - /// Value is a \a grpc_grpclb_client_stats. - GRPC_GRPCLB_CLIENT_STATS, - GRPC_CONTEXT_COUNT } grpc_context_index; diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 5fe750edbf3..f90c92efdc2 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -41,12 +41,42 @@ #define MAX_CREDENTIALS_METADATA_COUNT 4 namespace { + +/* We can have a per-channel credentials. */ +struct channel_data { + channel_data(grpc_channel_security_connector* security_connector, + grpc_auth_context* auth_context) + : security_connector( + security_connector->Ref(DEBUG_LOCATION, "client_auth_filter")), + auth_context(auth_context->Ref(DEBUG_LOCATION, "client_auth_filter")) {} + ~channel_data() { + security_connector.reset(DEBUG_LOCATION, "client_auth_filter"); + auth_context.reset(DEBUG_LOCATION, "client_auth_filter"); + } + + grpc_core::RefCountedPtr security_connector; + grpc_core::RefCountedPtr auth_context; +}; + /* We can have a per-call credentials. */ struct call_data { call_data(grpc_call_element* elem, const grpc_call_element_args& args) - : arena(args.arena), - owning_call(args.call_stack), - call_combiner(args.call_combiner) {} + : owning_call(args.call_stack), call_combiner(args.call_combiner) { + channel_data* chand = static_cast(elem->channel_data); + GPR_ASSERT(args.context != nullptr); + if (args.context[GRPC_CONTEXT_SECURITY].value == nullptr) { + args.context[GRPC_CONTEXT_SECURITY].value = + grpc_client_security_context_create(args.arena, /*creds=*/nullptr); + args.context[GRPC_CONTEXT_SECURITY].destroy = + grpc_client_security_context_destroy; + } + grpc_client_security_context* sec_ctx = + static_cast( + args.context[GRPC_CONTEXT_SECURITY].value); + sec_ctx->auth_context.reset(DEBUG_LOCATION, "client_auth_filter"); + sec_ctx->auth_context = + chand->auth_context->Ref(DEBUG_LOCATION, "client_auth_filter"); + } // This method is technically the dtor of this class. However, since // `get_request_metadata_cancel_closure` can run in parallel to @@ -61,7 +91,6 @@ struct call_data { grpc_auth_metadata_context_reset(&auth_md_context); } - gpr_arena* arena; grpc_call_stack* owning_call; grpc_call_combiner* call_combiner; grpc_core::RefCountedPtr creds; @@ -81,21 +110,6 @@ struct call_data { grpc_closure get_request_metadata_cancel_closure; }; -/* We can have a per-channel credentials. */ -struct channel_data { - channel_data(grpc_channel_security_connector* security_connector, - grpc_auth_context* auth_context) - : security_connector( - security_connector->Ref(DEBUG_LOCATION, "client_auth_filter")), - auth_context(auth_context->Ref(DEBUG_LOCATION, "client_auth_filter")) {} - ~channel_data() { - security_connector.reset(DEBUG_LOCATION, "client_auth_filter"); - auth_context.reset(DEBUG_LOCATION, "client_auth_filter"); - } - - grpc_core::RefCountedPtr security_connector; - grpc_core::RefCountedPtr auth_context; -}; } // namespace void grpc_auth_metadata_context_reset( @@ -307,24 +321,6 @@ static void auth_start_transport_stream_op_batch( call_data* calld = static_cast(elem->call_data); channel_data* chand = static_cast(elem->channel_data); - if (!batch->cancel_stream) { - // TODO(hcaseyal): move this to init_call_elem once issue #15927 is - // resolved. - GPR_ASSERT(batch->payload->context != nullptr); - if (batch->payload->context[GRPC_CONTEXT_SECURITY].value == nullptr) { - batch->payload->context[GRPC_CONTEXT_SECURITY].value = - grpc_client_security_context_create(calld->arena, /*creds=*/nullptr); - batch->payload->context[GRPC_CONTEXT_SECURITY].destroy = - grpc_client_security_context_destroy; - } - grpc_client_security_context* sec_ctx = - static_cast( - batch->payload->context[GRPC_CONTEXT_SECURITY].value); - sec_ctx->auth_context.reset(DEBUG_LOCATION, "client_auth_filter"); - sec_ctx->auth_context = - chand->auth_context->Ref(DEBUG_LOCATION, "client_auth_filter"); - } - if (batch->send_initial_metadata) { grpc_metadata_batch* metadata = batch->payload->send_initial_metadata.send_initial_metadata; diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 30482a1b3b1..b7e7fd40c00 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -71,6 +71,12 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_metadata(false, "metadata"); typedef void (*destroy_user_data_func)(void* user_data); +struct UserData { + gpr_mu mu_user_data; + gpr_atm destroy_user_data; + gpr_atm user_data; +}; + /* Shadow structure for grpc_mdelem_data for interned elements */ typedef struct interned_metadata { /* must be byte compatible with grpc_mdelem_data */ @@ -80,9 +86,7 @@ typedef struct interned_metadata { /* private only data */ gpr_atm refcnt; - gpr_mu mu_user_data; - gpr_atm destroy_user_data; - gpr_atm user_data; + UserData user_data; struct interned_metadata* bucket_next; } interned_metadata; @@ -95,6 +99,8 @@ typedef struct allocated_metadata { /* private only data */ gpr_atm refcnt; + + UserData user_data; } allocated_metadata; typedef struct mdtab_shard { @@ -178,16 +184,17 @@ static void gc_mdtab(mdtab_shard* shard) { for (i = 0; i < shard->capacity; i++) { prev_next = &shard->elems[i]; for (md = shard->elems[i]; md; md = next) { - void* user_data = (void*)gpr_atm_no_barrier_load(&md->user_data); + void* user_data = + (void*)gpr_atm_no_barrier_load(&md->user_data.user_data); next = md->bucket_next; if (gpr_atm_acq_load(&md->refcnt) == 0) { grpc_slice_unref_internal(md->key); grpc_slice_unref_internal(md->value); - if (md->user_data) { + if (md->user_data.user_data) { ((destroy_user_data_func)gpr_atm_no_barrier_load( - &md->destroy_user_data))(user_data); + &md->user_data.destroy_user_data))(user_data); } - gpr_mu_destroy(&md->mu_user_data); + gpr_mu_destroy(&md->user_data.mu_user_data); gpr_free(md); *prev_next = next; num_freed++; @@ -251,6 +258,9 @@ grpc_mdelem grpc_mdelem_create( allocated->key = grpc_slice_ref_internal(key); allocated->value = grpc_slice_ref_internal(value); gpr_atm_rel_store(&allocated->refcnt, 1); + allocated->user_data.user_data = 0; + allocated->user_data.destroy_user_data = 0; + gpr_mu_init(&allocated->user_data.mu_user_data); #ifndef NDEBUG if (grpc_trace_metadata.enabled()) { char* key_str = grpc_slice_to_c_string(allocated->key); @@ -299,11 +309,11 @@ grpc_mdelem grpc_mdelem_create( gpr_atm_rel_store(&md->refcnt, 1); md->key = grpc_slice_ref_internal(key); md->value = grpc_slice_ref_internal(value); - md->user_data = 0; - md->destroy_user_data = 0; + md->user_data.user_data = 0; + md->user_data.destroy_user_data = 0; md->bucket_next = shard->elems[idx]; shard->elems[idx] = md; - gpr_mu_init(&md->mu_user_data); + gpr_mu_init(&md->user_data.mu_user_data); #ifndef NDEBUG if (grpc_trace_metadata.enabled()) { char* key_str = grpc_slice_to_c_string(md->key); @@ -450,6 +460,13 @@ void grpc_mdelem_unref(grpc_mdelem gmd DEBUG_ARGS) { if (1 == prev_refcount) { grpc_slice_unref_internal(md->key); grpc_slice_unref_internal(md->value); + if (md->user_data.user_data) { + destroy_user_data_func destroy_user_data = + (destroy_user_data_func)gpr_atm_no_barrier_load( + &md->user_data.destroy_user_data); + destroy_user_data((void*)md->user_data.user_data); + } + gpr_mu_destroy(&md->user_data.mu_user_data); gpr_free(md); } break; @@ -457,58 +474,74 @@ void grpc_mdelem_unref(grpc_mdelem gmd DEBUG_ARGS) { } } +static void* get_user_data(UserData* user_data, void (*destroy_func)(void*)) { + if (gpr_atm_acq_load(&user_data->destroy_user_data) == + (gpr_atm)destroy_func) { + return (void*)gpr_atm_no_barrier_load(&user_data->user_data); + } else { + return nullptr; + } +} + void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void*)) { switch (GRPC_MDELEM_STORAGE(md)) { case GRPC_MDELEM_STORAGE_EXTERNAL: - case GRPC_MDELEM_STORAGE_ALLOCATED: return nullptr; case GRPC_MDELEM_STORAGE_STATIC: return (void*)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) - grpc_static_mdelem_table]; + case GRPC_MDELEM_STORAGE_ALLOCATED: { + allocated_metadata* am = + reinterpret_cast(GRPC_MDELEM_DATA(md)); + return get_user_data(&am->user_data, destroy_func); + } case GRPC_MDELEM_STORAGE_INTERNED: { interned_metadata* im = reinterpret_cast GRPC_MDELEM_DATA(md); - void* result; - if (gpr_atm_acq_load(&im->destroy_user_data) == (gpr_atm)destroy_func) { - return (void*)gpr_atm_no_barrier_load(&im->user_data); - } else { - return nullptr; - } - return result; + return get_user_data(&im->user_data, destroy_func); } } GPR_UNREACHABLE_CODE(return nullptr); } +static void* set_user_data(UserData* ud, void (*destroy_func)(void*), + void* user_data) { + GPR_ASSERT((user_data == nullptr) == (destroy_func == nullptr)); + gpr_mu_lock(&ud->mu_user_data); + if (gpr_atm_no_barrier_load(&ud->destroy_user_data)) { + /* user data can only be set once */ + gpr_mu_unlock(&ud->mu_user_data); + if (destroy_func != nullptr) { + destroy_func(user_data); + } + return (void*)gpr_atm_no_barrier_load(&ud->user_data); + } + gpr_atm_no_barrier_store(&ud->user_data, (gpr_atm)user_data); + gpr_atm_rel_store(&ud->destroy_user_data, (gpr_atm)destroy_func); + gpr_mu_unlock(&ud->mu_user_data); + return user_data; +} + void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), void* user_data) { switch (GRPC_MDELEM_STORAGE(md)) { case GRPC_MDELEM_STORAGE_EXTERNAL: - case GRPC_MDELEM_STORAGE_ALLOCATED: destroy_func(user_data); return nullptr; case GRPC_MDELEM_STORAGE_STATIC: destroy_func(user_data); return (void*)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) - grpc_static_mdelem_table]; + case GRPC_MDELEM_STORAGE_ALLOCATED: { + allocated_metadata* am = + reinterpret_cast(GRPC_MDELEM_DATA(md)); + return set_user_data(&am->user_data, destroy_func, user_data); + } case GRPC_MDELEM_STORAGE_INTERNED: { interned_metadata* im = reinterpret_cast GRPC_MDELEM_DATA(md); GPR_ASSERT(!is_mdelem_static(md)); - GPR_ASSERT((user_data == nullptr) == (destroy_func == nullptr)); - gpr_mu_lock(&im->mu_user_data); - if (gpr_atm_no_barrier_load(&im->destroy_user_data)) { - /* user data can only be set once */ - gpr_mu_unlock(&im->mu_user_data); - if (destroy_func != nullptr) { - destroy_func(user_data); - } - return (void*)gpr_atm_no_barrier_load(&im->user_data); - } - gpr_atm_no_barrier_store(&im->user_data, (gpr_atm)user_data); - gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func); - gpr_mu_unlock(&im->mu_user_data); - return user_data; + return set_user_data(&im->user_data, destroy_func, user_data); } } GPR_UNREACHABLE_CODE(return nullptr); diff --git a/test/core/end2end/end2end_nosec_tests.cc b/test/core/end2end/end2end_nosec_tests.cc index 614d1f98e2b..3ab55527da6 100644 --- a/test/core/end2end/end2end_nosec_tests.cc +++ b/test/core/end2end/end2end_nosec_tests.cc @@ -70,6 +70,8 @@ extern void filter_call_init_fails(grpc_end2end_test_config config); extern void filter_call_init_fails_pre_init(void); extern void filter_causes_close(grpc_end2end_test_config config); extern void filter_causes_close_pre_init(void); +extern void filter_context(grpc_end2end_test_config config); +extern void filter_context_pre_init(void); extern void filter_latency(grpc_end2end_test_config config); extern void filter_latency_pre_init(void); extern void filter_status_code(grpc_end2end_test_config config); @@ -207,6 +209,7 @@ void grpc_end2end_tests_pre_init(void) { empty_batch_pre_init(); filter_call_init_fails_pre_init(); filter_causes_close_pre_init(); + filter_context_pre_init(); filter_latency_pre_init(); filter_status_code_pre_init(); graceful_server_shutdown_pre_init(); @@ -292,6 +295,7 @@ void grpc_end2end_tests(int argc, char **argv, empty_batch(config); filter_call_init_fails(config); filter_causes_close(config); + filter_context(config); filter_latency(config); filter_status_code(config); graceful_server_shutdown(config); @@ -432,6 +436,10 @@ void grpc_end2end_tests(int argc, char **argv, filter_causes_close(config); continue; } + if (0 == strcmp("filter_context", argv[i])) { + filter_context(config); + continue; + } if (0 == strcmp("filter_latency", argv[i])) { filter_latency(config); continue; diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc index 9d3d231b3c5..b680da4433f 100644 --- a/test/core/end2end/end2end_tests.cc +++ b/test/core/end2end/end2end_tests.cc @@ -72,6 +72,8 @@ extern void filter_call_init_fails(grpc_end2end_test_config config); extern void filter_call_init_fails_pre_init(void); extern void filter_causes_close(grpc_end2end_test_config config); extern void filter_causes_close_pre_init(void); +extern void filter_context(grpc_end2end_test_config config); +extern void filter_context_pre_init(void); extern void filter_latency(grpc_end2end_test_config config); extern void filter_latency_pre_init(void); extern void filter_status_code(grpc_end2end_test_config config); @@ -210,6 +212,7 @@ void grpc_end2end_tests_pre_init(void) { empty_batch_pre_init(); filter_call_init_fails_pre_init(); filter_causes_close_pre_init(); + filter_context_pre_init(); filter_latency_pre_init(); filter_status_code_pre_init(); graceful_server_shutdown_pre_init(); @@ -296,6 +299,7 @@ void grpc_end2end_tests(int argc, char **argv, empty_batch(config); filter_call_init_fails(config); filter_causes_close(config); + filter_context(config); filter_latency(config); filter_status_code(config); graceful_server_shutdown(config); @@ -440,6 +444,10 @@ void grpc_end2end_tests(int argc, char **argv, filter_causes_close(config); continue; } + if (0 == strcmp("filter_context", argv[i])) { + filter_context(config); + continue; + } if (0 == strcmp("filter_latency", argv[i])) { filter_latency(config); continue; diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 0ff1b7ee796..f8ac7036530 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -124,6 +124,7 @@ END2END_TESTS = { 'empty_batch': default_test_options._replace(cpu_cost=LOWCPU), 'filter_causes_close': default_test_options._replace(cpu_cost=LOWCPU), 'filter_call_init_fails': default_test_options, + 'filter_context': default_test_options, 'filter_latency': default_test_options._replace(cpu_cost=LOWCPU), 'filter_status_code': default_test_options._replace(cpu_cost=LOWCPU), 'graceful_server_shutdown': default_test_options._replace( diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index ec32aa5102c..5174a7e5af5 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -215,6 +215,7 @@ END2END_TESTS = { "empty_batch": _test_options(), "filter_causes_close": _test_options(), "filter_call_init_fails": _test_options(), + "filter_context": _test_options(), "graceful_server_shutdown": _test_options(exclude_inproc = True), "hpack_size": _test_options( proxyable = False, diff --git a/test/core/end2end/tests/filter_context.cc b/test/core/end2end/tests/filter_context.cc new file mode 100644 index 00000000000..1d5d9e5e46a --- /dev/null +++ b/test/core/end2end/tests/filter_context.cc @@ -0,0 +1,318 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "src/core/lib/channel/channel_stack_builder.h" +#include "src/core/lib/surface/channel_init.h" +#include "test/core/end2end/cq_verifier.h" + +enum { TIMEOUT = 200000 }; + +static bool g_enable_filter = false; + +static void* tag(intptr_t t) { return (void*)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char* test_name, + grpc_channel_args* client_args, + grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_from_now(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_from_now(void) { + return n_seconds_from_now(5); +} + +static void drain_cq(grpc_completion_queue* cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), + grpc_timeout_seconds_to_deadline(5), + nullptr) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = nullptr; +} + +static void shutdown_client(grpc_end2end_test_fixture* f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = nullptr; +} + +static void end_test(grpc_end2end_test_fixture* f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); + grpc_completion_queue_destroy(f->shutdown_cq); +} + +// Simple request to test that filters see a consistent view of the +// call context. +static void test_request(grpc_end2end_test_config config) { + grpc_call* c; + grpc_call* s; + grpc_slice request_payload_slice = + grpc_slice_from_copied_string("hello world"); + grpc_byte_buffer* request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_end2end_test_fixture f = + begin_test(config, "filter_context", nullptr, nullptr); + cq_verifier* cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op* op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + + gpr_timespec deadline = five_seconds_from_now(); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->data.send_initial_metadata.metadata = nullptr; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast(op - ops), tag(1), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; + grpc_slice status_string = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_string; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(102), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_unref(s); + grpc_call_unref(c); + + cq_verifier_destroy(cqv); + + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(request_payload_recv); + + end_test(&f); + config.tear_down_data(&f); +} + +/******************************************************************************* + * Test context filter + */ + +struct call_data { + grpc_call_context_element* context; +}; + +static grpc_error* init_call_elem(grpc_call_element* elem, + const grpc_call_element_args* args) { + call_data* calld = static_cast(elem->call_data); + calld->context = args->context; + gpr_log(GPR_INFO, "init_call_elem(): context=%p", args->context); + return GRPC_ERROR_NONE; +} + +static void start_transport_stream_op_batch( + grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { + call_data* calld = static_cast(elem->call_data); + // If batch payload context is not null (which will happen in some + // cancellation cases), make sure we get the same context here that we + // saw in init_call_elem(). + gpr_log(GPR_INFO, "start_transport_stream_op_batch(): context=%p", + batch->payload->context); + if (batch->payload->context != nullptr) { + GPR_ASSERT(calld->context == batch->payload->context); + } + grpc_call_next_op(elem, batch); +} + +static void destroy_call_elem(grpc_call_element* elem, + const grpc_call_final_info* final_info, + grpc_closure* ignored) {} + +static grpc_error* init_channel_elem(grpc_channel_element* elem, + grpc_channel_element_args* args) { + return GRPC_ERROR_NONE; +} + +static void destroy_channel_elem(grpc_channel_element* elem) {} + +static const grpc_channel_filter test_filter = { + start_transport_stream_op_batch, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset_or_pollset_set, + destroy_call_elem, + 0, + init_channel_elem, + destroy_channel_elem, + grpc_channel_next_get_info, + "filter_context"}; + +/******************************************************************************* + * Registration + */ + +static bool maybe_add_filter(grpc_channel_stack_builder* builder, void* arg) { + grpc_channel_filter* filter = static_cast(arg); + if (g_enable_filter) { + // Want to add the filter as close to the end as possible, to make + // sure that all of the filters work well together. However, we + // can't add it at the very end, because the connected channel filter + // must be the last one. So we add it right before the last one. + grpc_channel_stack_builder_iterator* it = + grpc_channel_stack_builder_create_iterator_at_last(builder); + GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); + const bool retval = grpc_channel_stack_builder_add_filter_before( + it, filter, nullptr, nullptr); + grpc_channel_stack_builder_iterator_destroy(it); + return retval; + } else { + return true; + } +} + +static void init_plugin(void) { + grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, + maybe_add_filter, (void*)&test_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX, + maybe_add_filter, (void*)&test_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, + maybe_add_filter, (void*)&test_filter); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, + maybe_add_filter, (void*)&test_filter); +} + +static void destroy_plugin(void) {} + +void filter_context(grpc_end2end_test_config config) { + g_enable_filter = true; + test_request(config); + g_enable_filter = false; +} + +void filter_context_pre_init(void) { + grpc_register_plugin(init_plugin, destroy_plugin); +} diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc index 9a49d28ccce..e6b73de2de5 100644 --- a/test/core/transport/metadata_test.cc +++ b/test/core/transport/metadata_test.cc @@ -289,6 +289,28 @@ static void test_user_data_works(void) { grpc_shutdown(); } +static void test_user_data_works_for_allocated_md(void) { + int* ud1; + int* ud2; + grpc_mdelem md; + gpr_log(GPR_INFO, "test_user_data_works"); + + grpc_init(); + grpc_core::ExecCtx exec_ctx; + ud1 = static_cast(gpr_malloc(sizeof(int))); + *ud1 = 1; + ud2 = static_cast(gpr_malloc(sizeof(int))); + *ud2 = 2; + md = grpc_mdelem_from_slices(grpc_slice_from_static_string("abc"), + grpc_slice_from_static_string("123")); + grpc_mdelem_set_user_data(md, gpr_free, ud1); + grpc_mdelem_set_user_data(md, gpr_free, ud2); + GPR_ASSERT(grpc_mdelem_get_user_data(md, gpr_free) == ud1); + GRPC_MDELEM_UNREF(md); + + grpc_shutdown(); +} + static void verify_ascii_header_size(const char* key, const char* value, bool intern_key, bool intern_value) { grpc_mdelem elem = grpc_mdelem_from_slices( @@ -386,6 +408,7 @@ int main(int argc, char** argv) { test_create_many_persistant_metadata(); test_things_stick_around(); test_user_data_works(); + test_user_data_works_for_allocated_md(); grpc_shutdown(); return 0; } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index b56e65e50af..2288b88b517 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -1483,6 +1483,9 @@ class SingleBalancerWithClientLoadReportingTest : public GrpclbEnd2endTest { SingleBalancerWithClientLoadReportingTest() : GrpclbEnd2endTest(4, 1, 3) {} }; +// TODO(roth): Add test that when switching balancers, we don't include +// any calls that were sent prior to connecting to the new balancer. + TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) { SetNextResolutionAllBalancers(); const size_t kNumRpcsPerAddress = 100; diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 95b6ae65008..0b84b8a4b95 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8869,6 +8869,7 @@ "test/core/end2end/tests/empty_batch.cc", "test/core/end2end/tests/filter_call_init_fails.cc", "test/core/end2end/tests/filter_causes_close.cc", + "test/core/end2end/tests/filter_context.cc", "test/core/end2end/tests/filter_latency.cc", "test/core/end2end/tests/filter_status_code.cc", "test/core/end2end/tests/graceful_server_shutdown.cc", @@ -8967,6 +8968,7 @@ "test/core/end2end/tests/empty_batch.cc", "test/core/end2end/tests/filter_call_init_fails.cc", "test/core/end2end/tests/filter_causes_close.cc", + "test/core/end2end/tests/filter_context.cc", "test/core/end2end/tests/filter_latency.cc", "test/core/end2end/tests/filter_status_code.cc", "test/core/end2end/tests/graceful_server_shutdown.cc", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 9a202ecf167..6dc9eb7f0d1 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -7951,6 +7951,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_census_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -9703,6 +9726,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_compress_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -11411,6 +11457,28 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_fakesec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -12991,6 +13059,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_fd_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -14304,6 +14395,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_full_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -15970,6 +16084,25 @@ "linux" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_full+pipe_test", + "platforms": [ + "linux" + ] + }, { "args": [ "filter_latency" @@ -17500,6 +17633,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_full+trace_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -19206,6 +19362,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_full+workarounds_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -20977,6 +21156,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_http_proxy_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -22758,6 +22961,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv4_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -24460,6 +24686,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_ipv6_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -26162,6 +26411,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_local_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -27931,6 +28203,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_oauth2_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -29683,6 +29979,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_proxy_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -30787,6 +31107,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -32035,6 +32379,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair+trace_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -33243,6 +33611,32 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [ + "msan" + ], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_1byte_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -34638,6 +35032,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -36337,6 +36754,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_ssl_proxy_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -37494,6 +37935,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -39081,6 +39545,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "inproc_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -40164,6 +40651,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_census_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -41893,6 +42403,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_compress_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -43482,6 +44015,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_fd_nosec_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -44772,6 +45328,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_full_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -46419,6 +46998,25 @@ "linux" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_full+pipe_nosec_test", + "platforms": [ + "linux" + ] + }, { "args": [ "filter_latency" @@ -47926,6 +48524,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_full+trace_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -49609,6 +50230,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_full+workarounds_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -51356,6 +52000,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_http_proxy_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -53108,6 +53776,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_proxy_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -54188,6 +54880,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -55412,6 +56128,30 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair+trace_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -56594,6 +57334,32 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [ + "msan" + ], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_sockpair_1byte_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" @@ -57918,6 +58684,29 @@ "posix" ] }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_uds_nosec_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "filter_latency" From b606cad6ccfcc1785a181bcfcb0df603cb7d68f8 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 1 Mar 2019 16:14:24 -0800 Subject: [PATCH 573/814] Fold opencensus into grpc_impl namespace Moving opencensus into grpc_impl namespace.. --- BUILD | 1 + include/grpcpp/opencensus.h | 26 +------- include/grpcpp/opencensus_impl.h | 51 +++++++++++++++ src/cpp/ext/filters/census/grpc_plugin.cc | 65 ++++++++++--------- src/cpp/ext/filters/census/grpc_plugin.h | 6 +- src/cpp/ext/filters/census/views.cc | 31 +++++---- .../census/stats_plugin_end2end_test.cc | 2 +- .../microbenchmarks/bm_opencensus_plugin.cc | 6 +- 8 files changed, 114 insertions(+), 74 deletions(-) create mode 100644 include/grpcpp/opencensus_impl.h diff --git a/BUILD b/BUILD index 24c1fb31ced..f08a89fa5fc 100644 --- a/BUILD +++ b/BUILD @@ -2280,6 +2280,7 @@ grpc_cc_library( ], hdrs = [ "include/grpcpp/opencensus.h", + "include/grpcpp/opencensus_impl.h", "src/cpp/ext/filters/census/channel_filter.h", "src/cpp/ext/filters/census/client_filter.h", "src/cpp/ext/filters/census/context.h", diff --git a/include/grpcpp/opencensus.h b/include/grpcpp/opencensus.h index 29b221f7674..3b170336834 100644 --- a/include/grpcpp/opencensus.h +++ b/include/grpcpp/opencensus.h @@ -19,30 +19,6 @@ #ifndef GRPCPP_OPENCENSUS_H #define GRPCPP_OPENCENSUS_H -#include "opencensus/trace/span.h" - -namespace grpc { -// These symbols in this file will not be included in the binary unless -// grpc_opencensus_plugin build target was added as a dependency. At the moment -// it is only setup to be built with Bazel. - -// Registers the OpenCensus plugin with gRPC, so that it will be used for future -// RPCs. This must be called before any views are created. -void RegisterOpenCensusPlugin(); - -// RPC stats definitions, defined by -// https://github.com/census-instrumentation/opencensus-specs/blob/master/stats/gRPC.md - -// Registers the cumulative gRPC views so that they will be exported by any -// registered stats exporter. For on-task stats, construct a View using the -// ViewDescriptors below. -void RegisterOpenCensusViewsForExport(); - -class ServerContext; - -// Returns the tracing Span for the current RPC. -::opencensus::trace::Span GetSpanFromServerContext(ServerContext* context); - -} // namespace grpc +#include "grpcpp/opencensus_impl.h" #endif // GRPCPP_OPENCENSUS_H diff --git a/include/grpcpp/opencensus_impl.h b/include/grpcpp/opencensus_impl.h new file mode 100644 index 00000000000..631d2b861fd --- /dev/null +++ b/include/grpcpp/opencensus_impl.h @@ -0,0 +1,51 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_OPENCENSUS_IMPL_H +#define GRPCPP_OPENCENSUS_IMPL_H + +#include "opencensus/trace/span.h" + +namespace grpc { + +class ServerContext; +} +namespace grpc_impl { +// These symbols in this file will not be included in the binary unless +// grpc_opencensus_plugin build target was added as a dependency. At the moment +// it is only setup to be built with Bazel. + +// Registers the OpenCensus plugin with gRPC, so that it will be used for future +// RPCs. This must be called before any views are created. +void RegisterOpenCensusPlugin(); + +// RPC stats definitions, defined by +// https://github.com/census-instrumentation/opencensus-specs/blob/master/stats/gRPC.md + +// Registers the cumulative gRPC views so that they will be exported by any +// registered stats exporter. For on-task stats, construct a View using the +// ViewDescriptors below. +void RegisterOpenCensusViewsForExport(); + +// Returns the tracing Span for the current RPC. +::opencensus::trace::Span GetSpanFromServerContext( + grpc::ServerContext* context); + +} // namespace grpc_impl + +#endif // GRPCPP_OPENCENSUS_IMPL_H diff --git a/src/cpp/ext/filters/census/grpc_plugin.cc b/src/cpp/ext/filters/census/grpc_plugin.cc index f978ed3bf51..c5018f0673a 100644 --- a/src/cpp/ext/filters/census/grpc_plugin.cc +++ b/src/cpp/ext/filters/census/grpc_plugin.cc @@ -30,35 +30,6 @@ namespace grpc { -void RegisterOpenCensusPlugin() { - RegisterChannelFilter( - "opencensus_client", GRPC_CLIENT_CHANNEL, INT_MAX /* priority */, - nullptr /* condition function */); - RegisterChannelFilter( - "opencensus_server", GRPC_SERVER_CHANNEL, INT_MAX /* priority */, - nullptr /* condition function */); - - // Access measures to ensure they are initialized. Otherwise, creating a view - // before the first RPC would cause an error. - RpcClientSentBytesPerRpc(); - RpcClientReceivedBytesPerRpc(); - RpcClientRoundtripLatency(); - RpcClientServerLatency(); - RpcClientSentMessagesPerRpc(); - RpcClientReceivedMessagesPerRpc(); - - RpcServerSentBytesPerRpc(); - RpcServerReceivedBytesPerRpc(); - RpcServerServerLatency(); - RpcServerSentMessagesPerRpc(); - RpcServerReceivedMessagesPerRpc(); -} - -::opencensus::trace::Span GetSpanFromServerContext(ServerContext* context) { - return reinterpret_cast(context->census_context()) - ->Span(); -} - // These measure definitions should be kept in sync across opencensus // implementations--see // https://github.com/census-instrumentation/opencensus-java/blob/master/contrib/grpc_metrics/src/main/java/io/opencensus/contrib/grpc/metrics/RpcMeasureConstants.java. @@ -126,5 +97,39 @@ ABSL_CONST_INIT const absl::string_view ABSL_CONST_INIT const absl::string_view kRpcServerServerLatencyMeasureName = "grpc.io/server/server_latency"; - } // namespace grpc +namespace grpc_impl { + +void RegisterOpenCensusPlugin() { + grpc::RegisterChannelFilter( + "opencensus_client", GRPC_CLIENT_CHANNEL, INT_MAX /* priority */, + nullptr /* condition function */); + grpc::RegisterChannelFilter( + "opencensus_server", GRPC_SERVER_CHANNEL, INT_MAX /* priority */, + nullptr /* condition function */); + + // Access measures to ensure they are initialized. Otherwise, creating a view + // before the first RPC would cause an error. + grpc::RpcClientSentBytesPerRpc(); + grpc::RpcClientReceivedBytesPerRpc(); + grpc::RpcClientRoundtripLatency(); + grpc::RpcClientServerLatency(); + grpc::RpcClientSentMessagesPerRpc(); + grpc::RpcClientReceivedMessagesPerRpc(); + + grpc::RpcServerSentBytesPerRpc(); + grpc::RpcServerReceivedBytesPerRpc(); + grpc::RpcServerServerLatency(); + grpc::RpcServerSentMessagesPerRpc(); + grpc::RpcServerReceivedMessagesPerRpc(); +} + +::opencensus::trace::Span GetSpanFromServerContext( + grpc::ServerContext* context) { + return reinterpret_cast(context->census_context()) + ->Span(); +} + +} // namespace grpc_impl diff --git a/src/cpp/ext/filters/census/grpc_plugin.h b/src/cpp/ext/filters/census/grpc_plugin.h index 9e319cb994e..209fad139ce 100644 --- a/src/cpp/ext/filters/census/grpc_plugin.h +++ b/src/cpp/ext/filters/census/grpc_plugin.h @@ -22,12 +22,14 @@ #include #include "absl/strings/string_view.h" -#include "include/grpcpp/opencensus.h" +#include "include/grpcpp/opencensus_impl.h" #include "opencensus/stats/stats.h" -namespace grpc { +namespace grpc_impl { class ServerContext; +} +namespace grpc { // The tag keys set when recording RPC stats. ::opencensus::stats::TagKey ClientMethodTagKey(); diff --git a/src/cpp/ext/filters/census/views.cc b/src/cpp/ext/filters/census/views.cc index 2c0c5f72950..102745ab4c2 100644 --- a/src/cpp/ext/filters/census/views.cc +++ b/src/cpp/ext/filters/census/views.cc @@ -25,6 +25,23 @@ #include "opencensus/stats/internal/set_aggregation_window.h" #include "opencensus/stats/stats.h" +namespace grpc_impl { + +void RegisterOpenCensusViewsForExport() { + grpc::ClientSentMessagesPerRpcCumulative().RegisterForExport(); + grpc::ClientSentBytesPerRpcCumulative().RegisterForExport(); + grpc::ClientReceivedMessagesPerRpcCumulative().RegisterForExport(); + grpc::ClientReceivedBytesPerRpcCumulative().RegisterForExport(); + grpc::ClientRoundtripLatencyCumulative().RegisterForExport(); + grpc::ClientServerLatencyCumulative().RegisterForExport(); + + grpc::ServerSentMessagesPerRpcCumulative().RegisterForExport(); + grpc::ServerSentBytesPerRpcCumulative().RegisterForExport(); + grpc::ServerReceivedMessagesPerRpcCumulative().RegisterForExport(); + grpc::ServerReceivedBytesPerRpcCumulative().RegisterForExport(); + grpc::ServerServerLatencyCumulative().RegisterForExport(); +} +} namespace grpc { using ::opencensus::stats::Aggregation; @@ -71,20 +88,6 @@ ViewDescriptor HourDescriptor() { } // namespace -void RegisterOpenCensusViewsForExport() { - ClientSentMessagesPerRpcCumulative().RegisterForExport(); - ClientSentBytesPerRpcCumulative().RegisterForExport(); - ClientReceivedMessagesPerRpcCumulative().RegisterForExport(); - ClientReceivedBytesPerRpcCumulative().RegisterForExport(); - ClientRoundtripLatencyCumulative().RegisterForExport(); - ClientServerLatencyCumulative().RegisterForExport(); - - ServerSentMessagesPerRpcCumulative().RegisterForExport(); - ServerSentBytesPerRpcCumulative().RegisterForExport(); - ServerReceivedMessagesPerRpcCumulative().RegisterForExport(); - ServerReceivedBytesPerRpcCumulative().RegisterForExport(); - ServerServerLatencyCumulative().RegisterForExport(); -} // client cumulative const ViewDescriptor& ClientSentBytesPerRpcCumulative() { diff --git a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc index 73394028309..ad788a2dd68 100644 --- a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc +++ b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc @@ -58,7 +58,7 @@ class EchoServer final : public EchoTestService::Service { class StatsPluginEnd2EndTest : public ::testing::Test { protected: - static void SetUpTestCase() { RegisterOpenCensusPlugin(); } + static void SetUpTestCase() { grpc_impl::RegisterOpenCensusPlugin(); } void SetUp() { // Set up a synchronous server on a different thread to avoid the asynch diff --git a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc index 9d42eb891df..d23c4f0573f 100644 --- a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc +++ b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc @@ -29,7 +29,9 @@ #include "test/cpp/microbenchmarks/helpers.h" absl::once_flag once; -void RegisterOnce() { absl::call_once(once, grpc::RegisterOpenCensusPlugin); } +void RegisterOnce() { + absl::call_once(once, grpc_impl::RegisterOpenCensusPlugin); +} class EchoServer final : public grpc::testing::EchoTestService::Service { grpc::Status Echo(grpc::ServerContext* context, @@ -99,7 +101,7 @@ static void BM_E2eLatencyCensusEnabled(benchmark::State& state) { RegisterOnce(); // This we can safely repeat, and doing so clears accumulated data to avoid // initialization costs varying between runs. - grpc::RegisterOpenCensusViewsForExport(); + grpc_impl::RegisterOpenCensusViewsForExport(); EchoServerThread server; std::unique_ptr stub = From 168df1cb5fd49b9faaf12278bf029c87ad1b1ba8 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Mon, 4 Mar 2019 16:01:45 -0800 Subject: [PATCH 574/814] Check hashes for pip wheels before installing --- test/distrib/python/test_packages.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/distrib/python/test_packages.sh b/test/distrib/python/test_packages.sh index 755daa10211..433148e6bd7 100755 --- a/test/distrib/python/test_packages.sh +++ b/test/distrib/python/test_packages.sh @@ -41,7 +41,7 @@ PYTHON=$VIRTUAL_ENV/bin/python function at_least_one_installs() { for file in "$@"; do - if "$PYTHON" -m pip install "$file"; then + if "$PYTHON" -m pip install --require-hashes "$file"; then return 0 fi done From 3b7a47cde64e873183af706a2e421d1d171c13e2 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 1 Mar 2019 17:01:54 -0800 Subject: [PATCH 575/814] Moving ::grpc::ServerBuilder to ::grpc_impl::ServerBuilder This change moves ServerBuilder class from grpc namespace to grpc_impl namespace. --- BUILD | 1 + CMakeLists.txt | 3 + Makefile | 3 + build.yaml | 1 + gRPC-C++.podspec | 1 + .../grpcpp/impl/codegen/completion_queue.h | 7 +- include/grpcpp/impl/server_builder_plugin.h | 7 +- include/grpcpp/server.h | 2 +- include/grpcpp/server_builder.h | 307 +--------------- include/grpcpp/server_builder_impl.h | 337 ++++++++++++++++++ src/cpp/server/server_builder.cc | 45 +-- test/cpp/interop/interop_server.cc | 2 +- test/cpp/qps/qps_server_builder.cc | 2 +- 13 files changed, 385 insertions(+), 333 deletions(-) create mode 100644 include/grpcpp/server_builder_impl.h diff --git a/BUILD b/BUILD index 24c1fb31ced..24cddc2eccb 100644 --- a/BUILD +++ b/BUILD @@ -247,6 +247,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/security/server_credentials.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", + "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", "include/grpcpp/server_posix.h", "include/grpcpp/support/async_stream.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 939e83c481f..6045ecca885 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3027,6 +3027,7 @@ foreach(_hdr include/grpcpp/security/server_credentials.h include/grpcpp/server.h include/grpcpp/server_builder.h + include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h include/grpcpp/server_posix.h include/grpcpp/support/async_stream.h @@ -3618,6 +3619,7 @@ foreach(_hdr include/grpcpp/security/server_credentials.h include/grpcpp/server.h include/grpcpp/server_builder.h + include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h include/grpcpp/server_posix.h include/grpcpp/support/async_stream.h @@ -4573,6 +4575,7 @@ foreach(_hdr include/grpcpp/security/server_credentials.h include/grpcpp/server.h include/grpcpp/server_builder.h + include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h include/grpcpp/server_posix.h include/grpcpp/support/async_stream.h diff --git a/Makefile b/Makefile index 3c890797431..015ee37c629 100644 --- a/Makefile +++ b/Makefile @@ -5448,6 +5448,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/server_credentials.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ + include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ include/grpcpp/support/async_stream.h \ @@ -6048,6 +6049,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/server_credentials.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ + include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ include/grpcpp/support/async_stream.h \ @@ -6960,6 +6962,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/server_credentials.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ + include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ include/grpcpp/support/async_stream.h \ diff --git a/build.yaml b/build.yaml index c18630ecdd3..15328c4a7f6 100644 --- a/build.yaml +++ b/build.yaml @@ -1368,6 +1368,7 @@ filegroups: - include/grpcpp/security/server_credentials.h - include/grpcpp/server.h - include/grpcpp/server_builder.h + - include/grpcpp/server_builder_impl.h - include/grpcpp/server_context.h - include/grpcpp/server_posix.h - include/grpcpp/support/async_stream.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 0f3888975c9..eeabf304af4 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -111,6 +111,7 @@ Pod::Spec.new do |s| 'include/grpcpp/security/server_credentials.h', 'include/grpcpp/server.h', 'include/grpcpp/server_builder.h', + 'include/grpcpp/server_builder_impl.h', 'include/grpcpp/server_context.h', 'include/grpcpp/server_posix.h', 'include/grpcpp/support/async_stream.h', diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 4812f0253d4..73556ce9899 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -41,6 +41,10 @@ struct grpc_completion_queue; +namespace grpc_impl { + +class ServerBuilder; +} namespace grpc { template @@ -63,7 +67,6 @@ class ChannelInterface; class ClientContext; class CompletionQueue; class Server; -class ServerBuilder; class ServerContext; class ServerInterface; @@ -405,7 +408,7 @@ class ServerCompletionQueue : public CompletionQueue { polling_type_(polling_type) {} grpc_cq_polling_type polling_type_; - friend class ServerBuilder; + friend class ::grpc_impl::ServerBuilder; friend class Server; }; diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 39450b42d56..2898f8cfae7 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -23,9 +23,12 @@ #include -namespace grpc { +namespace grpc_impl { class ServerBuilder; +} +namespace grpc { + class ServerInitializer; class ChannelArguments; @@ -40,7 +43,7 @@ class ServerBuilderPlugin { /// UpdateServerBuilder will be called at an early stage in /// ServerBuilder::BuildAndStart(), right after the ServerBuilderOptions have /// done their updates. - virtual void UpdateServerBuilder(ServerBuilder* builder) {} + virtual void UpdateServerBuilder(grpc_impl::ServerBuilder* builder) {} /// InitServer will be called in ServerBuilder::BuildAndStart(), after the /// Server instance is created. diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 248f20452a5..3d9edf8f1c7 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -198,7 +198,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { } friend class AsyncGenericService; - friend class ServerBuilder; + friend class ::grpc_impl::ServerBuilder; friend class ServerInitializer; class SyncRequest; diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 028b8cffaa7..5b8fc72eeea 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015-2016 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,312 +19,11 @@ #ifndef GRPCPP_SERVER_BUILDER_H #define GRPCPP_SERVER_BUILDER_H -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -struct grpc_resource_quota; +#include namespace grpc { -class AsyncGenericService; -class ResourceQuota; -class CompletionQueue; -class Server; -class ServerCompletionQueue; -class ServerCredentials; -class Service; - -namespace testing { -class ServerBuilderPluginTest; -} // namespace testing - -/// A builder class for the creation and startup of \a grpc::Server instances. -class ServerBuilder { - public: - ServerBuilder(); - virtual ~ServerBuilder(); - - ////////////////////////////////////////////////////////////////////////////// - // Primary API's - - /// Return a running server which is ready for processing calls. - /// Before calling, one typically needs to ensure that: - /// 1. a service is registered - so that the server knows what to serve - /// (via RegisterService, or RegisterAsyncGenericService) - /// 2. a listening port has been added - so the server knows where to receive - /// traffic (via AddListeningPort) - /// 3. [for async api only] completion queues have been added via - /// AddCompletionQueue - virtual std::unique_ptr BuildAndStart(); - - /// Register a service. This call does not take ownership of the service. - /// The service must exist for the lifetime of the \a Server instance returned - /// by \a BuildAndStart(). - /// Matches requests with any :authority - ServerBuilder& RegisterService(Service* service); - - /// Enlists an endpoint \a addr (port with an optional IP address) to - /// bind the \a grpc::Server object to be created to. - /// - /// It can be invoked multiple times. - /// - /// \param addr_uri The address to try to bind to the server in URI form. If - /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, - /// please use IPv6 any, i.e., [::]:, which also accepts IPv4 - /// connections. Valid values include dns:///localhost:1234, / - /// 192.168.1.1:31416, dns:///[::1]:27182, etc.). - /// \param creds The credentials associated with the server. - /// \param selected_port[out] If not `nullptr`, gets populated with the port - /// number bound to the \a grpc::Server for the corresponding endpoint after - /// it is successfully bound by BuildAndStart(), 0 otherwise. AddListeningPort - /// does not modify this pointer. - ServerBuilder& AddListeningPort(const grpc::string& addr_uri, - std::shared_ptr creds, - int* selected_port = nullptr); - - /// Add a completion queue for handling asynchronous services. - /// - /// Best performance is typically obtained by using one thread per polling - /// completion queue. - /// - /// Caller is required to shutdown the server prior to shutting down the - /// returned completion queue. Caller is also required to drain the - /// completion queue after shutting it down. A typical usage scenario: - /// - /// // While building the server: - /// ServerBuilder builder; - /// ... - /// cq_ = builder.AddCompletionQueue(); - /// server_ = builder.BuildAndStart(); - /// - /// // While shutting down the server; - /// server_->Shutdown(); - /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()! - /// // Drain the cq_ that was created - /// void* ignored_tag; - /// bool ignored_ok; - /// while (cq_->Next(&ignored_tag, &ignored_ok)) { } - /// - /// \param is_frequently_polled This is an optional parameter to inform gRPC - /// library about whether this completion queue would be frequently polled - /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is - /// 'true' and is the recommended setting. Setting this to 'false' (i.e. - /// not polling the completion queue frequently) will have a significantly - /// negative performance impact and hence should not be used in production - /// use cases. - std::unique_ptr AddCompletionQueue( - bool is_frequently_polled = true); - - ////////////////////////////////////////////////////////////////////////////// - // Less commonly used RegisterService variants - - /// Register a service. This call does not take ownership of the service. - /// The service must exist for the lifetime of the \a Server instance returned - /// by \a BuildAndStart(). - /// Only matches requests with :authority \a host - ServerBuilder& RegisterService(const grpc::string& host, Service* service); - - /// Register a generic service. - /// Matches requests with any :authority - /// This is mostly useful for writing generic gRPC Proxies where the exact - /// serialization format is unknown - ServerBuilder& RegisterAsyncGenericService(AsyncGenericService* service); - - ////////////////////////////////////////////////////////////////////////////// - // Fine control knobs - - /// Set max receive message size in bytes. - /// The default is GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH. - ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) { - max_receive_message_size_ = max_receive_message_size; - return *this; - } - - /// Set max send message size in bytes. - /// The default is GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH. - ServerBuilder& SetMaxSendMessageSize(int max_send_message_size) { - max_send_message_size_ = max_send_message_size; - return *this; - } - - /// \deprecated For backward compatibility. - ServerBuilder& SetMaxMessageSize(int max_message_size) { - return SetMaxReceiveMessageSize(max_message_size); - } - - /// Set the support status for compression algorithms. All algorithms are - /// enabled by default. - /// - /// Incoming calls compressed with an unsupported algorithm will fail with - /// \a GRPC_STATUS_UNIMPLEMENTED. - ServerBuilder& SetCompressionAlgorithmSupportStatus( - grpc_compression_algorithm algorithm, bool enabled); - - /// The default compression level to use for all channel calls in the - /// absence of a call-specific level. - ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level); - - /// The default compression algorithm to use for all channel calls in the - /// absence of a call-specific level. Note that it overrides any compression - /// level set by \a SetDefaultCompressionLevel. - ServerBuilder& SetDefaultCompressionAlgorithm( - grpc_compression_algorithm algorithm); - - /// Set the attached buffer pool for this server - ServerBuilder& SetResourceQuota(const ResourceQuota& resource_quota); - - ServerBuilder& SetOption(std::unique_ptr option); - - /// Options for synchronous servers. - enum SyncServerOption { - NUM_CQS, ///< Number of completion queues. - MIN_POLLERS, ///< Minimum number of polling threads. - MAX_POLLERS, ///< Maximum number of polling threads. - CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds. - }; - - /// Only useful if this is a Synchronous server. - ServerBuilder& SetSyncServerOption(SyncServerOption option, int value); - - /// Add a channel argument (an escape hatch to tuning core library parameters - /// directly) - template - ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) { - return SetOption(MakeChannelArgumentOption(arg, value)); - } - - /// For internal use only: Register a ServerBuilderPlugin factory function. - static void InternalAddPluginFactory( - std::unique_ptr (*CreatePlugin)()); - - /// Enable a server workaround. Do not use unless you know what the workaround - /// does. For explanation and detailed descriptions of workarounds, see - /// doc/workarounds.md. - ServerBuilder& EnableWorkaround(grpc_workaround_list id); - - /// NOTE: class experimental_type is not part of the public API of this class. - /// TODO(yashykt): Integrate into public API when this is no longer - /// experimental. - class experimental_type { - public: - explicit experimental_type(ServerBuilder* builder) : builder_(builder) {} - - void SetInterceptorCreators( - std::vector< - std::unique_ptr> - interceptor_creators) { - builder_->interceptor_creators_ = std::move(interceptor_creators); - } - - private: - ServerBuilder* builder_; - }; - - /// NOTE: The function experimental() is not stable public API. It is a view - /// to the experimental components of this class. It may be changed or removed - /// at any time. - experimental_type experimental() { return experimental_type(this); } - - protected: - /// Experimental, to be deprecated - struct Port { - grpc::string addr; - std::shared_ptr creds; - int* selected_port; - }; - - /// Experimental, to be deprecated - typedef std::unique_ptr HostString; - struct NamedService { - explicit NamedService(Service* s) : service(s) {} - NamedService(const grpc::string& h, Service* s) - : host(new grpc::string(h)), service(s) {} - HostString host; - Service* service; - }; - - /// Experimental, to be deprecated - std::vector ports() { return ports_; } - - /// Experimental, to be deprecated - std::vector services() { - std::vector service_refs; - for (auto& ptr : services_) { - service_refs.push_back(ptr.get()); - } - return service_refs; - } - - /// Experimental, to be deprecated - std::vector options() { - std::vector option_refs; - for (auto& ptr : options_) { - option_refs.push_back(ptr.get()); - } - return option_refs; - } - - private: - friend class ::grpc::testing::ServerBuilderPluginTest; - - struct SyncServerSettings { - SyncServerSettings() - : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} - - /// Number of server completion queues to create to listen to incoming RPCs. - int num_cqs; - - /// Minimum number of threads per completion queue that should be listening - /// to incoming RPCs. - int min_pollers; - - /// Maximum number of threads per completion queue that can be listening to - /// incoming RPCs. - int max_pollers; - - /// The timeout for server completion queue's AsyncNext call. - int cq_timeout_msec; - }; - - int max_receive_message_size_; - int max_send_message_size_; - std::vector> options_; - std::vector> services_; - std::vector ports_; - - SyncServerSettings sync_server_settings_; - - /// List of completion queues added via \a AddCompletionQueue method. - std::vector cqs_; - - std::shared_ptr creds_; - std::vector> plugins_; - grpc_resource_quota* resource_quota_; - AsyncGenericService* generic_service_; - struct { - bool is_set; - grpc_compression_level level; - } maybe_default_compression_level_; - struct { - bool is_set; - grpc_compression_algorithm algorithm; - } maybe_default_compression_algorithm_; - uint32_t enabled_compression_algorithms_bitset_; - std::vector> - interceptor_creators_; -}; - +typedef ::grpc_impl::ServerBuilder ServerBuilder; } // namespace grpc #endif // GRPCPP_SERVER_BUILDER_H diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h new file mode 100644 index 00000000000..fafff4fb36e --- /dev/null +++ b/include/grpcpp/server_builder_impl.h @@ -0,0 +1,337 @@ +/* + * + * Copyright 2015-2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SERVER_BUILDER_IMPL_H +#define GRPCPP_SERVER_BUILDER_IMPL_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +struct grpc_resource_quota; + +namespace grpc { + +class AsyncGenericService; +class ResourceQuota; +class CompletionQueue; +class Server; +class ServerCompletionQueue; +class ServerCredentials; +class Service; + +namespace testing { +class ServerBuilderPluginTest; +} // namespace testing +} // namespace grpc +namespace grpc_impl { + +/// A builder class for the creation and startup of \a grpc::Server instances. +class ServerBuilder { + public: + ServerBuilder(); + virtual ~ServerBuilder(); + + ////////////////////////////////////////////////////////////////////////////// + // Primary API's + + /// Return a running server which is ready for processing calls. + /// Before calling, one typically needs to ensure that: + /// 1. a service is registered - so that the server knows what to serve + /// (via RegisterService, or RegisterAsyncGenericService) + /// 2. a listening port has been added - so the server knows where to receive + /// traffic (via AddListeningPort) + /// 3. [for async api only] completion queues have been added via + /// AddCompletionQueue + virtual std::unique_ptr BuildAndStart(); + + /// Register a service. This call does not take ownership of the service. + /// The service must exist for the lifetime of the \a Server instance returned + /// by \a BuildAndStart(). + /// Matches requests with any :authority + ServerBuilder& RegisterService(grpc::Service* service); + + /// Enlists an endpoint \a addr (port with an optional IP address) to + /// bind the \a grpc::Server object to be created to. + /// + /// It can be invoked multiple times. + /// + /// \param addr_uri The address to try to bind to the server in URI form. If + /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, + /// please use IPv6 any, i.e., [::]:, which also accepts IPv4 + /// connections. Valid values include dns:///localhost:1234, / + /// 192.168.1.1:31416, dns:///[::1]:27182, etc.). + /// \param creds The credentials associated with the server. + /// \param selected_port[out] If not `nullptr`, gets populated with the port + /// number bound to the \a grpc::Server for the corresponding endpoint after + /// it is successfully bound by BuildAndStart(), 0 otherwise. AddListeningPort + /// does not modify this pointer. + ServerBuilder& AddListeningPort( + const grpc::string& addr_uri, + std::shared_ptr creds, + int* selected_port = nullptr); + + /// Add a completion queue for handling asynchronous services. + /// + /// Best performance is typically obtained by using one thread per polling + /// completion queue. + /// + /// Caller is required to shutdown the server prior to shutting down the + /// returned completion queue. Caller is also required to drain the + /// completion queue after shutting it down. A typical usage scenario: + /// + /// // While building the server: + /// ServerBuilder builder; + /// ... + /// cq_ = builder.AddCompletionQueue(); + /// server_ = builder.BuildAndStart(); + /// + /// // While shutting down the server; + /// server_->Shutdown(); + /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()! + /// // Drain the cq_ that was created + /// void* ignored_tag; + /// bool ignored_ok; + /// while (cq_->Next(&ignored_tag, &ignored_ok)) { } + /// + /// \param is_frequently_polled This is an optional parameter to inform gRPC + /// library about whether this completion queue would be frequently polled + /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is + /// 'true' and is the recommended setting. Setting this to 'false' (i.e. + /// not polling the completion queue frequently) will have a significantly + /// negative performance impact and hence should not be used in production + /// use cases. + std::unique_ptr AddCompletionQueue( + bool is_frequently_polled = true); + + ////////////////////////////////////////////////////////////////////////////// + // Less commonly used RegisterService variants + + /// Register a service. This call does not take ownership of the service. + /// The service must exist for the lifetime of the \a Server instance + /// returned by \a BuildAndStart(). Only matches requests with :authority \a + /// host + ServerBuilder& RegisterService(const grpc::string& host, + grpc::Service* service); + + /// Register a generic service. + /// Matches requests with any :authority + /// This is mostly useful for writing generic gRPC Proxies where the exact + /// serialization format is unknown + ServerBuilder& RegisterAsyncGenericService( + grpc::AsyncGenericService* service); + + ////////////////////////////////////////////////////////////////////////////// + // Fine control knobs + + /// Set max receive message size in bytes. + /// The default is GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH. + ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) { + max_receive_message_size_ = max_receive_message_size; + return *this; + } + + /// Set max send message size in bytes. + /// The default is GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH. + ServerBuilder& SetMaxSendMessageSize(int max_send_message_size) { + max_send_message_size_ = max_send_message_size; + return *this; + } + + /// \deprecated For backward compatibility. + ServerBuilder& SetMaxMessageSize(int max_message_size) { + return SetMaxReceiveMessageSize(max_message_size); + } + + /// Set the support status for compression algorithms. All algorithms are + /// enabled by default. + /// + /// Incoming calls compressed with an unsupported algorithm will fail with + /// \a GRPC_STATUS_UNIMPLEMENTED. + ServerBuilder& SetCompressionAlgorithmSupportStatus( + grpc_compression_algorithm algorithm, bool enabled); + + /// The default compression level to use for all channel calls in the + /// absence of a call-specific level. + ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level); + + /// The default compression algorithm to use for all channel calls in the + /// absence of a call-specific level. Note that it overrides any compression + /// level set by \a SetDefaultCompressionLevel. + ServerBuilder& SetDefaultCompressionAlgorithm( + grpc_compression_algorithm algorithm); + + /// Set the attached buffer pool for this server + ServerBuilder& SetResourceQuota(const grpc::ResourceQuota& resource_quota); + + ServerBuilder& SetOption(std::unique_ptr option); + + /// Options for synchronous servers. + enum SyncServerOption { + NUM_CQS, ///< Number of completion queues. + MIN_POLLERS, ///< Minimum number of polling threads. + MAX_POLLERS, ///< Maximum number of polling threads. + CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds. + }; + + /// Only useful if this is a Synchronous server. + ServerBuilder& SetSyncServerOption(SyncServerOption option, int value); + + /// Add a channel argument (an escape hatch to tuning core library parameters + /// directly) + template + ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) { + return SetOption(grpc::MakeChannelArgumentOption(arg, value)); + } + + /// For internal use only: Register a ServerBuilderPlugin factory function. + static void InternalAddPluginFactory( + std::unique_ptr (*CreatePlugin)()); + + /// Enable a server workaround. Do not use unless you know what the workaround + /// does. For explanation and detailed descriptions of workarounds, see + /// doc/workarounds.md. + ServerBuilder& EnableWorkaround(grpc_workaround_list id); + + /// NOTE: class experimental_type is not part of the public API of this class. + /// TODO(yashykt): Integrate into public API when this is no longer + /// experimental. + class experimental_type { + public: + explicit experimental_type(grpc_impl::ServerBuilder* builder) + : builder_(builder) {} + + void SetInterceptorCreators( + std::vector> + interceptor_creators) { + builder_->interceptor_creators_ = std::move(interceptor_creators); + } + + private: + ServerBuilder* builder_; + }; + + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + + protected: + /// Experimental, to be deprecated + struct Port { + grpc::string addr; + std::shared_ptr creds; + int* selected_port; + }; + + /// Experimental, to be deprecated + typedef std::unique_ptr HostString; + struct NamedService { + explicit NamedService(grpc::Service* s) : service(s) {} + NamedService(const grpc::string& h, grpc::Service* s) + : host(new grpc::string(h)), service(s) {} + HostString host; + grpc::Service* service; + }; + + /// Experimental, to be deprecated + std::vector ports() { return ports_; } + + /// Experimental, to be deprecated + std::vector services() { + std::vector service_refs; + for (auto& ptr : services_) { + service_refs.push_back(ptr.get()); + } + return service_refs; + } + + /// Experimental, to be deprecated + std::vector options() { + std::vector option_refs; + for (auto& ptr : options_) { + option_refs.push_back(ptr.get()); + } + return option_refs; + } + + private: + friend class ::grpc::testing::ServerBuilderPluginTest; + + struct SyncServerSettings { + SyncServerSettings() + : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} + + /// Number of server completion queues to create to listen to incoming RPCs. + int num_cqs; + + /// Minimum number of threads per completion queue that should be listening + /// to incoming RPCs. + int min_pollers; + + /// Maximum number of threads per completion queue that can be listening to + /// incoming RPCs. + int max_pollers; + + /// The timeout for server completion queue's AsyncNext call. + int cq_timeout_msec; + }; + + int max_receive_message_size_; + int max_send_message_size_; + std::vector> options_; + std::vector> services_; + std::vector ports_; + + SyncServerSettings sync_server_settings_; + + /// List of completion queues added via \a AddCompletionQueue method. + std::vector cqs_; + + std::shared_ptr creds_; + std::vector> plugins_; + grpc_resource_quota* resource_quota_; + grpc::AsyncGenericService* generic_service_; + struct { + bool is_set; + grpc_compression_level level; + } maybe_default_compression_level_; + struct { + bool is_set; + grpc_compression_algorithm algorithm; + } maybe_default_compression_algorithm_; + uint32_t enabled_compression_algorithms_bitset_; + std::vector< + std::unique_ptr> + interceptor_creators_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_SERVER_BUILDER_IMPL_H diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index b7fad558abb..2c52671f9d3 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -29,15 +29,15 @@ #include "src/core/lib/gpr/useful.h" #include "src/cpp/server/thread_pool_interface.h" -namespace grpc { +namespace grpc_impl { -static std::vector (*)()>* +static std::vector (*)()>* g_plugin_factory_list; static gpr_once once_init_plugin_list = GPR_ONCE_INIT; static void do_plugin_list_init(void) { g_plugin_factory_list = - new std::vector (*)()>(); + new std::vector (*)()>(); } ServerBuilder::ServerBuilder() @@ -68,29 +68,29 @@ ServerBuilder::~ServerBuilder() { } } -std::unique_ptr ServerBuilder::AddCompletionQueue( +std::unique_ptr ServerBuilder::AddCompletionQueue( bool is_frequently_polled) { - ServerCompletionQueue* cq = new ServerCompletionQueue( + grpc::ServerCompletionQueue* cq = new grpc::ServerCompletionQueue( GRPC_CQ_NEXT, is_frequently_polled ? GRPC_CQ_DEFAULT_POLLING : GRPC_CQ_NON_LISTENING, nullptr); cqs_.push_back(cq); - return std::unique_ptr(cq); + return std::unique_ptr(cq); } -ServerBuilder& ServerBuilder::RegisterService(Service* service) { +ServerBuilder& ServerBuilder::RegisterService(grpc::Service* service) { services_.emplace_back(new NamedService(service)); return *this; } ServerBuilder& ServerBuilder::RegisterService(const grpc::string& addr, - Service* service) { + grpc::Service* service) { services_.emplace_back(new NamedService(addr, service)); return *this; } ServerBuilder& ServerBuilder::RegisterAsyncGenericService( - AsyncGenericService* service) { + grpc::AsyncGenericService* service) { if (generic_service_) { gpr_log(GPR_ERROR, "Adding multiple AsyncGenericService is unsupported for now. " @@ -103,7 +103,7 @@ ServerBuilder& ServerBuilder::RegisterAsyncGenericService( } ServerBuilder& ServerBuilder::SetOption( - std::unique_ptr option) { + std::unique_ptr option) { options_.push_back(std::move(option)); return *this; } @@ -162,8 +162,8 @@ ServerBuilder& ServerBuilder::SetResourceQuota( } ServerBuilder& ServerBuilder::AddListeningPort( - const grpc::string& addr_uri, std::shared_ptr creds, - int* selected_port) { + const grpc::string& addr_uri, + std::shared_ptr creds, int* selected_port) { const grpc::string uri_scheme = "dns:"; grpc::string addr = addr_uri; if (addr_uri.compare(0, uri_scheme.size(), uri_scheme) == 0) { @@ -176,8 +176,8 @@ ServerBuilder& ServerBuilder::AddListeningPort( return *this; } -std::unique_ptr ServerBuilder::BuildAndStart() { - ChannelArguments args; +std::unique_ptr ServerBuilder::BuildAndStart() { + grpc::ChannelArguments args; for (auto option = options_.begin(); option != options_.end(); ++option) { (*option)->UpdateArguments(&args); (*option)->UpdatePlugins(&plugins_); @@ -239,9 +239,10 @@ std::unique_ptr ServerBuilder::BuildAndStart() { // This is different from the completion queues added to the server via // ServerBuilder's AddCompletionQueue() method (those completion queues // are in 'cqs_' member variable of ServerBuilder object) - std::shared_ptr>> - sync_server_cqs(std::make_shared< - std::vector>>()); + std::shared_ptr>> + sync_server_cqs( + std::make_shared< + std::vector>>()); bool has_frequently_polled_cqs = false; for (auto it = cqs_.begin(); it != cqs_.end(); ++it) { @@ -270,7 +271,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { // Create completion queues to listen to incoming rpc requests for (int i = 0; i < sync_server_settings_.num_cqs; i++) { sync_server_cqs->emplace_back( - new ServerCompletionQueue(GRPC_CQ_NEXT, polling_type, nullptr)); + new grpc::ServerCompletionQueue(GRPC_CQ_NEXT, polling_type, nullptr)); } } @@ -291,13 +292,13 @@ std::unique_ptr ServerBuilder::BuildAndStart() { gpr_log(GPR_INFO, "Callback server."); } - std::unique_ptr server(new Server( + std::unique_ptr server(new grpc::Server( max_receive_message_size_, &args, sync_server_cqs, sync_server_settings_.min_pollers, sync_server_settings_.max_pollers, sync_server_settings_.cq_timeout_msec, resource_quota_, std::move(interceptor_creators_))); - ServerInitializer* initializer = server->initializer(); + grpc::ServerInitializer* initializer = server->initializer(); // Register all the completion queues with the server. i.e // 1. sync_server_cqs: internal completion queues created IF this is a sync @@ -379,7 +380,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { } void ServerBuilder::InternalAddPluginFactory( - std::unique_ptr (*CreatePlugin)()) { + std::unique_ptr (*CreatePlugin)()) { gpr_once_init(&once_init_plugin_list, do_plugin_list_init); (*g_plugin_factory_list).push_back(CreatePlugin); } @@ -394,4 +395,4 @@ ServerBuilder& ServerBuilder::EnableWorkaround(grpc_workaround_list id) { } } -} // namespace grpc +} // namespace grpc_impl diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index 6570bbf9696..7a72ff2b877 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -46,7 +46,6 @@ DEFINE_int32(port, 0, "Server port."); DEFINE_int32(max_send_message_size, -1, "The maximum send message size."); using grpc::Server; -using grpc::ServerBuilder; using grpc::ServerContext; using grpc::ServerCredentials; using grpc::ServerReader; @@ -64,6 +63,7 @@ using grpc::testing::StreamingInputCallResponse; using grpc::testing::StreamingOutputCallRequest; using grpc::testing::StreamingOutputCallResponse; using grpc::testing::TestService; +using grpc_impl::ServerBuilder; const char kEchoInitialMetadataKey[] = "x-grpc-test-echo-initial"; const char kEchoTrailingBinMetadataKey[] = "x-grpc-test-echo-trailing-bin"; diff --git a/test/cpp/qps/qps_server_builder.cc b/test/cpp/qps/qps_server_builder.cc index 5fbc682b756..adfb4de6d98 100644 --- a/test/cpp/qps/qps_server_builder.cc +++ b/test/cpp/qps/qps_server_builder.cc @@ -18,7 +18,7 @@ #include "qps_server_builder.h" -using grpc::ServerBuilder; +using grpc_impl::ServerBuilder; namespace grpc { namespace testing { From 921df1c923858de38a4c282ec5236a57cb1ef1c1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 28 Feb 2019 09:53:10 +0100 Subject: [PATCH 576/814] run_tests.py: increase timeout for pre-build step --- tools/run_tests/run_tests.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 986e7cd58c2..ed1c41e3256 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -106,6 +106,7 @@ def platform_string(): _DEFAULT_TIMEOUT_SECONDS = 5 * 60 +_PRE_BUILD_STEP_TIMEOUT_SECONDS = 10 * 60 def run_shell_command(cmd, env=None, cwd=None): @@ -1634,7 +1635,10 @@ def build_step_environ(cfg): build_steps = list( set( jobset.JobSpec( - cmdline, environ=build_step_environ(build_config), flake_retries=2) + cmdline, + environ=build_step_environ(build_config), + timeout_seconds=_PRE_BUILD_STEP_TIMEOUT_SECONDS, + flake_retries=2) for l in languages for cmdline in l.pre_build_steps())) if make_targets: From f776bee37611d0dbdf73ac0e198d7024cb9716ee Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 5 Mar 2019 11:26:44 +0100 Subject: [PATCH 577/814] add retries for downloading interop matrix images --- tools/interop_matrix/run_interop_matrix_tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index de054e5d878..3f92c8e6641 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -224,7 +224,8 @@ def _pull_images_for_lang(lang, images): cmdline=cmdline, shortname='pull_image_%s' % (image), timeout_seconds=_PULL_IMAGE_TIMEOUT_SECONDS, - shell=True) + shell=True, + flake_retries=2) download_specs.append(spec) # too many image downloads at once tend to get stuck max_pull_jobs = min(args.jobs, _MAX_PARALLEL_DOWNLOADS) From 762676249ef1b316814ba8b1f6489206b36805d3 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 5 Mar 2019 06:32:03 -0800 Subject: [PATCH 578/814] Make grpclb child policy configurable. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 344 +++++++++++++----- test/cpp/end2end/grpclb_end2end_test.cc | 144 ++++++++ 2 files changed, 402 insertions(+), 86 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index c5d1ff22a9d..c1f2846f046 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -39,15 +39,14 @@ /// the balancer, we update the round_robin policy with the new list of /// addresses. If we cannot communicate with the balancer on startup, /// however, we may enter fallback mode, in which case we will populate -/// the RR policy's addresses from the backend addresses returned by the +/// the child policy's addresses from the backend addresses returned by the /// resolver. /// -/// Once an RR policy instance is in place (and getting updated as described), +/// Once a child policy instance is in place (and getting updated as described), /// calls for a pick, a ping, or a cancellation will be serviced right -/// away by forwarding them to the RR instance. Any time there's no RR -/// policy available (i.e., right after the creation of the gRPCLB policy), -/// pick and ping requests are added to a list of pending picks and pings -/// to be flushed and serviced when the RR policy instance becomes available. +/// away by forwarding them to the child policy instance. Any time there's no +/// child policy available (i.e., right after the creation of the gRPCLB +/// policy), pick requests are queued. /// /// \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the /// high level design and details. @@ -279,16 +278,23 @@ class GrpcLb : public LoadBalancingPolicy { UniquePtr picker) override; void RequestReresolution() override; + void set_child(LoadBalancingPolicy* child) { child_ = child; } + private: + bool CalledByPendingChild() const; + bool CalledByCurrentChild() const; + RefCountedPtr parent_; + LoadBalancingPolicy* child_ = nullptr; }; ~GrpcLb(); void ShutdownLocked() override; - // Helper function used in UpdateLocked(). + // Helper functions used in UpdateLocked(). void ProcessChannelArgsLocked(const grpc_channel_args& args); + void ParseLbConfig(Config* grpclb_config); // Methods for dealing with the balancer channel and call. void StartBalancerCallLocked(); @@ -296,10 +302,11 @@ class GrpcLb : public LoadBalancingPolicy { void StartBalancerCallRetryTimerLocked(); static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error); - // Methods for dealing with the RR policy. - grpc_channel_args* CreateRoundRobinPolicyArgsLocked(); - void CreateRoundRobinPolicyLocked(Args args); - void CreateOrUpdateRoundRobinPolicyLocked(); + // Methods for dealing with the child policy. + grpc_channel_args* CreateChildPolicyArgsLocked(); + OrphanablePtr CreateChildPolicyLocked( + const char* name, grpc_channel_args* args); + void CreateOrUpdateChildPolicyLocked(); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -345,8 +352,14 @@ class GrpcLb : public LoadBalancingPolicy { grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; - // The RR policy to use for the backends. - OrphanablePtr rr_policy_; + // The child policy to use for the backends. + OrphanablePtr child_policy_; + // When switching child policies, the new policy will be stored here + // until it reports READY, at which point it will be moved to child_policy_. + OrphanablePtr pending_child_policy_; + // The child policy name and config. + UniquePtr child_policy_name_; + RefCountedPtr child_policy_config_; }; // @@ -558,14 +571,30 @@ GrpcLb::Picker::PickResult GrpcLb::Picker::Pick(PickState* pick, // GrpcLb::Helper // +bool GrpcLb::Helper::CalledByPendingChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->pending_child_policy_.get(); +} + +bool GrpcLb::Helper::CalledByCurrentChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->child_policy_.get(); +} + Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { - if (parent_->shutting_down_) return nullptr; + if (parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return nullptr; + } return parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, const grpc_channel_args& args) { - if (parent_->shutting_down_) return nullptr; + if (parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return nullptr; + } return parent_->channel_control_helper()->CreateChannel(target, args); } @@ -576,31 +605,50 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, GRPC_ERROR_UNREF(state_error); return; } + // If this request is from the pending child policy, ignore it until + // it reports READY, at which point we swap it into place. + if (CalledByPendingChild()) { + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, + "[grpclb %p helper %p] pending child policy %p reports state=%s", + parent_.get(), this, parent_->pending_child_policy_.get(), + grpc_connectivity_state_name(state)); + } + if (state != GRPC_CHANNEL_READY) { + GRPC_ERROR_UNREF(state_error); + return; + } + parent_->child_policy_ = std::move(parent_->pending_child_policy_); + } else if (!CalledByCurrentChild()) { + // This request is from an outdated child, so ignore it. + GRPC_ERROR_UNREF(state_error); + return; + } // There are three cases to consider here: // 1. We're in fallback mode. In this case, we're always going to use - // RR's result, so we pass its picker through as-is. + // the child policy's result, so we pass its picker through as-is. // 2. The serverlist contains only drop entries. In this case, we // want to use our own picker so that we can return the drops. // 3. Not in fallback mode and serverlist is not all drops (i.e., it // may be empty or contain at least one backend address). There are // two sub-cases: - // a. RR is reporting state READY. In this case, we wrap RR's - // picker in our own, so that we can handle drops and LB token - // metadata for each pick. - // b. RR is reporting a state other than READY. In this case, we - // don't want to use our own picker, because we don't want to - // process drops for picks that yield a QUEUE result; this would + // a. The child policy is reporting state READY. In this case, we wrap + // the child's picker in our own, so that we can handle drops and LB + // token metadata for each pick. + // b. The child policy is reporting a state other than READY. In this + // case, we don't want to use our own picker, because we don't want + // to process drops for picks that yield a QUEUE result; this would // result in dropping too many calls, since we will see the // queued picks multiple times, and we'd consider each one a // separate call for the drop calculation. // - // Cases 1 and 3b: return picker from RR as-is. + // Cases 1 and 3b: return picker from the child policy as-is. if (parent_->serverlist_ == nullptr || (!parent_->serverlist_->ContainsAllDropEntries() && state != GRPC_CHANNEL_READY)) { if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p helper %p] state=%s passing RR picker %p as-is", + "[grpclb %p helper %p] state=%s passing child picker %p as-is", parent_.get(), this, grpc_connectivity_state_name(state), picker.get()); } @@ -608,9 +656,9 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, std::move(picker)); return; } - // Cases 2 and 3a: wrap picker from RR in our own picker. + // Cases 2 and 3a: wrap picker from the child in our own picker. if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping RR picker %p", + gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping child picker %p", parent_.get(), this, grpc_connectivity_state_name(state), picker.get()); } @@ -628,15 +676,19 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, void GrpcLb::Helper::RequestReresolution() { if (parent_->shutting_down_) return; + // If there is a pending child policy, ignore re-resolution requests + // from the current child policy (or any outdated pending child). + if (parent_->pending_child_policy_ != nullptr && !CalledByPendingChild()) { + return; + } if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Re-resolution requested from the internal RR policy " - "(%p).", - parent_.get(), parent_->rr_policy_.get()); + "[grpclb %p] Re-resolution requested from child policy (%p).", + parent_.get(), child_); } // If we are talking to a balancer, we expect to get updated addresses // from the balancer, so we can ignore the re-resolution request from - // the RR policy. Otherwise, pass the re-resolution request up to the + // the child policy. Otherwise, pass the re-resolution request up to the // channel. if (parent_->lb_calld_ == nullptr || !parent_->lb_calld_->seen_initial_response()) { @@ -984,7 +1036,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( // instance will be destroyed either upon the next update or when the // GrpcLb instance is destroyed. grpclb_policy->serverlist_ = std::move(serverlist_wrapper); - grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); + grpclb_policy->CreateOrUpdateChildPolicyLocked(); } } else { // No valid initial response or serverlist found. @@ -1200,7 +1252,8 @@ void GrpcLb::ShutdownLocked() { if (fallback_timer_callback_pending_) { grpc_timer_cancel(&lb_fallback_timer_); } - rr_policy_.reset(); + child_policy_.reset(); + pending_child_policy_.reset(); // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -1220,17 +1273,24 @@ void GrpcLb::ResetBackoffLocked() { if (lb_channel_ != nullptr) { grpc_channel_reset_connect_backoff(lb_channel_); } - if (rr_policy_ != nullptr) { - rr_policy_->ResetBackoffLocked(); + if (child_policy_ != nullptr) { + child_policy_->ResetBackoffLocked(); + } + if (pending_child_policy_ != nullptr) { + pending_child_policy_->ResetBackoffLocked(); } } void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { - // delegate to the RoundRobin to fill the children subchannels. - if (rr_policy_ != nullptr) { - rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + // delegate to the child policy to fill the children subchannels. + if (child_policy_ != nullptr) { + child_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + } + if (pending_child_policy_ != nullptr) { + pending_child_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); } gpr_atm uuid = gpr_atm_no_barrier_load(&lb_channel_uuid_); if (uuid != 0) { @@ -1238,6 +1298,32 @@ void GrpcLb::FillChildRefsForChannelz( } } +void GrpcLb::UpdateLocked(const grpc_channel_args& args, + RefCountedPtr lb_config) { + const bool is_initial_update = lb_channel_ == nullptr; + ParseLbConfig(lb_config.get()); + ProcessChannelArgsLocked(args); + // Update the existing child policy. + if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); + // If this is the initial update, start the fallback timer. + if (is_initial_update) { + if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && + !fallback_timer_callback_pending_) { + grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; + Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Ref for callback + GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, + grpc_combiner_scheduler(combiner())); + fallback_timer_callback_pending_ = true; + grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); + } + StartBalancerCallLocked(); + } +} + +// +// helpers for UpdateLocked() +// + // Returns the backend addresses extracted from the given addresses. UniquePtr ExtractBackendAddresses( const ServerAddressList& addresses) { @@ -1299,25 +1385,26 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { grpc_channel_args_destroy(lb_channel_args); } -void GrpcLb::UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) { - const bool is_initial_update = lb_channel_ == nullptr; - ProcessChannelArgsLocked(args); - // Update the existing RR policy. - if (rr_policy_ != nullptr) CreateOrUpdateRoundRobinPolicyLocked(); - // If this is the initial update, start the fallback timer and the - // balancer call. - if (is_initial_update) { - if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && - !fallback_timer_callback_pending_) { - grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; - Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Ref for callback - GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, - grpc_combiner_scheduler(combiner())); - fallback_timer_callback_pending_ = true; - grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); +void GrpcLb::ParseLbConfig(Config* grpclb_config) { + const grpc_json* child_policy = nullptr; + if (grpclb_config != nullptr) { + const grpc_json* grpclb_config_json = grpclb_config->json(); + for (const grpc_json* field = grpclb_config_json; field != nullptr; + field = field->next) { + if (field->key == nullptr) return; + if (strcmp(field->key, "childPolicy") == 0) { + if (child_policy != nullptr) return; // Duplicate. + child_policy = ParseLoadBalancingConfig(field); + } } - StartBalancerCallLocked(); + } + if (child_policy != nullptr) { + child_policy_name_ = UniquePtr(gpr_strdup(child_policy->key)); + child_policy_config_ = MakeRefCounted( + child_policy->child, grpclb_config->service_config()); + } else { + child_policy_name_.reset(); + child_policy_config_.reset(); } } @@ -1352,7 +1439,7 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { grpclb_policy); } GPR_ASSERT(grpclb_policy->fallback_backend_addresses_ != nullptr); - grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); + grpclb_policy->CreateOrUpdateChildPolicyLocked(); } grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); } @@ -1396,10 +1483,10 @@ void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) { } // -// code for interacting with the RR policy +// code for interacting with the child policy // -grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { +grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked() { ServerAddressList tmp_addresses; ServerAddressList* addresses = &tmp_addresses; bool is_backend_from_grpclb_load_balancer = false; @@ -1408,7 +1495,7 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats()); is_backend_from_grpclb_load_balancer = true; } else { - // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't + // If CreateOrUpdateChildPolicyLocked() is invoked when we haven't // received any serverlist from the balancer, we use the fallback backends // returned by the resolver. Note that the fallback backend list may be // empty, in which case the new round_robin policy will keep the requested @@ -1435,49 +1522,134 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); ++num_args_to_add; } - grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( + return grpc_channel_args_copy_and_add_and_remove( args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, num_args_to_add); - return args; } -void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { - GPR_ASSERT(rr_policy_ == nullptr); - rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - "round_robin", std::move(args)); - if (GPR_UNLIKELY(rr_policy_ == nullptr)) { - gpr_log(GPR_ERROR, "[grpclb %p] Failure creating a RoundRobin policy", - this); - return; +OrphanablePtr GrpcLb::CreateChildPolicyLocked( + const char* name, grpc_channel_args* args) { + Helper* helper = New(Ref()); + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = combiner(); + lb_policy_args.args = args; + lb_policy_args.channel_control_helper = + UniquePtr(helper); + OrphanablePtr lb_policy = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + name, std::move(lb_policy_args)); + if (GPR_UNLIKELY(lb_policy == nullptr)) { + gpr_log(GPR_ERROR, "[grpclb %p] Failure creating child policy %s", this, + name); + return nullptr; } + helper->set_child(lb_policy.get()); if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, - rr_policy_.get()); + gpr_log(GPR_INFO, "[grpclb %p] Created new child policy %s (%p)", this, + name, lb_policy.get()); } // Add the gRPC LB's interested_parties pollset_set to that of the newly - // created RR policy. This will make the RR policy progress upon activity on - // gRPC LB, which in turn is tied to the application's call. - grpc_pollset_set_add_pollset_set(rr_policy_->interested_parties(), + // created child policy. This will make the child policy progress upon + // activity on gRPC LB, which in turn is tied to the application's call. + grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(), interested_parties()); + return lb_policy; } -void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { +void GrpcLb::CreateOrUpdateChildPolicyLocked() { if (shutting_down_) return; - grpc_channel_args* args = CreateRoundRobinPolicyArgsLocked(); + grpc_channel_args* args = CreateChildPolicyArgsLocked(); GPR_ASSERT(args != nullptr); - if (rr_policy_ == nullptr) { - LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = combiner(); - lb_policy_args.args = args; - lb_policy_args.channel_control_helper = - UniquePtr(New(Ref())); - CreateRoundRobinPolicyLocked(std::move(lb_policy_args)); + // If the child policy name changes, we need to create a new child + // policy. When this happens, we leave child_policy_ as-is and store + // the new child policy in pending_child_policy_. Once the new child + // policy transitions into state READY, we swap it into child_policy_, + // replacing the original child policy. So pending_child_policy_ is + // non-null only between when we apply an update that changes the child + // policy name and when the new child reports state READY. + // + // Updates can arrive at any point during this transition. We always + // apply updates relative to the most recently created child policy, + // even if the most recent one is still in pending_child_policy_. This + // is true both when applying the updates to an existing child policy + // and when determining whether we need to create a new policy. + // + // As a result of this, there are several cases to consider here: + // + // 1. We have no existing child policy (i.e., we have started up but + // have not yet received a serverlist from the balancer or gone + // into fallback mode; in this case, both child_policy_ and + // pending_child_policy_ are null). In this case, we create a + // new child policy and store it in child_policy_. + // + // 2. We have an existing child policy and have no pending child policy + // from a previous update (i.e., either there has not been a + // previous update that changed the policy name, or we have already + // finished swapping in the new policy; in this case, child_policy_ + // is non-null but pending_child_policy_ is null). In this case: + // a. If child_policy_->name() equals child_policy_name, then we + // update the existing child policy. + // b. If child_policy_->name() does not equal child_policy_name, + // we create a new policy. The policy will be stored in + // pending_child_policy_ and will later be swapped into + // child_policy_ by the helper when the new child transitions + // into state READY. + // + // 3. We have an existing child policy and have a pending child policy + // from a previous update (i.e., a previous update set + // pending_child_policy_ as per case 2b above and that policy has + // not yet transitioned into state READY and been swapped into + // child_policy_; in this case, both child_policy_ and + // pending_child_policy_ are non-null). In this case: + // a. If pending_child_policy_->name() equals child_policy_name, + // then we update the existing pending child policy. + // b. If pending_child_policy->name() does not equal + // child_policy_name, then we create a new policy. The new + // policy is stored in pending_child_policy_ (replacing the one + // that was there before, which will be immediately shut down) + // and will later be swapped into child_policy_ by the helper + // when the new child transitions into state READY. + const char* child_policy_name = + child_policy_name_ == nullptr ? "round_robin" : child_policy_name_.get(); + const bool create_policy = + // case 1 + child_policy_ == nullptr || + // case 2b + (pending_child_policy_ == nullptr && + strcmp(child_policy_->name(), child_policy_name) != 0) || + // case 3b + (pending_child_policy_ != nullptr && + strcmp(pending_child_policy_->name(), child_policy_name) != 0); + LoadBalancingPolicy* policy_to_update = nullptr; + if (create_policy) { + // Cases 1, 2b, and 3b: create a new child policy. + // If child_policy_ is null, we set it (case 1), else we set + // pending_child_policy_ (cases 2b and 3b). + auto& lb_policy = + child_policy_ == nullptr ? child_policy_ : pending_child_policy_; + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, "[grpclb %p] Creating new %schild policy %s", this, + child_policy_ == nullptr ? "" : "pending ", child_policy_name); + } + lb_policy = CreateChildPolicyLocked(child_policy_name, args); + policy_to_update = lb_policy.get(); + } else { + // Cases 2a and 3a: update an existing policy. + // If we have a pending child policy, send the update to the pending + // policy (case 3a), else send it to the current policy (case 2a). + policy_to_update = pending_child_policy_ != nullptr + ? pending_child_policy_.get() + : child_policy_.get(); } + GPR_ASSERT(policy_to_update != nullptr); + // Update the policy. if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Updating RR policy %p", this, - rr_policy_.get()); + gpr_log(GPR_INFO, "[grpclb %p] Updating %schild policy %p", this, + policy_to_update == pending_child_policy_.get() ? "pending " : "", + policy_to_update); } - rr_policy_->UpdateLocked(*args, nullptr); + policy_to_update->UpdateLocked(*args, child_policy_config_); + // Clean up. grpc_channel_args_destroy(args); } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 2288b88b517..31353ba1304 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -723,6 +723,150 @@ TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfig) { EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } +TEST_F(SingleBalancerTest, UsePickFirstChildPolicy) { + SetNextResolutionAllBalancers( + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"pick_first\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + const size_t kNumRpcs = num_backends_ * 2; + CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); + balancers_[0]->NotifyDoneWithServerlists(); + // Check that all requests went to the first backend. This verifies + // that we used pick_first instead of round_robin as the child policy. + EXPECT_EQ(backend_servers_[0].service_->request_count(), kNumRpcs); + for (size_t i = 1; i < backends_.size(); ++i) { + EXPECT_EQ(backend_servers_[i].service_->request_count(), 0UL); + } + // The balancer got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, SwapChildPolicy) { + SetNextResolutionAllBalancers( + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"pick_first\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + const size_t kNumRpcs = num_backends_ * 2; + CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); + // Check that all requests went to the first backend. This verifies + // that we used pick_first instead of round_robin as the child policy. + EXPECT_EQ(backend_servers_[0].service_->request_count(), kNumRpcs); + for (size_t i = 1; i < backends_.size(); ++i) { + EXPECT_EQ(backend_servers_[i].service_->request_count(), 0UL); + } + // Send new resolution that removes child policy from service config. + SetNextResolutionAllBalancers("{}"); + WaitForAllBackends(); + CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); + // Check that every backend saw the same number of requests. This verifies + // that we used round_robin. + for (size_t i = 0; i < backends_.size(); ++i) { + EXPECT_EQ(backend_servers_[i].service_->request_count(), 2UL); + } + // Done. + balancers_[0]->NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, UpdatesGoToMostRecentChildPolicy) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + int unreachable_balancer_port = grpc_pick_unused_port_or_die(); + int unreachable_backend_port = grpc_pick_unused_port_or_die(); + // Phase 1: Start with RR pointing to first backend. + gpr_log(GPR_INFO, "PHASE 1: Initial setup with RR with first backend"); + SetNextResolution( + { + // Unreachable balancer. + {unreachable_balancer_port, true, ""}, + // Fallback address: first backend. + {backend_servers_[0].port_, false, ""}, + }, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"round_robin\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + // RPCs should go to first backend. + WaitForBackend(0); + // Phase 2: Switch to PF pointing to unreachable backend. + gpr_log(GPR_INFO, "PHASE 2: Update to use PF with unreachable backend"); + SetNextResolution( + { + // Unreachable balancer. + {unreachable_balancer_port, true, ""}, + // Fallback address: unreachable backend. + {unreachable_backend_port, false, ""}, + }, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"pick_first\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + // RPCs should continue to go to the first backend, because the new + // PF child policy will never go into state READY. + WaitForBackend(0); + // Phase 3: Switch back to RR pointing to second and third backends. + // This ensures that we create a new policy rather than updating the + // pending PF policy. + gpr_log(GPR_INFO, "PHASE 3: Update to use RR again with two backends"); + SetNextResolution( + { + // Unreachable balancer. + {unreachable_balancer_port, true, ""}, + // Fallback address: second and third backends. + {backend_servers_[1].port_, false, ""}, + {backend_servers_[2].port_, false, ""}, + }, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"round_robin\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + // RPCs should go to the second and third backends. + WaitForBackend(1); + WaitForBackend(2); +} + TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { SetNextResolutionAllBalancers(); // Same backend listed twice. From 840e7a2861d5221074dca0e745afa0f8fbc820b0 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 5 Mar 2019 07:28:32 -0800 Subject: [PATCH 579/814] Store LB policy name in Config object. --- .../ext/filters/client_channel/lb_policy.h | 3 ++- .../client_channel/lb_policy/grpclb/grpclb.cc | 16 ++++++-------- .../client_channel/lb_policy/xds/xds.cc | 22 ++++++++----------- .../client_channel/resolver_result_parsing.cc | 4 ++-- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 7a876966524..ee5d860b378 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -210,7 +210,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { RefCountedPtr service_config) : json_(lb_config), service_config_(std::move(service_config)) {} - const grpc_json* json() const { return json_; } + const char* name() const { return json_->key; } + const grpc_json* config() const { return json_->child; } RefCountedPtr service_config() const { return service_config_; } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index c1f2846f046..d6c8a60fbfe 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -357,8 +357,7 @@ class GrpcLb : public LoadBalancingPolicy { // When switching child policies, the new policy will be stored here // until it reports READY, at which point it will be moved to child_policy_. OrphanablePtr pending_child_policy_; - // The child policy name and config. - UniquePtr child_policy_name_; + // The child policy config. RefCountedPtr child_policy_config_; }; @@ -1388,7 +1387,7 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { void GrpcLb::ParseLbConfig(Config* grpclb_config) { const grpc_json* child_policy = nullptr; if (grpclb_config != nullptr) { - const grpc_json* grpclb_config_json = grpclb_config->json(); + const grpc_json* grpclb_config_json = grpclb_config->config(); for (const grpc_json* field = grpclb_config_json; field != nullptr; field = field->next) { if (field->key == nullptr) return; @@ -1399,11 +1398,9 @@ void GrpcLb::ParseLbConfig(Config* grpclb_config) { } } if (child_policy != nullptr) { - child_policy_name_ = UniquePtr(gpr_strdup(child_policy->key)); - child_policy_config_ = MakeRefCounted( - child_policy->child, grpclb_config->service_config()); + child_policy_config_ = + MakeRefCounted(child_policy, grpclb_config->service_config()); } else { - child_policy_name_.reset(); child_policy_config_.reset(); } } @@ -1609,8 +1606,9 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() { // that was there before, which will be immediately shut down) // and will later be swapped into child_policy_ by the helper // when the new child transitions into state READY. - const char* child_policy_name = - child_policy_name_ == nullptr ? "round_robin" : child_policy_name_.get(); + const char* child_policy_name = child_policy_config_ == nullptr + ? "round_robin" + : child_policy_config_->name(); const bool create_policy = // case 1 child_policy_ == nullptr || diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 6c10d876af7..e6ce4fef782 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -302,7 +302,6 @@ class XdsLb : public LoadBalancingPolicy { // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. - UniquePtr fallback_policy_name_; RefCountedPtr fallback_policy_config_; int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. @@ -313,7 +312,6 @@ class XdsLb : public LoadBalancingPolicy { grpc_closure lb_on_fallback_; // The policy to use for the backends. - UniquePtr child_policy_name_; RefCountedPtr child_policy_config_; OrphanablePtr child_policy_; }; @@ -1079,7 +1077,7 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { } void XdsLb::ParseLbConfig(Config* xds_config) { - const grpc_json* xds_config_json = xds_config->json(); + const grpc_json* xds_config_json = xds_config->config(); const char* balancer_name = nullptr; grpc_json* child_policy = nullptr; grpc_json* fallback_policy = nullptr; @@ -1099,17 +1097,15 @@ void XdsLb::ParseLbConfig(Config* xds_config) { } } if (balancer_name == nullptr) return; // Required field. + balancer_name_ = UniquePtr(gpr_strdup(balancer_name)); if (child_policy != nullptr) { - child_policy_name_ = UniquePtr(gpr_strdup(child_policy->key)); - child_policy_config_ = MakeRefCounted(child_policy->child, - xds_config->service_config()); + child_policy_config_ = + MakeRefCounted(child_policy, xds_config->service_config()); } if (fallback_policy != nullptr) { - fallback_policy_name_ = UniquePtr(gpr_strdup(fallback_policy->key)); - fallback_policy_config_ = MakeRefCounted( - fallback_policy->child, xds_config->service_config()); + fallback_policy_config_ = + MakeRefCounted(fallback_policy, xds_config->service_config()); } - balancer_name_ = UniquePtr(gpr_strdup(balancer_name)); } void XdsLb::UpdateLocked(const grpc_channel_args& args, @@ -1328,16 +1324,16 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { GPR_ASSERT(args != nullptr); // TODO(juanlishen): If the child policy is not configured via service config, // use whatever algorithm is specified by the balancer. - // TODO(juanlishen): Switch policy according to child_policy_config->key. + // TODO(juanlishen): Switch policy according to child_policy_config_->name(). if (child_policy_ == nullptr) { LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); lb_policy_args.args = args; lb_policy_args.channel_control_helper = UniquePtr(New(Ref())); - CreateChildPolicyLocked(child_policy_name_ == nullptr + CreateChildPolicyLocked(child_policy_config_ == nullptr ? "round_robin" - : child_policy_name_.get(), + : child_policy_config_->name(), std::move(lb_policy_args)); if (grpc_lb_xds_trace.enabled()) { gpr_log(GPR_INFO, "[xdslb %p] Created a new child policy %p", this, diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index aaa63178793..ad23c735b51 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -148,8 +148,8 @@ void ProcessedResolverResult::ParseLbConfigFromServiceConfig( LoadBalancingPolicy::ParseLoadBalancingConfig(field); if (policy != nullptr) { lb_policy_name_.reset(gpr_strdup(policy->key)); - lb_policy_config_ = MakeRefCounted( - policy->child, service_config_); + lb_policy_config_ = + MakeRefCounted(policy, service_config_); } } From c060d55cc7b9dae35cc9cec50756405e69e9b1f3 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 5 Mar 2019 14:01:01 -0500 Subject: [PATCH 580/814] Revert "Introduce grpc_byte_buffer_reader_peek and use it for Protobuf parsing." --- grpc.def | 1 - include/grpc/impl/codegen/byte_buffer.h | 13 ---- include/grpcpp/impl/codegen/core_codegen.h | 2 - .../impl/codegen/core_codegen_interface.h | 2 - .../grpcpp/impl/codegen/proto_buffer_reader.h | 18 ++--- src/core/lib/surface/byte_buffer_reader.cc | 17 ----- src/cpp/common/core_codegen.cc | 5 -- src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 - src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 - test/core/surface/byte_buffer_reader_test.cc | 70 ------------------ .../core/surface/public_headers_must_be_c89.c | 1 - test/cpp/microbenchmarks/bm_byte_buffer.cc | 71 +------------------ 12 files changed, 11 insertions(+), 194 deletions(-) diff --git a/grpc.def b/grpc.def index 922f95383a3..e0a08d22c19 100644 --- a/grpc.def +++ b/grpc.def @@ -149,7 +149,6 @@ EXPORTS grpc_byte_buffer_reader_init grpc_byte_buffer_reader_destroy grpc_byte_buffer_reader_next - grpc_byte_buffer_reader_peek grpc_byte_buffer_reader_readall grpc_raw_byte_buffer_from_reader gpr_log_severity_string diff --git a/include/grpc/impl/codegen/byte_buffer.h b/include/grpc/impl/codegen/byte_buffer.h index 12479068155..774655ed66f 100644 --- a/include/grpc/impl/codegen/byte_buffer.h +++ b/include/grpc/impl/codegen/byte_buffer.h @@ -73,19 +73,6 @@ GRPCAPI void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader); GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice); -/** EXPERIMENTAL API - This function may be removed and changed, in the future. - * - * Updates \a slice with the next piece of data from from \a reader and returns - * 1. Returns 0 at the end of the stream. Caller is responsible for making sure - * the slice pointer remains valid when accessed. - * - * NOTE: Do not use this function unless the caller can guarantee that the - * underlying grpc_byte_buffer outlasts the use of the slice. This is only - * safe when the underlying grpc_byte_buffer remains immutable while slice - * is being accessed. */ -GRPCAPI int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, - grpc_slice** slice); - /** Merge all data from \a reader into single slice */ GRPCAPI grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader* reader); diff --git a/include/grpcpp/impl/codegen/core_codegen.h b/include/grpcpp/impl/codegen/core_codegen.h index 27729e0d5db..b7ddb0c791c 100644 --- a/include/grpcpp/impl/codegen/core_codegen.h +++ b/include/grpcpp/impl/codegen/core_codegen.h @@ -85,8 +85,6 @@ class CoreCodegen final : public CoreCodegenInterface { grpc_byte_buffer_reader* reader) override; int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) override; - int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, - grpc_slice** slice) override; grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) override; diff --git a/include/grpcpp/impl/codegen/core_codegen_interface.h b/include/grpcpp/impl/codegen/core_codegen_interface.h index 3792c3d4693..1d92b4f0dff 100644 --- a/include/grpcpp/impl/codegen/core_codegen_interface.h +++ b/include/grpcpp/impl/codegen/core_codegen_interface.h @@ -92,8 +92,6 @@ class CoreCodegenInterface { grpc_byte_buffer_reader* reader) = 0; virtual int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) = 0; - virtual int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, - grpc_slice** slice) = 0; virtual grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) = 0; diff --git a/include/grpcpp/impl/codegen/proto_buffer_reader.h b/include/grpcpp/impl/codegen/proto_buffer_reader.h index 734da366f3a..9acae476b11 100644 --- a/include/grpcpp/impl/codegen/proto_buffer_reader.h +++ b/include/grpcpp/impl/codegen/proto_buffer_reader.h @@ -73,7 +73,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { } /// If we have backed up previously, we need to return the backed-up slice if (backup_count_ > 0) { - *data = GRPC_SLICE_START_PTR(*slice_) + GRPC_SLICE_LENGTH(*slice_) - + *data = GRPC_SLICE_START_PTR(slice_) + GRPC_SLICE_LENGTH(slice_) - backup_count_; GPR_CODEGEN_ASSERT(backup_count_ <= INT_MAX); *size = (int)backup_count_; @@ -81,14 +81,15 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { return true; } /// Otherwise get the next slice from the byte buffer reader - if (!g_core_codegen_interface->grpc_byte_buffer_reader_peek(&reader_, + if (!g_core_codegen_interface->grpc_byte_buffer_reader_next(&reader_, &slice_)) { return false; } - *data = GRPC_SLICE_START_PTR(*slice_); + g_core_codegen_interface->grpc_slice_unref(slice_); + *data = GRPC_SLICE_START_PTR(slice_); // On win x64, int is only 32bit - GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(*slice_) <= INT_MAX); - byte_count_ += * size = (int)GRPC_SLICE_LENGTH(*slice_); + GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX); + byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_); return true; } @@ -99,7 +100,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { /// bytes that have already been returned by the last call of Next. /// So do the backup and have that ready for a later Next. void BackUp(int count) override { - GPR_CODEGEN_ASSERT(count <= static_cast(GRPC_SLICE_LENGTH(*slice_))); + GPR_CODEGEN_ASSERT(count <= static_cast(GRPC_SLICE_LENGTH(slice_))); backup_count_ = count; } @@ -134,15 +135,14 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { int64_t backup_count() { return backup_count_; } void set_backup_count(int64_t backup_count) { backup_count_ = backup_count; } grpc_byte_buffer_reader* reader() { return &reader_; } - grpc_slice* slice() { return slice_; } - grpc_slice** mutable_slice_ptr() { return &slice_; } + grpc_slice* slice() { return &slice_; } private: int64_t byte_count_; ///< total bytes read since object creation int64_t backup_count_; ///< how far backed up in the stream we are grpc_byte_buffer_reader reader_; ///< internal object to read \a grpc_slice ///< from the \a grpc_byte_buffer - grpc_slice* slice_; ///< current slice passed back to the caller + grpc_slice slice_; ///< current slice passed back to the caller Status status_; ///< status of the entire object }; diff --git a/src/core/lib/surface/byte_buffer_reader.cc b/src/core/lib/surface/byte_buffer_reader.cc index ed8ecc49590..1debc98ea0c 100644 --- a/src/core/lib/surface/byte_buffer_reader.cc +++ b/src/core/lib/surface/byte_buffer_reader.cc @@ -91,23 +91,6 @@ void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader) { } } -int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, - grpc_slice** slice) { - switch (reader->buffer_in->type) { - case GRPC_BB_RAW: { - grpc_slice_buffer* slice_buffer; - slice_buffer = &reader->buffer_out->data.raw.slice_buffer; - if (reader->current.index < slice_buffer->count) { - *slice = &slice_buffer->slices[reader->current.index]; - reader->current.index += 1; - return 1; - } - break; - } - } - return 0; -} - int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) { switch (reader->buffer_in->type) { diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc index 665305ca0a5..ab5f601fdd4 100644 --- a/src/cpp/common/core_codegen.cc +++ b/src/cpp/common/core_codegen.cc @@ -139,11 +139,6 @@ int CoreCodegen::grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, return ::grpc_byte_buffer_reader_next(reader, slice); } -int CoreCodegen::grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, - grpc_slice** slice) { - return ::grpc_byte_buffer_reader_peek(reader, slice); -} - grpc_byte_buffer* CoreCodegen::grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) { return ::grpc_raw_byte_buffer_create(slice, nslices); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index f8a31286115..fdbe0df4e52 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -172,7 +172,6 @@ grpc_byte_buffer_destroy_type grpc_byte_buffer_destroy_import; grpc_byte_buffer_reader_init_type grpc_byte_buffer_reader_init_import; grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_import; grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import; -grpc_byte_buffer_reader_peek_type grpc_byte_buffer_reader_peek_import; grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import; grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import; gpr_log_severity_string_type gpr_log_severity_string_import; @@ -441,7 +440,6 @@ void grpc_rb_load_imports(HMODULE library) { grpc_byte_buffer_reader_init_import = (grpc_byte_buffer_reader_init_type) GetProcAddress(library, "grpc_byte_buffer_reader_init"); grpc_byte_buffer_reader_destroy_import = (grpc_byte_buffer_reader_destroy_type) GetProcAddress(library, "grpc_byte_buffer_reader_destroy"); grpc_byte_buffer_reader_next_import = (grpc_byte_buffer_reader_next_type) GetProcAddress(library, "grpc_byte_buffer_reader_next"); - grpc_byte_buffer_reader_peek_import = (grpc_byte_buffer_reader_peek_type) GetProcAddress(library, "grpc_byte_buffer_reader_peek"); grpc_byte_buffer_reader_readall_import = (grpc_byte_buffer_reader_readall_type) GetProcAddress(library, "grpc_byte_buffer_reader_readall"); grpc_raw_byte_buffer_from_reader_import = (grpc_raw_byte_buffer_from_reader_type) GetProcAddress(library, "grpc_raw_byte_buffer_from_reader"); gpr_log_severity_string_import = (gpr_log_severity_string_type) GetProcAddress(library, "gpr_log_severity_string"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 275ca6e9cbf..cf16f0ca33b 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -491,9 +491,6 @@ extern grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_impo typedef int(*grpc_byte_buffer_reader_next_type)(grpc_byte_buffer_reader* reader, grpc_slice* slice); extern grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import; #define grpc_byte_buffer_reader_next grpc_byte_buffer_reader_next_import -typedef int(*grpc_byte_buffer_reader_peek_type)(grpc_byte_buffer_reader* reader, grpc_slice** slice); -extern grpc_byte_buffer_reader_peek_type grpc_byte_buffer_reader_peek_import; -#define grpc_byte_buffer_reader_peek grpc_byte_buffer_reader_peek_import typedef grpc_slice(*grpc_byte_buffer_reader_readall_type)(grpc_byte_buffer_reader* reader); extern grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import; #define grpc_byte_buffer_reader_readall grpc_byte_buffer_reader_readall_import diff --git a/test/core/surface/byte_buffer_reader_test.cc b/test/core/surface/byte_buffer_reader_test.cc index bc368c49657..301a1e283ba 100644 --- a/test/core/surface/byte_buffer_reader_test.cc +++ b/test/core/surface/byte_buffer_reader_test.cc @@ -101,73 +101,6 @@ static void test_read_none_compressed_slice(void) { grpc_byte_buffer_destroy(buffer); } -static void test_peek_one_slice(void) { - grpc_slice slice; - grpc_byte_buffer* buffer; - grpc_byte_buffer_reader reader; - grpc_slice* first_slice; - grpc_slice* second_slice; - int first_code, second_code; - - LOG_TEST("test_peek_one_slice"); - slice = grpc_slice_from_copied_string("test"); - buffer = grpc_raw_byte_buffer_create(&slice, 1); - grpc_slice_unref(slice); - GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && - "Couldn't init byte buffer reader"); - first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); - GPR_ASSERT(first_code != 0); - GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); - second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); - GPR_ASSERT(second_code == 0); - grpc_byte_buffer_destroy(buffer); -} - -static void test_peek_one_slice_malloc(void) { - grpc_slice slice; - grpc_byte_buffer* buffer; - grpc_byte_buffer_reader reader; - grpc_slice* first_slice; - grpc_slice* second_slice; - int first_code, second_code; - - LOG_TEST("test_peek_one_slice_malloc"); - slice = grpc_slice_malloc(4); - memcpy(GRPC_SLICE_START_PTR(slice), "test", 4); - buffer = grpc_raw_byte_buffer_create(&slice, 1); - grpc_slice_unref(slice); - GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && - "Couldn't init byte buffer reader"); - first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); - GPR_ASSERT(first_code != 0); - GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); - second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); - GPR_ASSERT(second_code == 0); - grpc_byte_buffer_destroy(buffer); -} - -static void test_peek_none_compressed_slice(void) { - grpc_slice slice; - grpc_byte_buffer* buffer; - grpc_byte_buffer_reader reader; - grpc_slice* first_slice; - grpc_slice* second_slice; - int first_code, second_code; - - LOG_TEST("test_peek_none_compressed_slice"); - slice = grpc_slice_from_copied_string("test"); - buffer = grpc_raw_byte_buffer_create(&slice, 1); - grpc_slice_unref(slice); - GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && - "Couldn't init byte buffer reader"); - first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); - GPR_ASSERT(first_code != 0); - GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); - second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); - GPR_ASSERT(second_code == 0); - grpc_byte_buffer_destroy(buffer); -} - static void test_read_corrupted_slice(void) { grpc_slice slice; grpc_byte_buffer* buffer; @@ -338,9 +271,6 @@ int main(int argc, char** argv) { test_read_one_slice(); test_read_one_slice_malloc(); test_read_none_compressed_slice(); - test_peek_one_slice(); - test_peek_one_slice_malloc(); - test_peek_none_compressed_slice(); test_read_gzip_compressed_slice(); test_read_deflate_compressed_slice(); test_read_corrupted_slice(); diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index fa02e76ec92..04d0506b3c2 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -209,7 +209,6 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_byte_buffer_reader_init); printf("%lx", (unsigned long) grpc_byte_buffer_reader_destroy); printf("%lx", (unsigned long) grpc_byte_buffer_reader_next); - printf("%lx", (unsigned long) grpc_byte_buffer_reader_peek); printf("%lx", (unsigned long) grpc_byte_buffer_reader_readall); printf("%lx", (unsigned long) grpc_raw_byte_buffer_from_reader); printf("%lx", (unsigned long) gpr_log_severity_string); diff --git a/test/cpp/microbenchmarks/bm_byte_buffer.cc b/test/cpp/microbenchmarks/bm_byte_buffer.cc index 644c27c4873..a359e6f6212 100644 --- a/test/cpp/microbenchmarks/bm_byte_buffer.cc +++ b/test/cpp/microbenchmarks/bm_byte_buffer.cc @@ -29,8 +29,9 @@ namespace grpc { namespace testing { +auto& force_library_initialization = Library::get(); + static void BM_ByteBuffer_Copy(benchmark::State& state) { - Library::get(); int num_slices = state.range(0); size_t slice_size = state.range(1); std::vector slices; @@ -47,74 +48,6 @@ static void BM_ByteBuffer_Copy(benchmark::State& state) { } BENCHMARK(BM_ByteBuffer_Copy)->Ranges({{1, 64}, {1, 1024 * 1024}}); -static void BM_ByteBufferReader_Next(benchmark::State& state) { - Library::get(); - const int num_slices = state.range(0); - constexpr size_t kSliceSize = 16; - std::vector slices; - for (int i = 0; i < num_slices; ++i) { - std::unique_ptr buf(new char[kSliceSize]); - slices.emplace_back(g_core_codegen_interface->grpc_slice_from_copied_buffer( - buf.get(), kSliceSize)); - } - grpc_byte_buffer* bb = g_core_codegen_interface->grpc_raw_byte_buffer_create( - slices.data(), num_slices); - grpc_byte_buffer_reader reader; - GPR_ASSERT( - g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); - while (state.KeepRunning()) { - grpc_slice* slice; - if (GPR_UNLIKELY(!g_core_codegen_interface->grpc_byte_buffer_reader_peek( - &reader, &slice))) { - g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); - GPR_ASSERT( - g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); - continue; - } - } - - g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); - g_core_codegen_interface->grpc_byte_buffer_destroy(bb); - for (auto& slice : slices) { - g_core_codegen_interface->grpc_slice_unref(slice); - } -} -BENCHMARK(BM_ByteBufferReader_Next)->Ranges({{64 * 1024, 1024 * 1024}}); - -static void BM_ByteBufferReader_Peek(benchmark::State& state) { - Library::get(); - const int num_slices = state.range(0); - constexpr size_t kSliceSize = 16; - std::vector slices; - for (int i = 0; i < num_slices; ++i) { - std::unique_ptr buf(new char[kSliceSize]); - slices.emplace_back(g_core_codegen_interface->grpc_slice_from_copied_buffer( - buf.get(), kSliceSize)); - } - grpc_byte_buffer* bb = g_core_codegen_interface->grpc_raw_byte_buffer_create( - slices.data(), num_slices); - grpc_byte_buffer_reader reader; - GPR_ASSERT( - g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); - while (state.KeepRunning()) { - grpc_slice* slice; - if (GPR_UNLIKELY(!g_core_codegen_interface->grpc_byte_buffer_reader_peek( - &reader, &slice))) { - g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); - GPR_ASSERT( - g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); - continue; - } - } - - g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); - g_core_codegen_interface->grpc_byte_buffer_destroy(bb); - for (auto& slice : slices) { - g_core_codegen_interface->grpc_slice_unref(slice); - } -} -BENCHMARK(BM_ByteBufferReader_Peek)->Ranges({{64 * 1024, 1024 * 1024}}); - } // namespace testing } // namespace grpc From 9febbf2d9281225f25d7138e877c285d52239362 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 5 Mar 2019 11:32:00 -0800 Subject: [PATCH 581/814] Revert "Make grpclb child policy configurable" --- .../client_channel/lb_policy/grpclb/grpclb.cc | 344 +++++------------- test/cpp/end2end/grpclb_end2end_test.cc | 144 -------- 2 files changed, 86 insertions(+), 402 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index c1f2846f046..c5d1ff22a9d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -39,14 +39,15 @@ /// the balancer, we update the round_robin policy with the new list of /// addresses. If we cannot communicate with the balancer on startup, /// however, we may enter fallback mode, in which case we will populate -/// the child policy's addresses from the backend addresses returned by the +/// the RR policy's addresses from the backend addresses returned by the /// resolver. /// -/// Once a child policy instance is in place (and getting updated as described), +/// Once an RR policy instance is in place (and getting updated as described), /// calls for a pick, a ping, or a cancellation will be serviced right -/// away by forwarding them to the child policy instance. Any time there's no -/// child policy available (i.e., right after the creation of the gRPCLB -/// policy), pick requests are queued. +/// away by forwarding them to the RR instance. Any time there's no RR +/// policy available (i.e., right after the creation of the gRPCLB policy), +/// pick and ping requests are added to a list of pending picks and pings +/// to be flushed and serviced when the RR policy instance becomes available. /// /// \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the /// high level design and details. @@ -278,23 +279,16 @@ class GrpcLb : public LoadBalancingPolicy { UniquePtr picker) override; void RequestReresolution() override; - void set_child(LoadBalancingPolicy* child) { child_ = child; } - private: - bool CalledByPendingChild() const; - bool CalledByCurrentChild() const; - RefCountedPtr parent_; - LoadBalancingPolicy* child_ = nullptr; }; ~GrpcLb(); void ShutdownLocked() override; - // Helper functions used in UpdateLocked(). + // Helper function used in UpdateLocked(). void ProcessChannelArgsLocked(const grpc_channel_args& args); - void ParseLbConfig(Config* grpclb_config); // Methods for dealing with the balancer channel and call. void StartBalancerCallLocked(); @@ -302,11 +296,10 @@ class GrpcLb : public LoadBalancingPolicy { void StartBalancerCallRetryTimerLocked(); static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error); - // Methods for dealing with the child policy. - grpc_channel_args* CreateChildPolicyArgsLocked(); - OrphanablePtr CreateChildPolicyLocked( - const char* name, grpc_channel_args* args); - void CreateOrUpdateChildPolicyLocked(); + // Methods for dealing with the RR policy. + grpc_channel_args* CreateRoundRobinPolicyArgsLocked(); + void CreateRoundRobinPolicyLocked(Args args); + void CreateOrUpdateRoundRobinPolicyLocked(); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -352,14 +345,8 @@ class GrpcLb : public LoadBalancingPolicy { grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; - // The child policy to use for the backends. - OrphanablePtr child_policy_; - // When switching child policies, the new policy will be stored here - // until it reports READY, at which point it will be moved to child_policy_. - OrphanablePtr pending_child_policy_; - // The child policy name and config. - UniquePtr child_policy_name_; - RefCountedPtr child_policy_config_; + // The RR policy to use for the backends. + OrphanablePtr rr_policy_; }; // @@ -571,30 +558,14 @@ GrpcLb::Picker::PickResult GrpcLb::Picker::Pick(PickState* pick, // GrpcLb::Helper // -bool GrpcLb::Helper::CalledByPendingChild() const { - GPR_ASSERT(child_ != nullptr); - return child_ == parent_->pending_child_policy_.get(); -} - -bool GrpcLb::Helper::CalledByCurrentChild() const { - GPR_ASSERT(child_ != nullptr); - return child_ == parent_->child_policy_.get(); -} - Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { - if (parent_->shutting_down_ || - (!CalledByPendingChild() && !CalledByCurrentChild())) { - return nullptr; - } + if (parent_->shutting_down_) return nullptr; return parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, const grpc_channel_args& args) { - if (parent_->shutting_down_ || - (!CalledByPendingChild() && !CalledByCurrentChild())) { - return nullptr; - } + if (parent_->shutting_down_) return nullptr; return parent_->channel_control_helper()->CreateChannel(target, args); } @@ -605,50 +576,31 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, GRPC_ERROR_UNREF(state_error); return; } - // If this request is from the pending child policy, ignore it until - // it reports READY, at which point we swap it into place. - if (CalledByPendingChild()) { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p helper %p] pending child policy %p reports state=%s", - parent_.get(), this, parent_->pending_child_policy_.get(), - grpc_connectivity_state_name(state)); - } - if (state != GRPC_CHANNEL_READY) { - GRPC_ERROR_UNREF(state_error); - return; - } - parent_->child_policy_ = std::move(parent_->pending_child_policy_); - } else if (!CalledByCurrentChild()) { - // This request is from an outdated child, so ignore it. - GRPC_ERROR_UNREF(state_error); - return; - } // There are three cases to consider here: // 1. We're in fallback mode. In this case, we're always going to use - // the child policy's result, so we pass its picker through as-is. + // RR's result, so we pass its picker through as-is. // 2. The serverlist contains only drop entries. In this case, we // want to use our own picker so that we can return the drops. // 3. Not in fallback mode and serverlist is not all drops (i.e., it // may be empty or contain at least one backend address). There are // two sub-cases: - // a. The child policy is reporting state READY. In this case, we wrap - // the child's picker in our own, so that we can handle drops and LB - // token metadata for each pick. - // b. The child policy is reporting a state other than READY. In this - // case, we don't want to use our own picker, because we don't want - // to process drops for picks that yield a QUEUE result; this would + // a. RR is reporting state READY. In this case, we wrap RR's + // picker in our own, so that we can handle drops and LB token + // metadata for each pick. + // b. RR is reporting a state other than READY. In this case, we + // don't want to use our own picker, because we don't want to + // process drops for picks that yield a QUEUE result; this would // result in dropping too many calls, since we will see the // queued picks multiple times, and we'd consider each one a // separate call for the drop calculation. // - // Cases 1 and 3b: return picker from the child policy as-is. + // Cases 1 and 3b: return picker from RR as-is. if (parent_->serverlist_ == nullptr || (!parent_->serverlist_->ContainsAllDropEntries() && state != GRPC_CHANNEL_READY)) { if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p helper %p] state=%s passing child picker %p as-is", + "[grpclb %p helper %p] state=%s passing RR picker %p as-is", parent_.get(), this, grpc_connectivity_state_name(state), picker.get()); } @@ -656,9 +608,9 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, std::move(picker)); return; } - // Cases 2 and 3a: wrap picker from the child in our own picker. + // Cases 2 and 3a: wrap picker from RR in our own picker. if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping child picker %p", + gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping RR picker %p", parent_.get(), this, grpc_connectivity_state_name(state), picker.get()); } @@ -676,19 +628,15 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, void GrpcLb::Helper::RequestReresolution() { if (parent_->shutting_down_) return; - // If there is a pending child policy, ignore re-resolution requests - // from the current child policy (or any outdated pending child). - if (parent_->pending_child_policy_ != nullptr && !CalledByPendingChild()) { - return; - } if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Re-resolution requested from child policy (%p).", - parent_.get(), child_); + "[grpclb %p] Re-resolution requested from the internal RR policy " + "(%p).", + parent_.get(), parent_->rr_policy_.get()); } // If we are talking to a balancer, we expect to get updated addresses // from the balancer, so we can ignore the re-resolution request from - // the child policy. Otherwise, pass the re-resolution request up to the + // the RR policy. Otherwise, pass the re-resolution request up to the // channel. if (parent_->lb_calld_ == nullptr || !parent_->lb_calld_->seen_initial_response()) { @@ -1036,7 +984,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( // instance will be destroyed either upon the next update or when the // GrpcLb instance is destroyed. grpclb_policy->serverlist_ = std::move(serverlist_wrapper); - grpclb_policy->CreateOrUpdateChildPolicyLocked(); + grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); } } else { // No valid initial response or serverlist found. @@ -1252,8 +1200,7 @@ void GrpcLb::ShutdownLocked() { if (fallback_timer_callback_pending_) { grpc_timer_cancel(&lb_fallback_timer_); } - child_policy_.reset(); - pending_child_policy_.reset(); + rr_policy_.reset(); // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -1273,24 +1220,17 @@ void GrpcLb::ResetBackoffLocked() { if (lb_channel_ != nullptr) { grpc_channel_reset_connect_backoff(lb_channel_); } - if (child_policy_ != nullptr) { - child_policy_->ResetBackoffLocked(); - } - if (pending_child_policy_ != nullptr) { - pending_child_policy_->ResetBackoffLocked(); + if (rr_policy_ != nullptr) { + rr_policy_->ResetBackoffLocked(); } } void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { - // delegate to the child policy to fill the children subchannels. - if (child_policy_ != nullptr) { - child_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); - } - if (pending_child_policy_ != nullptr) { - pending_child_policy_->FillChildRefsForChannelz(child_subchannels, - child_channels); + // delegate to the RoundRobin to fill the children subchannels. + if (rr_policy_ != nullptr) { + rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); } gpr_atm uuid = gpr_atm_no_barrier_load(&lb_channel_uuid_); if (uuid != 0) { @@ -1298,32 +1238,6 @@ void GrpcLb::FillChildRefsForChannelz( } } -void GrpcLb::UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) { - const bool is_initial_update = lb_channel_ == nullptr; - ParseLbConfig(lb_config.get()); - ProcessChannelArgsLocked(args); - // Update the existing child policy. - if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); - // If this is the initial update, start the fallback timer. - if (is_initial_update) { - if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && - !fallback_timer_callback_pending_) { - grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; - Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Ref for callback - GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, - grpc_combiner_scheduler(combiner())); - fallback_timer_callback_pending_ = true; - grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); - } - StartBalancerCallLocked(); - } -} - -// -// helpers for UpdateLocked() -// - // Returns the backend addresses extracted from the given addresses. UniquePtr ExtractBackendAddresses( const ServerAddressList& addresses) { @@ -1385,26 +1299,25 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { grpc_channel_args_destroy(lb_channel_args); } -void GrpcLb::ParseLbConfig(Config* grpclb_config) { - const grpc_json* child_policy = nullptr; - if (grpclb_config != nullptr) { - const grpc_json* grpclb_config_json = grpclb_config->json(); - for (const grpc_json* field = grpclb_config_json; field != nullptr; - field = field->next) { - if (field->key == nullptr) return; - if (strcmp(field->key, "childPolicy") == 0) { - if (child_policy != nullptr) return; // Duplicate. - child_policy = ParseLoadBalancingConfig(field); - } +void GrpcLb::UpdateLocked(const grpc_channel_args& args, + RefCountedPtr lb_config) { + const bool is_initial_update = lb_channel_ == nullptr; + ProcessChannelArgsLocked(args); + // Update the existing RR policy. + if (rr_policy_ != nullptr) CreateOrUpdateRoundRobinPolicyLocked(); + // If this is the initial update, start the fallback timer and the + // balancer call. + if (is_initial_update) { + if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && + !fallback_timer_callback_pending_) { + grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; + Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Ref for callback + GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, + grpc_combiner_scheduler(combiner())); + fallback_timer_callback_pending_ = true; + grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); } - } - if (child_policy != nullptr) { - child_policy_name_ = UniquePtr(gpr_strdup(child_policy->key)); - child_policy_config_ = MakeRefCounted( - child_policy->child, grpclb_config->service_config()); - } else { - child_policy_name_.reset(); - child_policy_config_.reset(); + StartBalancerCallLocked(); } } @@ -1439,7 +1352,7 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { grpclb_policy); } GPR_ASSERT(grpclb_policy->fallback_backend_addresses_ != nullptr); - grpclb_policy->CreateOrUpdateChildPolicyLocked(); + grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); } grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); } @@ -1483,10 +1396,10 @@ void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) { } // -// code for interacting with the child policy +// code for interacting with the RR policy // -grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked() { +grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { ServerAddressList tmp_addresses; ServerAddressList* addresses = &tmp_addresses; bool is_backend_from_grpclb_load_balancer = false; @@ -1495,7 +1408,7 @@ grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked() { lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats()); is_backend_from_grpclb_load_balancer = true; } else { - // If CreateOrUpdateChildPolicyLocked() is invoked when we haven't + // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't // received any serverlist from the balancer, we use the fallback backends // returned by the resolver. Note that the fallback backend list may be // empty, in which case the new round_robin policy will keep the requested @@ -1522,134 +1435,49 @@ grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked() { const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); ++num_args_to_add; } - return grpc_channel_args_copy_and_add_and_remove( + grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, num_args_to_add); + return args; } -OrphanablePtr GrpcLb::CreateChildPolicyLocked( - const char* name, grpc_channel_args* args) { - Helper* helper = New(Ref()); - LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = combiner(); - lb_policy_args.args = args; - lb_policy_args.channel_control_helper = - UniquePtr(helper); - OrphanablePtr lb_policy = - LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - name, std::move(lb_policy_args)); - if (GPR_UNLIKELY(lb_policy == nullptr)) { - gpr_log(GPR_ERROR, "[grpclb %p] Failure creating child policy %s", this, - name); - return nullptr; +void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { + GPR_ASSERT(rr_policy_ == nullptr); + rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + "round_robin", std::move(args)); + if (GPR_UNLIKELY(rr_policy_ == nullptr)) { + gpr_log(GPR_ERROR, "[grpclb %p] Failure creating a RoundRobin policy", + this); + return; } - helper->set_child(lb_policy.get()); if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Created new child policy %s (%p)", this, - name, lb_policy.get()); + gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, + rr_policy_.get()); } // Add the gRPC LB's interested_parties pollset_set to that of the newly - // created child policy. This will make the child policy progress upon - // activity on gRPC LB, which in turn is tied to the application's call. - grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(), + // created RR policy. This will make the RR policy progress upon activity on + // gRPC LB, which in turn is tied to the application's call. + grpc_pollset_set_add_pollset_set(rr_policy_->interested_parties(), interested_parties()); - return lb_policy; } -void GrpcLb::CreateOrUpdateChildPolicyLocked() { +void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { if (shutting_down_) return; - grpc_channel_args* args = CreateChildPolicyArgsLocked(); + grpc_channel_args* args = CreateRoundRobinPolicyArgsLocked(); GPR_ASSERT(args != nullptr); - // If the child policy name changes, we need to create a new child - // policy. When this happens, we leave child_policy_ as-is and store - // the new child policy in pending_child_policy_. Once the new child - // policy transitions into state READY, we swap it into child_policy_, - // replacing the original child policy. So pending_child_policy_ is - // non-null only between when we apply an update that changes the child - // policy name and when the new child reports state READY. - // - // Updates can arrive at any point during this transition. We always - // apply updates relative to the most recently created child policy, - // even if the most recent one is still in pending_child_policy_. This - // is true both when applying the updates to an existing child policy - // and when determining whether we need to create a new policy. - // - // As a result of this, there are several cases to consider here: - // - // 1. We have no existing child policy (i.e., we have started up but - // have not yet received a serverlist from the balancer or gone - // into fallback mode; in this case, both child_policy_ and - // pending_child_policy_ are null). In this case, we create a - // new child policy and store it in child_policy_. - // - // 2. We have an existing child policy and have no pending child policy - // from a previous update (i.e., either there has not been a - // previous update that changed the policy name, or we have already - // finished swapping in the new policy; in this case, child_policy_ - // is non-null but pending_child_policy_ is null). In this case: - // a. If child_policy_->name() equals child_policy_name, then we - // update the existing child policy. - // b. If child_policy_->name() does not equal child_policy_name, - // we create a new policy. The policy will be stored in - // pending_child_policy_ and will later be swapped into - // child_policy_ by the helper when the new child transitions - // into state READY. - // - // 3. We have an existing child policy and have a pending child policy - // from a previous update (i.e., a previous update set - // pending_child_policy_ as per case 2b above and that policy has - // not yet transitioned into state READY and been swapped into - // child_policy_; in this case, both child_policy_ and - // pending_child_policy_ are non-null). In this case: - // a. If pending_child_policy_->name() equals child_policy_name, - // then we update the existing pending child policy. - // b. If pending_child_policy->name() does not equal - // child_policy_name, then we create a new policy. The new - // policy is stored in pending_child_policy_ (replacing the one - // that was there before, which will be immediately shut down) - // and will later be swapped into child_policy_ by the helper - // when the new child transitions into state READY. - const char* child_policy_name = - child_policy_name_ == nullptr ? "round_robin" : child_policy_name_.get(); - const bool create_policy = - // case 1 - child_policy_ == nullptr || - // case 2b - (pending_child_policy_ == nullptr && - strcmp(child_policy_->name(), child_policy_name) != 0) || - // case 3b - (pending_child_policy_ != nullptr && - strcmp(pending_child_policy_->name(), child_policy_name) != 0); - LoadBalancingPolicy* policy_to_update = nullptr; - if (create_policy) { - // Cases 1, 2b, and 3b: create a new child policy. - // If child_policy_ is null, we set it (case 1), else we set - // pending_child_policy_ (cases 2b and 3b). - auto& lb_policy = - child_policy_ == nullptr ? child_policy_ : pending_child_policy_; - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Creating new %schild policy %s", this, - child_policy_ == nullptr ? "" : "pending ", child_policy_name); - } - lb_policy = CreateChildPolicyLocked(child_policy_name, args); - policy_to_update = lb_policy.get(); - } else { - // Cases 2a and 3a: update an existing policy. - // If we have a pending child policy, send the update to the pending - // policy (case 3a), else send it to the current policy (case 2a). - policy_to_update = pending_child_policy_ != nullptr - ? pending_child_policy_.get() - : child_policy_.get(); + if (rr_policy_ == nullptr) { + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = combiner(); + lb_policy_args.args = args; + lb_policy_args.channel_control_helper = + UniquePtr(New(Ref())); + CreateRoundRobinPolicyLocked(std::move(lb_policy_args)); } - GPR_ASSERT(policy_to_update != nullptr); - // Update the policy. if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Updating %schild policy %p", this, - policy_to_update == pending_child_policy_.get() ? "pending " : "", - policy_to_update); + gpr_log(GPR_INFO, "[grpclb %p] Updating RR policy %p", this, + rr_policy_.get()); } - policy_to_update->UpdateLocked(*args, child_policy_config_); - // Clean up. + rr_policy_->UpdateLocked(*args, nullptr); grpc_channel_args_destroy(args); } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 31353ba1304..2288b88b517 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -723,150 +723,6 @@ TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfig) { EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } -TEST_F(SingleBalancerTest, UsePickFirstChildPolicy) { - SetNextResolutionAllBalancers( - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"grpclb\":{\n" - " \"childPolicy\":[\n" - " { \"pick_first\":{} }\n" - " ]\n" - " } }\n" - " ]\n" - "}"); - ScheduleResponseForBalancer( - 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), - 0); - const size_t kNumRpcs = num_backends_ * 2; - CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); - balancers_[0]->NotifyDoneWithServerlists(); - // Check that all requests went to the first backend. This verifies - // that we used pick_first instead of round_robin as the child policy. - EXPECT_EQ(backend_servers_[0].service_->request_count(), kNumRpcs); - for (size_t i = 1; i < backends_.size(); ++i) { - EXPECT_EQ(backend_servers_[i].service_->request_count(), 0UL); - } - // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); -} - -TEST_F(SingleBalancerTest, SwapChildPolicy) { - SetNextResolutionAllBalancers( - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"grpclb\":{\n" - " \"childPolicy\":[\n" - " { \"pick_first\":{} }\n" - " ]\n" - " } }\n" - " ]\n" - "}"); - ScheduleResponseForBalancer( - 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), - 0); - const size_t kNumRpcs = num_backends_ * 2; - CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); - // Check that all requests went to the first backend. This verifies - // that we used pick_first instead of round_robin as the child policy. - EXPECT_EQ(backend_servers_[0].service_->request_count(), kNumRpcs); - for (size_t i = 1; i < backends_.size(); ++i) { - EXPECT_EQ(backend_servers_[i].service_->request_count(), 0UL); - } - // Send new resolution that removes child policy from service config. - SetNextResolutionAllBalancers("{}"); - WaitForAllBackends(); - CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); - // Check that every backend saw the same number of requests. This verifies - // that we used round_robin. - for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(backend_servers_[i].service_->request_count(), 2UL); - } - // Done. - balancers_[0]->NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); -} - -TEST_F(SingleBalancerTest, UpdatesGoToMostRecentChildPolicy) { - const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); - ResetStub(kFallbackTimeoutMs); - int unreachable_balancer_port = grpc_pick_unused_port_or_die(); - int unreachable_backend_port = grpc_pick_unused_port_or_die(); - // Phase 1: Start with RR pointing to first backend. - gpr_log(GPR_INFO, "PHASE 1: Initial setup with RR with first backend"); - SetNextResolution( - { - // Unreachable balancer. - {unreachable_balancer_port, true, ""}, - // Fallback address: first backend. - {backend_servers_[0].port_, false, ""}, - }, - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"grpclb\":{\n" - " \"childPolicy\":[\n" - " { \"round_robin\":{} }\n" - " ]\n" - " } }\n" - " ]\n" - "}"); - // RPCs should go to first backend. - WaitForBackend(0); - // Phase 2: Switch to PF pointing to unreachable backend. - gpr_log(GPR_INFO, "PHASE 2: Update to use PF with unreachable backend"); - SetNextResolution( - { - // Unreachable balancer. - {unreachable_balancer_port, true, ""}, - // Fallback address: unreachable backend. - {unreachable_backend_port, false, ""}, - }, - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"grpclb\":{\n" - " \"childPolicy\":[\n" - " { \"pick_first\":{} }\n" - " ]\n" - " } }\n" - " ]\n" - "}"); - // RPCs should continue to go to the first backend, because the new - // PF child policy will never go into state READY. - WaitForBackend(0); - // Phase 3: Switch back to RR pointing to second and third backends. - // This ensures that we create a new policy rather than updating the - // pending PF policy. - gpr_log(GPR_INFO, "PHASE 3: Update to use RR again with two backends"); - SetNextResolution( - { - // Unreachable balancer. - {unreachable_balancer_port, true, ""}, - // Fallback address: second and third backends. - {backend_servers_[1].port_, false, ""}, - {backend_servers_[2].port_, false, ""}, - }, - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"grpclb\":{\n" - " \"childPolicy\":[\n" - " { \"round_robin\":{} }\n" - " ]\n" - " } }\n" - " ]\n" - "}"); - // RPCs should go to the second and third backends. - WaitForBackend(1); - WaitForBackend(2); -} - TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { SetNextResolutionAllBalancers(); // Same backend listed twice. From 3f7d883054c1505a35b3cdbbe7f9aa3f68253fba Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 5 Mar 2019 12:07:03 -0800 Subject: [PATCH 582/814] Backport #18190 to 1.19.x --- src/python/grpcio/grpc/_channel.py | 2 +- src/python/grpcio/grpc/_interceptor.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index df06ffaeb3b..2d370fcb444 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -247,7 +247,7 @@ def _consume_request_iterator(request_iterator, state, call, request_serializer, consumption_thread.start() -class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): +class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too-many-ancestors def __init__(self, state, call, response_deserializer, deadline): super(_Rendezvous, self).__init__() diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py index fc0ad77eb9e..6c4e396ac23 100644 --- a/src/python/grpcio/grpc/_interceptor.py +++ b/src/python/grpcio/grpc/_interceptor.py @@ -80,7 +80,7 @@ def _unwrap_client_call_details(call_details, default_details): return method, timeout, metadata, credentials, wait_for_ready -class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): +class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): # pylint: disable=too-many-ancestors def __init__(self, exception, traceback): super(_FailureOutcome, self).__init__() @@ -126,7 +126,7 @@ class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call): def traceback(self, ignored_timeout=None): return self._traceback - def add_callback(self, callback): + def add_callback(self, unused_callback): return False def add_done_callback(self, fn): From e889fda4828872915229af82c286ae2be613f731 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 5 Mar 2019 13:29:55 -0800 Subject: [PATCH 583/814] Use real resolver in xds lb channel --- CMakeLists.txt | 48 + Makefile | 52 + build.yaml | 13 + include/grpc/impl/codegen/grpc_types.h | 4 + .../ext/filters/client_channel/lb_policy.h | 4 +- .../client_channel/lb_policy/xds/xds.cc | 722 +++++----- .../lb_policy/xds/xds_channel_secure.cc | 43 - .../resolver/fake/fake_resolver.cc | 34 +- .../resolver/fake/fake_resolver.h | 5 +- .../fake/fake_security_connector.cc | 9 +- test/cpp/end2end/BUILD | 22 + test/cpp/end2end/xds_end2end_test.cc | 1214 +++++++++++++++++ .../generated/sources_and_headers.json | 22 + tools/run_tests/generated/tests.json | 24 + 14 files changed, 1794 insertions(+), 422 deletions(-) create mode 100644 test/cpp/end2end/xds_end2end_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 939e83c481f..bccead24f28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -720,6 +720,7 @@ add_dependencies(buildtests_cxx transport_security_common_api_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx writes_per_rpc_test) endif() +add_dependencies(buildtests_cxx xds_end2end_test) add_dependencies(buildtests_cxx resolver_component_test_unsecure) add_dependencies(buildtests_cxx resolver_component_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -16232,6 +16233,53 @@ endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(xds_end2end_test + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h + test/cpp/end2end/xds_end2end_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +protobuf_generate_grpc_cpp( + src/proto/grpc/lb/v1/load_balancer.proto +) + +target_include_directories(xds_end2end_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(xds_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(public_headers_must_be_c89 test/core/surface/public_headers_must_be_c89.c ) diff --git a/Makefile b/Makefile index 3c890797431..94944265d61 100644 --- a/Makefile +++ b/Makefile @@ -1276,6 +1276,7 @@ time_change_test: $(BINDIR)/$(CONFIG)/time_change_test transport_pid_controller_test: $(BINDIR)/$(CONFIG)/transport_pid_controller_test transport_security_common_api_test: $(BINDIR)/$(CONFIG)/transport_security_common_api_test writes_per_rpc_test: $(BINDIR)/$(CONFIG)/writes_per_rpc_test +xds_end2end_test: $(BINDIR)/$(CONFIG)/xds_end2end_test public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 gen_hpack_tables: $(BINDIR)/$(CONFIG)/gen_hpack_tables gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters @@ -1787,6 +1788,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/transport_pid_controller_test \ $(BINDIR)/$(CONFIG)/transport_security_common_api_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \ + $(BINDIR)/$(CONFIG)/xds_end2end_test \ $(BINDIR)/$(CONFIG)/boringssl_crypto_test_data \ $(BINDIR)/$(CONFIG)/boringssl_asn1_test \ $(BINDIR)/$(CONFIG)/boringssl_base64_test \ @@ -1976,6 +1978,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/transport_pid_controller_test \ $(BINDIR)/$(CONFIG)/transport_security_common_api_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \ + $(BINDIR)/$(CONFIG)/xds_end2end_test \ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \ $(BINDIR)/$(CONFIG)/resolver_component_test \ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure \ @@ -2500,6 +2503,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/transport_security_common_api_test || ( echo test transport_security_common_api_test failed ; exit 1 ) $(E) "[RUN] Testing writes_per_rpc_test" $(Q) $(BINDIR)/$(CONFIG)/writes_per_rpc_test || ( echo test writes_per_rpc_test failed ; exit 1 ) + $(E) "[RUN] Testing xds_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/xds_end2end_test || ( echo test xds_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing resolver_component_tests_runner_invoker_unsecure" $(Q) $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure || ( echo test resolver_component_tests_runner_invoker_unsecure failed ; exit 1 ) $(E) "[RUN] Testing resolver_component_tests_runner_invoker" @@ -21308,6 +21313,53 @@ endif endif +XDS_END2END_TEST_SRC = \ + $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \ + test/cpp/end2end/xds_end2end_test.cc \ + +XDS_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(XDS_END2END_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/xds_end2end_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/xds_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/xds_end2end_test: $(PROTOBUF_DEP) $(XDS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(XDS_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/xds_end2end_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/xds_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_xds_end2end_test: $(XDS_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(XDS_END2END_TEST_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/xds_end2end_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc + + PUBLIC_HEADERS_MUST_BE_C89_SRC = \ test/core/surface/public_headers_must_be_c89.c \ diff --git a/build.yaml b/build.yaml index c18630ecdd3..621b9a4de2f 100644 --- a/build.yaml +++ b/build.yaml @@ -5644,6 +5644,19 @@ targets: - mac - linux - posix +- name: xds_end2end_test + gtest: true + build: test + language: c++ + src: + - src/proto/grpc/lb/v1/load_balancer.proto + - test/cpp/end2end/xds_end2end_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr - name: public_headers_must_be_c89 build: test language: c89 diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 79b182c4515..078db2b90a8 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -317,6 +317,10 @@ typedef struct { balancer before using fallback backend addresses from the resolver. If 0, fallback will never be used. Default value is 10000. */ #define GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS "grpc.grpclb_fallback_timeout_ms" +/* Timeout in milliseconds to wait for the serverlist from the xDS load + balancer before using fallback backend addresses from the resolver. + If 0, fallback will never be used. Default value is 10000. */ +#define GRPC_ARG_XDS_FALLBACK_TIMEOUT_MS "grpc.xds_fallback_timeout_ms" /** If non-zero, grpc server's cronet compression workaround will be enabled */ #define GRPC_ARG_WORKAROUND_CRONET_COMPRESSION \ "grpc.workaround.cronet_compression" diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 7a876966524..75dca52a615 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -297,8 +297,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { grpc_combiner* combiner() const { return combiner_; } - // Note: LB policies MUST NOT call any method on the helper from - // their constructor. + // Note: LB policies MUST NOT call any method on the helper from their + // constructor. // Note: This will return null after ShutdownLocked() has been called. ChannelControlHelper* channel_control_helper() const { return channel_control_helper_.get(); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 6c10d876af7..5153330a84e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -129,78 +129,128 @@ class XdsLb : public LoadBalancingPolicy { channelz::ChildRefsList* child_channels) override; private: - /// Contains a call to the LB server and all the data related to the call. - class BalancerCallState : public InternallyRefCounted { + /// Contains a channel to the LB server and all the data related to the + /// channel. + class BalancerChannelState + : public InternallyRefCounted { public: - explicit BalancerCallState( - RefCountedPtr parent_xdslb_policy); + /// Contains a call to the LB server and all the data related to the call. + class BalancerCallState : public InternallyRefCounted { + public: + explicit BalancerCallState(RefCountedPtr lb_chand); + + // It's the caller's responsibility to ensure that Orphan() is called from + // inside the combiner. + void Orphan() override; + + void StartQuery(); + + RefCountedPtr client_stats() const { + return client_stats_; + } + + bool seen_initial_response() const { return seen_initial_response_; } + + private: + // So Delete() can access our private dtor. + template + friend void grpc_core::Delete(T*); + + ~BalancerCallState(); + + XdsLb* xdslb_policy() const { return lb_chand_->xdslb_policy_.get(); } + + bool IsCurrentCallOnChannel() const { + return this == lb_chand_->lb_calld_.get(); + } + + void ScheduleNextClientLoadReportLocked(); + void SendClientLoadReportLocked(); + + static bool LoadReportCountersAreZero(xds_grpclb_request* request); + + static void MaybeSendClientLoadReportLocked(void* arg, grpc_error* error); + static void OnInitialRequestSentLocked(void* arg, grpc_error* error); + static void OnBalancerMessageReceivedLocked(void* arg, grpc_error* error); + static void OnBalancerStatusReceivedLocked(void* arg, grpc_error* error); + + // The owning LB channel. + RefCountedPtr lb_chand_; + + // The streaming call to the LB server. Always non-NULL. + grpc_call* lb_call_ = nullptr; + + // recv_initial_metadata + grpc_metadata_array lb_initial_metadata_recv_; + + // send_message + grpc_byte_buffer* send_message_payload_ = nullptr; + grpc_closure lb_on_initial_request_sent_; + + // recv_message + grpc_byte_buffer* recv_message_payload_ = nullptr; + grpc_closure lb_on_balancer_message_received_; + bool seen_initial_response_ = false; + + // recv_trailing_metadata + grpc_closure lb_on_balancer_status_received_; + grpc_metadata_array lb_trailing_metadata_recv_; + grpc_status_code lb_call_status_; + grpc_slice lb_call_status_details_; + + // The stats for client-side load reporting associated with this LB call. + // Created after the first serverlist is received. + RefCountedPtr client_stats_; + grpc_millis client_stats_report_interval_ = 0; + grpc_timer client_load_report_timer_; + bool client_load_report_timer_callback_pending_ = false; + bool last_client_load_report_counters_were_zero_ = false; + bool client_load_report_is_due_ = false; + // The closure used for either the load report timer or the callback for + // completion of sending the load report. + grpc_closure client_load_report_closure_; + }; + + BalancerChannelState(const char* balancer_name, + const grpc_channel_args& args, + RefCountedPtr parent_xdslb_policy); + ~BalancerChannelState(); - // It's the caller's responsibility to ensure that Orphan() is called from - // inside the combiner. void Orphan() override; - void StartQuery(); + grpc_channel* channel() const { return channel_; } + BalancerCallState* lb_calld() const { return lb_calld_.get(); } - XdsLbClientStats* client_stats() const { return client_stats_.get(); } + bool IsCurrentChannel() const { + return this == xdslb_policy_->lb_chand_.get(); + } + bool IsPendingChannel() const { + return this == xdslb_policy_->pending_lb_chand_.get(); + } + bool HasActiveCall() const { return lb_calld_ != nullptr; } - bool seen_initial_response() const { return seen_initial_response_; } + void StartCallRetryTimerLocked(); + static void OnCallRetryTimerLocked(void* arg, grpc_error* error); + void StartCallLocked(); private: - // So Delete() can access our private dtor. - template - friend void grpc_core::Delete(T*); - - ~BalancerCallState(); - - XdsLb* xdslb_policy() const { - return static_cast(xdslb_policy_.get()); - } - - void ScheduleNextClientLoadReportLocked(); - void SendClientLoadReportLocked(); - - static bool LoadReportCountersAreZero(xds_grpclb_request* request); - - static void MaybeSendClientLoadReportLocked(void* arg, grpc_error* error); - static void OnInitialRequestSentLocked(void* arg, grpc_error* error); - static void OnBalancerMessageReceivedLocked(void* arg, grpc_error* error); - static void OnBalancerStatusReceivedLocked(void* arg, grpc_error* error); - // The owning LB policy. - RefCountedPtr xdslb_policy_; + RefCountedPtr xdslb_policy_; - // The streaming call to the LB server. Always non-NULL. - grpc_call* lb_call_ = nullptr; + // The channel and its status. + grpc_channel* channel_; + bool shutting_down_ = false; - // recv_initial_metadata - grpc_metadata_array lb_initial_metadata_recv_; - - // send_message - grpc_byte_buffer* send_message_payload_ = nullptr; - grpc_closure lb_on_initial_request_sent_; - - // recv_message - grpc_byte_buffer* recv_message_payload_ = nullptr; - grpc_closure lb_on_balancer_message_received_; - bool seen_initial_response_ = false; - - // recv_trailing_metadata - grpc_closure lb_on_balancer_status_received_; - grpc_metadata_array lb_trailing_metadata_recv_; - grpc_status_code lb_call_status_; - grpc_slice lb_call_status_details_; - - // The stats for client-side load reporting associated with this LB call. - // Created after the first serverlist is received. - RefCountedPtr client_stats_; - grpc_millis client_stats_report_interval_ = 0; - grpc_timer client_load_report_timer_; - bool client_load_report_timer_callback_pending_ = false; - bool last_client_load_report_counters_were_zero_ = false; - bool client_load_report_is_due_ = false; - // The closure used for either the load report timer or the callback for - // completion of sending the load report. - grpc_closure client_load_report_closure_; + // The data associated with the current LB call. It holds a ref to this LB + // channel. It's instantiated every time we query for backends. It's reset + // whenever the current LB call is no longer needed (e.g., the LB policy is + // shutting down, or the LB call has ended). A non-NULL lb_calld_ always + // contains a non-NULL lb_call_. + OrphanablePtr lb_calld_; + BackOff lb_call_backoff_; + grpc_timer lb_call_retry_timer_; + grpc_closure lb_on_call_retry_; + bool retry_timer_callback_pending_ = false; }; class Picker : public SubchannelPicker { @@ -245,13 +295,13 @@ class XdsLb : public LoadBalancingPolicy { // found. Does nothing upon failure. void ParseLbConfig(Config* xds_config); - // Methods for dealing with the balancer channel and call. - void StartBalancerCallLocked(); + BalancerChannelState* LatestLbChannel() const { + return pending_lb_chand_ != nullptr ? pending_lb_chand_.get() + : lb_chand_.get(); + } + + // Callback to enter fallback mode. static void OnFallbackTimerLocked(void* arg, grpc_error* error); - void StartBalancerCallRetryTimerLocked(); - static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error); - static void OnBalancerChannelConnectivityChangedLocked(void* arg, - grpc_error* error); // Methods for dealing with the child policy. void CreateOrUpdateChildPolicyLocked(); @@ -271,30 +321,15 @@ class XdsLb : public LoadBalancingPolicy { bool shutting_down_ = false; // The channel for communicating with the LB server. - grpc_channel* lb_channel_ = nullptr; + OrphanablePtr lb_chand_; + OrphanablePtr pending_lb_chand_; // Mutex to protect the channel to the LB server. This is used when // processing a channelz request. - gpr_mu lb_channel_mu_; - grpc_connectivity_state lb_channel_connectivity_; - grpc_closure lb_channel_on_connectivity_changed_; - // Are we already watching the LB channel's connectivity? - bool watching_lb_channel_ = false; - // Response generator to inject address updates into lb_channel_. - RefCountedPtr response_generator_; + // TODO(juanlishen): Replace this with atomic. + gpr_mu lb_chand_mu_; - // The data associated with the current LB call. It holds a ref to this LB - // policy. It's initialized every time we query for backends. It's reset to - // NULL whenever the current LB call is no longer needed (e.g., the LB policy - // is shutting down, or the LB call has ended). A non-NULL lb_calld_ always - // contains a non-NULL lb_call_. - OrphanablePtr lb_calld_; // Timeout in milliseconds for the LB call. 0 means no deadline. int lb_call_timeout_ms_ = 0; - // Balancer call retry state. - BackOff lb_call_backoff_; - bool retry_timer_callback_pending_ = false; - grpc_timer lb_call_retry_timer_; - grpc_closure lb_on_call_retry_; // The deserialized response from the balancer. May be nullptr until one // such response has arrived. @@ -360,11 +395,11 @@ void XdsLb::Helper::UpdateState(grpc_connectivity_state state, // TODO(juanlishen): When in fallback mode, pass the child picker // through without wrapping it. (Or maybe use a different helper for // the fallback policy?) - RefCountedPtr client_stats; - if (parent_->lb_calld_ != nullptr && - parent_->lb_calld_->client_stats() != nullptr) { - client_stats = parent_->lb_calld_->client_stats()->Ref(); - } + GPR_ASSERT(parent_->lb_chand_ != nullptr); + RefCountedPtr client_stats = + parent_->lb_chand_->lb_calld() == nullptr + ? nullptr + : parent_->lb_chand_->lb_calld()->client_stats(); parent_->channel_control_helper()->UpdateState( state, state_error, UniquePtr( @@ -379,12 +414,13 @@ void XdsLb::Helper::RequestReresolution() { "(%p).", parent_.get(), parent_->child_policy_.get()); } + GPR_ASSERT(parent_->lb_chand_ != nullptr); // If we are talking to a balancer, we expect to get updated addresses // from the balancer, so we can ignore the re-resolution request from - // the RR policy. Otherwise, pass the re-resolution request up to the + // the child policy. Otherwise, pass the re-resolution request up to the // channel. - if (parent_->lb_calld_ == nullptr || - !parent_->lb_calld_->seen_initial_response()) { + if (parent_->lb_chand_->lb_calld() == nullptr || + !parent_->lb_chand_->lb_calld()->seen_initial_response()) { parent_->channel_control_helper()->RequestReresolution(); } } @@ -465,14 +501,98 @@ UniquePtr ProcessServerlist( } // -// XdsLb::BalancerCallState +// XdsLb::BalancerChannelState // -XdsLb::BalancerCallState::BalancerCallState( - RefCountedPtr parent_xdslb_policy) +XdsLb::BalancerChannelState::BalancerChannelState( + const char* balancer_name, const grpc_channel_args& args, + grpc_core::RefCountedPtr parent_xdslb_policy) + : InternallyRefCounted(&grpc_lb_xds_trace), + xdslb_policy_(std::move(parent_xdslb_policy)), + lb_call_backoff_( + BackOff::Options() + .set_initial_backoff(GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS * + 1000) + .set_multiplier(GRPC_XDS_RECONNECT_BACKOFF_MULTIPLIER) + .set_jitter(GRPC_XDS_RECONNECT_JITTER) + .set_max_backoff(GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { + channel_ = xdslb_policy_->channel_control_helper()->CreateChannel( + balancer_name, args); + GPR_ASSERT(channel_ != nullptr); + StartCallLocked(); +} + +XdsLb::BalancerChannelState::~BalancerChannelState() { + grpc_channel_destroy(channel_); +} + +void XdsLb::BalancerChannelState::Orphan() { + shutting_down_ = true; + lb_calld_.reset(); + if (retry_timer_callback_pending_) grpc_timer_cancel(&lb_call_retry_timer_); + Unref(DEBUG_LOCATION, "lb_channel_orphaned"); +} + +void XdsLb::BalancerChannelState::StartCallRetryTimerLocked() { + grpc_millis next_try = lb_call_backoff_.NextAttemptTime(); + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] Failed to connect to LB server (lb_chand: %p)...", + xdslb_policy_.get(), this); + grpc_millis timeout = next_try - ExecCtx::Get()->Now(); + if (timeout > 0) { + gpr_log(GPR_INFO, "[xdslb %p] ... retry_timer_active in %" PRId64 "ms.", + xdslb_policy_.get(), timeout); + } else { + gpr_log(GPR_INFO, "[xdslb %p] ... retry_timer_active immediately.", + xdslb_policy_.get()); + } + } + Ref(DEBUG_LOCATION, "on_balancer_call_retry_timer").release(); + GRPC_CLOSURE_INIT(&lb_on_call_retry_, &OnCallRetryTimerLocked, this, + grpc_combiner_scheduler(xdslb_policy_->combiner())); + grpc_timer_init(&lb_call_retry_timer_, next_try, &lb_on_call_retry_); + retry_timer_callback_pending_ = true; +} + +void XdsLb::BalancerChannelState::OnCallRetryTimerLocked(void* arg, + grpc_error* error) { + BalancerChannelState* lb_chand = static_cast(arg); + lb_chand->retry_timer_callback_pending_ = false; + if (!lb_chand->shutting_down_ && error == GRPC_ERROR_NONE && + lb_chand->lb_calld_ == nullptr) { + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] Restarting call to LB server (lb_chand: %p)", + lb_chand->xdslb_policy_.get(), lb_chand); + } + lb_chand->StartCallLocked(); + } + lb_chand->Unref(DEBUG_LOCATION, "on_balancer_call_retry_timer"); +} + +void XdsLb::BalancerChannelState::StartCallLocked() { + if (shutting_down_) return; + GPR_ASSERT(channel_ != nullptr); + GPR_ASSERT(lb_calld_ == nullptr); + lb_calld_ = MakeOrphanable(Ref()); + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] Query for backends (lb_chand: %p, lb_calld: %p)", + xdslb_policy_.get(), this, lb_calld_.get()); + } + lb_calld_->StartQuery(); +} + +// +// XdsLb::BalancerChannelState::BalancerCallState +// + +XdsLb::BalancerChannelState::BalancerCallState::BalancerCallState( + RefCountedPtr lb_chand) : InternallyRefCounted(&grpc_lb_xds_trace), - xdslb_policy_(std::move(parent_xdslb_policy)) { - GPR_ASSERT(xdslb_policy_ != nullptr); + lb_chand_(std::move(lb_chand)) { + GPR_ASSERT(xdslb_policy() != nullptr); GPR_ASSERT(!xdslb_policy()->shutting_down_); // Init the LB call. Note that the LB call will progress every time there's // activity in xdslb_policy_->interested_parties(), which is comprised of @@ -484,8 +604,8 @@ XdsLb::BalancerCallState::BalancerCallState( ? GRPC_MILLIS_INF_FUTURE : ExecCtx::Get()->Now() + xdslb_policy()->lb_call_timeout_ms_; lb_call_ = grpc_channel_create_pollset_set_call( - xdslb_policy()->lb_channel_, nullptr, GRPC_PROPAGATE_DEFAULTS, - xdslb_policy_->interested_parties(), + lb_chand_->channel_, nullptr, GRPC_PROPAGATE_DEFAULTS, + xdslb_policy()->interested_parties(), GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD, nullptr, deadline, nullptr); // Init the LB call request payload. @@ -509,7 +629,7 @@ XdsLb::BalancerCallState::BalancerCallState( grpc_combiner_scheduler(xdslb_policy()->combiner())); } -XdsLb::BalancerCallState::~BalancerCallState() { +XdsLb::BalancerChannelState::BalancerCallState::~BalancerCallState() { GPR_ASSERT(lb_call_ != nullptr); grpc_call_unref(lb_call_); grpc_metadata_array_destroy(&lb_initial_metadata_recv_); @@ -519,7 +639,7 @@ XdsLb::BalancerCallState::~BalancerCallState() { grpc_slice_unref_internal(lb_call_status_details_); } -void XdsLb::BalancerCallState::Orphan() { +void XdsLb::BalancerChannelState::BalancerCallState::Orphan() { GPR_ASSERT(lb_call_ != nullptr); // If we are here because xdslb_policy wants to cancel the call, // lb_on_balancer_status_received_ will complete the cancellation and clean @@ -534,11 +654,11 @@ void XdsLb::BalancerCallState::Orphan() { // in lb_on_balancer_status_received_ instead of here. } -void XdsLb::BalancerCallState::StartQuery() { +void XdsLb::BalancerChannelState::BalancerCallState::StartQuery() { GPR_ASSERT(lb_call_ != nullptr); if (grpc_lb_xds_trace.enabled()) { gpr_log(GPR_INFO, "[xdslb %p] Starting LB call (lb_calld: %p, lb_call: %p)", - xdslb_policy_.get(), this, lb_call_); + xdslb_policy(), this, lb_call_); } // Create the ops. grpc_call_error call_error; @@ -606,7 +726,8 @@ void XdsLb::BalancerCallState::StartQuery() { GPR_ASSERT(GRPC_CALL_OK == call_error); } -void XdsLb::BalancerCallState::ScheduleNextClientLoadReportLocked() { +void XdsLb::BalancerChannelState::BalancerCallState:: + ScheduleNextClientLoadReportLocked() { const grpc_millis next_client_load_report_time = ExecCtx::Get()->Now() + client_stats_report_interval_; GRPC_CLOSURE_INIT(&client_load_report_closure_, @@ -617,12 +738,11 @@ void XdsLb::BalancerCallState::ScheduleNextClientLoadReportLocked() { client_load_report_timer_callback_pending_ = true; } -void XdsLb::BalancerCallState::MaybeSendClientLoadReportLocked( - void* arg, grpc_error* error) { +void XdsLb::BalancerChannelState::BalancerCallState:: + MaybeSendClientLoadReportLocked(void* arg, grpc_error* error) { BalancerCallState* lb_calld = static_cast(arg); - XdsLb* xdslb_policy = lb_calld->xdslb_policy(); lb_calld->client_load_report_timer_callback_pending_ = false; - if (error != GRPC_ERROR_NONE || lb_calld != xdslb_policy->lb_calld_.get()) { + if (error != GRPC_ERROR_NONE || !lb_calld->IsCurrentCallOnChannel()) { lb_calld->Unref(DEBUG_LOCATION, "client_load_report"); return; } @@ -636,7 +756,7 @@ void XdsLb::BalancerCallState::MaybeSendClientLoadReportLocked( } } -bool XdsLb::BalancerCallState::LoadReportCountersAreZero( +bool XdsLb::BalancerChannelState::BalancerCallState::LoadReportCountersAreZero( xds_grpclb_request* request) { XdsLbClientStats::DroppedCallCounts* drop_entries = static_cast( @@ -650,7 +770,8 @@ bool XdsLb::BalancerCallState::LoadReportCountersAreZero( } // TODO(vpowar): Use LRS to send the client Load Report. -void XdsLb::BalancerCallState::SendClientLoadReportLocked() { +void XdsLb::BalancerChannelState::BalancerCallState:: + SendClientLoadReportLocked() { // Construct message payload. GPR_ASSERT(send_message_payload_ == nullptr); xds_grpclb_request* request = @@ -671,27 +792,27 @@ void XdsLb::BalancerCallState::SendClientLoadReportLocked() { xds_grpclb_request_destroy(request); } -void XdsLb::BalancerCallState::OnInitialRequestSentLocked(void* arg, - grpc_error* error) { +void XdsLb::BalancerChannelState::BalancerCallState::OnInitialRequestSentLocked( + void* arg, grpc_error* error) { BalancerCallState* lb_calld = static_cast(arg); grpc_byte_buffer_destroy(lb_calld->send_message_payload_); lb_calld->send_message_payload_ = nullptr; // If we attempted to send a client load report before the initial request was // sent (and this lb_calld is still in use), send the load report now. if (lb_calld->client_load_report_is_due_ && - lb_calld == lb_calld->xdslb_policy()->lb_calld_.get()) { + lb_calld->IsCurrentCallOnChannel()) { lb_calld->SendClientLoadReportLocked(); lb_calld->client_load_report_is_due_ = false; } lb_calld->Unref(DEBUG_LOCATION, "on_initial_request_sent"); } -void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( - void* arg, grpc_error* error) { +void XdsLb::BalancerChannelState::BalancerCallState:: + OnBalancerMessageReceivedLocked(void* arg, grpc_error* error) { BalancerCallState* lb_calld = static_cast(arg); XdsLb* xdslb_policy = lb_calld->xdslb_policy(); // Empty payload means the LB call was cancelled. - if (lb_calld != xdslb_policy->lb_calld_.get() || + if (!lb_calld->IsCurrentCallOnChannel() || lb_calld->recv_message_payload_ == nullptr) { lb_calld->Unref(DEBUG_LOCATION, "on_message_received"); return; @@ -709,20 +830,25 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( nullptr) { // Have NOT seen initial response, look for initial response. if (initial_response->has_client_stats_report_interval) { - lb_calld->client_stats_report_interval_ = GPR_MAX( - GPR_MS_PER_SEC, xds_grpclb_duration_to_millis( - &initial_response->client_stats_report_interval)); - if (grpc_lb_xds_trace.enabled()) { + const grpc_millis interval = xds_grpclb_duration_to_millis( + &initial_response->client_stats_report_interval); + if (interval > 0) { + lb_calld->client_stats_report_interval_ = + GPR_MAX(GPR_MS_PER_SEC, interval); + } + } + if (grpc_lb_xds_trace.enabled()) { + if (lb_calld->client_stats_report_interval_ != 0) { gpr_log(GPR_INFO, "[xdslb %p] Received initial LB response message; " "client load reporting interval = %" PRId64 " milliseconds", xdslb_policy, lb_calld->client_stats_report_interval_); + } else { + gpr_log(GPR_INFO, + "[xdslb %p] Received initial LB response message; client load " + "reporting NOT enabled", + xdslb_policy); } - } else if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Received initial LB response message; client load " - "reporting NOT enabled", - xdslb_policy); } xds_grpclb_initial_response_destroy(initial_response); lb_calld->seen_initial_response_ = true; @@ -745,7 +871,23 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( } } /* update serverlist */ + // TODO(juanlishen): Don't ingore empty serverlist. if (serverlist->num_servers > 0) { + // Pending LB channel receives a serverlist; promote it. + // Note that this call can't be on a discarded pending channel, because + // such channels don't have any current call but we have checked this call + // is a current call. + if (!lb_calld->lb_chand_->IsCurrentChannel()) { + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] Promoting pending LB channel %p to replace " + "current LB channel %p", + xdslb_policy, lb_calld->lb_chand_.get(), + lb_calld->xdslb_policy()->lb_chand_.get()); + } + lb_calld->xdslb_policy()->lb_chand_ = + std::move(lb_calld->xdslb_policy()->pending_lb_chand_); + } // Start sending client load report only after we start using the // serverlist returned from the current LB call. if (lb_calld->client_stats_report_interval_ > 0 && @@ -818,37 +960,53 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked( } } -void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked( - void* arg, grpc_error* error) { +void XdsLb::BalancerChannelState::BalancerCallState:: + OnBalancerStatusReceivedLocked(void* arg, grpc_error* error) { BalancerCallState* lb_calld = static_cast(arg); XdsLb* xdslb_policy = lb_calld->xdslb_policy(); + BalancerChannelState* lb_chand = lb_calld->lb_chand_.get(); GPR_ASSERT(lb_calld->lb_call_ != nullptr); if (grpc_lb_xds_trace.enabled()) { char* status_details = grpc_slice_to_c_string(lb_calld->lb_call_status_details_); gpr_log(GPR_INFO, "[xdslb %p] Status from LB server received. Status = %d, details " - "= '%s', (lb_calld: %p, lb_call: %p), error '%s'", - xdslb_policy, lb_calld->lb_call_status_, status_details, lb_calld, - lb_calld->lb_call_, grpc_error_string(error)); + "= '%s', (lb_chand: %p, lb_calld: %p, lb_call: %p), error '%s'", + xdslb_policy, lb_calld->lb_call_status_, status_details, lb_chand, + lb_calld, lb_calld->lb_call_, grpc_error_string(error)); gpr_free(status_details); } - // If this lb_calld is still in use, this call ended because of a failure so - // we want to retry connecting. Otherwise, we have deliberately ended this - // call and no further action is required. - if (lb_calld == xdslb_policy->lb_calld_.get()) { - xdslb_policy->lb_calld_.reset(); + // Ignore status from a stale call. + if (lb_calld->IsCurrentCallOnChannel()) { + // Because this call is the current one on the channel, the channel can't + // have been swapped out; otherwise, the call should have been reset. + GPR_ASSERT(lb_chand->IsCurrentChannel() || lb_chand->IsPendingChannel()); GPR_ASSERT(!xdslb_policy->shutting_down_); - xdslb_policy->channel_control_helper()->RequestReresolution(); - if (lb_calld->seen_initial_response_) { - // If we lose connection to the LB server, reset the backoff and restart - // the LB call immediately. - xdslb_policy->lb_call_backoff_.Reset(); - xdslb_policy->StartBalancerCallLocked(); + if (lb_chand != xdslb_policy->LatestLbChannel()) { + // This channel must be the current one and there is a pending one. Swap + // in the pending one and we are done. + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p] Promoting pending LB channel %p to replace " + "current LB channel %p", + xdslb_policy, lb_calld->lb_chand_.get(), + lb_calld->xdslb_policy()->lb_chand_.get()); + } + xdslb_policy->lb_chand_ = std::move(xdslb_policy->pending_lb_chand_); } else { - // If this LB call fails establishing any connection to the LB server, - // retry later. - xdslb_policy->StartBalancerCallRetryTimerLocked(); + // This channel is the most recently created one. Try to restart the call + // and reresolve. + lb_chand->lb_calld_.reset(); + if (lb_calld->seen_initial_response_) { + // If we lost connection to the LB server, reset the backoff and restart + // the LB call immediately. + lb_chand->lb_call_backoff_.Reset(); + lb_chand->StartCallLocked(); + } else { + // If we failed to connect to the LB server, retry later. + lb_chand->StartCallRetryTimerLocked(); + } + xdslb_policy->channel_control_helper()->RequestReresolution(); } } lb_calld->Unref(DEBUG_LOCATION, "lb_call_ended"); @@ -858,53 +1016,23 @@ void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -UniquePtr ExtractBalancerAddresses( - const ServerAddressList& addresses) { - auto balancer_addresses = MakeUnique(); - for (size_t i = 0; i < addresses.size(); ++i) { - if (addresses[i].IsBalancer()) { - balancer_addresses->emplace_back(addresses[i]); - } - } - return balancer_addresses; -} - -/* Returns the channel args for the LB channel, used to create a bidirectional - * stream for the reception of load balancing updates. - * - * Inputs: - * - \a addresses: corresponding to the balancers. - * - \a response_generator: in order to propagate updates from the resolver - * above the grpclb policy. - * - \a args: other args inherited from the xds policy. */ -grpc_channel_args* BuildBalancerChannelArgs( - const ServerAddressList& addresses, - FakeResolverResponseGenerator* response_generator, - const grpc_channel_args* args) { - UniquePtr balancer_addresses = - ExtractBalancerAddresses(addresses); - // Channel args to remove. +// Returns the channel args for the LB channel, used to create a bidirectional +// stream for the reception of load balancing updates. +grpc_channel_args* BuildBalancerChannelArgs(const grpc_channel_args* args) { static const char* args_to_remove[] = { // LB policy name, since we want to use the default (pick_first) in // the LB channel. GRPC_ARG_LB_POLICY_NAME, + // The service config that contains the LB config. We don't want to + // recursively use xds in the LB channel. + GRPC_ARG_SERVICE_CONFIG, // The channel arg for the server URI, since that will be different for // the LB channel than for the parent channel. The client channel // factory will re-add this arg with the right value. GRPC_ARG_SERVER_URI, // The resolved addresses, which will be generated by the name resolver - // used in the LB channel. Note that the LB channel will use the fake - // resolver, so this won't actually generate a query to DNS (or some - // other name service). However, the addresses returned by the fake - // resolver will have is_balancer=false, whereas our own addresses have - // is_balancer=true. We need the LB channel to return addresses with - // is_balancer=false so that it does not wind up recursively using the - // xds LB policy, as per the special case logic in client_channel.c. + // used in the LB channel. GRPC_ARG_SERVER_ADDRESS_LIST, - // The fake resolver response generator, because we are replacing it - // with the one from the xds policy, used to propagate updates to - // the LB channel. - GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, // The LB channel should use the authority indicated by the target // authority table (see \a grpc_lb_policy_xds_modify_lb_channel_args), // as opposed to the authority from the parent channel. @@ -916,14 +1044,6 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New server address list. - // Note that we pass these in both when creating the LB channel - // and via the fake resolver. The latter is what actually gets used. - CreateServerAddressListChannelArg(balancer_addresses.get()), - // The fake resolver response generator, which we use to inject - // address updates into the LB channel. - grpc_core::FakeResolverResponseGenerator::MakeChannelArg( - response_generator), // A channel arg indicating the target is a xds load balancer. grpc_channel_arg_integer_create( const_cast(GRPC_ARG_ADDRESS_IS_XDS_LOAD_BALANCER), 1), @@ -944,21 +1064,8 @@ grpc_channel_args* BuildBalancerChannelArgs( // ctor and dtor // -XdsLb::XdsLb(Args args) - : LoadBalancingPolicy(std::move(args)), - response_generator_(MakeRefCounted()), - lb_call_backoff_( - BackOff::Options() - .set_initial_backoff(GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS * - 1000) - .set_multiplier(GRPC_XDS_RECONNECT_BACKOFF_MULTIPLIER) - .set_jitter(GRPC_XDS_RECONNECT_JITTER) - .set_max_backoff(GRPC_XDS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { - // Initialization. - gpr_mu_init(&lb_channel_mu_); - GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, - &XdsLb::OnBalancerChannelConnectivityChangedLocked, this, - grpc_combiner_scheduler(args.combiner)); +XdsLb::XdsLb(Args args) : LoadBalancingPolicy(std::move(args)) { + gpr_mu_init(&lb_chand_mu_); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -982,7 +1089,7 @@ XdsLb::XdsLb(Args args) } XdsLb::~XdsLb() { - gpr_mu_destroy(&lb_channel_mu_); + gpr_mu_destroy(&lb_chand_mu_); gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); if (serverlist_ != nullptr) { @@ -992,10 +1099,6 @@ XdsLb::~XdsLb() { void XdsLb::ShutdownLocked() { shutting_down_ = true; - lb_calld_.reset(); - if (retry_timer_callback_pending_) { - grpc_timer_cancel(&lb_call_retry_timer_); - } if (fallback_timer_callback_pending_) { grpc_timer_cancel(&lb_fallback_timer_); } @@ -1004,11 +1107,10 @@ void XdsLb::ShutdownLocked() { // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be // alive when that callback is invoked. - if (lb_channel_ != nullptr) { - gpr_mu_lock(&lb_channel_mu_); - grpc_channel_destroy(lb_channel_); - lb_channel_ = nullptr; - gpr_mu_unlock(&lb_channel_mu_); + { + MutexLock lock(&lb_chand_mu_); + lb_chand_.reset(); + pending_lb_chand_.reset(); } } @@ -1017,8 +1119,11 @@ void XdsLb::ShutdownLocked() { // void XdsLb::ResetBackoffLocked() { - if (lb_channel_ != nullptr) { - grpc_channel_reset_connect_backoff(lb_channel_); + if (lb_chand_ != nullptr) { + grpc_channel_reset_connect_backoff(lb_chand_->channel()); + } + if (pending_lb_chand_ != nullptr) { + grpc_channel_reset_connect_backoff(pending_lb_chand_->channel()); } if (child_policy_ != nullptr) { child_policy_->ResetBackoffLocked(); @@ -1027,12 +1132,19 @@ void XdsLb::ResetBackoffLocked() { void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { - // delegate to the child_policy_ to fill the children subchannels. + // Delegate to the child_policy_ to fill the children subchannels. child_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); - MutexLock lock(&lb_channel_mu_); - if (lb_channel_ != nullptr) { + MutexLock lock(&lb_chand_mu_); + if (lb_chand_ != nullptr) { grpc_core::channelz::ChannelNode* channel_node = - grpc_channel_get_channelz_node(lb_channel_); + grpc_channel_get_channelz_node(lb_chand_->channel()); + if (channel_node != nullptr) { + child_channels->push_back(channel_node->uuid()); + } + } + if (pending_lb_chand_ != nullptr) { + grpc_core::channelz::ChannelNode* channel_node = + grpc_channel_get_channelz_node(pending_lb_chand_->channel()); if (channel_node != nullptr) { child_channels->push_back(channel_node->uuid()); } @@ -1059,22 +1171,29 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { args_ = grpc_channel_args_copy_and_add_and_remove( &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1); // Construct args for balancer channel. - grpc_channel_args* lb_channel_args = - BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args); - // Create balancer channel if needed. - if (lb_channel_ == nullptr) { - char* uri_str; - gpr_asprintf(&uri_str, "fake:///%s", server_name_); - gpr_mu_lock(&lb_channel_mu_); - lb_channel_ = - channel_control_helper()->CreateChannel(uri_str, *lb_channel_args); - gpr_mu_unlock(&lb_channel_mu_); - GPR_ASSERT(lb_channel_ != nullptr); - gpr_free(uri_str); + grpc_channel_args* lb_channel_args = BuildBalancerChannelArgs(&args); + // Create an LB channel if we don't have one yet or the balancer name has + // changed from the last received one. + bool create_lb_channel = lb_chand_ == nullptr; + if (lb_chand_ != nullptr) { + UniquePtr last_balancer_name( + grpc_channel_get_target(LatestLbChannel()->channel())); + create_lb_channel = + strcmp(last_balancer_name.get(), balancer_name_.get()) != 0; + } + if (create_lb_channel) { + OrphanablePtr lb_chand = + MakeOrphanable(balancer_name_.get(), + *lb_channel_args, Ref()); + if (lb_chand_ == nullptr || !lb_chand_->HasActiveCall()) { + GPR_ASSERT(pending_lb_chand_ == nullptr); + // If we do not have a working LB channel yet, use the newly created one. + lb_chand_ = std::move(lb_chand); + } else { + // Otherwise, wait until the new LB channel to be ready to swap it in. + pending_lb_chand_ = std::move(lb_chand); + } } - // Propagate updates to the LB channel (pick_first) through the fake - // resolver. - response_generator_->SetResponse(lb_channel_args); grpc_channel_args_destroy(lb_channel_args); } @@ -1114,12 +1233,13 @@ void XdsLb::ParseLbConfig(Config* xds_config) { void XdsLb::UpdateLocked(const grpc_channel_args& args, RefCountedPtr lb_config) { - const bool is_initial_update = lb_channel_ == nullptr; + const bool is_initial_update = lb_chand_ == nullptr; ParseLbConfig(lb_config.get()); // TODO(juanlishen): Pass fallback policy config update after fallback policy // is added. if (balancer_name_ == nullptr) { gpr_log(GPR_ERROR, "[xdslb %p] LB config parsing fails.", this); + return; } ProcessChannelArgsLocked(args); // Update the existing child policy. @@ -1139,24 +1259,6 @@ void XdsLb::UpdateLocked(const grpc_channel_args& args, fallback_timer_callback_pending_ = true; grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); } - StartBalancerCallLocked(); - } else if (!watching_lb_channel_) { - // If this is not the initial update and we're not already watching - // the LB channel's connectivity state, start a watch now. This - // ensures that we'll know when to switch to a new balancer call. - lb_channel_connectivity_ = grpc_channel_check_connectivity_state( - lb_channel_, true /* try to connect */); - grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(lb_channel_)); - GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); - watching_lb_channel_ = true; - // Ref held by closure. - Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity").release(); - grpc_client_channel_watch_connectivity_state( - client_channel_elem, - grpc_polling_entity_create_from_pollset_set(interested_parties()), - &lb_channel_connectivity_, &lb_channel_on_connectivity_changed_, - nullptr); } } @@ -1164,20 +1266,6 @@ void XdsLb::UpdateLocked(const grpc_channel_args& args, // code for balancer channel and call // -void XdsLb::StartBalancerCallLocked() { - GPR_ASSERT(lb_channel_ != nullptr); - if (shutting_down_) return; - // Init the LB call data. - GPR_ASSERT(lb_calld_ == nullptr); - lb_calld_ = MakeOrphanable(Ref()); - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, - "[xdslb %p] Query for backends (lb_channel: %p, lb_calld: %p)", - this, lb_channel_, lb_calld_.get()); - } - lb_calld_->StartQuery(); -} - void XdsLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { XdsLb* xdslb_policy = static_cast(arg); xdslb_policy->fallback_timer_callback_pending_ = false; @@ -1194,88 +1282,6 @@ void XdsLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { xdslb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); } -void XdsLb::StartBalancerCallRetryTimerLocked() { - grpc_millis next_try = lb_call_backoff_.NextAttemptTime(); - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Connection to LB server lost...", this); - grpc_millis timeout = next_try - ExecCtx::Get()->Now(); - if (timeout > 0) { - gpr_log(GPR_INFO, "[xdslb %p] ... retry_timer_active in %" PRId64 "ms.", - this, timeout); - } else { - gpr_log(GPR_INFO, "[xdslb %p] ... retry_timer_active immediately.", this); - } - } - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = Ref(DEBUG_LOCATION, "on_balancer_call_retry_timer"); - self.release(); - GRPC_CLOSURE_INIT(&lb_on_call_retry_, &XdsLb::OnBalancerCallRetryTimerLocked, - this, grpc_combiner_scheduler(combiner())); - retry_timer_callback_pending_ = true; - grpc_timer_init(&lb_call_retry_timer_, next_try, &lb_on_call_retry_); -} - -void XdsLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) { - XdsLb* xdslb_policy = static_cast(arg); - xdslb_policy->retry_timer_callback_pending_ = false; - if (!xdslb_policy->shutting_down_ && error == GRPC_ERROR_NONE && - xdslb_policy->lb_calld_ == nullptr) { - if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Restarting call to LB server", - xdslb_policy); - } - xdslb_policy->StartBalancerCallLocked(); - } - xdslb_policy->Unref(DEBUG_LOCATION, "on_balancer_call_retry_timer"); -} - -// Invoked as part of the update process. It continues watching the LB channel -// until it shuts down or becomes READY. It's invoked even if the LB channel -// stayed READY throughout the update (for example if the update is identical). -void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg, - grpc_error* error) { - XdsLb* xdslb_policy = static_cast(arg); - if (xdslb_policy->shutting_down_) goto done; - // Re-initialize the lb_call. This should also take care of updating the - // child policy. Note that the current child policy, if any, will - // stay in effect until an update from the new lb_call is received. - switch (xdslb_policy->lb_channel_connectivity_) { - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_TRANSIENT_FAILURE: { - // Keep watching the LB channel. - grpc_channel_element* client_channel_elem = - grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(xdslb_policy->lb_channel_)); - GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); - grpc_client_channel_watch_connectivity_state( - client_channel_elem, - grpc_polling_entity_create_from_pollset_set( - xdslb_policy->interested_parties()), - &xdslb_policy->lb_channel_connectivity_, - &xdslb_policy->lb_channel_on_connectivity_changed_, nullptr); - break; - } - // The LB channel may be IDLE because it's shut down before the update. - // Restart the LB call to kick the LB channel into gear. - case GRPC_CHANNEL_IDLE: - case GRPC_CHANNEL_READY: - xdslb_policy->lb_calld_.reset(); - if (xdslb_policy->retry_timer_callback_pending_) { - grpc_timer_cancel(&xdslb_policy->lb_call_retry_timer_); - } - xdslb_policy->lb_call_backoff_.Reset(); - xdslb_policy->StartBalancerCallLocked(); - // Fall through. - case GRPC_CHANNEL_SHUTDOWN: - done: - xdslb_policy->watching_lb_channel_ = false; - xdslb_policy->Unref(DEBUG_LOCATION, - "watch_lb_channel_connectivity_cb_shutdown"); - } -} - // // code for interacting with the child policy // @@ -1360,18 +1366,6 @@ class XdsFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( LoadBalancingPolicy::Args args) const override { - /* Count the number of gRPC-LB addresses. There must be at least one. */ - const ServerAddressList* addresses = - FindServerAddressListChannelArg(args.args); - if (addresses == nullptr) return nullptr; - bool found_balancer_address = false; - for (size_t i = 0; i < addresses->size(); ++i) { - if ((*addresses)[i].IsBalancer()) { - found_balancer_address = true; - break; - } - } - if (!found_balancer_address) return nullptr; return OrphanablePtr(New(std::move(args))); } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc index 55c646e6eed..7f8c232d6d0 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc @@ -33,55 +33,12 @@ #include "src/core/lib/security/transport/target_authority_table.h" #include "src/core/lib/slice/slice_internal.h" -namespace grpc_core { -namespace { - -int BalancerNameCmp(const grpc_core::UniquePtr& a, - const grpc_core::UniquePtr& b) { - return strcmp(a.get(), b.get()); -} - -RefCountedPtr CreateTargetAuthorityTable( - const ServerAddressList& addresses) { - TargetAuthorityTable::Entry* target_authority_entries = - static_cast( - gpr_zalloc(sizeof(*target_authority_entries) * addresses.size())); - for (size_t i = 0; i < addresses.size(); ++i) { - char* addr_str; - GPR_ASSERT( - grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true) > 0); - target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str); - gpr_free(addr_str); - char* balancer_name = grpc_channel_arg_get_string(grpc_channel_args_find( - addresses[i].args(), GRPC_ARG_ADDRESS_BALANCER_NAME)); - target_authority_entries[i].value.reset(gpr_strdup(balancer_name)); - } - RefCountedPtr target_authority_table = - TargetAuthorityTable::Create(addresses.size(), target_authority_entries, - BalancerNameCmp); - gpr_free(target_authority_entries); - return target_authority_table; -} - -} // namespace -} // namespace grpc_core - grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args( grpc_channel_args* args) { const char* args_to_remove[1]; size_t num_args_to_remove = 0; grpc_arg args_to_add[2]; size_t num_args_to_add = 0; - // Add arg for targets info table. - grpc_core::ServerAddressList* addresses = - grpc_core::FindServerAddressListChannelArg(args); - GPR_ASSERT(addresses != nullptr); - grpc_core::RefCountedPtr - target_authority_table = - grpc_core::CreateTargetAuthorityTable(*addresses); - args_to_add[num_args_to_add++] = - grpc_core::CreateTargetAuthorityTableChannelArg( - target_authority_table.get()); // Substitute the channel credentials with a version without call // credentials: the load balancer is not necessarily trusted to handle // bearer token credentials. diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index 258339491c1..3489f3d491b 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -86,7 +86,14 @@ FakeResolver::FakeResolver(const ResolverArgs& args) : Resolver(args.combiner) { channel_args_ = grpc_channel_args_copy(args.args); FakeResolverResponseGenerator* response_generator = FakeResolverResponseGenerator::GetFromArgs(args.args); - if (response_generator != nullptr) response_generator->resolver_ = this; + if (response_generator != nullptr) { + response_generator->resolver_ = this; + if (response_generator->response_ != nullptr) { + response_generator->SetResponse(response_generator->response_); + grpc_channel_args_destroy(response_generator->response_); + response_generator->response_ = nullptr; + } + } } FakeResolver::~FakeResolver() { @@ -114,6 +121,9 @@ void FakeResolver::RequestReresolutionLocked() { void FakeResolver::MaybeFinishNextLocked() { if (next_completion_ != nullptr && (next_results_ != nullptr || return_failure_)) { + // When both next_results_ and channel_args_ contain an arg with the same + // name, only the one in next_results_ will be kept since next_results_ is + // before channel_args_. *target_result_ = return_failure_ ? nullptr : grpc_channel_args_union(next_results_, channel_args_); @@ -157,15 +167,19 @@ void FakeResolverResponseGenerator::SetResponseLocked(void* arg, void FakeResolverResponseGenerator::SetResponse(grpc_channel_args* response) { GPR_ASSERT(response != nullptr); - GPR_ASSERT(resolver_ != nullptr); - SetResponseClosureArg* closure_arg = New(); - closure_arg->generator = this; - closure_arg->response = grpc_channel_args_copy(response); - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, SetResponseLocked, - closure_arg, - grpc_combiner_scheduler(resolver_->combiner())), - GRPC_ERROR_NONE); + if (resolver_ != nullptr) { + SetResponseClosureArg* closure_arg = New(); + closure_arg->generator = this; + closure_arg->response = grpc_channel_args_copy(response); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, SetResponseLocked, + closure_arg, + grpc_combiner_scheduler(resolver_->combiner())), + GRPC_ERROR_NONE); + } else { + GPR_ASSERT(response_ == nullptr); + response_ = grpc_channel_args_copy(response); + } } void FakeResolverResponseGenerator::SetReresolutionResponseLocked( diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h index d86111c3829..f423e6d46db 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h @@ -44,7 +44,9 @@ class FakeResolverResponseGenerator FakeResolverResponseGenerator() {} // Instructs the fake resolver associated with the response generator - // instance to trigger a new resolution with the specified response. + // instance to trigger a new resolution with the specified response. If the + // resolver is not available yet, delays response setting until it is. This + // can be called at most once before the resolver is available. void SetResponse(grpc_channel_args* next_response); // Sets the re-resolution response, which is returned by the fake resolver @@ -79,6 +81,7 @@ class FakeResolverResponseGenerator static void SetFailureLocked(void* arg, grpc_error* error); FakeResolver* resolver_ = nullptr; // Do not own. + grpc_channel_args* response_ = nullptr; }; } // namespace grpc_core diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.cc b/src/core/lib/security/security_connector/fake/fake_security_connector.cc index a0e2e6f030b..c55fd34d0e2 100644 --- a/src/core/lib/security/security_connector/fake/fake_security_connector.cc +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc @@ -26,6 +26,8 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" +#include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h" #include "src/core/ext/transport/chttp2/alpn/alpn.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/handshaker.h" @@ -53,8 +55,11 @@ class grpc_fake_channel_security_connector final target_(gpr_strdup(target)), expected_targets_( gpr_strdup(grpc_fake_transport_get_expected_targets(args))), - is_lb_channel_(grpc_core::FindTargetAuthorityTableInArgs(args) != - nullptr) { + is_lb_channel_( + grpc_channel_args_find( + args, GRPC_ARG_ADDRESS_IS_XDS_LOAD_BALANCER) != nullptr || + grpc_channel_args_find( + args, GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER) != nullptr) { const grpc_arg* target_name_override_arg = grpc_channel_args_find(args, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); if (target_name_override_arg != nullptr) { diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index d80fa33a83a..43dee177e7a 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -439,6 +439,28 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "xds_end2end_test", + srcs = ["xds_end2end_test.cc"], + external_deps = [ + "gmock", + "gtest", + ], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//:grpc_resolver_fake", + "//src/proto/grpc/lb/v1:load_balancer_proto", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//src/proto/grpc/testing/duplicate:echo_duplicate_proto", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + grpc_cc_test( name = "proto_server_reflection_test", srcs = ["proto_server_reflection_test.cc"], diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc new file mode 100644 index 00000000000..09556675d43 --- /dev/null +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -0,0 +1,1214 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/security/credentials/fake/fake_credentials.h" +#include "src/cpp/client/secure_credentials.h" +#include "src/cpp/server/secure_server_credentials.h" + +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#include "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" + +#include +#include + +// TODO(dgq): Other scenarios in need of testing: +// - Send a serverlist with faulty ip:port addresses (port > 2^16, etc). +// - Test reception of invalid serverlist +// - Test pinging +// - Test against a non-LB server. +// - Random LB server closing the stream unexpectedly. +// - Test using DNS-resolvable names (localhost?) +// - Test handling of creation of faulty RR instance by having the LB return a +// serverlist with non-existent backends after having initially returned a +// valid one. +// +// Findings from end to end testing to be covered here: +// - Handling of LB servers restart, including reconnection after backing-off +// retries. +// - Destruction of load balanced channel (and therefore of xds instance) +// while: +// 1) the internal LB call is still active. This should work by virtue +// of the weak reference the LB call holds. The call should be terminated as +// part of the xds shutdown process. +// 2) the retry timer is active. Again, the weak reference it holds should +// prevent a premature call to \a glb_destroy. +// - Restart of backend servers with no changes to serverlist. This exercises +// the RR handover mechanism. + +using std::chrono::system_clock; + +using grpc::lb::v1::LoadBalanceRequest; +using grpc::lb::v1::LoadBalanceResponse; +using grpc::lb::v1::LoadBalancer; + +namespace grpc { +namespace testing { +namespace { + +template +class CountedService : public ServiceType { + public: + size_t request_count() { + std::unique_lock lock(mu_); + return request_count_; + } + + size_t response_count() { + std::unique_lock lock(mu_); + return response_count_; + } + + void IncreaseResponseCount() { + std::unique_lock lock(mu_); + ++response_count_; + } + void IncreaseRequestCount() { + std::unique_lock lock(mu_); + ++request_count_; + } + + void ResetCounters() { + std::unique_lock lock(mu_); + request_count_ = 0; + response_count_ = 0; + } + + protected: + std::mutex mu_; + + private: + size_t request_count_ = 0; + size_t response_count_ = 0; +}; + +using BackendService = CountedService; +using BalancerService = CountedService; + +const char g_kCallCredsMdKey[] = "Balancer should not ..."; +const char g_kCallCredsMdValue[] = "... receive me"; + +class BackendServiceImpl : public BackendService { + public: + BackendServiceImpl() {} + + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) override { + // Backend should receive the call credentials metadata. + auto call_credentials_entry = + context->client_metadata().find(g_kCallCredsMdKey); + EXPECT_NE(call_credentials_entry, context->client_metadata().end()); + if (call_credentials_entry != context->client_metadata().end()) { + EXPECT_EQ(call_credentials_entry->second, g_kCallCredsMdValue); + } + IncreaseRequestCount(); + const auto status = TestServiceImpl::Echo(context, request, response); + IncreaseResponseCount(); + AddClient(context->peer()); + return status; + } + + // Returns true on its first invocation, false otherwise. + bool Shutdown() { + std::unique_lock lock(mu_); + const bool prev = !shutdown_; + shutdown_ = true; + gpr_log(GPR_INFO, "Backend: shut down"); + return prev; + } + + std::set clients() { + std::unique_lock lock(clients_mu_); + return clients_; + } + + private: + void AddClient(const grpc::string& client) { + std::unique_lock lock(clients_mu_); + clients_.insert(client); + } + + std::mutex mu_; + bool shutdown_ = false; + std::mutex clients_mu_; + std::set clients_; +}; + +grpc::string Ip4ToPackedString(const char* ip_str) { + struct in_addr ip4; + GPR_ASSERT(inet_pton(AF_INET, ip_str, &ip4) == 1); + return grpc::string(reinterpret_cast(&ip4), sizeof(ip4)); +} + +struct ClientStats { + size_t num_calls_started = 0; + size_t num_calls_finished = 0; + size_t num_calls_finished_with_client_failed_to_send = 0; + size_t num_calls_finished_known_received = 0; + std::map drop_token_counts; + + ClientStats& operator+=(const ClientStats& other) { + num_calls_started += other.num_calls_started; + num_calls_finished += other.num_calls_finished; + num_calls_finished_with_client_failed_to_send += + other.num_calls_finished_with_client_failed_to_send; + num_calls_finished_known_received += + other.num_calls_finished_known_received; + for (const auto& p : other.drop_token_counts) { + drop_token_counts[p.first] += p.second; + } + return *this; + } +}; + +class BalancerServiceImpl : public BalancerService { + public: + using Stream = ServerReaderWriter; + using ResponseDelayPair = std::pair; + + explicit BalancerServiceImpl(int client_load_reporting_interval_seconds) + : client_load_reporting_interval_seconds_( + client_load_reporting_interval_seconds), + shutdown_(false) {} + + Status BalanceLoad(ServerContext* context, Stream* stream) override { + // TODO(juanlishen): Clean up the scoping. + gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this); + { + std::unique_lock lock(mu_); + if (shutdown_) goto done; + } + + { + // Balancer shouldn't receive the call credentials metadata. + EXPECT_EQ(context->client_metadata().find(g_kCallCredsMdKey), + context->client_metadata().end()); + LoadBalanceRequest request; + std::vector responses_and_delays; + + if (!stream->Read(&request)) { + goto done; + } + IncreaseRequestCount(); + gpr_log(GPR_INFO, "LB[%p]: received initial message '%s'", this, + request.DebugString().c_str()); + + { + LoadBalanceResponse initial_response; + initial_response.mutable_initial_response() + ->mutable_client_stats_report_interval() + ->set_seconds(client_load_reporting_interval_seconds_); + stream->Write(initial_response); + } + + { + std::unique_lock lock(mu_); + responses_and_delays = responses_and_delays_; + } + for (const auto& response_and_delay : responses_and_delays) { + { + std::unique_lock lock(mu_); + if (shutdown_) goto done; + } + SendResponse(stream, response_and_delay.first, + response_and_delay.second); + } + { + std::unique_lock lock(mu_); + if (shutdown_) goto done; + serverlist_cond_.wait(lock, [this] { return serverlist_ready_; }); + } + + if (client_load_reporting_interval_seconds_ > 0) { + request.Clear(); + if (stream->Read(&request)) { + gpr_log(GPR_INFO, "LB[%p]: received client load report message '%s'", + this, request.DebugString().c_str()); + GPR_ASSERT(request.has_client_stats()); + // We need to acquire the lock here in order to prevent the notify_one + // below from firing before its corresponding wait is executed. + std::lock_guard lock(mu_); + client_stats_.num_calls_started += + request.client_stats().num_calls_started(); + client_stats_.num_calls_finished += + request.client_stats().num_calls_finished(); + client_stats_.num_calls_finished_with_client_failed_to_send += + request.client_stats() + .num_calls_finished_with_client_failed_to_send(); + client_stats_.num_calls_finished_known_received += + request.client_stats().num_calls_finished_known_received(); + for (const auto& drop_token_count : + request.client_stats().calls_finished_with_drop()) { + client_stats_ + .drop_token_counts[drop_token_count.load_balance_token()] += + drop_token_count.num_calls(); + } + load_report_ready_ = true; + load_report_cond_.notify_one(); + } + } + } + done: + gpr_log(GPR_INFO, "LB[%p]: done", this); + return Status::OK; + } + + void add_response(const LoadBalanceResponse& response, int send_after_ms) { + std::unique_lock lock(mu_); + responses_and_delays_.push_back(std::make_pair(response, send_after_ms)); + } + + // Returns true on its first invocation, false otherwise. + bool Shutdown() { + bool prev; + { + std::unique_lock lock(mu_); + prev = !shutdown_; + shutdown_ = true; + } + NotifyDoneWithServerlists(); + gpr_log(GPR_INFO, "LB[%p]: shut down", this); + return prev; + } + + static LoadBalanceResponse BuildResponseForBackends( + const std::vector& backend_ports, + const std::map& drop_token_counts) { + LoadBalanceResponse response; + for (const auto& drop_token_count : drop_token_counts) { + for (size_t i = 0; i < drop_token_count.second; ++i) { + auto* server = response.mutable_server_list()->add_servers(); + server->set_drop(true); + server->set_load_balance_token(drop_token_count.first); + } + } + for (const int& backend_port : backend_ports) { + auto* server = response.mutable_server_list()->add_servers(); + server->set_ip_address(Ip4ToPackedString("127.0.0.1")); + server->set_port(backend_port); + static int token_count = 0; + char* token; + gpr_asprintf(&token, "token%03d", ++token_count); + server->set_load_balance_token(token); + gpr_free(token); + } + return response; + } + + const ClientStats& WaitForLoadReport() { + std::unique_lock lock(mu_); + load_report_cond_.wait(lock, [this] { return load_report_ready_; }); + load_report_ready_ = false; + return client_stats_; + } + + void NotifyDoneWithServerlists() { + std::lock_guard lock(mu_); + serverlist_ready_ = true; + serverlist_cond_.notify_all(); + } + + private: + void SendResponse(Stream* stream, const LoadBalanceResponse& response, + int delay_ms) { + gpr_log(GPR_INFO, "LB[%p]: sleeping for %d ms...", this, delay_ms); + if (delay_ms > 0) { + gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(delay_ms)); + } + gpr_log(GPR_INFO, "LB[%p]: Woke up! Sending response '%s'", this, + response.DebugString().c_str()); + IncreaseResponseCount(); + stream->Write(response); + } + + const int client_load_reporting_interval_seconds_; + std::vector responses_and_delays_; + std::mutex mu_; + std::condition_variable load_report_cond_; + bool load_report_ready_ = false; + std::condition_variable serverlist_cond_; + bool serverlist_ready_ = false; + ClientStats client_stats_; + bool shutdown_; +}; + +class XdsEnd2endTest : public ::testing::Test { + protected: + XdsEnd2endTest(int num_backends, int num_balancers, + int client_load_reporting_interval_seconds) + : server_host_("localhost"), + num_backends_(num_backends), + num_balancers_(num_balancers), + client_load_reporting_interval_seconds_( + client_load_reporting_interval_seconds) { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1"); + } + + void SetUp() override { + response_generator_ = + grpc_core::MakeRefCounted(); + lb_channel_response_generator_ = + grpc_core::MakeRefCounted(); + // Start the backends. + for (size_t i = 0; i < num_backends_; ++i) { + backends_.emplace_back(new BackendServiceImpl()); + backend_servers_.emplace_back(ServerThread( + "backend", server_host_, backends_.back().get())); + } + // Start the load balancers. + for (size_t i = 0; i < num_balancers_; ++i) { + balancers_.emplace_back( + new BalancerServiceImpl(client_load_reporting_interval_seconds_)); + balancer_servers_.emplace_back(ServerThread( + "balancer", server_host_, balancers_.back().get())); + } + ResetStub(); + } + + void TearDown() override { + for (size_t i = 0; i < backends_.size(); ++i) { + if (backends_[i]->Shutdown()) backend_servers_[i].Shutdown(); + } + for (size_t i = 0; i < balancers_.size(); ++i) { + if (balancers_[i]->Shutdown()) balancer_servers_[i].Shutdown(); + } + } + + void ResetStub(int fallback_timeout = 0, + const grpc::string& expected_targets = "") { + ChannelArguments args; + // TODO(juanlishen): Add setter to ChannelArguments. + args.SetInt(GRPC_ARG_XDS_FALLBACK_TIMEOUT_MS, fallback_timeout); + args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, + response_generator_.get()); + if (!expected_targets.empty()) { + args.SetString(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS, expected_targets); + } + std::ostringstream uri; + uri << "fake:///" << kApplicationTargetName_; + // TODO(dgq): templatize tests to run everything using both secure and + // insecure channel credentials. + grpc_channel_credentials* channel_creds = + grpc_fake_transport_security_credentials_create(); + grpc_call_credentials* call_creds = grpc_md_only_test_credentials_create( + g_kCallCredsMdKey, g_kCallCredsMdValue, false); + std::shared_ptr creds( + new SecureChannelCredentials(grpc_composite_channel_credentials_create( + channel_creds, call_creds, nullptr))); + call_creds->Unref(); + channel_creds->Unref(); + channel_ = CreateCustomChannel(uri.str(), creds, args); + stub_ = grpc::testing::EchoTestService::NewStub(channel_); + } + + void ResetBackendCounters() { + for (const auto& backend : backends_) backend->ResetCounters(); + } + + ClientStats WaitForLoadReports() { + ClientStats client_stats; + for (const auto& balancer : balancers_) { + client_stats += balancer->WaitForLoadReport(); + } + return client_stats; + } + + bool SeenAllBackends() { + for (const auto& backend : backends_) { + if (backend->request_count() == 0) return false; + } + return true; + } + + void SendRpcAndCount(int* num_total, int* num_ok, int* num_failure, + int* num_drops) { + const Status status = SendRpc(); + if (status.ok()) { + ++*num_ok; + } else { + if (status.error_message() == "Call dropped by load balancing policy") { + ++*num_drops; + } else { + ++*num_failure; + } + } + ++*num_total; + } + + std::tuple WaitForAllBackends( + int num_requests_multiple_of = 1) { + int num_ok = 0; + int num_failure = 0; + int num_drops = 0; + int num_total = 0; + while (!SeenAllBackends()) { + SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops); + } + while (num_total % num_requests_multiple_of != 0) { + SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops); + } + ResetBackendCounters(); + gpr_log(GPR_INFO, + "Performed %d warm up requests (a multiple of %d) against the " + "backends. %d succeeded, %d failed, %d dropped.", + num_total, num_requests_multiple_of, num_ok, num_failure, + num_drops); + return std::make_tuple(num_ok, num_failure, num_drops); + } + + void WaitForBackend(size_t backend_idx) { + do { + (void)SendRpc(); + } while (backends_[backend_idx]->request_count() == 0); + ResetBackendCounters(); + } + + grpc_core::ServerAddressList CreateLbAddressesFromPortList( + const std::vector& ports) { + grpc_core::ServerAddressList addresses; + for (int port : ports) { + char* lb_uri_str; + gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port); + grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true); + GPR_ASSERT(lb_uri != nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + std::vector args_to_add; + grpc_channel_args* args = grpc_channel_args_copy_and_add( + nullptr, args_to_add.data(), args_to_add.size()); + addresses.emplace_back(address.addr, address.len, args); + grpc_uri_destroy(lb_uri); + gpr_free(lb_uri_str); + } + return addresses; + } + + void SetNextResolution(const std::vector& ports, + const char* service_config_json = nullptr, + grpc_core::FakeResolverResponseGenerator* + lb_channel_response_generator = nullptr) { + grpc_core::ExecCtx exec_ctx; + grpc_core::ServerAddressList addresses = + CreateLbAddressesFromPortList(ports); + std::vector args = { + CreateServerAddressListChannelArg(&addresses), + grpc_core::FakeResolverResponseGenerator::MakeChannelArg( + lb_channel_response_generator == nullptr + ? lb_channel_response_generator_.get() + : lb_channel_response_generator)}; + if (service_config_json != nullptr) { + args.push_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_SERVICE_CONFIG), + const_cast(service_config_json))); + } + grpc_channel_args fake_result = {args.size(), args.data()}; + response_generator_->SetResponse(&fake_result); + } + + void SetNextResolutionForLbChannelAllBalancers( + const char* service_config_json = nullptr, + grpc_core::FakeResolverResponseGenerator* lb_channel_response_generator = + nullptr) { + std::vector ports; + for (size_t i = 0; i < balancer_servers_.size(); ++i) { + ports.emplace_back(balancer_servers_[i].port_); + } + SetNextResolutionForLbChannel(ports, service_config_json, + lb_channel_response_generator); + } + + void SetNextResolutionForLbChannel( + const std::vector& ports, const char* service_config_json = nullptr, + grpc_core::FakeResolverResponseGenerator* lb_channel_response_generator = + nullptr) { + grpc_core::ExecCtx exec_ctx; + grpc_core::ServerAddressList addresses = + CreateLbAddressesFromPortList(ports); + std::vector args = { + CreateServerAddressListChannelArg(&addresses), + }; + if (service_config_json != nullptr) { + args.push_back(grpc_channel_arg_string_create( + const_cast(GRPC_ARG_SERVICE_CONFIG), + const_cast(service_config_json))); + } + grpc_channel_args fake_result = {args.size(), args.data()}; + if (lb_channel_response_generator == nullptr) { + lb_channel_response_generator = lb_channel_response_generator_.get(); + } + lb_channel_response_generator->SetResponse(&fake_result); + } + + void SetNextReresolutionResponse(const std::vector& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::ServerAddressList addresses = + CreateLbAddressesFromPortList(ports); + grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); + grpc_channel_args fake_result = {1, &fake_addresses}; + response_generator_->SetReresolutionResponse(&fake_result); + } + + const std::vector GetBackendPorts(const size_t start_index = 0) const { + std::vector backend_ports; + for (size_t i = start_index; i < backend_servers_.size(); ++i) { + backend_ports.push_back(backend_servers_[i].port_); + } + return backend_ports; + } + + void ScheduleResponseForBalancer(size_t i, + const LoadBalanceResponse& response, + int delay_ms) { + balancers_.at(i)->add_response(response, delay_ms); + } + + Status SendRpc(EchoResponse* response = nullptr, int timeout_ms = 1000, + bool wait_for_ready = false) { + const bool local_response = (response == nullptr); + if (local_response) response = new EchoResponse; + EchoRequest request; + request.set_message(kRequestMessage_); + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); + if (wait_for_ready) context.set_wait_for_ready(true); + Status status = stub_->Echo(&context, request, response); + if (local_response) delete response; + return status; + } + + void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000, + bool wait_for_ready = false) { + for (size_t i = 0; i < times; ++i) { + EchoResponse response; + const Status status = SendRpc(&response, timeout_ms, wait_for_ready); + EXPECT_TRUE(status.ok()) << "code=" << status.error_code() + << " message=" << status.error_message(); + EXPECT_EQ(response.message(), kRequestMessage_); + } + } + + void CheckRpcSendFailure() { + const Status status = SendRpc(); + EXPECT_FALSE(status.ok()); + } + + template + struct ServerThread { + explicit ServerThread(const grpc::string& type, + const grpc::string& server_host, T* service) + : type_(type), service_(service) { + std::mutex mu; + // We need to acquire the lock here in order to prevent the notify_one + // by ServerThread::Start from firing before the wait below is hit. + std::unique_lock lock(mu); + port_ = grpc_pick_unused_port_or_die(); + gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); + std::condition_variable cond; + thread_.reset(new std::thread( + std::bind(&ServerThread::Start, this, server_host, &mu, &cond))); + cond.wait(lock); + gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); + } + + void Start(const grpc::string& server_host, std::mutex* mu, + std::condition_variable* cond) { + // We need to acquire the lock here in order to prevent the notify_one + // below from firing before its corresponding wait is executed. + std::lock_guard lock(*mu); + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + std::shared_ptr creds(new SecureServerCredentials( + grpc_fake_transport_security_server_credentials_create())); + builder.AddListeningPort(server_address.str(), creds); + builder.RegisterService(service_); + server_ = builder.BuildAndStart(); + cond->notify_one(); + } + + void Shutdown() { + gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str()); + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + thread_->join(); + gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str()); + } + + int port_; + grpc::string type_; + std::unique_ptr server_; + T* service_; + std::unique_ptr thread_; + }; + + const grpc::string server_host_; + const size_t num_backends_; + const size_t num_balancers_; + const int client_load_reporting_interval_seconds_; + std::shared_ptr channel_; + std::unique_ptr stub_; + std::vector> backends_; + std::vector> balancers_; + std::vector> backend_servers_; + std::vector> balancer_servers_; + grpc_core::RefCountedPtr + response_generator_; + grpc_core::RefCountedPtr + lb_channel_response_generator_; + const grpc::string kRequestMessage_ = "Live long and prosper."; + const grpc::string kApplicationTargetName_ = "application_target_name"; + const grpc::string kDefaultServiceConfig_ = + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{ \"balancerName\": \"fake:///lb\" } }\n" + " ]\n" + "}"; +}; + +class SingleBalancerTest : public XdsEnd2endTest { + public: + SingleBalancerTest() : XdsEnd2endTest(4, 1, 0) {} +}; + +TEST_F(SingleBalancerTest, Vanilla) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcsPerAddress = 100; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + // Make sure that trying to connect works without a call. + channel_->GetState(true /* try_to_connect */); + // We need to wait for all backends to come online. + WaitForAllBackends(); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); + // Each backend should have gotten 100 requests. + for (size_t i = 0; i < backends_.size(); ++i) { + EXPECT_EQ(kNumRpcsPerAddress, + backend_servers_[i].service_->request_count()); + } + balancers_[0]->NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + + // Check LB policy name for the channel. + EXPECT_EQ("xds_experimental", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + // Same backend listed twice. + std::vector ports; + ports.push_back(backend_servers_[0].port_); + ports.push_back(backend_servers_[0].port_); + const size_t kNumRpcsPerAddress = 10; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(ports, {}), 0); + // We need to wait for the backend to come online. + WaitForBackend(0); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * ports.size()); + // Backend should have gotten 20 requests. + EXPECT_EQ(kNumRpcsPerAddress * 2, + backend_servers_[0].service_->request_count()); + // And they should have come from a single client port, because of + // subchannel sharing. + EXPECT_EQ(1UL, backends_[0]->clients().size()); + balancers_[0]->NotifyDoneWithServerlists(); +} + +TEST_F(SingleBalancerTest, SecureNaming) { + // TODO(juanlishen): Use separate fake creds for the balancer channel. + ResetStub(0, kApplicationTargetName_ + ";lb"); + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannel({balancer_servers_[0].port_}); + const size_t kNumRpcsPerAddress = 100; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + // Make sure that trying to connect works without a call. + channel_->GetState(true /* try_to_connect */); + // We need to wait for all backends to come online. + WaitForAllBackends(); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); + + // Each backend should have gotten 100 requests. + for (size_t i = 0; i < backends_.size(); ++i) { + EXPECT_EQ(kNumRpcsPerAddress, + backend_servers_[i].service_->request_count()); + } + // The balancer got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); +} + +TEST_F(SingleBalancerTest, SecureNamingDeathTest) { + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + // Make sure that we blow up (via abort() from the security connector) when + // the name from the balancer doesn't match expectations. + ASSERT_DEATH( + { + ResetStub(0, kApplicationTargetName_ + ";lb"); + SetNextResolution({}, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{ \"balancerName\": " + "\"fake:///wrong_lb\" } }\n" + " ]\n" + "}"); + SetNextResolutionForLbChannel({balancer_servers_[0].port_}); + channel_->WaitForConnected(grpc_timeout_seconds_to_deadline(1)); + }, + ""); +} + +TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); + const int kCallDeadlineMs = kServerlistDelayMs * 2; + // First response is an empty serverlist, sent right away. + ScheduleResponseForBalancer(0, LoadBalanceResponse(), 0); + // Send non-empty serverlist only after kServerlistDelayMs + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + kServerlistDelayMs); + const auto t0 = system_clock::now(); + // Client will block: LB will initially send empty serverlist. + CheckRpcSendOk(1, kCallDeadlineMs, true /* wait_for_ready */); + const auto ellapsed_ms = + std::chrono::duration_cast( + system_clock::now() - t0); + // but eventually, the LB sends a serverlist update that allows the call to + // proceed. The call delay must be larger than the delay in sending the + // populated serverlist but under the call's deadline (which is enforced by + // the call's deadline). + EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs); + balancers_[0]->NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent two responses. + EXPECT_EQ(2U, balancer_servers_[0].service_->response_count()); +} + +TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumUnreachableServers = 5; + std::vector ports; + for (size_t i = 0; i < kNumUnreachableServers; ++i) { + ports.push_back(grpc_pick_unused_port_or_die()); + } + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(ports, {}), 0); + const Status status = SendRpc(); + // The error shouldn't be DEADLINE_EXCEEDED. + EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code()); + balancers_[0]->NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); +} + +// The fallback tests are deferred because the fallback mode hasn't been +// supported yet. + +// TODO(juanlishen): Add TEST_F(SingleBalancerTest, Fallback) + +// TODO(juanlishen): Add TEST_F(SingleBalancerTest, FallbackUpdate) + +TEST_F(SingleBalancerTest, BackendsRestart) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcsPerAddress = 100; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + // Make sure that trying to connect works without a call. + channel_->GetState(true /* try_to_connect */); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); + balancers_[0]->NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + for (size_t i = 0; i < backends_.size(); ++i) { + if (backends_[i]->Shutdown()) backend_servers_[i].Shutdown(); + } + CheckRpcSendFailure(); + for (size_t i = 0; i < num_backends_; ++i) { + backends_.emplace_back(new BackendServiceImpl()); + backend_servers_.emplace_back(ServerThread( + "backend", server_host_, backends_.back().get())); + } + // The following RPC will fail due to the backend ports having changed. It + // will nonetheless exercise the xds-roundrobin handling of the RR policy + // having gone into shutdown. + // TODO(dgq): implement the "backend restart" component as well. We need extra + // machinery to either update the LB responses "on the fly" or instruct + // backends which ports to restart on. + CheckRpcSendFailure(); +} + +class UpdatesTest : public XdsEnd2endTest { + public: + UpdatesTest() : XdsEnd2endTest(4, 3, 0) {} +}; + +TEST_F(UpdatesTest, UpdateBalancersButKeepUsingOriginalBalancer) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const std::vector first_backend{GetBackendPorts()[0]}; + const std::vector second_backend{GetBackendPorts()[1]}; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(first_backend, {}), 0); + ScheduleResponseForBalancer( + 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0); + + // Wait until the first backend is ready. + WaitForBackend(0); + + // Send 10 requests. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + + // All 10 requests should have gone to the first backend. + EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + + // Balancer 0 got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + SetNextResolutionForLbChannel({balancer_servers_[1].port_}); + gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + + EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); + // Send 10 seconds worth of RPCs + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // The current LB call is still working, so xds continued using it to the + // first balancer, which doesn't assign the second backend. + EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); +} + +TEST_F(UpdatesTest, UpdateBalancerName) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const std::vector first_backend{GetBackendPorts()[0]}; + const std::vector second_backend{GetBackendPorts()[1]}; + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(first_backend, {}), 0); + ScheduleResponseForBalancer( + 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0); + + // Wait until the first backend is ready. + WaitForBackend(0); + + // Send 10 requests. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + + // All 10 requests should have gone to the first backend. + EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + + // Balancer 0 got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + + std::vector ports; + ports.emplace_back(balancer_servers_[1].port_); + auto new_lb_channel_response_generator = + grpc_core::MakeRefCounted(); + SetNextResolutionForLbChannel(ports, nullptr, + new_lb_channel_response_generator.get()); + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE BALANCER NAME =========="); + SetNextResolution({}, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{ \"balancerName\": " + "\"fake:///updated_lb\" } }\n" + " ]\n" + "}", + new_lb_channel_response_generator.get()); + gpr_log(GPR_INFO, "========= UPDATED BALANCER NAME =========="); + + // Wait until update has been processed, as signaled by the second backend + // receiving a request. + EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + WaitForBackend(1); + + backend_servers_[1].service_->ResetCounters(); + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + // All 10 requests should have gone to the second backend. + EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); + + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancer_servers_[1].service_->request_count()); + EXPECT_EQ(1U, balancer_servers_[1].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); +} + +// Send an update with the same set of LBs as the one in SetUp() in order to +// verify that the LB channel inside xds keeps the initial connection (which +// by definition is also present in the update). +TEST_F(UpdatesTest, UpdateBalancersRepeated) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannelAllBalancers(); + const std::vector first_backend{GetBackendPorts()[0]}; + const std::vector second_backend{GetBackendPorts()[0]}; + + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(first_backend, {}), 0); + ScheduleResponseForBalancer( + 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0); + + // Wait until the first backend is ready. + WaitForBackend(0); + + // Send 10 requests. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + + // All 10 requests should have gone to the first backend. + EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + + // Balancer 0 got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + + std::vector ports; + ports.emplace_back(balancer_servers_[0].port_); + ports.emplace_back(balancer_servers_[1].port_); + ports.emplace_back(balancer_servers_[2].port_); + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + SetNextResolutionForLbChannel(ports); + gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + + EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); + // Send 10 seconds worth of RPCs + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // xds continued using the original LB call to the first balancer, which + // doesn't assign the second backend. + EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + + ports.clear(); + ports.emplace_back(balancer_servers_[0].port_); + ports.emplace_back(balancer_servers_[1].port_); + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 2 =========="); + SetNextResolutionForLbChannel(ports); + gpr_log(GPR_INFO, "========= UPDATE 2 DONE =========="); + + EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_millis(10000, GPR_TIMESPAN)); + // Send 10 seconds worth of RPCs + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // xds continued using the original LB call to the first balancer, which + // doesn't assign the second backend. + EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); +} + +TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { + SetNextResolution({}, kDefaultServiceConfig_.c_str()); + SetNextResolutionForLbChannel({balancer_servers_[0].port_}); + const std::vector first_backend{GetBackendPorts()[0]}; + const std::vector second_backend{GetBackendPorts()[1]}; + + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(first_backend, {}), 0); + ScheduleResponseForBalancer( + 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0); + + // Start servers and send 10 RPCs per server. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + // All 10 requests should have gone to the first backend. + EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + + // Kill balancer 0 + gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); + if (balancers_[0]->Shutdown()) balancer_servers_[0].Shutdown(); + gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); + + // This is serviced by the existing child policy. + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + // All 10 requests should again have gone to the first backend. + EXPECT_EQ(20U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + + // Balancer 0 got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + SetNextResolutionForLbChannel({balancer_servers_[1].port_}); + gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + + // Wait until update has been processed, as signaled by the second backend + // receiving a request. In the meantime, the client continues to be serviced + // (by the first backend) without interruption. + EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + WaitForBackend(1); + + // This is serviced by the updated RR policy + backend_servers_[1].service_->ResetCounters(); + gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); + // All 10 requests should have gone to the second backend. + EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); + + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + // The second balancer, published as part of the first update, may end up + // getting two requests (that is, 1 <= #req <= 2) if the LB call retry timer + // firing races with the arrival of the update containing the second + // balancer. + EXPECT_GE(balancer_servers_[1].service_->request_count(), 1U); + EXPECT_GE(balancer_servers_[1].service_->response_count(), 1U); + EXPECT_LE(balancer_servers_[1].service_->request_count(), 2U); + EXPECT_LE(balancer_servers_[1].service_->response_count(), 2U); + EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); + EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); +} + +// The re-resolution tests are deferred because they rely on the fallback mode, +// which hasn't been supported. + +// TODO(juanlishen): Add TEST_F(UpdatesTest, ReresolveDeadBackend). + +// TODO(juanlishen): Add TEST_F(UpdatesWithClientLoadReportingTest, +// ReresolveDeadBalancer) + +// The drop tests are deferred because the drop handling hasn't been added yet. + +// TODO(roth): Add TEST_F(SingleBalancerTest, Drop) + +// TODO(roth): Add TEST_F(SingleBalancerTest, DropAllFirst) + +// TODO(roth): Add TEST_F(SingleBalancerTest, DropAll) + +class SingleBalancerWithClientLoadReportingTest : public XdsEnd2endTest { + public: + SingleBalancerWithClientLoadReportingTest() : XdsEnd2endTest(4, 1, 3) {} +}; + +// The client load reporting tests are deferred because the client load +// reporting hasn't been supported yet. + +// TODO(vpowar): Add TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) + +// TODO(roth): Add TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_init(); + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + const auto result = RUN_ALL_TESTS(); + grpc_shutdown(); + return result; +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 0b84b8a4b95..5a1eafda6c2 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -5002,6 +5002,28 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [ + "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h", + "src/proto/grpc/lb/v1/load_balancer.pb.h", + "src/proto/grpc/lb/v1/load_balancer_mock.grpc.pb.h" + ], + "is_filegroup": false, + "language": "c++", + "name": "xds_end2end_test", + "src": [ + "test/cpp/end2end/xds_end2end_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 6dc9eb7f0d1..9399b9f6b9d 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -5686,6 +5686,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "xds_end2end_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From 6d75cfe426c4acaf5c5d7a35e2b8dd9277e71348 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 5 Mar 2019 14:18:01 -0800 Subject: [PATCH 584/814] Revert "Merge pull request #18254 from grpc/revert-18078-grpclb_child_policy_configurable" This reverts commit 6dcf6d164510a66efa831f2620e6511ffda0eba1, reversing changes made to a2f1e924defce11bdbf97375a7410d34b5661d6b. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 344 +++++++++++++----- test/cpp/end2end/grpclb_end2end_test.cc | 144 ++++++++ 2 files changed, 402 insertions(+), 86 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index c5d1ff22a9d..c1f2846f046 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -39,15 +39,14 @@ /// the balancer, we update the round_robin policy with the new list of /// addresses. If we cannot communicate with the balancer on startup, /// however, we may enter fallback mode, in which case we will populate -/// the RR policy's addresses from the backend addresses returned by the +/// the child policy's addresses from the backend addresses returned by the /// resolver. /// -/// Once an RR policy instance is in place (and getting updated as described), +/// Once a child policy instance is in place (and getting updated as described), /// calls for a pick, a ping, or a cancellation will be serviced right -/// away by forwarding them to the RR instance. Any time there's no RR -/// policy available (i.e., right after the creation of the gRPCLB policy), -/// pick and ping requests are added to a list of pending picks and pings -/// to be flushed and serviced when the RR policy instance becomes available. +/// away by forwarding them to the child policy instance. Any time there's no +/// child policy available (i.e., right after the creation of the gRPCLB +/// policy), pick requests are queued. /// /// \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the /// high level design and details. @@ -279,16 +278,23 @@ class GrpcLb : public LoadBalancingPolicy { UniquePtr picker) override; void RequestReresolution() override; + void set_child(LoadBalancingPolicy* child) { child_ = child; } + private: + bool CalledByPendingChild() const; + bool CalledByCurrentChild() const; + RefCountedPtr parent_; + LoadBalancingPolicy* child_ = nullptr; }; ~GrpcLb(); void ShutdownLocked() override; - // Helper function used in UpdateLocked(). + // Helper functions used in UpdateLocked(). void ProcessChannelArgsLocked(const grpc_channel_args& args); + void ParseLbConfig(Config* grpclb_config); // Methods for dealing with the balancer channel and call. void StartBalancerCallLocked(); @@ -296,10 +302,11 @@ class GrpcLb : public LoadBalancingPolicy { void StartBalancerCallRetryTimerLocked(); static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error); - // Methods for dealing with the RR policy. - grpc_channel_args* CreateRoundRobinPolicyArgsLocked(); - void CreateRoundRobinPolicyLocked(Args args); - void CreateOrUpdateRoundRobinPolicyLocked(); + // Methods for dealing with the child policy. + grpc_channel_args* CreateChildPolicyArgsLocked(); + OrphanablePtr CreateChildPolicyLocked( + const char* name, grpc_channel_args* args); + void CreateOrUpdateChildPolicyLocked(); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -345,8 +352,14 @@ class GrpcLb : public LoadBalancingPolicy { grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; - // The RR policy to use for the backends. - OrphanablePtr rr_policy_; + // The child policy to use for the backends. + OrphanablePtr child_policy_; + // When switching child policies, the new policy will be stored here + // until it reports READY, at which point it will be moved to child_policy_. + OrphanablePtr pending_child_policy_; + // The child policy name and config. + UniquePtr child_policy_name_; + RefCountedPtr child_policy_config_; }; // @@ -558,14 +571,30 @@ GrpcLb::Picker::PickResult GrpcLb::Picker::Pick(PickState* pick, // GrpcLb::Helper // +bool GrpcLb::Helper::CalledByPendingChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->pending_child_policy_.get(); +} + +bool GrpcLb::Helper::CalledByCurrentChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->child_policy_.get(); +} + Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { - if (parent_->shutting_down_) return nullptr; + if (parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return nullptr; + } return parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, const grpc_channel_args& args) { - if (parent_->shutting_down_) return nullptr; + if (parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return nullptr; + } return parent_->channel_control_helper()->CreateChannel(target, args); } @@ -576,31 +605,50 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, GRPC_ERROR_UNREF(state_error); return; } + // If this request is from the pending child policy, ignore it until + // it reports READY, at which point we swap it into place. + if (CalledByPendingChild()) { + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, + "[grpclb %p helper %p] pending child policy %p reports state=%s", + parent_.get(), this, parent_->pending_child_policy_.get(), + grpc_connectivity_state_name(state)); + } + if (state != GRPC_CHANNEL_READY) { + GRPC_ERROR_UNREF(state_error); + return; + } + parent_->child_policy_ = std::move(parent_->pending_child_policy_); + } else if (!CalledByCurrentChild()) { + // This request is from an outdated child, so ignore it. + GRPC_ERROR_UNREF(state_error); + return; + } // There are three cases to consider here: // 1. We're in fallback mode. In this case, we're always going to use - // RR's result, so we pass its picker through as-is. + // the child policy's result, so we pass its picker through as-is. // 2. The serverlist contains only drop entries. In this case, we // want to use our own picker so that we can return the drops. // 3. Not in fallback mode and serverlist is not all drops (i.e., it // may be empty or contain at least one backend address). There are // two sub-cases: - // a. RR is reporting state READY. In this case, we wrap RR's - // picker in our own, so that we can handle drops and LB token - // metadata for each pick. - // b. RR is reporting a state other than READY. In this case, we - // don't want to use our own picker, because we don't want to - // process drops for picks that yield a QUEUE result; this would + // a. The child policy is reporting state READY. In this case, we wrap + // the child's picker in our own, so that we can handle drops and LB + // token metadata for each pick. + // b. The child policy is reporting a state other than READY. In this + // case, we don't want to use our own picker, because we don't want + // to process drops for picks that yield a QUEUE result; this would // result in dropping too many calls, since we will see the // queued picks multiple times, and we'd consider each one a // separate call for the drop calculation. // - // Cases 1 and 3b: return picker from RR as-is. + // Cases 1 and 3b: return picker from the child policy as-is. if (parent_->serverlist_ == nullptr || (!parent_->serverlist_->ContainsAllDropEntries() && state != GRPC_CHANNEL_READY)) { if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p helper %p] state=%s passing RR picker %p as-is", + "[grpclb %p helper %p] state=%s passing child picker %p as-is", parent_.get(), this, grpc_connectivity_state_name(state), picker.get()); } @@ -608,9 +656,9 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, std::move(picker)); return; } - // Cases 2 and 3a: wrap picker from RR in our own picker. + // Cases 2 and 3a: wrap picker from the child in our own picker. if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping RR picker %p", + gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping child picker %p", parent_.get(), this, grpc_connectivity_state_name(state), picker.get()); } @@ -628,15 +676,19 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, void GrpcLb::Helper::RequestReresolution() { if (parent_->shutting_down_) return; + // If there is a pending child policy, ignore re-resolution requests + // from the current child policy (or any outdated pending child). + if (parent_->pending_child_policy_ != nullptr && !CalledByPendingChild()) { + return; + } if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Re-resolution requested from the internal RR policy " - "(%p).", - parent_.get(), parent_->rr_policy_.get()); + "[grpclb %p] Re-resolution requested from child policy (%p).", + parent_.get(), child_); } // If we are talking to a balancer, we expect to get updated addresses // from the balancer, so we can ignore the re-resolution request from - // the RR policy. Otherwise, pass the re-resolution request up to the + // the child policy. Otherwise, pass the re-resolution request up to the // channel. if (parent_->lb_calld_ == nullptr || !parent_->lb_calld_->seen_initial_response()) { @@ -984,7 +1036,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( // instance will be destroyed either upon the next update or when the // GrpcLb instance is destroyed. grpclb_policy->serverlist_ = std::move(serverlist_wrapper); - grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); + grpclb_policy->CreateOrUpdateChildPolicyLocked(); } } else { // No valid initial response or serverlist found. @@ -1200,7 +1252,8 @@ void GrpcLb::ShutdownLocked() { if (fallback_timer_callback_pending_) { grpc_timer_cancel(&lb_fallback_timer_); } - rr_policy_.reset(); + child_policy_.reset(); + pending_child_policy_.reset(); // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -1220,17 +1273,24 @@ void GrpcLb::ResetBackoffLocked() { if (lb_channel_ != nullptr) { grpc_channel_reset_connect_backoff(lb_channel_); } - if (rr_policy_ != nullptr) { - rr_policy_->ResetBackoffLocked(); + if (child_policy_ != nullptr) { + child_policy_->ResetBackoffLocked(); + } + if (pending_child_policy_ != nullptr) { + pending_child_policy_->ResetBackoffLocked(); } } void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { - // delegate to the RoundRobin to fill the children subchannels. - if (rr_policy_ != nullptr) { - rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + // delegate to the child policy to fill the children subchannels. + if (child_policy_ != nullptr) { + child_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + } + if (pending_child_policy_ != nullptr) { + pending_child_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); } gpr_atm uuid = gpr_atm_no_barrier_load(&lb_channel_uuid_); if (uuid != 0) { @@ -1238,6 +1298,32 @@ void GrpcLb::FillChildRefsForChannelz( } } +void GrpcLb::UpdateLocked(const grpc_channel_args& args, + RefCountedPtr lb_config) { + const bool is_initial_update = lb_channel_ == nullptr; + ParseLbConfig(lb_config.get()); + ProcessChannelArgsLocked(args); + // Update the existing child policy. + if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); + // If this is the initial update, start the fallback timer. + if (is_initial_update) { + if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && + !fallback_timer_callback_pending_) { + grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; + Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Ref for callback + GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, + grpc_combiner_scheduler(combiner())); + fallback_timer_callback_pending_ = true; + grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); + } + StartBalancerCallLocked(); + } +} + +// +// helpers for UpdateLocked() +// + // Returns the backend addresses extracted from the given addresses. UniquePtr ExtractBackendAddresses( const ServerAddressList& addresses) { @@ -1299,25 +1385,26 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { grpc_channel_args_destroy(lb_channel_args); } -void GrpcLb::UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) { - const bool is_initial_update = lb_channel_ == nullptr; - ProcessChannelArgsLocked(args); - // Update the existing RR policy. - if (rr_policy_ != nullptr) CreateOrUpdateRoundRobinPolicyLocked(); - // If this is the initial update, start the fallback timer and the - // balancer call. - if (is_initial_update) { - if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && - !fallback_timer_callback_pending_) { - grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; - Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Ref for callback - GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, - grpc_combiner_scheduler(combiner())); - fallback_timer_callback_pending_ = true; - grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); +void GrpcLb::ParseLbConfig(Config* grpclb_config) { + const grpc_json* child_policy = nullptr; + if (grpclb_config != nullptr) { + const grpc_json* grpclb_config_json = grpclb_config->json(); + for (const grpc_json* field = grpclb_config_json; field != nullptr; + field = field->next) { + if (field->key == nullptr) return; + if (strcmp(field->key, "childPolicy") == 0) { + if (child_policy != nullptr) return; // Duplicate. + child_policy = ParseLoadBalancingConfig(field); + } } - StartBalancerCallLocked(); + } + if (child_policy != nullptr) { + child_policy_name_ = UniquePtr(gpr_strdup(child_policy->key)); + child_policy_config_ = MakeRefCounted( + child_policy->child, grpclb_config->service_config()); + } else { + child_policy_name_.reset(); + child_policy_config_.reset(); } } @@ -1352,7 +1439,7 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { grpclb_policy); } GPR_ASSERT(grpclb_policy->fallback_backend_addresses_ != nullptr); - grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked(); + grpclb_policy->CreateOrUpdateChildPolicyLocked(); } grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); } @@ -1396,10 +1483,10 @@ void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) { } // -// code for interacting with the RR policy +// code for interacting with the child policy // -grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { +grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked() { ServerAddressList tmp_addresses; ServerAddressList* addresses = &tmp_addresses; bool is_backend_from_grpclb_load_balancer = false; @@ -1408,7 +1495,7 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats()); is_backend_from_grpclb_load_balancer = true; } else { - // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't + // If CreateOrUpdateChildPolicyLocked() is invoked when we haven't // received any serverlist from the balancer, we use the fallback backends // returned by the resolver. Note that the fallback backend list may be // empty, in which case the new round_robin policy will keep the requested @@ -1435,49 +1522,134 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); ++num_args_to_add; } - grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( + return grpc_channel_args_copy_and_add_and_remove( args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, num_args_to_add); - return args; } -void GrpcLb::CreateRoundRobinPolicyLocked(Args args) { - GPR_ASSERT(rr_policy_ == nullptr); - rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - "round_robin", std::move(args)); - if (GPR_UNLIKELY(rr_policy_ == nullptr)) { - gpr_log(GPR_ERROR, "[grpclb %p] Failure creating a RoundRobin policy", - this); - return; +OrphanablePtr GrpcLb::CreateChildPolicyLocked( + const char* name, grpc_channel_args* args) { + Helper* helper = New(Ref()); + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = combiner(); + lb_policy_args.args = args; + lb_policy_args.channel_control_helper = + UniquePtr(helper); + OrphanablePtr lb_policy = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + name, std::move(lb_policy_args)); + if (GPR_UNLIKELY(lb_policy == nullptr)) { + gpr_log(GPR_ERROR, "[grpclb %p] Failure creating child policy %s", this, + name); + return nullptr; } + helper->set_child(lb_policy.get()); if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Created new RR policy %p", this, - rr_policy_.get()); + gpr_log(GPR_INFO, "[grpclb %p] Created new child policy %s (%p)", this, + name, lb_policy.get()); } // Add the gRPC LB's interested_parties pollset_set to that of the newly - // created RR policy. This will make the RR policy progress upon activity on - // gRPC LB, which in turn is tied to the application's call. - grpc_pollset_set_add_pollset_set(rr_policy_->interested_parties(), + // created child policy. This will make the child policy progress upon + // activity on gRPC LB, which in turn is tied to the application's call. + grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(), interested_parties()); + return lb_policy; } -void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() { +void GrpcLb::CreateOrUpdateChildPolicyLocked() { if (shutting_down_) return; - grpc_channel_args* args = CreateRoundRobinPolicyArgsLocked(); + grpc_channel_args* args = CreateChildPolicyArgsLocked(); GPR_ASSERT(args != nullptr); - if (rr_policy_ == nullptr) { - LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = combiner(); - lb_policy_args.args = args; - lb_policy_args.channel_control_helper = - UniquePtr(New(Ref())); - CreateRoundRobinPolicyLocked(std::move(lb_policy_args)); + // If the child policy name changes, we need to create a new child + // policy. When this happens, we leave child_policy_ as-is and store + // the new child policy in pending_child_policy_. Once the new child + // policy transitions into state READY, we swap it into child_policy_, + // replacing the original child policy. So pending_child_policy_ is + // non-null only between when we apply an update that changes the child + // policy name and when the new child reports state READY. + // + // Updates can arrive at any point during this transition. We always + // apply updates relative to the most recently created child policy, + // even if the most recent one is still in pending_child_policy_. This + // is true both when applying the updates to an existing child policy + // and when determining whether we need to create a new policy. + // + // As a result of this, there are several cases to consider here: + // + // 1. We have no existing child policy (i.e., we have started up but + // have not yet received a serverlist from the balancer or gone + // into fallback mode; in this case, both child_policy_ and + // pending_child_policy_ are null). In this case, we create a + // new child policy and store it in child_policy_. + // + // 2. We have an existing child policy and have no pending child policy + // from a previous update (i.e., either there has not been a + // previous update that changed the policy name, or we have already + // finished swapping in the new policy; in this case, child_policy_ + // is non-null but pending_child_policy_ is null). In this case: + // a. If child_policy_->name() equals child_policy_name, then we + // update the existing child policy. + // b. If child_policy_->name() does not equal child_policy_name, + // we create a new policy. The policy will be stored in + // pending_child_policy_ and will later be swapped into + // child_policy_ by the helper when the new child transitions + // into state READY. + // + // 3. We have an existing child policy and have a pending child policy + // from a previous update (i.e., a previous update set + // pending_child_policy_ as per case 2b above and that policy has + // not yet transitioned into state READY and been swapped into + // child_policy_; in this case, both child_policy_ and + // pending_child_policy_ are non-null). In this case: + // a. If pending_child_policy_->name() equals child_policy_name, + // then we update the existing pending child policy. + // b. If pending_child_policy->name() does not equal + // child_policy_name, then we create a new policy. The new + // policy is stored in pending_child_policy_ (replacing the one + // that was there before, which will be immediately shut down) + // and will later be swapped into child_policy_ by the helper + // when the new child transitions into state READY. + const char* child_policy_name = + child_policy_name_ == nullptr ? "round_robin" : child_policy_name_.get(); + const bool create_policy = + // case 1 + child_policy_ == nullptr || + // case 2b + (pending_child_policy_ == nullptr && + strcmp(child_policy_->name(), child_policy_name) != 0) || + // case 3b + (pending_child_policy_ != nullptr && + strcmp(pending_child_policy_->name(), child_policy_name) != 0); + LoadBalancingPolicy* policy_to_update = nullptr; + if (create_policy) { + // Cases 1, 2b, and 3b: create a new child policy. + // If child_policy_ is null, we set it (case 1), else we set + // pending_child_policy_ (cases 2b and 3b). + auto& lb_policy = + child_policy_ == nullptr ? child_policy_ : pending_child_policy_; + if (grpc_lb_glb_trace.enabled()) { + gpr_log(GPR_INFO, "[grpclb %p] Creating new %schild policy %s", this, + child_policy_ == nullptr ? "" : "pending ", child_policy_name); + } + lb_policy = CreateChildPolicyLocked(child_policy_name, args); + policy_to_update = lb_policy.get(); + } else { + // Cases 2a and 3a: update an existing policy. + // If we have a pending child policy, send the update to the pending + // policy (case 3a), else send it to the current policy (case 2a). + policy_to_update = pending_child_policy_ != nullptr + ? pending_child_policy_.get() + : child_policy_.get(); } + GPR_ASSERT(policy_to_update != nullptr); + // Update the policy. if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, "[grpclb %p] Updating RR policy %p", this, - rr_policy_.get()); + gpr_log(GPR_INFO, "[grpclb %p] Updating %schild policy %p", this, + policy_to_update == pending_child_policy_.get() ? "pending " : "", + policy_to_update); } - rr_policy_->UpdateLocked(*args, nullptr); + policy_to_update->UpdateLocked(*args, child_policy_config_); + // Clean up. grpc_channel_args_destroy(args); } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 2288b88b517..31353ba1304 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -723,6 +723,150 @@ TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfig) { EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } +TEST_F(SingleBalancerTest, UsePickFirstChildPolicy) { + SetNextResolutionAllBalancers( + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"pick_first\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + const size_t kNumRpcs = num_backends_ * 2; + CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); + balancers_[0]->NotifyDoneWithServerlists(); + // Check that all requests went to the first backend. This verifies + // that we used pick_first instead of round_robin as the child policy. + EXPECT_EQ(backend_servers_[0].service_->request_count(), kNumRpcs); + for (size_t i = 1; i < backends_.size(); ++i) { + EXPECT_EQ(backend_servers_[i].service_->request_count(), 0UL); + } + // The balancer got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, SwapChildPolicy) { + SetNextResolutionAllBalancers( + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"pick_first\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), + 0); + const size_t kNumRpcs = num_backends_ * 2; + CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); + // Check that all requests went to the first backend. This verifies + // that we used pick_first instead of round_robin as the child policy. + EXPECT_EQ(backend_servers_[0].service_->request_count(), kNumRpcs); + for (size_t i = 1; i < backends_.size(); ++i) { + EXPECT_EQ(backend_servers_[i].service_->request_count(), 0UL); + } + // Send new resolution that removes child policy from service config. + SetNextResolutionAllBalancers("{}"); + WaitForAllBackends(); + CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); + // Check that every backend saw the same number of requests. This verifies + // that we used round_robin. + for (size_t i = 0; i < backends_.size(); ++i) { + EXPECT_EQ(backend_servers_[i].service_->request_count(), 2UL); + } + // Done. + balancers_[0]->NotifyDoneWithServerlists(); + // The balancer got a single request. + EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, UpdatesGoToMostRecentChildPolicy) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + int unreachable_balancer_port = grpc_pick_unused_port_or_die(); + int unreachable_backend_port = grpc_pick_unused_port_or_die(); + // Phase 1: Start with RR pointing to first backend. + gpr_log(GPR_INFO, "PHASE 1: Initial setup with RR with first backend"); + SetNextResolution( + { + // Unreachable balancer. + {unreachable_balancer_port, true, ""}, + // Fallback address: first backend. + {backend_servers_[0].port_, false, ""}, + }, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"round_robin\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + // RPCs should go to first backend. + WaitForBackend(0); + // Phase 2: Switch to PF pointing to unreachable backend. + gpr_log(GPR_INFO, "PHASE 2: Update to use PF with unreachable backend"); + SetNextResolution( + { + // Unreachable balancer. + {unreachable_balancer_port, true, ""}, + // Fallback address: unreachable backend. + {unreachable_backend_port, false, ""}, + }, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"pick_first\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + // RPCs should continue to go to the first backend, because the new + // PF child policy will never go into state READY. + WaitForBackend(0); + // Phase 3: Switch back to RR pointing to second and third backends. + // This ensures that we create a new policy rather than updating the + // pending PF policy. + gpr_log(GPR_INFO, "PHASE 3: Update to use RR again with two backends"); + SetNextResolution( + { + // Unreachable balancer. + {unreachable_balancer_port, true, ""}, + // Fallback address: second and third backends. + {backend_servers_[1].port_, false, ""}, + {backend_servers_[2].port_, false, ""}, + }, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{\n" + " \"childPolicy\":[\n" + " { \"round_robin\":{} }\n" + " ]\n" + " } }\n" + " ]\n" + "}"); + // RPCs should go to the second and third backends. + WaitForBackend(1); + WaitForBackend(2); +} + TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { SetNextResolutionAllBalancers(); // Same backend listed twice. From 8369b0552986dcdbaccda924357a1e92295a230b Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 5 Mar 2019 14:31:55 -0800 Subject: [PATCH 585/814] Fix a memory leak --- src/core/lib/compression/stream_compression_gzip.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/compression/stream_compression_gzip.cc b/src/core/lib/compression/stream_compression_gzip.cc index 682f712843a..bffdb1fd17d 100644 --- a/src/core/lib/compression/stream_compression_gzip.cc +++ b/src/core/lib/compression/stream_compression_gzip.cc @@ -60,7 +60,7 @@ static bool gzip_flate(grpc_stream_compression_context_gzip* ctx, if (r < 0 && r != Z_BUF_ERROR) { gpr_log(GPR_ERROR, "zlib error (%d)", r); grpc_slice_unref_internal(slice_out); - + grpc_slice_unref_internal(slice); return false; } else if (r == Z_STREAM_END && ctx->flate == inflate) { eoc = true; From 94c38ee0a13d0e2fc0931c56db7dfcede6200da1 Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 5 Mar 2019 14:34:24 -0800 Subject: [PATCH 586/814] Add fuzzer test case --- ...imized-grpc_client_fuzzer-5765697914404864 | Bin 0 -> 1066 bytes tools/run_tests/generated/tests.json | 23 ++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 test/core/end2end/fuzzers/client_fuzzer_corpus/clusterfuzz-testcase-minimized-grpc_client_fuzzer-5765697914404864 diff --git a/test/core/end2end/fuzzers/client_fuzzer_corpus/clusterfuzz-testcase-minimized-grpc_client_fuzzer-5765697914404864 b/test/core/end2end/fuzzers/client_fuzzer_corpus/clusterfuzz-testcase-minimized-grpc_client_fuzzer-5765697914404864 new file mode 100644 index 0000000000000000000000000000000000000000..e8a60f5a9b532e916ab42651c02a16dcf0c56aed GIT binary patch literal 1066 zcmZQzU|?YY0~QWOIUs|P!H|`KDWjyMfDtS#*bkx@C;ItmPK@=N=r?g9kg0C(r#?~B zPiy7Gi3|Pw{FoRR9C*@;7`Pc2_c82)0Y-)}>m@aAKKo>WpiWkn>(nf3*@7}NSy`xx zc|h99(a{m60UOOAl3rAhtecpeoLW$#o0^xLp8|H)fDm+aEHBvGVE<<3rL&}0Wfl Date: Tue, 5 Mar 2019 14:46:16 -0800 Subject: [PATCH 587/814] Add lock for channelz access outside of the combiner. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index c1f2846f046..e21b1789172 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -352,6 +352,9 @@ class GrpcLb : public LoadBalancingPolicy { grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; + // Lock held when modifying the value of child_policy_ or + // pending_child_policy_. + gpr_mu child_policy_mu_; // The child policy to use for the backends. OrphanablePtr child_policy_; // When switching child policies, the new policy will be stored here @@ -618,6 +621,7 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, GRPC_ERROR_UNREF(state_error); return; } + MutexLock lock(&parent_->child_policy_mu_); parent_->child_policy_ = std::move(parent_->pending_child_policy_); } else if (!CalledByCurrentChild()) { // This request is from an outdated child, so ignore it. @@ -1216,6 +1220,7 @@ GrpcLb::GrpcLb(Args args) .set_jitter(GRPC_GRPCLB_RECONNECT_JITTER) .set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { + gpr_mu_init(&child_policy_mu_); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -1241,6 +1246,7 @@ GrpcLb::GrpcLb(Args args) GrpcLb::~GrpcLb() { gpr_free((void*)server_name_); grpc_channel_args_destroy(args_); + gpr_mu_destroy(&child_policy_mu_); } void GrpcLb::ShutdownLocked() { @@ -1252,8 +1258,11 @@ void GrpcLb::ShutdownLocked() { if (fallback_timer_callback_pending_) { grpc_timer_cancel(&lb_fallback_timer_); } - child_policy_.reset(); - pending_child_policy_.reset(); + { + MutexLock lock(&child_policy_mu_); + child_policy_.reset(); + pending_child_policy_.reset(); + } // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -1284,13 +1293,19 @@ void GrpcLb::ResetBackoffLocked() { void GrpcLb::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { - // delegate to the child policy to fill the children subchannels. - if (child_policy_ != nullptr) { - child_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); - } - if (pending_child_policy_ != nullptr) { - pending_child_policy_->FillChildRefsForChannelz(child_subchannels, - child_channels); + { + // Delegate to the child policy to fill the children subchannels. + // This must be done holding child_policy_mu_, since this method + // does not run in the combiner. + MutexLock lock(&child_policy_mu_); + if (child_policy_ != nullptr) { + child_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } + if (pending_child_policy_ != nullptr) { + pending_child_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } } gpr_atm uuid = gpr_atm_no_barrier_load(&lb_channel_uuid_); if (uuid != 0) { @@ -1625,13 +1640,18 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() { // Cases 1, 2b, and 3b: create a new child policy. // If child_policy_ is null, we set it (case 1), else we set // pending_child_policy_ (cases 2b and 3b). - auto& lb_policy = - child_policy_ == nullptr ? child_policy_ : pending_child_policy_; if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, "[grpclb %p] Creating new %schild policy %s", this, child_policy_ == nullptr ? "" : "pending ", child_policy_name); } - lb_policy = CreateChildPolicyLocked(child_policy_name, args); + auto new_policy = CreateChildPolicyLocked(child_policy_name, args); + // Swap the policy into place. + auto& lb_policy = + child_policy_ == nullptr ? child_policy_ : pending_child_policy_; + { + MutexLock lock(&child_policy_mu_); + lb_policy = std::move(new_policy); + } policy_to_update = lb_policy.get(); } else { // Cases 2a and 3a: update an existing policy. From 0c8418c4bfb831cb1f7781fc36410d3908429ac9 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 5 Mar 2019 15:08:23 -0800 Subject: [PATCH 588/814] WIP. Start BUILD file --- examples/python/multiprocessing/BUILD | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index e69de29bb2d..e47fb654aac 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -0,0 +1,28 @@ +load("@grpc_python_dependencies//:requirements.bzl", "requirement") + +py_binary( + name = "client", + testonly = 1, + srcs = ["client.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio" + ], +) + +py_binary( + name = "server", + testonly = 1, + srcs = ["server.py"], + deps = [ + "//src/python/grpcio/grpc:grpcio" + ], +) + +py_test( + name = "_multiprocessing_example_test", + srcs = ["test/_multiprocessing_example_test.py"], + data = [ + ":client", + ":server" + ] +) From 57759a3525b9c708933ec86da2d907342cc09077 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Tue, 5 Mar 2019 15:25:37 -0800 Subject: [PATCH 589/814] Added automated test for network transitions on iOS devices --- .../GrpcIosTest.xcodeproj/project.pbxproj | 135 +++++++++++++- .../GrpcIosTestUITests/GrpcIosTestUITests.m | 174 ++++++++++++++++++ .../GrpcIosTestUITests/Info.plist | 22 +++ src/objective-c/manual_tests/Main.storyboard | 1 + src/objective-c/manual_tests/Podfile | 4 +- src/objective-c/manual_tests/ViewController.m | 22 ++- src/objective-c/manual_tests/main.m | 2 + 7 files changed, 352 insertions(+), 8 deletions(-) create mode 100644 src/objective-c/manual_tests/GrpcIosTestUITests/GrpcIosTestUITests.m create mode 100644 src/objective-c/manual_tests/GrpcIosTestUITests/Info.plist diff --git a/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj b/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj index 9063719aa2e..3ad16c3af6e 100644 --- a/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj +++ b/src/objective-c/manual_tests/GrpcIosTest.xcodeproj/project.pbxproj @@ -12,8 +12,19 @@ 5EDA909C220DF1B00046D27A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EDA9096220DF1B00046D27A /* main.m */; }; 5EDA909E220DF1B00046D27A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5EDA9098220DF1B00046D27A /* Main.storyboard */; }; 5EDA909F220DF1B00046D27A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EDA9099220DF1B00046D27A /* AppDelegate.m */; }; + B0C18CA7222DEF140002B502 /* GrpcIosTestUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C18CA6222DEF140002B502 /* GrpcIosTestUITests.m */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + B0C18CA9222DEF140002B502 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5EDA9073220DF0BC0046D27A /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5EDA907A220DF0BC0046D27A; + remoteInfo = GrpcIosTest; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ 1D22EC48A487B02F76135EA3 /* libPods-GrpcIosTest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-GrpcIosTest.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 5EDA907B220DF0BC0046D27A /* GrpcIosTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GrpcIosTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -24,6 +35,9 @@ 5EDA9099220DF1B00046D27A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; }; 7C9FAFB11727DCA50888C1B8 /* Pods-GrpcIosTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GrpcIosTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GrpcIosTest/Pods-GrpcIosTest.debug.xcconfig"; sourceTree = ""; }; A4E7CA72304A7B43FE8A5BC7 /* Pods-GrpcIosTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GrpcIosTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-GrpcIosTest/Pods-GrpcIosTest.release.xcconfig"; sourceTree = ""; }; + B0C18CA4222DEF140002B502 /* GrpcIosTestUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GrpcIosTestUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + B0C18CA6222DEF140002B502 /* GrpcIosTestUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GrpcIosTestUITests.m; sourceTree = ""; }; + B0C18CA8222DEF140002B502 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -35,6 +49,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + B0C18CA1222DEF140002B502 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -55,6 +76,7 @@ 5EDA9096220DF1B00046D27A /* main.m */, 5EDA9098220DF1B00046D27A /* Main.storyboard */, 5EDA9094220DF1B00046D27A /* ViewController.m */, + B0C18CA5222DEF140002B502 /* GrpcIosTestUITests */, 5EDA907C220DF0BC0046D27A /* Products */, 2B8131AC634883AFEC02557C /* Pods */, E73D92116C1C328622A8C77F /* Frameworks */, @@ -65,10 +87,20 @@ isa = PBXGroup; children = ( 5EDA907B220DF0BC0046D27A /* GrpcIosTest.app */, + B0C18CA4222DEF140002B502 /* GrpcIosTestUITests.xctest */, ); name = Products; sourceTree = ""; }; + B0C18CA5222DEF140002B502 /* GrpcIosTestUITests */ = { + isa = PBXGroup; + children = ( + B0C18CA6222DEF140002B502 /* GrpcIosTestUITests.m */, + B0C18CA8222DEF140002B502 /* Info.plist */, + ); + path = GrpcIosTestUITests; + sourceTree = ""; + }; E73D92116C1C328622A8C77F /* Frameworks */ = { isa = PBXGroup; children = ( @@ -99,6 +131,24 @@ productReference = 5EDA907B220DF0BC0046D27A /* GrpcIosTest.app */; productType = "com.apple.product-type.application"; }; + B0C18CA3222DEF140002B502 /* GrpcIosTestUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = B0C18CAD222DEF140002B502 /* Build configuration list for PBXNativeTarget "GrpcIosTestUITests" */; + buildPhases = ( + B0C18CA0222DEF140002B502 /* Sources */, + B0C18CA1222DEF140002B502 /* Frameworks */, + B0C18CA2222DEF140002B502 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + B0C18CAA222DEF140002B502 /* PBXTargetDependency */, + ); + name = GrpcIosTestUITests; + productName = GrpcIosTestUITests; + productReference = B0C18CA4222DEF140002B502 /* GrpcIosTestUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -111,6 +161,10 @@ 5EDA907A220DF0BC0046D27A = { CreatedOnToolsVersion = 10.0; }; + B0C18CA3222DEF140002B502 = { + CreatedOnToolsVersion = 10.0; + TestTargetID = 5EDA907A220DF0BC0046D27A; + }; }; }; buildConfigurationList = 5EDA9076220DF0BC0046D27A /* Build configuration list for PBXProject "GrpcIosTest" */; @@ -127,6 +181,7 @@ projectRoot = ""; targets = ( 5EDA907A220DF0BC0046D27A /* GrpcIosTest */, + B0C18CA3222DEF140002B502 /* GrpcIosTestUITests */, ); }; /* End PBXProject section */ @@ -140,6 +195,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + B0C18CA2222DEF140002B502 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -200,8 +262,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + B0C18CA0222DEF140002B502 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B0C18CA7222DEF140002B502 /* GrpcIosTestUITests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + B0C18CAA222DEF140002B502 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5EDA907A220DF0BC0046D27A /* GrpcIosTest */; + targetProxy = B0C18CA9222DEF140002B502 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ 5EDA908F220DF0BD0046D27A /* Debug */ = { isa = XCBuildConfiguration; @@ -321,7 +399,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Manual; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = EQHXZ8M8AV; INFOPLIST_FILE = Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -330,7 +408,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = io.grpc.GrpcIosTest; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; + PROVISIONING_PROFILE_SPECIFIER = "Google Development"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -341,7 +419,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Manual; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = EQHXZ8M8AV; INFOPLIST_FILE = Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -350,11 +428,51 @@ ); PRODUCT_BUNDLE_IDENTIFIER = io.grpc.GrpcIosTest; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; + PROVISIONING_PROFILE_SPECIFIER = "Google Development"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; + B0C18CAB222DEF140002B502 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = EQHXZ8M8AV; + INFOPLIST_FILE = GrpcIosTestUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.GrpcIosTestUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = "Google Development"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = GrpcIosTest; + }; + name = Debug; + }; + B0C18CAC222DEF140002B502 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = EQHXZ8M8AV; + INFOPLIST_FILE = GrpcIosTestUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.GrpcIosTestUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = "Google Development"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = GrpcIosTest; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -376,6 +494,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + B0C18CAD222DEF140002B502 /* Build configuration list for PBXNativeTarget "GrpcIosTestUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B0C18CAB222DEF140002B502 /* Debug */, + B0C18CAC222DEF140002B502 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 5EDA9073220DF0BC0046D27A /* Project object */; diff --git a/src/objective-c/manual_tests/GrpcIosTestUITests/GrpcIosTestUITests.m b/src/objective-c/manual_tests/GrpcIosTestUITests/GrpcIosTestUITests.m new file mode 100644 index 00000000000..b0a929e689d --- /dev/null +++ b/src/objective-c/manual_tests/GrpcIosTestUITests/GrpcIosTestUITests.m @@ -0,0 +1,174 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +NSTimeInterval const kWaitTime = 30; + +@interface GrpcIosTestUITests : XCTestCase +@end + +@implementation GrpcIosTestUITests { + XCUIApplication *testApp; + XCUIApplication *settingsApp; +} + +- (void)setUp { + self.continueAfterFailure = NO; + [[[XCUIApplication alloc] init] launch]; + testApp = [[XCUIApplication alloc] initWithBundleIdentifier:@"io.grpc.GrpcIosTest"]; + settingsApp = [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.Preferences"]; + [settingsApp activate]; + // Go back to the first page of Settings. + XCUIElement *backButton = settingsApp.navigationBars.buttons.firstMatch; + while (backButton.exists) { + [backButton tap]; + } + XCTAssert([settingsApp.navigationBars[@"Settings"] waitForExistenceWithTimeout:kWaitTime]); + // Turn off airplane mode + [self setAirplaneMode:NO]; +} + +- (void)tearDown { +} + +- (void)doUnaryCall { + [testApp activate]; + [testApp.buttons[@"Unary call"] tap]; +} + +- (void)doStreamingCall { + [testApp activate]; + [testApp.buttons[@"Start streaming call"] tap]; + [testApp.buttons[@"Send Message"] tap]; + [testApp.buttons[@"Stop streaming call"] tap]; +} + +- (void)expectCallSuccess { + XCTAssert([testApp.staticTexts[@"Call done"] waitForExistenceWithTimeout:kWaitTime]); +} + +- (void)expectCallFailed { + XCTAssert([testApp.staticTexts[@"Call failed"] waitForExistenceWithTimeout:kWaitTime]); +} + +- (void)setAirplaneMode:(BOOL)to { + [settingsApp activate]; + XCUIElement *mySwitch = settingsApp.tables.element.cells.switches[@"Airplane Mode"]; + BOOL from = [(NSString *)mySwitch.value boolValue]; + if (from != to) { + [mySwitch tap]; + // wait for gRPC to detect the change + sleep(10); + } + XCTAssert([(NSString *)mySwitch.value boolValue] == to); +} + +- (void)testBackgroundBeforeUnaryCall { + // Open test app + [testApp activate]; + + // Send test app to background + [XCUIDevice.sharedDevice pressButton:XCUIDeviceButtonHome]; + sleep(5); + + // Bring test app to foreground and make a unary call. Call should succeed + [self doUnaryCall]; + [self expectCallSuccess]; +} + +- (void)testBackgroundBeforeStreamingCall { + // Open test app + [testApp activate]; + + // Send test app to background + [XCUIDevice.sharedDevice pressButton:XCUIDeviceButtonHome]; + sleep(5); + + // Bring test app to foreground and make a streaming call. Call should succeed. + [self doStreamingCall]; + [self expectCallSuccess]; +} + +- (void)testUnaryCallAfterNetworkFlap { + // Open test app and make a unary call. Channel to server should be open after this. + [self doUnaryCall]; + [self expectCallSuccess]; + + // Toggle airplane mode on and off + [self setAirplaneMode:YES]; + [self setAirplaneMode:NO]; + + // Bring test app to foreground and make a unary call. The call should succeed + [self doUnaryCall]; + [self expectCallSuccess]; +} + +- (void)testStreamingCallAfterNetworkFlap { + // Open test app and make a unary call. Channel to server should be open after this. + [self doUnaryCall]; + [self expectCallSuccess]; + + // Toggle airplane mode on and off + [self setAirplaneMode:YES]; + [self setAirplaneMode:NO]; + + [self doStreamingCall]; + [self expectCallSuccess]; +} + +- (void)testUnaryCallWhileNetworkDown { + // Open test app and make a unary call. Channel to server should be open after this. + [self doUnaryCall]; + [self expectCallSuccess]; + + // Turn on airplane mode + [self setAirplaneMode:YES]; + + // Unary call should fail + [self doUnaryCall]; + [self expectCallFailed]; + + // Turn off airplane mode + [self setAirplaneMode:NO]; + + // Unary call should succeed + [self doUnaryCall]; + [self expectCallSuccess]; +} + +- (void)testStreamingCallWhileNetworkDown { + // Open test app and make a unary call. Channel to server should be open after this. + [self doUnaryCall]; + [self expectCallSuccess]; + + // Turn on airplane mode + [self setAirplaneMode:YES]; + + // Streaming call should fail + [self doStreamingCall]; + [self expectCallFailed]; + + // Turn off airplane mode + [self setAirplaneMode:NO]; + + // Unary call should succeed + [self doStreamingCall]; + [self expectCallSuccess]; +} +@end diff --git a/src/objective-c/manual_tests/GrpcIosTestUITests/Info.plist b/src/objective-c/manual_tests/GrpcIosTestUITests/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/manual_tests/GrpcIosTestUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/manual_tests/Main.storyboard b/src/objective-c/manual_tests/Main.storyboard index e88f30e324b..e7e0530efcd 100644 --- a/src/objective-c/manual_tests/Main.storyboard +++ b/src/objective-c/manual_tests/Main.storyboard @@ -4,6 +4,7 @@ + diff --git a/src/objective-c/manual_tests/Podfile b/src/objective-c/manual_tests/Podfile index 7cb650a3412..919e649be71 100644 --- a/src/objective-c/manual_tests/Podfile +++ b/src/objective-c/manual_tests/Podfile @@ -18,8 +18,8 @@ GrpcIosTest pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true - pod 'gRPC', :path => GRPC_LOCAL_SRC - pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'gRPC/CFStream', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/CFStream-Implementation', :path => GRPC_LOCAL_SRC pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC, :inhibit_warnings => true pod 'RemoteTest', :path => "../tests/RemoteTestClient", :inhibit_warnings => true diff --git a/src/objective-c/manual_tests/ViewController.m b/src/objective-c/manual_tests/ViewController.m index 00bb516bdfc..813b176f3e8 100644 --- a/src/objective-c/manual_tests/ViewController.m +++ b/src/objective-c/manual_tests/ViewController.m @@ -27,7 +27,7 @@ NSString *const kRemoteHost = @"grpc-test.sandbox.googleapis.com"; const int32_t kMessageSize = 100; @interface ViewController : UIViewController - +@property(strong, nonatomic) UILabel *fromLabel; @end @implementation ViewController { @@ -35,16 +35,25 @@ const int32_t kMessageSize = 100; dispatch_queue_t _dispatchQueue; GRPCStreamingProtoCall *_call; } +- (instancetype)init { + self = [super init]; + return self; +} - (void)viewDidLoad { [super viewDidLoad]; _dispatchQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); + _fromLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 500, 200, 20)]; + _fromLabel.textColor = [UIColor blueColor]; + _fromLabel.backgroundColor = [UIColor whiteColor]; + [self.view addSubview:_fromLabel]; } - (IBAction)tapUnaryCall:(id)sender { if (_service == nil) { _service = [RMTTestService serviceWithHost:kRemoteHost]; } + self->_fromLabel.text = @""; // Set up request proto message RMTSimpleRequest *request = [RMTSimpleRequest message]; @@ -61,6 +70,7 @@ const int32_t kMessageSize = 100; if (_service == nil) { _service = [RMTTestService serviceWithHost:kRemoteHost]; } + self->_fromLabel.text = @""; // Set up request proto message RMTStreamingOutputCallRequest *request = RMTStreamingOutputCallRequest.message; @@ -92,7 +102,6 @@ const int32_t kMessageSize = 100; if (_call == nil) return; [_call finish]; - _call = nil; } @@ -107,6 +116,15 @@ const int32_t kMessageSize = 100; - (void)didCloseWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(nullable NSError *)error { NSLog(@"Recv trailing metadata: %@, error: %@", trailingMetadata, error); + if (error == nil) { + dispatch_async(dispatch_get_main_queue(), ^{ + self->_fromLabel.text = @"Call done"; + }); + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + self->_fromLabel.text = @"Call failed"; + }); + } } - (dispatch_queue_t)dispatchQueue { diff --git a/src/objective-c/manual_tests/main.m b/src/objective-c/manual_tests/main.m index 2797c6f17f2..451b50cc0e2 100644 --- a/src/objective-c/manual_tests/main.m +++ b/src/objective-c/manual_tests/main.m @@ -21,6 +21,8 @@ int main(int argc, char* argv[]) { @autoreleasepool { + // enable CFStream API + setenv("grpc_cfstream", "1", 1); return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } From 07bfbec8f9c55961bc797f6ad25f04a612ca1bb5 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 5 Mar 2019 16:09:31 -0800 Subject: [PATCH 590/814] Fix hanging build --- src/python/grpcio/commands.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index 27b98362c11..d6353fc5a07 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -217,11 +217,15 @@ class BuildExt(build_ext.build_ext): """Test if default compiler is okay with specifying c++ version when invoked in C mode. GCC is okay with this, while clang is not. """ + print("Checking if compiler okay") cc_test = subprocess.Popen( ['cc', '-x', 'c', '-std=c++11', '-'], + stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - _, cc_err = cc_test.communicate(input='int main(){return 0;}') + print("Attempting to communicate") + _, cc_err = cc_test.communicate(input=b'int main(){return 0;}') + print("Completed with compiler") return not 'invalid argument' in str(cc_err) # This special conditioning is here due to difference of compiler From efa1f8b993eaf6061e8b54a8f3dcd7089b709f48 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 5 Mar 2019 16:11:05 -0800 Subject: [PATCH 591/814] Remove debug prints --- src/python/grpcio/commands.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index d6353fc5a07..d189c2869d0 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -217,15 +217,12 @@ class BuildExt(build_ext.build_ext): """Test if default compiler is okay with specifying c++ version when invoked in C mode. GCC is okay with this, while clang is not. """ - print("Checking if compiler okay") cc_test = subprocess.Popen( ['cc', '-x', 'c', '-std=c++11', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - print("Attempting to communicate") _, cc_err = cc_test.communicate(input=b'int main(){return 0;}') - print("Completed with compiler") return not 'invalid argument' in str(cc_err) # This special conditioning is here due to difference of compiler From 04609b1ea5aa743182f0d910d86d054a113f60e6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 6 Mar 2019 11:00:13 +0100 Subject: [PATCH 592/814] Revert "Strip Python wheel binary" --- test/distrib/python/test_packages.sh | 2 +- .../artifacts/build_package_python.sh | 18 ------------------ 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/test/distrib/python/test_packages.sh b/test/distrib/python/test_packages.sh index 433148e6bd7..755daa10211 100755 --- a/test/distrib/python/test_packages.sh +++ b/test/distrib/python/test_packages.sh @@ -41,7 +41,7 @@ PYTHON=$VIRTUAL_ENV/bin/python function at_least_one_installs() { for file in "$@"; do - if "$PYTHON" -m pip install --require-hashes "$file"; then + if "$PYTHON" -m pip install "$file"; then return 0 fi done diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh index 193d75db62a..29801a5b867 100755 --- a/tools/run_tests/artifacts/build_package_python.sh +++ b/tools/run_tests/artifacts/build_package_python.sh @@ -23,24 +23,6 @@ mkdir -p artifacts/ # and we only collect them here to deliver them to the distribtest phase. cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/python_*/* artifacts/ || true -strip_binary_wheel() { - WHEEL_PATH="$1" - TEMP_WHEEL_DIR=$(mktemp -d) - wheel unpack "$WHEEL_PATH" -d "$TEMP_WHEEL_DIR" - find "$TEMP_WHEEL_DIR" -name "_protoc_compiler*.so" -exec strip --strip-debug {} ";" - find "$TEMP_WHEEL_DIR" -name "cygrpc*.so" -exec strip --strip-debug {} ";" - - WHEEL_FILE=$(basename "$WHEEL_PATH") - DISTRIBUTION_NAME=$(basename "$WHEEL_PATH" | cut -d '-' -f 1) - VERSION=$(basename "$WHEEL_PATH" | cut -d '-' -f 2) - wheel pack "$TEMP_WHEEL_DIR/$DISTRIBUTION_NAME-$VERSION" -d "$TEMP_WHEEL_DIR" - mv "$TEMP_WHEEL_DIR/$WHEEL_FILE" "$WHEEL_PATH" -} - -for wheel in artifacts/*.whl; do - strip_binary_wheel "$wheel" -done - # TODO: all the artifact builder configurations generate a grpcio-VERSION.tar.gz # source distribution package, and only one of them will end up # in the artifacts/ directory. They should be all equivalent though. From 50a1ddab5c6126f8f91c16e78e9595c3388f7f13 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 6 Mar 2019 07:57:21 -0800 Subject: [PATCH 593/814] Revert "Revert "Strip Python wheel binary"" This reverts commit 04609b1ea5aa743182f0d910d86d054a113f60e6. --- test/distrib/python/test_packages.sh | 2 +- .../artifacts/build_package_python.sh | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/test/distrib/python/test_packages.sh b/test/distrib/python/test_packages.sh index 755daa10211..433148e6bd7 100755 --- a/test/distrib/python/test_packages.sh +++ b/test/distrib/python/test_packages.sh @@ -41,7 +41,7 @@ PYTHON=$VIRTUAL_ENV/bin/python function at_least_one_installs() { for file in "$@"; do - if "$PYTHON" -m pip install "$file"; then + if "$PYTHON" -m pip install --require-hashes "$file"; then return 0 fi done diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh index 29801a5b867..193d75db62a 100755 --- a/tools/run_tests/artifacts/build_package_python.sh +++ b/tools/run_tests/artifacts/build_package_python.sh @@ -23,6 +23,24 @@ mkdir -p artifacts/ # and we only collect them here to deliver them to the distribtest phase. cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/python_*/* artifacts/ || true +strip_binary_wheel() { + WHEEL_PATH="$1" + TEMP_WHEEL_DIR=$(mktemp -d) + wheel unpack "$WHEEL_PATH" -d "$TEMP_WHEEL_DIR" + find "$TEMP_WHEEL_DIR" -name "_protoc_compiler*.so" -exec strip --strip-debug {} ";" + find "$TEMP_WHEEL_DIR" -name "cygrpc*.so" -exec strip --strip-debug {} ";" + + WHEEL_FILE=$(basename "$WHEEL_PATH") + DISTRIBUTION_NAME=$(basename "$WHEEL_PATH" | cut -d '-' -f 1) + VERSION=$(basename "$WHEEL_PATH" | cut -d '-' -f 2) + wheel pack "$TEMP_WHEEL_DIR/$DISTRIBUTION_NAME-$VERSION" -d "$TEMP_WHEEL_DIR" + mv "$TEMP_WHEEL_DIR/$WHEEL_FILE" "$WHEEL_PATH" +} + +for wheel in artifacts/*.whl; do + strip_binary_wheel "$wheel" +done + # TODO: all the artifact builder configurations generate a grpcio-VERSION.tar.gz # source distribution package, and only one of them will end up # in the artifacts/ directory. They should be all equivalent though. From 1603242add0cf088b3f07496a188f43536b7216f Mon Sep 17 00:00:00 2001 From: Michael Behr Date: Wed, 6 Mar 2019 12:39:22 -0500 Subject: [PATCH 594/814] Parse additional metadata flag manually instead of by regex --- test/cpp/interop/client.cc | 60 ++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index f091aa0e1a1..ad83a5c4249 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -17,7 +17,6 @@ */ #include -#include #include #include @@ -105,26 +104,48 @@ namespace { // Parse the contents of FLAGS_additional_metadata into a map. Allow // alphanumeric characters and dashes in keys, and any character but semicolons -// in values. -std::multimap ParseAdditionalMetadataFlag( - const grpc::string& flag) { - std::multimap additional_metadata; +// in values. On failure, log an error and return false. +bool ParseAdditionalMetadataFlag( + const grpc::string& flag, + std::multimap* additional_metadata) { + size_t start_pos = 0; + while (start_pos < flag.length()) { + size_t colon_pos = flag.find(':', start_pos); + if (colon_pos == grpc::string::npos) { + gpr_log(GPR_ERROR, + "Couldn't parse metadata flag: extra characters at end of flag"); + return false; + } + size_t semicolon_pos = flag.find(';', colon_pos); - // Key in group 1; value in group 2. - std::regex re("([-a-zA-Z0-9]+):([^;]*);?"); - auto metadata_entries_begin = std::sregex_iterator( - flag.begin(), flag.end(), re, std::regex_constants::match_continuous); - auto metadata_entries_end = std::sregex_iterator(); + grpc::string key = flag.substr(start_pos, colon_pos - start_pos); + grpc::string value = + flag.substr(colon_pos + 1, semicolon_pos - colon_pos - 1); + + constexpr char alphanum_and_hyphen[] = + "-0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (key.find_first_not_of(alphanum_and_hyphen) != grpc::string::npos) { + gpr_log(GPR_ERROR, + "Couldn't parse metadata flag: key contains characters other " + "than alphanumeric and hyphens: %s", + key.c_str()); + return false; + } - for (std::sregex_iterator i = metadata_entries_begin; - i != metadata_entries_end; ++i) { - std::smatch match = *i; gpr_log(GPR_INFO, "Adding additional metadata with key %s and value %s", - match[1].str().c_str(), match[2].str().c_str()); - additional_metadata.insert({match[1].str(), match[2].str()}); + key.c_str(), value.c_str()); + additional_metadata->insert({key, value}); + + if (semicolon_pos == grpc::string::npos) { + break; + } else { + start_pos = semicolon_pos + 1; + } } - return additional_metadata; + return true; } } // namespace @@ -141,8 +162,11 @@ int main(int argc, char** argv) { return CreateChannelForTestCase(test_case); }; } else { - std::multimap additional_metadata = - ParseAdditionalMetadataFlag(FLAGS_additional_metadata); + std::multimap additional_metadata; + if (!ParseAdditionalMetadataFlag(FLAGS_additional_metadata, + &additional_metadata)) { + return 1; + } channel_creation_func = [test_case, additional_metadata]() { std::vector Date: Wed, 6 Mar 2019 08:11:46 -0800 Subject: [PATCH 595/814] Remove GIL for grpc_call_unref --- src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi index 0a31d9c52ff..6e4574af8d5 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi @@ -85,9 +85,10 @@ cdef class Call: return result def __dealloc__(self): - if self.c_call != NULL: - grpc_call_unref(self.c_call) - grpc_shutdown_blocking() + with nogil: + if self.c_call != NULL: + grpc_call_unref(self.c_call) + grpc_shutdown_blocking() # The object *should* always be valid from Python. Used for debugging. @property From f7dd48b2b67a28973577e0e6ba206059c5edc645 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 1 Mar 2019 13:32:36 -0800 Subject: [PATCH 596/814] Moving ::grpc::ResourceQuota to ::grpc_impl::ResouceQuota This change moves ResourceQuota class fron grpc namespace to grpc_impl namespace. --- BUILD | 3 +- CMakeLists.txt | 3 + Makefile | 3 + build.yaml | 1 + gRPC-C++.podspec | 1 + include/grpcpp/resource_quota.h | 45 +----------- include/grpcpp/resource_quota_impl.h | 68 +++++++++++++++++++ include/grpcpp/server_builder.h | 9 ++- include/grpcpp/support/channel_arguments.h | 9 ++- src/cpp/common/channel_arguments.cc | 2 +- src/cpp/common/resource_quota_cc.cc | 4 +- src/cpp/server/server_builder.cc | 7 +- test/cpp/end2end/end2end_test.cc | 5 ++ test/cpp/end2end/thread_stress_test.cc | 5 ++ test/cpp/qps/server.h | 5 ++ test/cpp/qps/server_async.cc | 1 - tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + .../generated/sources_and_headers.json | 2 + 19 files changed, 122 insertions(+), 53 deletions(-) create mode 100644 include/grpcpp/resource_quota_impl.h diff --git a/BUILD b/BUILD index 24c1fb31ced..2b90f82aa00 100644 --- a/BUILD +++ b/BUILD @@ -192,8 +192,8 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpc++/impl/service_type.h", "include/grpc++/impl/sync_cxx11.h", "include/grpc++/impl/sync_no_cxx11.h", - "include/grpc++/resource_quota.h", "include/grpc++/security/auth_context.h", + "include/grpc++/resource_quota.h", "include/grpc++/security/auth_metadata_processor.h", "include/grpc++/security/credentials.h", "include/grpc++/security/server_credentials.h", @@ -241,6 +241,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/impl/sync_cxx11.h", "include/grpcpp/impl/sync_no_cxx11.h", "include/grpcpp/resource_quota.h", + "include/grpcpp/resource_quota_impl.h", "include/grpcpp/security/auth_context.h", "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/credentials.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 1bab5e6cba2..14a1bdee404 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3021,6 +3021,7 @@ foreach(_hdr include/grpcpp/impl/server_initializer.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h + include/grpcpp/resource_quota_impl.h include/grpcpp/security/auth_context.h include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/credentials.h @@ -3612,6 +3613,7 @@ foreach(_hdr include/grpcpp/impl/server_initializer.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h + include/grpcpp/resource_quota_impl.h include/grpcpp/security/auth_context.h include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/credentials.h @@ -4567,6 +4569,7 @@ foreach(_hdr include/grpcpp/impl/server_initializer.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h + include/grpcpp/resource_quota_impl.h include/grpcpp/security/auth_context.h include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/credentials.h diff --git a/Makefile b/Makefile index a2789e40431..4a95766d398 100644 --- a/Makefile +++ b/Makefile @@ -5442,6 +5442,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ + include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/credentials.h \ @@ -6042,6 +6043,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ + include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/credentials.h \ @@ -6954,6 +6956,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ + include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/credentials.h \ diff --git a/build.yaml b/build.yaml index c18630ecdd3..8e5fb57801e 100644 --- a/build.yaml +++ b/build.yaml @@ -1362,6 +1362,7 @@ filegroups: - include/grpcpp/impl/server_initializer.h - include/grpcpp/impl/service_type.h - include/grpcpp/resource_quota.h + - include/grpcpp/resource_quota_impl.h - include/grpcpp/security/auth_context.h - include/grpcpp/security/auth_metadata_processor.h - include/grpcpp/security/credentials.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 0f3888975c9..a4cc2b2b26d 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -105,6 +105,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/server_initializer.h', 'include/grpcpp/impl/service_type.h', 'include/grpcpp/resource_quota.h', + 'include/grpcpp/resource_quota_impl.h', 'include/grpcpp/security/auth_context.h', 'include/grpcpp/security/auth_metadata_processor.h', 'include/grpcpp/security/credentials.h', diff --git a/include/grpcpp/resource_quota.h b/include/grpcpp/resource_quota.h index 50bd1cb849a..333767b95c5 100644 --- a/include/grpcpp/resource_quota.h +++ b/include/grpcpp/resource_quota.h @@ -1,6 +1,6 @@ /* * - * Copyright 2016 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,50 +19,11 @@ #ifndef GRPCPP_RESOURCE_QUOTA_H #define GRPCPP_RESOURCE_QUOTA_H -struct grpc_resource_quota; - -#include -#include +#include namespace grpc { -/// ResourceQuota represents a bound on memory and thread usage by the gRPC -/// library. A ResourceQuota can be attached to a server (via \a ServerBuilder), -/// or a client channel (via \a ChannelArguments). -/// gRPC will attempt to keep memory and threads used by all attached entities -/// below the ResourceQuota bound. -class ResourceQuota final : private GrpcLibraryCodegen { - public: - /// \param name - a unique name for this ResourceQuota. - explicit ResourceQuota(const grpc::string& name); - ResourceQuota(); - ~ResourceQuota(); - - /// Resize this \a ResourceQuota to a new size. If \a new_size is smaller - /// than the current size of the pool, memory usage will be monotonically - /// decreased until it falls under \a new_size. - /// No time bound is given for this to occur however. - ResourceQuota& Resize(size_t new_size); - - /// Set the max number of threads that can be allocated from this - /// ResourceQuota object. - /// - /// If the new_max_threads value is smaller than the current value, no new - /// threads are allocated until the number of active threads fall below - /// new_max_threads. There is no time bound on when this may happen i.e none - /// of the current threads are forcefully destroyed and all threads run their - /// normal course. - ResourceQuota& SetMaxThreads(int new_max_threads); - - grpc_resource_quota* c_resource_quota() const { return impl_; } - - private: - ResourceQuota(const ResourceQuota& rhs); - ResourceQuota& operator=(const ResourceQuota& rhs); - - grpc_resource_quota* const impl_; -}; - +typedef ::grpc_impl::ResourceQuota ResourceQuota; } // namespace grpc #endif // GRPCPP_RESOURCE_QUOTA_H diff --git a/include/grpcpp/resource_quota_impl.h b/include/grpcpp/resource_quota_impl.h new file mode 100644 index 00000000000..16c0e35385b --- /dev/null +++ b/include/grpcpp/resource_quota_impl.h @@ -0,0 +1,68 @@ +/* + * + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_RESOURCE_QUOTA_IMPL_H +#define GRPCPP_RESOURCE_QUOTA_IMPL_H + +struct grpc_resource_quota; + +#include +#include + +namespace grpc_impl { + +/// ResourceQuota represents a bound on memory and thread usage by the gRPC +/// library. A ResourceQuota can be attached to a server (via \a ServerBuilder), +/// or a client channel (via \a ChannelArguments). +/// gRPC will attempt to keep memory and threads used by all attached entities +/// below the ResourceQuota bound. +class ResourceQuota final : private ::grpc::GrpcLibraryCodegen { + public: + /// \param name - a unique name for this ResourceQuota. + explicit ResourceQuota(const grpc::string& name); + ResourceQuota(); + ~ResourceQuota(); + + /// Resize this \a ResourceQuota to a new size. If \a new_size is smaller + /// than the current size of the pool, memory usage will be monotonically + /// decreased until it falls under \a new_size. + /// No time bound is given for this to occur however. + ResourceQuota& Resize(size_t new_size); + + /// Set the max number of threads that can be allocated from this + /// ResourceQuota object. + /// + /// If the new_max_threads value is smaller than the current value, no new + /// threads are allocated until the number of active threads fall below + /// new_max_threads. There is no time bound on when this may happen i.e none + /// of the current threads are forcefully destroyed and all threads run their + /// normal course. + ResourceQuota& SetMaxThreads(int new_max_threads); + + grpc_resource_quota* c_resource_quota() const { return impl_; } + + private: + ResourceQuota(const ResourceQuota& rhs); + ResourceQuota& operator=(const ResourceQuota& rhs); + + grpc_resource_quota* const impl_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_RESOURCE_QUOTA_IMPL_H diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 028b8cffaa7..ce5f3ef89c9 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -35,10 +35,14 @@ struct grpc_resource_quota; +namespace grpc_impl { + +class ResourceQuota; +} + namespace grpc { class AsyncGenericService; -class ResourceQuota; class CompletionQueue; class Server; class ServerCompletionQueue; @@ -182,7 +186,8 @@ class ServerBuilder { grpc_compression_algorithm algorithm); /// Set the attached buffer pool for this server - ServerBuilder& SetResourceQuota(const ResourceQuota& resource_quota); + ServerBuilder& SetResourceQuota( + const ::grpc_impl::ResourceQuota& resource_quota); ServerBuilder& SetOption(std::unique_ptr option); diff --git a/include/grpcpp/support/channel_arguments.h b/include/grpcpp/support/channel_arguments.h index 217929d4aca..48ae4246462 100644 --- a/include/grpcpp/support/channel_arguments.h +++ b/include/grpcpp/support/channel_arguments.h @@ -26,13 +26,16 @@ #include #include +namespace grpc_impl { + +class ResourceQuota; +} + namespace grpc { namespace testing { class ChannelArgumentsTest; } // namespace testing -class ResourceQuota; - /// Options for channel creation. The user can use generic setters to pass /// key value pairs down to C channel creation code. For gRPC related options, /// concrete setters are provided. @@ -83,7 +86,7 @@ class ChannelArguments { void SetUserAgentPrefix(const grpc::string& user_agent_prefix); /// Set the buffer pool to be attached to the constructed channel. - void SetResourceQuota(const ResourceQuota& resource_quota); + void SetResourceQuota(const ::grpc_impl::ResourceQuota& resource_quota); /// Set the max receive and send message sizes. void SetMaxReceiveMessageSize(int size); diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index 214d72f853f..c3d75054b9b 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -143,7 +143,7 @@ void ChannelArguments::SetUserAgentPrefix( } void ChannelArguments::SetResourceQuota( - const grpc::ResourceQuota& resource_quota) { + const grpc_impl::ResourceQuota& resource_quota) { SetPointerWithVtable(GRPC_ARG_RESOURCE_QUOTA, resource_quota.c_resource_quota(), grpc_resource_quota_arg_vtable()); diff --git a/src/cpp/common/resource_quota_cc.cc b/src/cpp/common/resource_quota_cc.cc index 276e5f79548..4fab2975d89 100644 --- a/src/cpp/common/resource_quota_cc.cc +++ b/src/cpp/common/resource_quota_cc.cc @@ -19,7 +19,7 @@ #include #include -namespace grpc { +namespace grpc_impl { ResourceQuota::ResourceQuota() : impl_(grpc_resource_quota_create(nullptr)) {} @@ -37,4 +37,4 @@ ResourceQuota& ResourceQuota::SetMaxThreads(int new_max_threads) { grpc_resource_quota_set_max_threads(impl_, new_max_threads); return *this; } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index b7fad558abb..a8ea514d785 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -29,6 +29,11 @@ #include "src/core/lib/gpr/useful.h" #include "src/cpp/server/thread_pool_interface.h" +namespace grpc_impl { + +class ResourceQuota; +} + namespace grpc { static std::vector (*)()>* @@ -152,7 +157,7 @@ ServerBuilder& ServerBuilder::SetDefaultCompressionAlgorithm( } ServerBuilder& ServerBuilder::SetResourceQuota( - const grpc::ResourceQuota& resource_quota) { + const grpc_impl::ResourceQuota& resource_quota) { if (resource_quota_ != nullptr) { grpc_resource_quota_unref(resource_quota_); } diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index f58a472bfaf..f7b9ee4b0b0 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -64,6 +64,11 @@ using std::chrono::system_clock; } \ } while (0) +namespace grpc_impl { + +class ResourceQuota; +} + namespace grpc { namespace testing { namespace { diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index e30ce0dbcbf..e308e591d1a 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -48,6 +48,11 @@ const int kNumAsyncReceiveThreads = 50; const int kNumAsyncServerThreads = 50; const int kNumRpcs = 1000; // Number of RPCs per thread +namespace grpc_impl { + +class ResourceQuota; +} + namespace grpc { namespace testing { diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h index 89b0e3af4b2..3aec8644a94 100644 --- a/test/cpp/qps/server.h +++ b/test/cpp/qps/server.h @@ -34,6 +34,11 @@ #include "test/cpp/qps/usage_timer.h" #include "test/cpp/util/test_credentials_provider.h" +namespace grpc_impl { + +class ResourceQuota; +} + namespace grpc { namespace testing { diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index a5f8347c269..9343fd311e1 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 9f17a25298a..367160a0ca9 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -995,6 +995,7 @@ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ +include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/credentials.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 664a6b3acfe..62be71a0f72 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -997,6 +997,7 @@ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ +include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/credentials.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 95b6ae65008..682ecf9bc3e 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11386,6 +11386,7 @@ "include/grpcpp/impl/server_initializer.h", "include/grpcpp/impl/service_type.h", "include/grpcpp/resource_quota.h", + "include/grpcpp/resource_quota_impl.h", "include/grpcpp/security/auth_context.h", "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/credentials.h", @@ -11495,6 +11496,7 @@ "include/grpcpp/impl/server_initializer.h", "include/grpcpp/impl/service_type.h", "include/grpcpp/resource_quota.h", + "include/grpcpp/resource_quota_impl.h", "include/grpcpp/security/auth_context.h", "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/credentials.h", From 5e5e337b033baf097b3edefd351695e8e6d34763 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 4 Mar 2019 17:56:03 -0800 Subject: [PATCH 597/814] fix from clang format code Add fixes from clang_format_code.sh. --- src/cpp/ext/filters/census/views.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cpp/ext/filters/census/views.cc b/src/cpp/ext/filters/census/views.cc index 102745ab4c2..d7e3c81a955 100644 --- a/src/cpp/ext/filters/census/views.cc +++ b/src/cpp/ext/filters/census/views.cc @@ -41,7 +41,7 @@ void RegisterOpenCensusViewsForExport() { grpc::ServerReceivedBytesPerRpcCumulative().RegisterForExport(); grpc::ServerServerLatencyCumulative().RegisterForExport(); } -} +} // namespace grpc_impl namespace grpc { using ::opencensus::stats::Aggregation; @@ -88,7 +88,6 @@ ViewDescriptor HourDescriptor() { } // namespace - // client cumulative const ViewDescriptor& ClientSentBytesPerRpcCumulative() { const static ViewDescriptor descriptor = From 705cb09f1da3116133afe76b390ff3831ffa3ab1 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 5 Mar 2019 14:21:05 -0800 Subject: [PATCH 598/814] Fix run_test and clang format errors Make changes suggested by the script. --- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/run_tests/generated/sources_and_headers.json | 2 ++ 3 files changed, 4 insertions(+) diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 9f17a25298a..49f0419bacf 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1001,6 +1001,7 @@ include/grpcpp/security/credentials.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ +include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ include/grpcpp/support/async_stream.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 664a6b3acfe..2af7ba6ccc0 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1003,6 +1003,7 @@ include/grpcpp/security/credentials.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ +include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ include/grpcpp/support/async_stream.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 0b84b8a4b95..97138d5dc63 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11394,6 +11394,7 @@ "include/grpcpp/security/server_credentials.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", + "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", "include/grpcpp/server_posix.h", "include/grpcpp/support/async_stream.h", @@ -11503,6 +11504,7 @@ "include/grpcpp/security/server_credentials.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", + "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", "include/grpcpp/server_posix.h", "include/grpcpp/support/async_stream.h", From 548beec563be0c822a62f8d23173d79a112e05df Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 6 Mar 2019 10:35:38 -0800 Subject: [PATCH 599/814] Fix qps composer.json --- src/php/tests/qps/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/tests/qps/composer.json b/src/php/tests/qps/composer.json index 0f4b0c04ba4..c2d73f00ed9 100644 --- a/src/php/tests/qps/composer.json +++ b/src/php/tests/qps/composer.json @@ -1,7 +1,7 @@ { "require": { "grpc/grpc": "dev-master", - "google/protobuf": "v3.5.1.1" + "google/protobuf": "^v3.3.0" }, "autoload": { "psr-4": { From d85e6f4e94f14acd9dc3b8ead09165812324f500 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 6 Mar 2019 08:13:22 -0800 Subject: [PATCH 600/814] Make grpclb work when selected via service config with no balancer addresses. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 12 ------ test/cpp/end2end/grpclb_end2end_test.cc | 41 +++++++++++++++++++ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index e21b1789172..77cd1059398 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1681,18 +1681,6 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( LoadBalancingPolicy::Args args) const override { - /* Count the number of gRPC-LB addresses. There must be at least one. */ - const ServerAddressList* addresses = - FindServerAddressListChannelArg(args.args); - if (addresses == nullptr) return nullptr; - bool found_balancer = false; - for (size_t i = 0; i < addresses->size(); ++i) { - if ((*addresses)[i].IsBalancer()) { - found_balancer = true; - break; - } - } - if (!found_balancer) return nullptr; return OrphanablePtr(New(std::move(args))); } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 31353ba1304..fe865ed4b72 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -723,6 +723,47 @@ TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfig) { EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } +TEST_F(SingleBalancerTest, + SelectGrpclbWithMigrationServiceConfigAndNoAddresses) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + SetNextResolution({}, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"grpclb\":{} }\n" + " ]\n" + "}"); + // Try to connect. + EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(true)); + // Should go into state TRANSIENT_FAILURE when we enter fallback mode. + const gpr_timespec deadline = grpc_timeout_seconds_to_deadline(1); + grpc_connectivity_state state; + while ((state = channel_->GetState(false)) != + GRPC_CHANNEL_TRANSIENT_FAILURE) { + ASSERT_TRUE(channel_->WaitForStateChange(state, deadline)); + } + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + +TEST_F(SingleBalancerTest, + SelectGrpclbWithMigrationServiceConfigAndNoBalancerAddresses) { + const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + // Resolution includes fallback address but no balancers. + SetNextResolution({AddressData{backend_servers_[0].port_, false, ""}}, + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"grpclb\":{} }\n" + " ]\n" + "}"); + CheckRpcSendOk(1, 1000 /* timeout_ms */, true /* wait_for_ready */); + // Check LB policy name for the channel. + EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); +} + TEST_F(SingleBalancerTest, UsePickFirstChildPolicy) { SetNextResolutionAllBalancers( "{\n" From cf70b744f1656b55a3db815685b1a2b195f36532 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 6 Mar 2019 15:02:29 -0800 Subject: [PATCH 601/814] Silent the check_on_pr failure --- tools/run_tests/python_utils/check_on_pr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index 8250dd76e02..fff455f7d5e 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -76,7 +76,7 @@ def _access_token(): time.sleep(_ACCESS_TOKEN_FETCH_RETRIES_INTERVAL_S) else: print("error: Unable to fetch access token, exiting...") - sys.exit(1) + sys.exit(0) return _ACCESS_TOKEN_CACHE['token'] From 6b437ca80faf527bea5e3176af517f9325dc4426 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 6 Mar 2019 15:30:33 -0800 Subject: [PATCH 602/814] Increase the retry interval --- tools/run_tests/python_utils/check_on_pr.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/python_utils/check_on_pr.py b/tools/run_tests/python_utils/check_on_pr.py index fff455f7d5e..f2b0f24e4fe 100644 --- a/tools/run_tests/python_utils/check_on_pr.py +++ b/tools/run_tests/python_utils/check_on_pr.py @@ -29,8 +29,8 @@ _GITHUB_APP_ID = 22338 _INSTALLATION_ID = 519109 _ACCESS_TOKEN_CACHE = None -_ACCESS_TOKEN_FETCH_RETRIES = 5 -_ACCESS_TOKEN_FETCH_RETRIES_INTERVAL_S = 1 +_ACCESS_TOKEN_FETCH_RETRIES = 6 +_ACCESS_TOKEN_FETCH_RETRIES_INTERVAL_S = 15 def _jwt_token(): From a6596b2fd51993e9001af5c35512eca1efd07e38 Mon Sep 17 00:00:00 2001 From: yang-g Date: Wed, 6 Mar 2019 15:43:12 -0800 Subject: [PATCH 603/814] Fix fuzzer test --- src/core/lib/gpr/cpu_posix.cc | 5 ++- ...rpc_percent_decode_fuzzer-5652313562808320 | 1 + test/core/slice/percent_decode_fuzzer.cc | 27 +++++++-------- test/core/slice/percent_encode_fuzzer.cc | 34 +++++++++---------- tools/run_tests/generated/tests.json | 23 +++++++++++++ 5 files changed, 54 insertions(+), 36 deletions(-) create mode 100644 test/core/slice/percent_decode_corpus/clusterfuzz-testcase-minimized-grpc_percent_decode_fuzzer-5652313562808320 diff --git a/src/core/lib/gpr/cpu_posix.cc b/src/core/lib/gpr/cpu_posix.cc index 915fd4976c2..59f583e4a0d 100644 --- a/src/core/lib/gpr/cpu_posix.cc +++ b/src/core/lib/gpr/cpu_posix.cc @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -52,7 +51,7 @@ unsigned gpr_cpu_num_cores(void) { static void delete_thread_id(void* value) { if (value) { - gpr_free(value); + free(value); } } @@ -71,7 +70,7 @@ unsigned gpr_cpu_current_cpu(void) { unsigned int* thread_id = static_cast(pthread_getspecific(thread_id_key)); if (thread_id == nullptr) { - thread_id = static_cast(gpr_malloc(sizeof(unsigned int))); + thread_id = static_cast(malloc(sizeof(unsigned int))); pthread_setspecific(thread_id_key, thread_id); } diff --git a/test/core/slice/percent_decode_corpus/clusterfuzz-testcase-minimized-grpc_percent_decode_fuzzer-5652313562808320 b/test/core/slice/percent_decode_corpus/clusterfuzz-testcase-minimized-grpc_percent_decode_fuzzer-5652313562808320 new file mode 100644 index 00000000000..797993a54d0 --- /dev/null +++ b/test/core/slice/percent_decode_corpus/clusterfuzz-testcase-minimized-grpc_percent_decode_fuzzer-5652313562808320 @@ -0,0 +1 @@ +%c4%cc%c4%cc%cc%ccccc%cccc%ccc%ccc%cc%ccc%ccc \ No newline at end of file diff --git a/test/core/slice/percent_decode_fuzzer.cc b/test/core/slice/percent_decode_fuzzer.cc index 11f71d92c46..da8e03a4662 100644 --- a/test/core/slice/percent_decode_fuzzer.cc +++ b/test/core/slice/percent_decode_fuzzer.cc @@ -31,23 +31,20 @@ bool squelch = true; bool leak_check = true; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + grpc_core::testing::LeakDetector leak_detector(true); grpc_init(); - { - grpc_core::testing::LeakDetector leak_detector(true); - grpc_slice input = grpc_slice_from_copied_buffer((const char*)data, size); - grpc_slice output; - if (grpc_strict_percent_decode_slice( - input, grpc_url_percent_encoding_unreserved_bytes, &output)) { - grpc_slice_unref(output); - } - if (grpc_strict_percent_decode_slice( - input, grpc_compatible_percent_encoding_unreserved_bytes, - &output)) { - grpc_slice_unref(output); - } - grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); - grpc_slice_unref(input); + grpc_slice input = grpc_slice_from_copied_buffer((const char*)data, size); + grpc_slice output; + if (grpc_strict_percent_decode_slice( + input, grpc_url_percent_encoding_unreserved_bytes, &output)) { + grpc_slice_unref(output); } + if (grpc_strict_percent_decode_slice( + input, grpc_compatible_percent_encoding_unreserved_bytes, &output)) { + grpc_slice_unref(output); + } + grpc_slice_unref(grpc_permissive_percent_decode_slice(input)); + grpc_slice_unref(input); grpc_shutdown_blocking(); return 0; } diff --git a/test/core/slice/percent_encode_fuzzer.cc b/test/core/slice/percent_encode_fuzzer.cc index 1da982bba28..4efa7a8d8e7 100644 --- a/test/core/slice/percent_encode_fuzzer.cc +++ b/test/core/slice/percent_encode_fuzzer.cc @@ -31,25 +31,23 @@ bool squelch = true; bool leak_check = true; static void test(const uint8_t* data, size_t size, const uint8_t* dict) { + grpc_core::testing::LeakDetector leak_detector(true); grpc_init(); - { - grpc_core::testing::LeakDetector leak_detector(true); - grpc_slice input = grpc_slice_from_copied_buffer( - reinterpret_cast(data), size); - grpc_slice output = grpc_percent_encode_slice(input, dict); - grpc_slice decoded_output; - // encoder must always produce decodable output - GPR_ASSERT(grpc_strict_percent_decode_slice(output, dict, &decoded_output)); - grpc_slice permissive_decoded_output = - grpc_permissive_percent_decode_slice(output); - // and decoded output must always match the input - GPR_ASSERT(grpc_slice_eq(input, decoded_output)); - GPR_ASSERT(grpc_slice_eq(input, permissive_decoded_output)); - grpc_slice_unref(input); - grpc_slice_unref(output); - grpc_slice_unref(decoded_output); - grpc_slice_unref(permissive_decoded_output); - } + grpc_slice input = + grpc_slice_from_copied_buffer(reinterpret_cast(data), size); + grpc_slice output = grpc_percent_encode_slice(input, dict); + grpc_slice decoded_output; + // encoder must always produce decodable output + GPR_ASSERT(grpc_strict_percent_decode_slice(output, dict, &decoded_output)); + grpc_slice permissive_decoded_output = + grpc_permissive_percent_decode_slice(output); + // and decoded output must always match the input + GPR_ASSERT(grpc_slice_eq(input, decoded_output)); + GPR_ASSERT(grpc_slice_eq(input, permissive_decoded_output)); + grpc_slice_unref(input); + grpc_slice_unref(output); + grpc_slice_unref(decoded_output); + grpc_slice_unref(permissive_decoded_output); grpc_shutdown_blocking(); } diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 9df57b5e151..2e82995bc8e 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -169172,6 +169172,29 @@ ], "uses_polling": false }, + { + "args": [ + "test/core/slice/percent_decode_corpus/clusterfuzz-testcase-minimized-grpc_percent_decode_fuzzer-5652313562808320" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 0.1, + "exclude_configs": [ + "tsan" + ], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "percent_decode_fuzzer_one_entry", + "platforms": [ + "mac", + "linux" + ], + "uses_polling": false + }, { "args": [ "test/core/slice/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758" From ab06853fc9a4e1a7bc58c9b6cc4aeaad1f9e666a Mon Sep 17 00:00:00 2001 From: billfeng327 Date: Wed, 6 Mar 2019 15:47:49 -0800 Subject: [PATCH 604/814] C++ Windows test builds --- bazel/grpc_build_system.bzl | 16 +++++++++++++--- bazel/grpc_deps.bzl | 10 +++++----- test/core/bad_connection/BUILD | 1 + test/core/client_channel/BUILD | 1 + test/core/end2end/generate_tests.bzl | 15 +++++++++++---- test/core/iomgr/BUILD | 10 ++++++++++ test/cpp/common/BUILD | 1 + test/cpp/end2end/BUILD | 2 ++ test/cpp/interop/BUILD | 1 + test/cpp/microbenchmarks/BUILD | 17 +++++++++++++++++ .../generate_resolver_component_tests.bzl | 5 ++++- test/cpp/performance/BUILD | 1 + test/cpp/qps/qps_benchmark_script.bzl | 1 + test/cpp/server/BUILD | 3 +++ test/cpp/server/load_reporter/BUILD | 1 + tools/remote_build/windows.bazelrc | 2 ++ 16 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 tools/remote_build/windows.bazelrc diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 3ea8e305ca5..c4f133ed6e5 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -28,6 +28,12 @@ load("//bazel:cc_grpc_library.bzl", "cc_grpc_library") # The set of pollers to test against if a test exercises polling POLLERS = ["epollex", "epoll1", "poll", "poll-cv"] +def is_msvc(): + return select({ + "//:windows_msvc": True, + "//conditions:default": False, + }) + def if_not_windows(a): return select({ "//:windows": [], @@ -80,7 +86,8 @@ def grpc_cc_library( visibility = None, alwayslink = 0, data = [], - use_cfstream = False): + use_cfstream = False, + tags = []): copts = [] if use_cfstream: copts = if_mac(["-DGRPC_CFSTREAM"]) @@ -116,6 +123,7 @@ def grpc_cc_library( ], alwayslink = alwayslink, data = data, + tags = tags, ) def grpc_proto_plugin(name, srcs = [], deps = []): @@ -158,8 +166,9 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data "size": size, "timeout": timeout, "exec_compatible_with": exec_compatible_with, + "tags": tags, } - if uses_polling: + if uses_polling and not is_msvc(): native.cc_test(testonly = True, tags = ["manual"], **args) for poller in POLLERS: native.sh_test( @@ -180,7 +189,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data else: native.cc_test(**args) -def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = []): +def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = [], tags = []): copts = [] if language.upper() == "C": copts = ["-std=c99"] @@ -194,6 +203,7 @@ def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], da deps = deps + _get_external_deps(external_deps), copts = copts, linkopts = if_not_windows(["-pthread"]) + linkopts, + tags = tags, ) def grpc_generate_one_off_targets(): diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index e2e47292242..799e864484c 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -147,16 +147,16 @@ def grpc_deps(): if "com_github_gflags_gflags" not in native.existing_rules(): http_archive( name = "com_github_gflags_gflags", - strip_prefix = "gflags-30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e", - url = "https://github.com/gflags/gflags/archive/30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e.tar.gz", + strip_prefix = "gflags-28f50e0fed19872e0fd50dd23ce2ee8cd759338e", + url = "https://github.com/gflags/gflags/archive/28f50e0fed19872e0fd50dd23ce2ee8cd759338e.tar.gz", ) if "com_github_google_benchmark" not in native.existing_rules(): http_archive( name = "com_github_google_benchmark", - build_file = "@com_github_grpc_grpc//third_party:benchmark.BUILD", - strip_prefix = "benchmark-9913418d323e64a0111ca0da81388260c2bbe1e9", - url = "https://github.com/google/benchmark/archive/9913418d323e64a0111ca0da81388260c2bbe1e9.tar.gz", + #build_file = "@com_github_grpc_grpc//third_party:benchmark.BUILD", + strip_prefix = "benchmark-e776aa0275e293707b6a0901e0e8d8a8a3679508", + url = "https://github.com/google/benchmark/archive/e776aa0275e293707b6a0901e0e8d8a8a3679508.tar.gz", ) if "com_github_cares_cares" not in native.existing_rules(): diff --git a/test/core/bad_connection/BUILD b/test/core/bad_connection/BUILD index 8ada933e796..4de9c0eb2d8 100644 --- a/test/core/bad_connection/BUILD +++ b/test/core/bad_connection/BUILD @@ -29,4 +29,5 @@ grpc_cc_binary( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD index 57e5191af4c..d67f326aa6d 100644 --- a/test/core/client_channel/BUILD +++ b/test/core/client_channel/BUILD @@ -52,6 +52,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index ec32aa5102c..cb1d88a3014 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -15,7 +15,7 @@ """Generates the appropriate build.json data for all the end2end tests.""" -load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library") +load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library", "is_msvc") POLLERS = ["epollex", "epoll1", "poll", "poll-cv"] @@ -31,7 +31,8 @@ def _fixture_options( is_http2 = True, supports_proxy_auth = False, supports_write_buffering = True, - client_channel = True): + client_channel = True, + supports_msvc = True,): return struct( fullstack = fullstack, includes_proxy = includes_proxy, @@ -44,6 +45,7 @@ def _fixture_options( supports_proxy_auth = supports_proxy_auth, supports_write_buffering = supports_write_buffering, client_channel = client_channel, + supports_msvc = supports_msvc, #_platforms=_platforms, ) @@ -119,10 +121,11 @@ END2END_NOSEC_FIXTURES = { client_channel = False, secure = False, _platforms = ["linux", "mac", "posix"], + supports_msvc = False, ), "h2_full": _fixture_options(secure = False), - "h2_full+pipe": _fixture_options(secure = False, _platforms = ["linux"]), - "h2_full+trace": _fixture_options(secure = False, tracing = True), + "h2_full+pipe": _fixture_options(secure = False, _platforms = ["linux"], supports_msvc = False), + "h2_full+trace": _fixture_options(secure = False, tracing = True, supports_msvc = False), "h2_full+workarounds": _fixture_options(secure = False), "h2_http_proxy": _fixture_options(secure = False, supports_proxy_auth = True), "h2_proxy": _fixture_options(secure = False, includes_proxy = True), @@ -151,6 +154,7 @@ END2END_NOSEC_FIXTURES = { dns_resolver = False, _platforms = ["linux", "mac", "posix"], secure = False, + supports_msvc = False, ), } @@ -328,6 +332,9 @@ END2END_TESTS = { } def _compatible(fopt, topt): + if is_msvc: + if not fopt.supports_msvc: + return False if topt.needs_fullstack: if not fopt.fullstack: return False diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 7daabd50527..f9da7f7ba73 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -81,6 +81,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -92,6 +93,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -103,6 +105,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -139,6 +142,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -153,6 +157,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -214,6 +219,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -225,6 +231,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -237,6 +244,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -259,6 +267,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -303,6 +312,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD index 01699b26add..e4ed3bc5460 100644 --- a/test/cpp/common/BUILD +++ b/test/cpp/common/BUILD @@ -28,6 +28,7 @@ grpc_cc_test( "//:grpc++_unsecure", "//test/core/util:grpc_test_util_unsecure", ], + tags = ["exclude_windows"], ) grpc_cc_test( diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index d80fa33a83a..82ad1e9387a 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -99,6 +99,7 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -607,6 +608,7 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index f36494d98db..d74566f56a7 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -161,4 +161,5 @@ grpc_cc_test( "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], + tags = ["exclude_windows"], ) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 70b4000780c..db37d37af6c 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -45,6 +45,7 @@ grpc_cc_library( "//test/core/util:grpc_test_util_unsecure", "//test/cpp/util:test_config", ], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -52,6 +53,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_closure.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -59,6 +61,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_alarm.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -73,6 +76,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_byte_buffer.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -80,6 +84,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_channel.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -87,6 +92,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_call_create.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -94,6 +100,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_cq.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -101,6 +108,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_cq_multiple_threads.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -108,6 +116,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_error.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_library( @@ -117,6 +126,7 @@ grpc_cc_library( "fullstack_streaming_ping_pong.h", ], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -126,6 +136,7 @@ grpc_cc_binary( "bm_fullstack_streaming_ping_pong.cc", ], deps = [":fullstack_streaming_ping_pong_h"], + tags = ["exclude_windows"], ) grpc_cc_library( @@ -144,6 +155,7 @@ grpc_cc_binary( "bm_fullstack_streaming_pump.cc", ], deps = [":fullstack_streaming_pump_h"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -151,6 +163,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_fullstack_trickle.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_library( @@ -169,6 +182,7 @@ grpc_cc_binary( "bm_fullstack_unary_ping_pong.cc", ], deps = [":fullstack_unary_ping_pong_h"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -176,6 +190,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_metadata.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -183,6 +198,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_chttp2_hpack.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) grpc_cc_binary( @@ -202,4 +218,5 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_timer.cc"], deps = [":helpers"], + tags = ["exclude_windows"], ) diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl index f36021560c1..8e584289628 100755 --- a/test/cpp/naming/generate_resolver_component_tests.bzl +++ b/test/cpp/naming/generate_resolver_component_tests.bzl @@ -33,6 +33,7 @@ def generate_resolver_component_tests(): "//:gpr", "//test/cpp/util:test_config", ], + tags = ["exclude_windows"], ) # meant to be invoked only through the top-level shell script driver grpc_cc_binary( @@ -52,6 +53,7 @@ def generate_resolver_component_tests(): "//:gpr", "//test/cpp/util:test_config", ], + tags = ["exclude_windows"], ) grpc_cc_test( name = "resolver_component_tests_runner_invoker%s" % unsecure_build_config_suffix, @@ -77,5 +79,6 @@ def generate_resolver_component_tests(): args = [ "--test_bin_name=resolver_component_test%s" % unsecure_build_config_suffix, "--running_under_bazel=true", - ] + ], + tags = ["exclude_windows"], ) diff --git a/test/cpp/performance/BUILD b/test/cpp/performance/BUILD index 4fe95d5905e..ddc41e75102 100644 --- a/test/cpp/performance/BUILD +++ b/test/cpp/performance/BUILD @@ -31,4 +31,5 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_base", ], + tags = ["exclude_windows"], ) diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl index 855caa0d37c..23b42c02b64 100644 --- a/test/cpp/qps/qps_benchmark_script.bzl +++ b/test/cpp/qps/qps_benchmark_script.bzl @@ -75,5 +75,6 @@ def json_run_localhost_batch(): ], tags = [ "json_run_localhost", + "exclude_windows", ], ) diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD index 050b83f5c4f..3c4b35af709 100644 --- a/test/cpp/server/BUILD +++ b/test/cpp/server/BUILD @@ -29,6 +29,7 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -42,6 +43,7 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], + tags = ["exclude_windows"], ) grpc_cc_test( @@ -55,4 +57,5 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], + tags = ["exclude_windows"], ) diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD index 8d876c56d29..2286119324b 100644 --- a/test/cpp/server/load_reporter/BUILD +++ b/test/cpp/server/load_reporter/BUILD @@ -45,6 +45,7 @@ grpc_cc_test( "//:lb_server_load_reporting_filter", "//test/core/util:grpc_test_util", ], + tags = ["exclude_windows"], ) grpc_cc_test( diff --git a/tools/remote_build/windows.bazelrc b/tools/remote_build/windows.bazelrc new file mode 100644 index 00000000000..a74f23b8048 --- /dev/null +++ b/tools/remote_build/windows.bazelrc @@ -0,0 +1,2 @@ +build --test_tag_filters=-exclude_windows +build --build_tag_filters=-exclude_windows \ No newline at end of file From 4814972080ea8490085e6fb60e31c6e96cb50771 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 6 Mar 2019 15:00:02 -0800 Subject: [PATCH 605/814] Install `wheel` right before use it --- tools/run_tests/artifacts/build_package_python.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh index 193d75db62a..29a26bc081c 100755 --- a/tools/run_tests/artifacts/build_package_python.sh +++ b/tools/run_tests/artifacts/build_package_python.sh @@ -23,17 +23,20 @@ mkdir -p artifacts/ # and we only collect them here to deliver them to the distribtest phase. cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/python_*/* artifacts/ || true +apt-get install -y python-pip +python -m pip install wheel --user + strip_binary_wheel() { WHEEL_PATH="$1" TEMP_WHEEL_DIR=$(mktemp -d) - wheel unpack "$WHEEL_PATH" -d "$TEMP_WHEEL_DIR" + python -m wheel unpack "$WHEEL_PATH" -d "$TEMP_WHEEL_DIR" find "$TEMP_WHEEL_DIR" -name "_protoc_compiler*.so" -exec strip --strip-debug {} ";" find "$TEMP_WHEEL_DIR" -name "cygrpc*.so" -exec strip --strip-debug {} ";" WHEEL_FILE=$(basename "$WHEEL_PATH") DISTRIBUTION_NAME=$(basename "$WHEEL_PATH" | cut -d '-' -f 1) VERSION=$(basename "$WHEEL_PATH" | cut -d '-' -f 2) - wheel pack "$TEMP_WHEEL_DIR/$DISTRIBUTION_NAME-$VERSION" -d "$TEMP_WHEEL_DIR" + python -m wheel pack "$TEMP_WHEEL_DIR/$DISTRIBUTION_NAME-$VERSION" -d "$TEMP_WHEEL_DIR" mv "$TEMP_WHEEL_DIR/$WHEEL_FILE" "$WHEEL_PATH" } From e0059af33b69806cb35e2cf125e301d500095b50 Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Wed, 6 Mar 2019 16:44:37 -0800 Subject: [PATCH 606/814] Adding a few potential breaking changes --- doc/core/pending_api_cleanups.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/core/pending_api_cleanups.md b/doc/core/pending_api_cleanups.md index 67d587deadc..f330240cadf 100644 --- a/doc/core/pending_api_cleanups.md +++ b/doc/core/pending_api_cleanups.md @@ -15,3 +15,7 @@ number: `include/grpc/impl/codegen/grpc_types.h` (commit `af00d8b`) (cannot be done until after next grpc release, so that TensorFlow can use the same code both internally and externally) +- get rid of all of the grpc++ headers that are currently deprecated + in favor of their grpcpp counterpart due to iOS' parsing issue on the + + sign. +- require a C++ runtime for all languages. From 0a36746ebe1dafd58b44620294ca571d592c3b06 Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Wed, 6 Mar 2019 16:45:25 -0800 Subject: [PATCH 607/814] Changing + to plus. --- doc/core/pending_api_cleanups.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/core/pending_api_cleanups.md b/doc/core/pending_api_cleanups.md index f330240cadf..eb44659c9e0 100644 --- a/doc/core/pending_api_cleanups.md +++ b/doc/core/pending_api_cleanups.md @@ -17,5 +17,5 @@ number: use the same code both internally and externally) - get rid of all of the grpc++ headers that are currently deprecated in favor of their grpcpp counterpart due to iOS' parsing issue on the - + sign. + plus sign. - require a C++ runtime for all languages. From fc56889a5cef2f43df22748a813cc5ed91df91f6 Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Wed, 6 Mar 2019 16:47:30 -0800 Subject: [PATCH 608/814] Removing the change about headers, since it's the wrong file. --- doc/core/pending_api_cleanups.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/core/pending_api_cleanups.md b/doc/core/pending_api_cleanups.md index eb44659c9e0..5a8270349a4 100644 --- a/doc/core/pending_api_cleanups.md +++ b/doc/core/pending_api_cleanups.md @@ -15,7 +15,4 @@ number: `include/grpc/impl/codegen/grpc_types.h` (commit `af00d8b`) (cannot be done until after next grpc release, so that TensorFlow can use the same code both internally and externally) -- get rid of all of the grpc++ headers that are currently deprecated - in favor of their grpcpp counterpart due to iOS' parsing issue on the - plus sign. - require a C++ runtime for all languages. From 5030177c5c2276b4f5e283a212d1c74741138e3b Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 6 Mar 2019 18:17:11 -0800 Subject: [PATCH 609/814] Add comment to address reviewer feedback --- src/cpp/server/server_cc.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 4d5c8179fce..6e78e93b835 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -361,6 +361,12 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { static_assert(std::is_base_of::value, "ServerContextType must be derived from ServerContext"); + // The constructor needs to know the server for this callback request and its + // index in the server's request count array to allow for proper dynamic + // requesting of incoming RPCs. For codegen services, the values of method and + // method_tag represent the defined characteristics of the method being + // requested. For generic services, method and method_tag are nullptr since + // these services don't have pre-defined methods or method registration tags. CallbackRequest(Server* server, size_t method_idx, internal::RpcServiceMethod* method, void* method_tag) : server_(server), From 18b19105f2d97f9418d9a1e4fb4f66e4e4740028 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Mon, 4 Mar 2019 14:19:43 -0500 Subject: [PATCH 610/814] Implement TCP_INQ for gRPC in Linux TCP_INQ is a socket option we added to Linux to report pending bytes on the socket as a control message. Using TCP_INQ we can accurately decide whether to continue read or not. Add an urgent parameter, when we do not want to wait for EPOLLIN. This commit improves the latency of 1 RPC unary (minimal benchmark) significantly: Before: l_50: 61.3584984733 l_90: 94.8328711277 l_99: 126.211351174 l_999: 158.722406029 After: l_50: 51.3546011488 (-16%) l_90: 72.3420731581 (-23%) l_99: 103.280218974 (-18%) l_999: 130.905689996 (-17%) --- .../client_channel/http_connect_handshaker.cc | 4 +- .../chttp2/transport/chttp2_transport.cc | 3 +- src/core/lib/http/httpcli.cc | 2 +- src/core/lib/iomgr/endpoint.cc | 4 +- src/core/lib/iomgr/endpoint.h | 5 +- src/core/lib/iomgr/endpoint_cfstream.cc | 2 +- src/core/lib/iomgr/port.h | 3 + src/core/lib/iomgr/tcp_custom.cc | 2 +- src/core/lib/iomgr/tcp_posix.cc | 208 +++++++++++++----- src/core/lib/iomgr/tcp_windows.cc | 2 +- .../lib/security/transport/secure_endpoint.cc | 4 +- .../security/transport/security_handshaker.cc | 7 +- test/core/bad_client/bad_client.cc | 3 +- test/core/end2end/bad_server_response_test.cc | 6 +- .../end2end/fixtures/http_proxy_fixture.cc | 12 +- .../readahead_handshaker_server_ssl.cc | 3 +- test/core/iomgr/endpoint_tests.cc | 13 +- test/core/iomgr/tcp_posix_test.cc | 9 +- test/core/security/secure_endpoint_test.cc | 2 +- .../transport/chttp2/settings_timeout_test.cc | 3 +- test/core/util/mock_endpoint.cc | 2 +- test/core/util/passthru_endpoint.cc | 2 +- test/core/util/trickle_endpoint.cc | 4 +- .../microbenchmarks/bm_chttp2_transport.cc | 2 +- 24 files changed, 213 insertions(+), 94 deletions(-) diff --git a/src/core/ext/filters/client_channel/http_connect_handshaker.cc b/src/core/ext/filters/client_channel/http_connect_handshaker.cc index fa5aaa9e7ce..2b1eb92bbd4 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -144,7 +144,7 @@ void HttpConnectHandshaker::OnWriteDone(void* arg, grpc_error* error) { // The read callback inherits our ref to the handshaker. grpc_endpoint_read(handshaker->args_->endpoint, handshaker->args_->read_buffer, - &handshaker->response_read_closure_); + &handshaker->response_read_closure_, /*urgent=*/true); gpr_mu_unlock(&handshaker->mu_); } } @@ -207,7 +207,7 @@ void HttpConnectHandshaker::OnReadDone(void* arg, grpc_error* error) { grpc_slice_buffer_reset_and_unref_internal(handshaker->args_->read_buffer); grpc_endpoint_read(handshaker->args_->endpoint, handshaker->args_->read_buffer, - &handshaker->response_read_closure_); + &handshaker->response_read_closure_, /*urgent=*/true); gpr_mu_unlock(&handshaker->mu_); return; } diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 306349b7910..888c1757be1 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -2577,7 +2577,8 @@ static void read_action_locked(void* tp, grpc_error* error) { grpc_slice_buffer_reset_and_unref_internal(&t->read_buffer); if (keep_reading) { - grpc_endpoint_read(t->ep, &t->read_buffer, &t->read_action_locked); + const bool urgent = t->goaway_error != GRPC_ERROR_NONE; + grpc_endpoint_read(t->ep, &t->read_buffer, &t->read_action_locked, urgent); grpc_chttp2_act_on_flowctl_action(t->flow_control->MakeAction(), t, nullptr); GRPC_CHTTP2_UNREF_TRANSPORT(t, "keep_reading"); diff --git a/src/core/lib/http/httpcli.cc b/src/core/lib/http/httpcli.cc index 8c9ce4da0d3..8a8da8b1604 100644 --- a/src/core/lib/http/httpcli.cc +++ b/src/core/lib/http/httpcli.cc @@ -121,7 +121,7 @@ static void append_error(internal_request* req, grpc_error* error) { } static void do_read(internal_request* req) { - grpc_endpoint_read(req->ep, &req->incoming, &req->on_read); + grpc_endpoint_read(req->ep, &req->incoming, &req->on_read, /*urgent=*/true); } static void on_read(void* user_data, grpc_error* error) { diff --git a/src/core/lib/iomgr/endpoint.cc b/src/core/lib/iomgr/endpoint.cc index 06316c60315..bb07fe79608 100644 --- a/src/core/lib/iomgr/endpoint.cc +++ b/src/core/lib/iomgr/endpoint.cc @@ -23,8 +23,8 @@ grpc_core::TraceFlag grpc_tcp_trace(false, "tcp"); void grpc_endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { - ep->vtable->read(ep, slices, cb); + grpc_closure* cb, bool urgent) { + ep->vtable->read(ep, slices, cb, urgent); } void grpc_endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* slices, diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h index 79c8ece263a..932e7e15b9a 100644 --- a/src/core/lib/iomgr/endpoint.h +++ b/src/core/lib/iomgr/endpoint.h @@ -36,7 +36,8 @@ typedef struct grpc_endpoint_vtable grpc_endpoint_vtable; class Timestamps; struct grpc_endpoint_vtable { - void (*read)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb); + void (*read)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb, + bool urgent); void (*write)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb, void* arg); void (*add_to_pollset)(grpc_endpoint* ep, grpc_pollset* pollset); @@ -56,7 +57,7 @@ struct grpc_endpoint_vtable { Valid slices may be placed into \a slices even when the callback is invoked with error != GRPC_ERROR_NONE. */ void grpc_endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb); + grpc_closure* cb, bool urgent); char* grpc_endpoint_get_peer(grpc_endpoint* ep); diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index 25146e7861c..6de22972dbf 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -251,7 +251,7 @@ static void CFStreamReadAllocationDone(void* arg, grpc_error* error) { } static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { CFStreamEndpoint* ep_impl = reinterpret_cast(ep); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, "CFStream endpoint:%p read (%p, %p) length:%zu", ep_impl, diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 7b6ca1bc0e1..3248343e27c 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -60,6 +60,9 @@ #define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_MSG_NOSIGNAL 1 #define GRPC_HAVE_UNIX_SOCKET 1 +/* Linux has TCP_INQ support since 4.18, but it is safe to set + the socket option on older kernels. */ +#define GRPC_HAVE_TCP_INQ 1 #ifdef LINUX_VERSION_CODE #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) #define GRPC_LINUX_ERRQUEUE 1 diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc index 1e5696e1279..f7ad120b026 100644 --- a/src/core/lib/iomgr/tcp_custom.cc +++ b/src/core/lib/iomgr/tcp_custom.cc @@ -192,7 +192,7 @@ static void tcp_read_allocation_done(void* tcpp, grpc_error* error) { } static void endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); GPR_ASSERT(tcp->read_cb == nullptr); diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 525288a77ae..960a45b7b26 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #include #include @@ -54,6 +56,15 @@ #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" +#ifndef SOL_TCP +#define SOL_TCP IPPROTO_TCP +#endif + +#ifndef TCP_INQ +#define TCP_INQ 36 +#define TCP_CM_INQ TCP_INQ +#endif + #ifdef GRPC_HAVE_MSG_NOSIGNAL #define SENDMSG_FLAGS MSG_NOSIGNAL #else @@ -88,8 +99,11 @@ struct grpc_tcp { grpc_slice_buffer last_read_buffer; grpc_slice_buffer* incoming_buffer; + int inq; /* bytes pending on the socket from the last read. */ + bool inq_capable; /* cache whether kernel supports inq */ + grpc_slice_buffer* outgoing_buffer; - /** byte within outgoing_buffer->slices[0] to write next */ + /* byte within outgoing_buffer->slices[0] to write next */ size_t outgoing_byte_idx; grpc_closure* read_cb; @@ -429,69 +443,140 @@ static void tcp_do_read(grpc_tcp* tcp) { GPR_TIMER_SCOPE("tcp_do_read", 0); struct msghdr msg; struct iovec iov[MAX_READ_IOVEC]; + char cmsgbuf[24 /*CMSG_SPACE(sizeof(int))*/]; ssize_t read_bytes; - size_t i; + size_t total_read_bytes = 0; - GPR_ASSERT(tcp->incoming_buffer->count <= MAX_READ_IOVEC); - - for (i = 0; i < tcp->incoming_buffer->count; i++) { + size_t iov_len = + std::min(MAX_READ_IOVEC, tcp->incoming_buffer->count); + for (size_t i = 0; i < iov_len; i++) { iov[i].iov_base = GRPC_SLICE_START_PTR(tcp->incoming_buffer->slices[i]); iov[i].iov_len = GRPC_SLICE_LENGTH(tcp->incoming_buffer->slices[i]); } - msg.msg_name = nullptr; - msg.msg_namelen = 0; - msg.msg_iov = iov; - msg.msg_iovlen = static_cast(tcp->incoming_buffer->count); - msg.msg_control = nullptr; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - GRPC_STATS_INC_TCP_READ_OFFER(tcp->incoming_buffer->length); - GRPC_STATS_INC_TCP_READ_OFFER_IOV_SIZE(tcp->incoming_buffer->count); - do { - GPR_TIMER_SCOPE("recvmsg", 0); - GRPC_STATS_INC_SYSCALL_READ(); - read_bytes = recvmsg(tcp->fd, &msg, 0); - } while (read_bytes < 0 && errno == EINTR); + /* Assume there is something on the queue. If we receive TCP_INQ from + * kernel, we will update this value, otherwise, we have to assume there is + * always something to read until we get EAGAIN. */ + tcp->inq = 1; - if (read_bytes < 0) { - /* NB: After calling call_read_cb a parallel call of the read handler may - * be running. */ - if (errno == EAGAIN) { - finish_estimate(tcp); - /* We've consumed the edge, request a new one */ - notify_on_read(tcp); + msg.msg_name = nullptr; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = static_cast(iov_len); + if (tcp->inq_capable) { + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); } else { - grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer); - call_read_cb(tcp, - tcp_annotate_error(GRPC_OS_ERROR(errno, "recvmsg"), tcp)); - TCP_UNREF(tcp, "read"); + msg.msg_control = nullptr; + msg.msg_controllen = 0; } - } else if (read_bytes == 0) { - /* 0 read size ==> end of stream */ - grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer); - call_read_cb( - tcp, tcp_annotate_error( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), tcp)); - TCP_UNREF(tcp, "read"); - } else { + msg.msg_flags = 0; + + GRPC_STATS_INC_TCP_READ_OFFER(tcp->incoming_buffer->length); + GRPC_STATS_INC_TCP_READ_OFFER_IOV_SIZE(tcp->incoming_buffer->count); + + do { + GPR_TIMER_SCOPE("recvmsg", 0); + GRPC_STATS_INC_SYSCALL_READ(); + read_bytes = recvmsg(tcp->fd, &msg, 0); + } while (read_bytes < 0 && errno == EINTR); + + /* We have read something in previous reads. We need to deliver those + * bytes to the upper layer. */ + if (read_bytes <= 0 && total_read_bytes > 0) { + tcp->inq = 1; + break; + } + + if (read_bytes < 0) { + /* NB: After calling call_read_cb a parallel call of the read handler may + * be running. */ + if (errno == EAGAIN) { + finish_estimate(tcp); + tcp->inq = 0; + /* We've consumed the edge, request a new one */ + notify_on_read(tcp); + } else { + grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer); + call_read_cb(tcp, + tcp_annotate_error(GRPC_OS_ERROR(errno, "recvmsg"), tcp)); + TCP_UNREF(tcp, "read"); + } + return; + } + if (read_bytes == 0) { + /* 0 read size ==> end of stream + * + * We may have read something, i.e., total_read_bytes > 0, but + * since the connection is closed we will drop the data here, because we + * can't call the callback multiple times. */ + grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer); + call_read_cb( + tcp, tcp_annotate_error( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Socket closed"), tcp)); + TCP_UNREF(tcp, "read"); + return; + } + GRPC_STATS_INC_TCP_READ_SIZE(read_bytes); add_to_estimate(tcp, static_cast(read_bytes)); - GPR_ASSERT((size_t)read_bytes <= tcp->incoming_buffer->length); - if (static_cast(read_bytes) == tcp->incoming_buffer->length) { - finish_estimate(tcp); - } else if (static_cast(read_bytes) < tcp->incoming_buffer->length) { - grpc_slice_buffer_trim_end( - tcp->incoming_buffer, - tcp->incoming_buffer->length - static_cast(read_bytes), - &tcp->last_read_buffer); + GPR_DEBUG_ASSERT((size_t)read_bytes <= + tcp->incoming_buffer->length - total_read_bytes); + +#ifdef GRPC_HAVE_TCP_INQ + if (tcp->inq_capable) { + GPR_DEBUG_ASSERT(!(msg.msg_flags & MSG_CTRUNC)); + struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); + for (; cmsg != nullptr; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_TCP && cmsg->cmsg_type == TCP_CM_INQ && + cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { + tcp->inq = *reinterpret_cast(CMSG_DATA(cmsg)); + } + } } - GPR_ASSERT((size_t)read_bytes == tcp->incoming_buffer->length); - call_read_cb(tcp, GRPC_ERROR_NONE); - TCP_UNREF(tcp, "read"); +#endif /* GRPC_HAVE_TCP_INQ */ + + total_read_bytes += read_bytes; + if (tcp->inq == 0 || total_read_bytes == tcp->incoming_buffer->length) { + /* We have filled incoming_buffer, and we cannot read any more. */ + break; + } + + /* We had a partial read, and still have space to read more data. + * So, adjust IOVs and try to read more. */ + size_t remaining = read_bytes; + size_t j = 0; + for (size_t i = 0; i < iov_len; i++) { + if (remaining >= iov[i].iov_len) { + remaining -= iov[i].iov_len; + continue; + } + if (remaining > 0) { + iov[j].iov_base = static_cast(iov[i].iov_base) + remaining; + iov[j].iov_len = iov[i].iov_len - remaining; + remaining = 0; + } else { + iov[j].iov_base = iov[i].iov_base; + iov[j].iov_len = iov[i].iov_len; + } + ++j; + } + iov_len = j; + } while (true); + + if (tcp->inq == 0) { + finish_estimate(tcp); } + + GPR_DEBUG_ASSERT(total_read_bytes > 0); + if (total_read_bytes < tcp->incoming_buffer->length) { + grpc_slice_buffer_trim_end(tcp->incoming_buffer, + tcp->incoming_buffer->length - total_read_bytes, + &tcp->last_read_buffer); + } + call_read_cb(tcp, GRPC_ERROR_NONE); + TCP_UNREF(tcp, "read"); } static void tcp_read_allocation_done(void* tcpp, grpc_error* error) { @@ -512,7 +597,8 @@ static void tcp_read_allocation_done(void* tcpp, grpc_error* error) { static void tcp_continue_read(grpc_tcp* tcp) { size_t target_read_size = get_target_read_size(tcp); - if (tcp->incoming_buffer->length < target_read_size / 2 && + /* Wait for allocation only when there is no buffer left. */ + if (tcp->incoming_buffer->length == 0 && tcp->incoming_buffer->count < MAX_READ_IOVEC) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p alloc_slices", tcp); @@ -544,7 +630,7 @@ static void tcp_handle_read(void* arg /* grpc_tcp */, grpc_error* error) { } static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { grpc_tcp* tcp = reinterpret_cast(ep); GPR_ASSERT(tcp->read_cb == nullptr); tcp->read_cb = cb; @@ -557,6 +643,11 @@ static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer, * the polling engine */ tcp->is_first_read = false; notify_on_read(tcp); + } else if (!urgent && tcp->inq == 0) { + /* Upper layer asked to read more but we know there is no pending data + * to read from previous reads. So, wait for POLLIN. + */ + notify_on_read(tcp); } else { /* Not the first time. We may or may not have more bytes available. In any * case call tcp->read_done_closure (i.e tcp_handle_read()) which does the @@ -1157,6 +1248,19 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->tb_head = nullptr; GRPC_CLOSURE_INIT(&tcp->read_done_closure, tcp_handle_read, tcp, grpc_schedule_on_exec_ctx); + /* Always assume there is something on the queue to read. */ + tcp->inq = 1; +#ifdef GRPC_HAVE_TCP_INQ + int one = 1; + if (setsockopt(tcp->fd, SOL_TCP, TCP_INQ, &one, sizeof(one)) == 0) { + tcp->inq_capable = true; + } else { + gpr_log(GPR_INFO, "cannot set inq fd=%d errno=%d", tcp->fd, errno); + tcp->inq_capable = false; + } +#else + tcp->inq_capable = false; +#endif /* GRPC_HAVE_TCP_INQ */ /* Start being notified on errors if event engine can track errors. */ if (grpc_event_engine_can_track_errors()) { /* Grab a ref to tcp so that we can safely access the tcp struct when diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 43817c5a024..7b464651ea1 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -241,7 +241,7 @@ static void on_read(void* tcpp, grpc_error* error) { #define DEFAULT_TARGET_READ_SIZE 8192 #define MAX_WSABUF_COUNT 16 static void win_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { grpc_tcp* tcp = (grpc_tcp*)ep; grpc_winsocket* handle = tcp->socket; grpc_winsocket_callback_info* info = &handle->read_info; diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc index 14fb55884f1..2a862492bd7 100644 --- a/src/core/lib/security/transport/secure_endpoint.cc +++ b/src/core/lib/security/transport/secure_endpoint.cc @@ -255,7 +255,7 @@ static void on_read(void* user_data, grpc_error* error) { } static void endpoint_read(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { secure_endpoint* ep = reinterpret_cast(secure_ep); ep->read_cb = cb; ep->read_buffer = slices; @@ -269,7 +269,7 @@ static void endpoint_read(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, return; } - grpc_endpoint_read(ep->wrapped_ep, &ep->source_buffer, &ep->on_read); + grpc_endpoint_read(ep->wrapped_ep, &ep->source_buffer, &ep->on_read, urgent); } static void flush_write_staging_buffer(secure_endpoint* ep, uint8_t** cur, diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index 5369574b854..3605bbe5974 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -283,7 +283,7 @@ grpc_error* SecurityHandshaker::OnHandshakeNextDoneLocked( if (result == TSI_INCOMPLETE_DATA) { GPR_ASSERT(bytes_to_send_size == 0); grpc_endpoint_read(args_->endpoint, args_->read_buffer, - &on_handshake_data_received_from_peer_); + &on_handshake_data_received_from_peer_, /*urgent=*/true); return error; } if (result != TSI_OK) { @@ -306,7 +306,7 @@ grpc_error* SecurityHandshaker::OnHandshakeNextDoneLocked( } else if (handshaker_result == nullptr) { // There is nothing to send, but need to read from peer. grpc_endpoint_read(args_->endpoint, args_->read_buffer, - &on_handshake_data_received_from_peer_); + &on_handshake_data_received_from_peer_, /*urgent=*/true); } else { // Handshake has finished, check peer and so on. error = CheckPeerLocked(); @@ -382,7 +382,8 @@ void SecurityHandshaker::OnHandshakeDataSentToPeerFn(void* arg, // We may be done. if (h->handshaker_result_ == nullptr) { grpc_endpoint_read(h->args_->endpoint, h->args_->read_buffer, - &h->on_handshake_data_received_from_peer_); + &h->on_handshake_data_received_from_peer_, + /*urgent=*/true); } else { error = h->CheckPeerLocked(); if (error != GRPC_ERROR_NONE) { diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc index ae1e42a4e0d..6b492523219 100644 --- a/test/core/bad_client/bad_client.cc +++ b/test/core/bad_client/bad_client.cc @@ -143,7 +143,8 @@ void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags, grpc_closure read_done_closure; GRPC_CLOSURE_INIT(&read_done_closure, set_read_done, &read_done_event, grpc_schedule_on_exec_ctx); - grpc_endpoint_read(sfd->client, &incoming, &read_done_closure); + grpc_endpoint_read(sfd->client, &incoming, &read_done_closure, + /*urgent=*/true); grpc_core::ExecCtx::Get()->Flush(); do { GPR_ASSERT(gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0); diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index 99cfec7adf6..3701a938a3d 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -126,7 +126,8 @@ static void handle_read(void* arg, grpc_error* error) { SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD) { handle_write(); } else { - grpc_endpoint_read(state.tcp, &state.temp_incoming_buffer, &on_read); + grpc_endpoint_read(state.tcp, &state.temp_incoming_buffer, &on_read, + /*urgent=*/false); } } @@ -142,7 +143,8 @@ static void on_connect(void* arg, grpc_endpoint* tcp, state.tcp = tcp; state.incoming_data_length = 0; grpc_endpoint_add_to_pollset(tcp, server->pollset); - grpc_endpoint_read(tcp, &state.temp_incoming_buffer, &on_read); + grpc_endpoint_read(tcp, &state.temp_incoming_buffer, &on_read, + /*urgent=*/false); } static gpr_timespec n_sec_deadline(int seconds) { diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index e6fc5dfcfca..6b5513f160e 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -271,7 +271,7 @@ static void on_client_read_done(void* arg, grpc_error* error) { } // Read more data. grpc_endpoint_read(conn->client_endpoint, &conn->client_read_buffer, - &conn->on_client_read_done); + &conn->on_client_read_done, /*urgent=*/false); } // Callback for reading data from the backend server, which will be @@ -302,7 +302,7 @@ static void on_server_read_done(void* arg, grpc_error* error) { } // Read more data. grpc_endpoint_read(conn->server_endpoint, &conn->server_read_buffer, - &conn->on_server_read_done); + &conn->on_server_read_done, /*urgent=*/false); } // Callback to write the HTTP response for the CONNECT request. @@ -323,9 +323,9 @@ static void on_write_response_done(void* arg, grpc_error* error) { proxy_connection_ref(conn, "server_read"); proxy_connection_unref(conn, "write_response"); grpc_endpoint_read(conn->client_endpoint, &conn->client_read_buffer, - &conn->on_client_read_done); + &conn->on_client_read_done, /*urgent=*/false); grpc_endpoint_read(conn->server_endpoint, &conn->server_read_buffer, - &conn->on_server_read_done); + &conn->on_server_read_done, /*urgent=*/false); } // Callback to connect to the backend server specified by the HTTP @@ -405,7 +405,7 @@ static void on_read_request_done(void* arg, grpc_error* error) { // If we're not done reading the request, read more data. if (conn->http_parser.state != GRPC_HTTP_BODY) { grpc_endpoint_read(conn->client_endpoint, &conn->client_read_buffer, - &conn->on_read_request_done); + &conn->on_read_request_done, /*urgent=*/false); return; } // Make sure we got a CONNECT request. @@ -503,7 +503,7 @@ static void on_accept(void* arg, grpc_endpoint* endpoint, grpc_http_parser_init(&conn->http_parser, GRPC_HTTP_REQUEST, &conn->http_request); grpc_endpoint_read(conn->client_endpoint, &conn->client_read_buffer, - &conn->on_read_request_done); + &conn->on_read_request_done, /*urgent=*/false); } // diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc index d91f2d2fe63..c0ab61136cb 100644 --- a/test/core/handshake/readahead_handshaker_server_ssl.cc +++ b/test/core/handshake/readahead_handshaker_server_ssl.cc @@ -59,7 +59,8 @@ class ReadAheadHandshaker : public Handshaker { void DoHandshake(grpc_tcp_server_acceptor* acceptor, grpc_closure* on_handshake_done, HandshakerArgs* args) override { - grpc_endpoint_read(args->endpoint, args->read_buffer, on_handshake_done); + grpc_endpoint_read(args->endpoint, args->read_buffer, on_handshake_done, + /*urgent=*/false); } }; diff --git a/test/core/iomgr/endpoint_tests.cc b/test/core/iomgr/endpoint_tests.cc index a9e8ba86c5d..beae24769f6 100644 --- a/test/core/iomgr/endpoint_tests.cc +++ b/test/core/iomgr/endpoint_tests.cc @@ -129,7 +129,8 @@ static void read_and_write_test_read_handler(void* data, grpc_error* error) { GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr)); gpr_mu_unlock(g_mu); } else if (error == GRPC_ERROR_NONE) { - grpc_endpoint_read(state->read_ep, &state->incoming, &state->done_read); + grpc_endpoint_read(state->read_ep, &state->incoming, &state->done_read, + /*urgent=*/false); } } @@ -216,8 +217,8 @@ static void read_and_write_test(grpc_endpoint_test_config config, read_and_write_test_write_handler(&state, GRPC_ERROR_NONE); grpc_core::ExecCtx::Get()->Flush(); - grpc_endpoint_read(state.read_ep, &state.incoming, &state.done_read); - + grpc_endpoint_read(state.read_ep, &state.incoming, &state.done_read, + /*urgent=*/false); if (shutdown) { gpr_log(GPR_DEBUG, "shutdown read"); grpc_endpoint_shutdown( @@ -282,14 +283,16 @@ static void multiple_shutdown_test(grpc_endpoint_test_config config) { grpc_endpoint_add_to_pollset(f.client_ep, g_pollset); grpc_endpoint_read(f.client_ep, &slice_buffer, GRPC_CLOSURE_CREATE(inc_on_failure, &fail_count, - grpc_schedule_on_exec_ctx)); + grpc_schedule_on_exec_ctx), + /*urgent=*/false); wait_for_fail_count(&fail_count, 0); grpc_endpoint_shutdown(f.client_ep, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown")); wait_for_fail_count(&fail_count, 1); grpc_endpoint_read(f.client_ep, &slice_buffer, GRPC_CLOSURE_CREATE(inc_on_failure, &fail_count, - grpc_schedule_on_exec_ctx)); + grpc_schedule_on_exec_ctx), + /*urgent=*/false); wait_for_fail_count(&fail_count, 2); grpc_slice_buffer_add(&slice_buffer, grpc_slice_from_copied_string("a")); grpc_endpoint_write(f.client_ep, &slice_buffer, diff --git a/test/core/iomgr/tcp_posix_test.cc b/test/core/iomgr/tcp_posix_test.cc index 5b601b1ae5f..33a4d973ed3 100644 --- a/test/core/iomgr/tcp_posix_test.cc +++ b/test/core/iomgr/tcp_posix_test.cc @@ -191,7 +191,8 @@ static void read_cb(void* user_data, grpc_error* error) { GRPC_LOG_IF_ERROR("kick", grpc_pollset_kick(g_pollset, nullptr))); gpr_mu_unlock(g_mu); } else { - grpc_endpoint_read(state->ep, &state->incoming, &state->read_cb); + grpc_endpoint_read(state->ep, &state->incoming, &state->read_cb, + /*urgent=*/false); gpr_mu_unlock(g_mu); } } @@ -229,7 +230,7 @@ static void read_test(size_t num_bytes, size_t slice_size) { grpc_slice_buffer_init(&state.incoming); GRPC_CLOSURE_INIT(&state.read_cb, read_cb, &state, grpc_schedule_on_exec_ctx); - grpc_endpoint_read(ep, &state.incoming, &state.read_cb); + grpc_endpoint_read(ep, &state.incoming, &state.read_cb, /*urgent=*/false); gpr_mu_lock(g_mu); while (state.read_bytes < state.target_read_bytes) { @@ -280,7 +281,7 @@ static void large_read_test(size_t slice_size) { grpc_slice_buffer_init(&state.incoming); GRPC_CLOSURE_INIT(&state.read_cb, read_cb, &state, grpc_schedule_on_exec_ctx); - grpc_endpoint_read(ep, &state.incoming, &state.read_cb); + grpc_endpoint_read(ep, &state.incoming, &state.read_cb, /*urgent=*/false); gpr_mu_lock(g_mu); while (state.read_bytes < state.target_read_bytes) { @@ -519,7 +520,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) { grpc_slice_buffer_init(&state.incoming); GRPC_CLOSURE_INIT(&state.read_cb, read_cb, &state, grpc_schedule_on_exec_ctx); - grpc_endpoint_read(ep, &state.incoming, &state.read_cb); + grpc_endpoint_read(ep, &state.incoming, &state.read_cb, /*urgent=*/false); gpr_mu_lock(g_mu); while (state.read_bytes < state.target_read_bytes) { diff --git a/test/core/security/secure_endpoint_test.cc b/test/core/security/secure_endpoint_test.cc index f6d02895b5f..3a2d599767a 100644 --- a/test/core/security/secure_endpoint_test.cc +++ b/test/core/security/secure_endpoint_test.cc @@ -182,7 +182,7 @@ static void test_leftover(grpc_endpoint_test_config config, size_t slice_size) { grpc_slice_buffer_init(&incoming); GRPC_CLOSURE_INIT(&done_closure, inc_call_ctr, &n, grpc_schedule_on_exec_ctx); - grpc_endpoint_read(f.client_ep, &incoming, &done_closure); + grpc_endpoint_read(f.client_ep, &incoming, &done_closure, /*urgent=*/false); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(n == 1); diff --git a/test/core/transport/chttp2/settings_timeout_test.cc b/test/core/transport/chttp2/settings_timeout_test.cc index a9789edbf2b..32a268ed521 100644 --- a/test/core/transport/chttp2/settings_timeout_test.cc +++ b/test/core/transport/chttp2/settings_timeout_test.cc @@ -133,7 +133,8 @@ class Client { grpc_millis deadline = grpc_core::ExecCtx::Get()->Now() + 3000; while (true) { EventState state; - grpc_endpoint_read(endpoint_, &read_buffer, state.closure()); + grpc_endpoint_read(endpoint_, &read_buffer, state.closure(), + /*urgent=*/true); if (!PollUntilDone(&state, deadline)) { retval = false; break; diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc index df2ee7aedfd..2f78a7f8a97 100644 --- a/test/core/util/mock_endpoint.cc +++ b/test/core/util/mock_endpoint.cc @@ -41,7 +41,7 @@ typedef struct mock_endpoint { } mock_endpoint; static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { mock_endpoint* m = reinterpret_cast(ep); gpr_mu_lock(&m->mu); if (m->read_buffer.count > 0) { diff --git a/test/core/util/passthru_endpoint.cc b/test/core/util/passthru_endpoint.cc index 51b6de46951..2d26902fc44 100644 --- a/test/core/util/passthru_endpoint.cc +++ b/test/core/util/passthru_endpoint.cc @@ -54,7 +54,7 @@ struct passthru_endpoint { }; static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { half* m = reinterpret_cast(ep); gpr_mu_lock(&m->parent->mu); if (m->parent->shutdown) { diff --git a/test/core/util/trickle_endpoint.cc b/test/core/util/trickle_endpoint.cc index b0da735e57f..bdac1334f48 100644 --- a/test/core/util/trickle_endpoint.cc +++ b/test/core/util/trickle_endpoint.cc @@ -47,9 +47,9 @@ typedef struct { } trickle_endpoint; static void te_read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { trickle_endpoint* te = reinterpret_cast(ep); - grpc_endpoint_read(te->wrapped, slices, cb); + grpc_endpoint_read(te->wrapped, slices, cb, urgent); } static void maybe_call_write_cb_locked(trickle_endpoint* te) { diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index dcfaa684773..baa6da3fbcf 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -92,7 +92,7 @@ class DummyEndpoint : public grpc_endpoint { } static void read(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, bool urgent) { static_cast(ep)->QueueRead(slices, cb); } From 240bf8676093d52107be1fffed5ed61ec06b61b4 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 6 Mar 2019 23:01:05 -0800 Subject: [PATCH 611/814] Add unimplemented RPC test --- .../end2end/client_callback_end2end_test.cc | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 893d009392d..3845c4c0b2a 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -1084,6 +1084,39 @@ TEST_P(ClientCallbackEnd2endTest, SimultaneousReadAndWritesDone) { test.Await(); } +TEST_P(ClientCallbackEnd2endTest, UnimplementedRpc) { + MAYBE_SKIP_TEST; + ChannelArguments args; + const auto& channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); + std::shared_ptr channel = + (GetParam().protocol == Protocol::TCP) + ? CreateCustomChannel(server_address_.str(), channel_creds, args) + : server_->InProcessChannel(args); + std::unique_ptr stub; + stub = grpc::testing::UnimplementedEchoService::NewStub(channel); + EchoRequest request; + EchoResponse response; + ClientContext cli_ctx; + request.set_message("Hello world."); + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub->experimental_async()->Unimplemented( + &cli_ctx, &request, &response, [&done, &mu, &cv](Status s) { + EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code()); + EXPECT_EQ("", s.error_message()); + + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } +} + std::vector CreateTestScenarios(bool test_insecure) { std::vector scenarios; std::vector credentials_types{ From b7f14fdab8c6da31b8009a4b4dc395a913660493 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 6 Mar 2019 23:43:34 -0800 Subject: [PATCH 612/814] Properly implement unimplemented RPCs at callback-only server --- include/grpcpp/server.h | 4 ++++ src/cpp/server/server_cc.cc | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 21c908aebdb..f5c99f22df2 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -326,6 +326,10 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { std::unique_ptr health_check_service_; bool health_check_service_disabled_; + // When appropriate, use a default callback generic service to handle + // unimplemented methods + std::unique_ptr unimplemented_service_; + // A special handler for resource exhausted in sync case std::unique_ptr resource_exhausted_handler_; diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 6e78e93b835..26e84f1aed4 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -1004,6 +1004,14 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { RegisterService(nullptr, default_health_check_service_impl); } + // If this server uses callback methods, then create a callback generic + // service to handle any unimplemented methods using the default reactor + // creator + if (!callback_reqs_to_start_.empty() && !has_callback_generic_service_) { + unimplemented_service_.reset(new experimental::CallbackGenericService); + RegisterCallbackGenericService(unimplemented_service_.get()); + } + grpc_server_start(server_); if (!has_async_generic_service_ && !has_callback_generic_service_) { From b1dbf6837358b87766564b7ab307b7e18b6fc5f4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 7 Mar 2019 03:15:08 -0500 Subject: [PATCH 613/814] update the docker image to netcore3 preview3 --- .../grpc_interop_aspnetcore/Dockerfile.template | 11 ++--------- .../interoptest/grpc_interop_aspnetcore/Dockerfile | 11 ++--------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template index a341592a2ab..e8f962403f7 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template @@ -1,6 +1,6 @@ %YAML 1.2 --- | - # Copyright 2017 gRPC authors. + # Copyright 2019 The gRPC Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,14 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM microsoft/dotnet:3.0.100-preview2-sdk-stretch - - RUN rm /usr/bin/dotnet # remove symlink - RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.azureedge.net/dotnet/Sdk/3.0.100-preview3-010313/dotnet-sdk-3.0.100-preview3-010313-linux-x64.tar.gz ${'\\'} - && mkdir -p /usr/share/dotnet ${'\\'} - && tar -zxf dotnet.tar.gz -C /usr/share/dotnet ${'\\'} - && rm dotnet.tar.gz ${'\\'} - && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet + FROM mcr.microsoft.com/dotnet/core/sdk:3.0.100-preview3-stretch # Define the default command. CMD ["bash"] diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile index 75a8a200ab4..26a21384911 100644 --- a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2017 gRPC authors. +# Copyright 2019 The gRPC Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,14 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM microsoft/dotnet:3.0.100-preview2-sdk-stretch - -RUN rm /usr/bin/dotnet # remove symlink -RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.azureedge.net/dotnet/Sdk/3.0.100-preview3-010313/dotnet-sdk-3.0.100-preview3-010313-linux-x64.tar.gz \ - && mkdir -p /usr/share/dotnet \ - && tar -zxf dotnet.tar.gz -C /usr/share/dotnet \ - && rm dotnet.tar.gz \ - && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet +FROM mcr.microsoft.com/dotnet/core/sdk:3.0.100-preview3-stretch # Define the default command. CMD ["bash"] From f422acdb7eef68dc499f99818606d0043365e23b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 7 Mar 2019 16:04:21 +0100 Subject: [PATCH 614/814] move MonoPInvokeCallbackAttribute to a separate file --- .../Internal/MonoPInvokeCallbackAttribute.cs | 40 +++++++++++++++++++ .../Grpc.Core/Internal/NativeLogRedirector.cs | 18 --------- 2 files changed, 40 insertions(+), 18 deletions(-) create mode 100644 src/csharp/Grpc.Core/Internal/MonoPInvokeCallbackAttribute.cs diff --git a/src/csharp/Grpc.Core/Internal/MonoPInvokeCallbackAttribute.cs b/src/csharp/Grpc.Core/Internal/MonoPInvokeCallbackAttribute.cs new file mode 100644 index 00000000000..64eb386a3c5 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/MonoPInvokeCallbackAttribute.cs @@ -0,0 +1,40 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; + +namespace Grpc.Core.Internal +{ + /// + /// Use this attribute to mark methods that will be called back from P/Invoke calls. + /// iOS (and probably other AOT platforms) needs to have delegates registered. + /// Instead of depending on Xamarin.iOS for this, we can just create our own, + /// the iOS runtime just checks for the type name. + /// See: https://docs.microsoft.com/en-gb/xamarin/ios/internals/limitations#reverse-callbacks + /// + [AttributeUsage(AttributeTargets.Method)] + internal sealed class MonoPInvokeCallbackAttribute : Attribute + { + public MonoPInvokeCallbackAttribute(Type type) + { + Type = type; + } + + public Type Type { get; private set; } + } +} diff --git a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs index 30264acb10b..062c0101b91 100644 --- a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs +++ b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs @@ -87,22 +87,4 @@ namespace Grpc.Core.Internal } } } - - /// - /// Use this attribute to mark methods that will be called back from P/Invoke calls. - /// iOS (and probably other AOT platforms) needs to have delegates registered. - /// Instead of depending on Xamarin.iOS for this, we can just create our own, - /// the iOS runtime just checks for the type name. - /// See: https://docs.microsoft.com/en-gb/xamarin/ios/internals/limitations#reverse-callbacks - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class MonoPInvokeCallbackAttribute : Attribute - { - public MonoPInvokeCallbackAttribute(Type type) - { - Type = type; - } - - public Type Type { get; private set; } - } } From 827c77bd240f5d6dbc9876e4c2db2b492953c862 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 7 Mar 2019 07:57:29 -0800 Subject: [PATCH 615/814] Use fallback before timeout if balancer channel reports TRANSIENT_FAILURE. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 80 +++++++++++++++++-- .../client_channel/lb_policy/xds/xds.cc | 3 + test/cpp/end2end/grpclb_end2end_test.cc | 14 ++++ test/cpp/end2end/xds_end2end_test.cc | 3 + 4 files changed, 94 insertions(+), 6 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 5b3bb40f8cd..d6dde0d7a79 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -295,8 +295,10 @@ class GrpcLb : public LoadBalancingPolicy { // Helper functions used in UpdateLocked(). void ProcessChannelArgsLocked(const grpc_channel_args& args); void ParseLbConfig(Config* grpclb_config); + static void OnBalancerChannelConnectivityChangedLocked(void* arg, + grpc_error* error); - // Methods for dealing with the balancer channel and call. + // Methods for dealing with the balancer call. void StartBalancerCallLocked(); static void OnFallbackTimerLocked(void* arg, grpc_error* error); void StartBalancerCallRetryTimerLocked(); @@ -323,6 +325,9 @@ class GrpcLb : public LoadBalancingPolicy { gpr_atm lb_channel_uuid_ = 0; // Response generator to inject address updates into lb_channel_. RefCountedPtr response_generator_; + // Connectivity state notification. + grpc_connectivity_state lb_channel_connectivity_ = GRPC_CHANNEL_IDLE; + grpc_closure lb_channel_on_connectivity_changed_; // The data associated with the current LB call. It holds a ref to this LB // policy. It's initialized every time we query for backends. It's reset to @@ -1030,6 +1035,12 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( } else { // New serverlist. if (grpclb_policy->serverlist_ == nullptr) { // Dispose of the fallback. + if (grpclb_policy->child_policy_ != nullptr) { + gpr_log(GPR_INFO, + "[grpclb %p] Received response from balancer; exiting " + "fallback mode", + grpclb_policy); + } grpclb_policy->fallback_backend_addresses_.reset(); if (grpclb_policy->fallback_timer_callback_pending_) { grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); @@ -1219,6 +1230,10 @@ GrpcLb::GrpcLb(Args args) .set_jitter(GRPC_GRPCLB_RECONNECT_JITTER) .set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { + // Initialization. + GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, + &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, + grpc_combiner_scheduler(args.combiner)); gpr_mu_init(&child_policy_mu_); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); @@ -1329,6 +1344,20 @@ void GrpcLb::UpdateLocked(const grpc_channel_args& args, grpc_combiner_scheduler(combiner())); fallback_timer_callback_pending_ = true; grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); + // Start watching the channel's connectivity state. If the channel + // goes into state TRANSIENT_FAILURE, we go into fallback mode even if + // the fallback timeout has not elapsed. + grpc_channel_element* client_channel_elem = + grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(lb_channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + // Ref held by callback. + Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity").release(); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set(interested_parties()), + &lb_channel_connectivity_, &lb_channel_on_connectivity_changed_, + nullptr); } StartBalancerCallLocked(); } @@ -1420,6 +1449,37 @@ void GrpcLb::ParseLbConfig(Config* grpclb_config) { } } +void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, + grpc_error* error) { + GrpcLb* self = static_cast(arg); + if (!self->shutting_down_ && self->fallback_timer_callback_pending_) { + if (self->lb_channel_connectivity_ != GRPC_CHANNEL_TRANSIENT_FAILURE) { + // Not in TRANSIENT_FAILURE. Renew connectivity watch. + grpc_channel_element* client_channel_elem = + grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(self->lb_channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set( + self->interested_parties()), + &self->lb_channel_connectivity_, + &self->lb_channel_on_connectivity_changed_, nullptr); + return; // Early out so we don't drop the ref below. + } + // In TRANSIENT_FAILURE. Cancel the fallback timer and go into + // fallback mode immediately. + gpr_log(GPR_INFO, + "[grpclb %p] balancer channel in state TRANSIENT_FAILURE; " + "entering fallback mode", + self); + grpc_timer_cancel(&self->lb_fallback_timer_); + self->CreateOrUpdateChildPolicyLocked(); + } + // Done watching connectivity state, so drop ref. + self->Unref(DEBUG_LOCATION, "watch_lb_channel_connectivity"); +} + // // code for balancer channel and call // @@ -1445,13 +1505,21 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { // actually runs, don't fall back. if (grpclb_policy->serverlist_ == nullptr && !grpclb_policy->shutting_down_ && error == GRPC_ERROR_NONE) { - if (grpc_lb_glb_trace.enabled()) { - gpr_log(GPR_INFO, - "[grpclb %p] Falling back to use backends from resolver", - grpclb_policy); - } + gpr_log(GPR_INFO, + "[grpclb %p] No response from balancer after fallback timeout; " + "entering fallback mode", + grpclb_policy); GPR_ASSERT(grpclb_policy->fallback_backend_addresses_ != nullptr); grpclb_policy->CreateOrUpdateChildPolicyLocked(); + // Cancel connectivity watch, since we no longer need it. + grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(grpclb_policy->lb_channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set( + grpclb_policy->interested_parties()), + nullptr, &grpclb_policy->lb_channel_on_connectivity_changed_, nullptr); } grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index dbe68190ff5..a9ca34e5a52 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1254,6 +1254,9 @@ void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_combiner_scheduler(combiner())); fallback_timer_callback_pending_ = true; grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); + // TODO(juanlishen): Monitor the connectivity state of the balancer + // channel. If the channel reports TRANSIENT_FAILURE before the + // fallback timeout expires, go into fallback mode early. } } } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index fe865ed4b72..abce031c539 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -1194,6 +1194,20 @@ TEST_F(SingleBalancerTest, FallbackUpdate) { EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); } +TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerChannelFails) { + const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + // Return an unreachable balancer and one fallback backend. + std::vector addresses; + addresses.emplace_back(AddressData{grpc_pick_unused_port_or_die(), true, ""}); + addresses.emplace_back(AddressData{backend_servers_[0].port_, false, ""}); + SetNextResolution(addresses); + // Send RPC with deadline less than the fallback timeout and make sure it + // succeeds. + CheckRpcSendOk(/* times */ 1, /* timeout_ms */ 1000, + /* wait_for_ready */ false); +} + TEST_F(SingleBalancerTest, BackendsRestart) { SetNextResolutionAllBalancers(); const size_t kNumRpcsPerAddress = 100; diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 09556675d43..667481bafd2 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -868,6 +868,9 @@ TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { // TODO(juanlishen): Add TEST_F(SingleBalancerTest, FallbackUpdate) +// TODO(juanlishen): Add TEST_F(SingleBalancerTest, +// FallbackEarlyWhenBalancerChannelFails) + TEST_F(SingleBalancerTest, BackendsRestart) { SetNextResolution({}, kDefaultServiceConfig_.c_str()); SetNextResolutionForLbChannelAllBalancers(); From 65ef4f5cef300fd63c127d8dcf485261e0e1420c Mon Sep 17 00:00:00 2001 From: billfeng327 Date: Thu, 7 Mar 2019 11:00:06 -0800 Subject: [PATCH 616/814] added TODO and updated documentation for manual local windows build --- tools/remote_build/README.md | 6 ++++++ tools/remote_build/windows.bazelrc | 1 + 2 files changed, 7 insertions(+) diff --git a/tools/remote_build/README.md b/tools/remote_build/README.md index 19739e9ee12..8a236973946 100644 --- a/tools/remote_build/README.md +++ b/tools/remote_build/README.md @@ -29,5 +29,11 @@ Sanitizer runs (asan, msan, tsan, ubsan): bazel --bazelrc=tools/remote_build/manual.bazelrc test --config=asan //test/... ``` +Run on Windows MSVC: +``` +# local manual run only for C++ targets (RBE to be supported) +bazel --bazelrc=tools/remote_build/windows.bazelrc test //test/cpp/... +``` + Available command line options can be found in [Bazel command line reference](https://docs.bazel.build/versions/master/command-line-reference.html) diff --git a/tools/remote_build/windows.bazelrc b/tools/remote_build/windows.bazelrc index a74f23b8048..86025006e3d 100644 --- a/tools/remote_build/windows.bazelrc +++ b/tools/remote_build/windows.bazelrc @@ -1,2 +1,3 @@ +# TODO(yfen): Merge with rbe_common.bazelrc and enable Windows RBE build --test_tag_filters=-exclude_windows build --build_tag_filters=-exclude_windows \ No newline at end of file From d15605c0e5813d25e2dd1a65805496488064a919 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 7 Mar 2019 12:42:51 -0800 Subject: [PATCH 617/814] Swap in new LB policy when it's ready --- .../client_channel/lb_policy/grpclb/grpclb.cc | 6 +- .../client_channel/lb_policy/xds/xds.cc | 225 ++++++++++++--- .../client_channel/resolving_lb_policy.cc | 270 ++++++++++++++---- .../client_channel/resolving_lb_policy.h | 13 +- 4 files changed, 417 insertions(+), 97 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index d6dde0d7a79..184215a3da9 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -307,7 +307,7 @@ class GrpcLb : public LoadBalancingPolicy { // Methods for dealing with the child policy. grpc_channel_args* CreateChildPolicyArgsLocked(); OrphanablePtr CreateChildPolicyLocked( - const char* name, grpc_channel_args* args); + const char* name, const grpc_channel_args* args); void CreateOrUpdateChildPolicyLocked(); // Who the client is trying to communicate with. @@ -685,7 +685,7 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, void GrpcLb::Helper::RequestReresolution() { if (parent_->shutting_down_) return; // If there is a pending child policy, ignore re-resolution requests - // from the current child policy (or any outdated pending child). + // from the current child policy (or any outdated child). if (parent_->pending_child_policy_ != nullptr && !CalledByPendingChild()) { return; } @@ -1608,7 +1608,7 @@ grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked() { } OrphanablePtr GrpcLb::CreateChildPolicyLocked( - const char* name, grpc_channel_args* args) { + const char* name, const grpc_channel_args* args) { Helper* helper = New(Ref()); LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index a9ca34e5a52..4b386d37797 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -278,8 +278,14 @@ class XdsLb : public LoadBalancingPolicy { UniquePtr picker) override; void RequestReresolution() override; + void set_child(LoadBalancingPolicy* child) { child_ = child; } + private: + bool CalledByPendingChild() const; + bool CalledByCurrentChild() const; + RefCountedPtr parent_; + LoadBalancingPolicy* child_ = nullptr; }; ~XdsLb(); @@ -306,7 +312,8 @@ class XdsLb : public LoadBalancingPolicy { // Methods for dealing with the child policy. void CreateOrUpdateChildPolicyLocked(); grpc_channel_args* CreateChildPolicyArgsLocked(); - void CreateChildPolicyLocked(const char* name, Args args); + OrphanablePtr CreateChildPolicyLocked( + const char* name, const grpc_channel_args* args); // Who the client is trying to communicate with. const char* server_name_ = nullptr; @@ -349,6 +356,10 @@ class XdsLb : public LoadBalancingPolicy { // The policy to use for the backends. RefCountedPtr child_policy_config_; OrphanablePtr child_policy_; + OrphanablePtr pending_child_policy_; + // Lock held when modifying the value of child_policy_ or + // pending_child_policy_. + gpr_mu child_policy_mu_; }; // @@ -372,14 +383,30 @@ XdsLb::Picker::PickResult XdsLb::Picker::Pick(PickState* pick, // XdsLb::Helper // +bool XdsLb::Helper::CalledByPendingChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->pending_child_policy_.get(); +} + +bool XdsLb::Helper::CalledByCurrentChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->child_policy_.get(); +} + Subchannel* XdsLb::Helper::CreateSubchannel(const grpc_channel_args& args) { - if (parent_->shutting_down_) return nullptr; + if (parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return nullptr; + } return parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* XdsLb::Helper::CreateChannel(const char* target, const grpc_channel_args& args) { - if (parent_->shutting_down_) return nullptr; + if (parent_->shutting_down_ || + (!CalledByPendingChild() && !CalledByCurrentChild())) { + return nullptr; + } return parent_->channel_control_helper()->CreateChannel(target, args); } @@ -390,6 +417,26 @@ void XdsLb::Helper::UpdateState(grpc_connectivity_state state, GRPC_ERROR_UNREF(state_error); return; } + // If this request is from the pending child policy, ignore it until + // it reports READY, at which point we swap it into place. + if (CalledByPendingChild()) { + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, + "[xdslb %p helper %p] pending child policy %p reports state=%s", + parent_.get(), this, parent_->pending_child_policy_.get(), + grpc_connectivity_state_name(state)); + } + if (state != GRPC_CHANNEL_READY) { + GRPC_ERROR_UNREF(state_error); + return; + } + MutexLock lock(&parent_->child_policy_mu_); + parent_->child_policy_ = std::move(parent_->pending_child_policy_); + } else if (!CalledByCurrentChild()) { + // This request is from an outdated child, so ignore it. + GRPC_ERROR_UNREF(state_error); + return; + } // TODO(juanlishen): When in fallback mode, pass the child picker // through without wrapping it. (Or maybe use a different helper for // the fallback policy?) @@ -406,6 +453,11 @@ void XdsLb::Helper::UpdateState(grpc_connectivity_state state, void XdsLb::Helper::RequestReresolution() { if (parent_->shutting_down_) return; + // If there is a pending child policy, ignore re-resolution requests + // from the current child policy (or any outdated child). + if (parent_->pending_child_policy_ != nullptr && !CalledByPendingChild()) { + return; + } if (grpc_lb_xds_trace.enabled()) { gpr_log(GPR_INFO, "[xdslb %p] Re-resolution requested from the internal RR policy " @@ -1064,6 +1116,7 @@ grpc_channel_args* BuildBalancerChannelArgs(const grpc_channel_args* args) { XdsLb::XdsLb(Args args) : LoadBalancingPolicy(std::move(args)) { gpr_mu_init(&lb_chand_mu_); + gpr_mu_init(&child_policy_mu_); // Record server name. const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI); const char* server_uri = grpc_channel_arg_get_string(arg); @@ -1093,6 +1146,7 @@ XdsLb::~XdsLb() { if (serverlist_ != nullptr) { xds_grpclb_destroy_serverlist(serverlist_); } + gpr_mu_destroy(&child_policy_mu_); } void XdsLb::ShutdownLocked() { @@ -1100,7 +1154,11 @@ void XdsLb::ShutdownLocked() { if (fallback_timer_callback_pending_) { grpc_timer_cancel(&lb_fallback_timer_); } - child_policy_.reset(); + { + MutexLock lock(&child_policy_mu_); + child_policy_.reset(); + pending_child_policy_.reset(); + } // We destroy the LB channel here instead of in our destructor because // destroying the channel triggers a last callback to // OnBalancerChannelConnectivityChangedLocked(), and we need to be @@ -1126,12 +1184,27 @@ void XdsLb::ResetBackoffLocked() { if (child_policy_ != nullptr) { child_policy_->ResetBackoffLocked(); } + if (pending_child_policy_ != nullptr) { + pending_child_policy_->ResetBackoffLocked(); + } } void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { - // Delegate to the child_policy_ to fill the children subchannels. - child_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); + { + // Delegate to the child_policy_ to fill the children subchannels. + // This must be done holding child_policy_mu_, since this method does not + // run in the combiner. + MutexLock lock(&child_policy_mu_); + if (child_policy_ != nullptr) { + child_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } + if (pending_child_policy_ != nullptr) { + pending_child_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } + } MutexLock lock(&lb_chand_mu_); if (lb_chand_ != nullptr) { grpc_core::channelz::ChannelNode* channel_node = @@ -1312,48 +1385,136 @@ grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { GPR_ARRAY_SIZE(args_to_add)); } -void XdsLb::CreateChildPolicyLocked(const char* name, Args args) { - GPR_ASSERT(child_policy_ == nullptr); - child_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - name, std::move(args)); - if (GPR_UNLIKELY(child_policy_ == nullptr)) { - gpr_log(GPR_ERROR, "[xdslb %p] Failure creating a child policy", this); - return; +OrphanablePtr XdsLb::CreateChildPolicyLocked( + const char* name, const grpc_channel_args* args) { + Helper* helper = New(Ref()); + LoadBalancingPolicy::Args lb_policy_args; + lb_policy_args.combiner = combiner(); + lb_policy_args.args = args; + lb_policy_args.channel_control_helper = + UniquePtr(helper); + OrphanablePtr lb_policy = + LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + name, std::move(lb_policy_args)); + if (GPR_UNLIKELY(lb_policy == nullptr)) { + gpr_log(GPR_ERROR, "[xdslb %p] Failure creating child policy %s", this, + name); + return nullptr; + } + helper->set_child(lb_policy.get()); + if (grpc_lb_xds_trace.enabled()) { + gpr_log(GPR_INFO, "[xdslb %p] Created new child policy %s (%p)", this, name, + lb_policy.get()); } // Add the xDS's interested_parties pollset_set to that of the newly created - // child policy. This will make the child policy progress upon activity on - // xDS LB, which in turn is tied to the application's call. - grpc_pollset_set_add_pollset_set(child_policy_->interested_parties(), + // child policy. This will make the child policy progress upon activity on xDS + // LB, which in turn is tied to the application's call. + grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(), interested_parties()); + return lb_policy; } void XdsLb::CreateOrUpdateChildPolicyLocked() { if (shutting_down_) return; grpc_channel_args* args = CreateChildPolicyArgsLocked(); GPR_ASSERT(args != nullptr); + // If the child policy name changes, we need to create a new child + // policy. When this happens, we leave child_policy_ as-is and store + // the new child policy in pending_child_policy_. Once the new child + // policy transitions into state READY, we swap it into child_policy_, + // replacing the original child policy. So pending_child_policy_ is + // non-null only between when we apply an update that changes the child + // policy name and when the new child reports state READY. + // + // Updates can arrive at any point during this transition. We always + // apply updates relative to the most recently created child policy, + // even if the most recent one is still in pending_child_policy_. This + // is true both when applying the updates to an existing child policy + // and when determining whether we need to create a new policy. + // + // As a result of this, there are several cases to consider here: + // + // 1. We have no existing child policy (i.e., we have started up but + // have not yet received a serverlist from the balancer or gone + // into fallback mode; in this case, both child_policy_ and + // pending_child_policy_ are null). In this case, we create a + // new child policy and store it in child_policy_. + // + // 2. We have an existing child policy and have no pending child policy + // from a previous update (i.e., either there has not been a + // previous update that changed the policy name, or we have already + // finished swapping in the new policy; in this case, child_policy_ + // is non-null but pending_child_policy_ is null). In this case: + // a. If child_policy_->name() equals child_policy_name, then we + // update the existing child policy. + // b. If child_policy_->name() does not equal child_policy_name, + // we create a new policy. The policy will be stored in + // pending_child_policy_ and will later be swapped into + // child_policy_ by the helper when the new child transitions + // into state READY. + // + // 3. We have an existing child policy and have a pending child policy + // from a previous update (i.e., a previous update set + // pending_child_policy_ as per case 2b above and that policy has + // not yet transitioned into state READY and been swapped into + // child_policy_; in this case, both child_policy_ and + // pending_child_policy_ are non-null). In this case: + // a. If pending_child_policy_->name() equals child_policy_name, + // then we update the existing pending child policy. + // b. If pending_child_policy->name() does not equal + // child_policy_name, then we create a new policy. The new + // policy is stored in pending_child_policy_ (replacing the one + // that was there before, which will be immediately shut down) + // and will later be swapped into child_policy_ by the helper + // when the new child transitions into state READY. // TODO(juanlishen): If the child policy is not configured via service config, // use whatever algorithm is specified by the balancer. - // TODO(juanlishen): Switch policy according to child_policy_config_->name(). - if (child_policy_ == nullptr) { - LoadBalancingPolicy::Args lb_policy_args; - lb_policy_args.combiner = combiner(); - lb_policy_args.args = args; - lb_policy_args.channel_control_helper = - UniquePtr(New(Ref())); - CreateChildPolicyLocked(child_policy_config_ == nullptr - ? "round_robin" - : child_policy_config_->name(), - std::move(lb_policy_args)); + const char* child_policy_name = child_policy_config_ == nullptr + ? "round_robin" + : child_policy_config_->name(); + const bool create_policy = + // case 1 + child_policy_ == nullptr || + // case 2b + (pending_child_policy_ == nullptr && + strcmp(child_policy_->name(), child_policy_name) != 0) || + // case 3b + (pending_child_policy_ != nullptr && + strcmp(pending_child_policy_->name(), child_policy_name) != 0); + LoadBalancingPolicy* policy_to_update = nullptr; + if (create_policy) { + // Cases 1, 2b, and 3b: create a new child policy. + // If child_policy_ is null, we set it (case 1), else we set + // pending_child_policy_ (cases 2b and 3b). if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Created a new child policy %p", this, - child_policy_.get()); + gpr_log(GPR_INFO, "[xdslb %p] Creating new %schild policy %s", this, + child_policy_ == nullptr ? "" : "pending ", child_policy_name); } + auto new_policy = CreateChildPolicyLocked(child_policy_name, args); + auto& lb_policy = + child_policy_ == nullptr ? child_policy_ : pending_child_policy_; + { + MutexLock lock(&child_policy_mu_); + lb_policy = std::move(new_policy); + } + policy_to_update = lb_policy.get(); + } else { + // Cases 2a and 3a: update an existing policy. + // If we have a pending child policy, send the update to the pending + // policy (case 3a), else send it to the current policy (case 2a). + policy_to_update = pending_child_policy_ != nullptr + ? pending_child_policy_.get() + : child_policy_.get(); } + GPR_ASSERT(policy_to_update != nullptr); + // Update the policy. if (grpc_lb_xds_trace.enabled()) { - gpr_log(GPR_INFO, "[xdslb %p] Updating child policy %p", this, - child_policy_.get()); + gpr_log(GPR_INFO, "[xdslb %p] Updating %schild policy %p", this, + policy_to_update == pending_child_policy_.get() ? "pending " : "", + policy_to_update); } - child_policy_->UpdateLocked(*args, child_policy_config_); + policy_to_update->UpdateLocked(*args, child_policy_config_); + // Clean up. grpc_channel_args_destroy(args); } diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index a02a7e8acdb..0dd51e8bc4c 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -47,6 +47,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/polling_entity.h" @@ -77,12 +78,14 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper Subchannel* CreateSubchannel(const grpc_channel_args& args) override { if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. + if (!CalledByCurrentChild() && !CalledByPendingChild()) return nullptr; return parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override { if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. + if (!CalledByCurrentChild() && !CalledByPendingChild()) return nullptr; return parent_->channel_control_helper()->CreateChannel(target, args); } @@ -93,11 +96,37 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper GRPC_ERROR_UNREF(state_error); return; } + // If this request is from the pending child policy, ignore it until + // it reports READY, at which point we swap it into place. + if (CalledByPendingChild()) { + if (parent_->tracer_->enabled()) { + gpr_log(GPR_INFO, + "resolving_lb=%p helper=%p: pending child policy %p reports " + "state=%s", + parent_.get(), this, child_, + grpc_connectivity_state_name(state)); + } + if (state != GRPC_CHANNEL_READY) { + GRPC_ERROR_UNREF(state_error); + return; + } + MutexLock lock(&parent_->lb_policy_mu_); + parent_->lb_policy_ = std::move(parent_->pending_lb_policy_); + } else if (!CalledByCurrentChild()) { + // This request is from an outdated child, so ignore it. + GRPC_ERROR_UNREF(state_error); + return; + } parent_->channel_control_helper()->UpdateState(state, state_error, std::move(picker)); } void RequestReresolution() override { + // If there is a pending child policy, ignore re-resolution requests + // from the current child policy (or any outdated child). + if (parent_->pending_lb_policy_ != nullptr && !CalledByPendingChild()) { + return; + } if (parent_->tracer_->enabled()) { gpr_log(GPR_INFO, "resolving_lb=%p: started name re-resolving", parent_.get()); @@ -107,8 +136,21 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper } } + void set_child(LoadBalancingPolicy* child) { child_ = child; } + private: + bool CalledByPendingChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->pending_lb_policy_.get(); + } + + bool CalledByCurrentChild() const { + GPR_ASSERT(child_ != nullptr); + return child_ == parent_->lb_policy_.get(); + }; + RefCountedPtr parent_; + LoadBalancingPolicy* child_ = nullptr; }; // @@ -146,6 +188,7 @@ ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( process_resolver_result_(process_resolver_result), process_resolver_result_user_data_(process_resolver_result_user_data) { GPR_ASSERT(process_resolver_result != nullptr); + gpr_mu_init(&lb_policy_mu_); *error = Init(*args.args); } @@ -169,22 +212,38 @@ grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) { ResolvingLoadBalancingPolicy::~ResolvingLoadBalancingPolicy() { GPR_ASSERT(resolver_ == nullptr); GPR_ASSERT(lb_policy_ == nullptr); + gpr_mu_destroy(&lb_policy_mu_); } void ResolvingLoadBalancingPolicy::ShutdownLocked() { if (resolver_ != nullptr) { resolver_.reset(); + MutexLock lock(&lb_policy_mu_); if (lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, + lb_policy_.get()); + } grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), interested_parties()); lb_policy_.reset(); } + if (pending_lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down pending lb_policy=%p", + this, pending_lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(pending_lb_policy_->interested_parties(), + interested_parties()); + pending_lb_policy_.reset(); + } } } void ResolvingLoadBalancingPolicy::ExitIdleLocked() { if (lb_policy_ != nullptr) { lb_policy_->ExitIdleLocked(); + if (pending_lb_policy_ != nullptr) pending_lb_policy_->ExitIdleLocked(); } else { if (!started_resolving_ && resolver_ != nullptr) { StartResolvingLocked(); @@ -197,17 +256,24 @@ void ResolvingLoadBalancingPolicy::ResetBackoffLocked() { resolver_->ResetBackoffLocked(); resolver_->RequestReresolutionLocked(); } - if (lb_policy_ != nullptr) { - lb_policy_->ResetBackoffLocked(); - } + if (lb_policy_ != nullptr) lb_policy_->ResetBackoffLocked(); + if (pending_lb_policy_ != nullptr) pending_lb_policy_->ResetBackoffLocked(); } void ResolvingLoadBalancingPolicy::FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) { + // Delegate to the lb_policy_ to fill the children subchannels. + // This must be done holding lb_policy_mu_, since this method does not + // run in the combiner. + MutexLock lock(&lb_policy_mu_); if (lb_policy_ != nullptr) { lb_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); } + if (pending_lb_policy_ != nullptr) { + pending_lb_policy_->FillChildRefsForChannelz(child_subchannels, + child_channels); + } } void ResolvingLoadBalancingPolicy::StartResolvingLocked() { @@ -229,14 +295,26 @@ void ResolvingLoadBalancingPolicy::OnResolverShutdownLocked(grpc_error* error) { if (tracer_->enabled()) { gpr_log(GPR_INFO, "resolving_lb=%p: shutting down", this); } - if (lb_policy_ != nullptr) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, - lb_policy_.get()); + { + MutexLock lock(&lb_policy_mu_); + if (lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, + lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), + interested_parties()); + lb_policy_.reset(); + } + if (pending_lb_policy_ != nullptr) { + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: shutting down pending lb_policy=%p", + this, pending_lb_policy_.get()); + } + grpc_pollset_set_del_pollset_set(pending_lb_policy_->interested_parties(), + interested_parties()); + pending_lb_policy_.reset(); } - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties()); - lb_policy_.reset(); } if (resolver_ != nullptr) { // This should never happen; it can only be triggered by a resolver @@ -260,53 +338,142 @@ void ResolvingLoadBalancingPolicy::OnResolverShutdownLocked(grpc_error* error) { Unref(); } -// Creates a new LB policy, replacing any previous one. +void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( + const char* lb_policy_name, RefCountedPtr lb_policy_config, + TraceStringVector* trace_strings) { + // If the child policy name changes, we need to create a new child + // policy. When this happens, we leave child_policy_ as-is and store + // the new child policy in pending_child_policy_. Once the new child + // policy transitions into state READY, we swap it into child_policy_, + // replacing the original child policy. So pending_child_policy_ is + // non-null only between when we apply an update that changes the child + // policy name and when the new child reports state READY. + // + // Updates can arrive at any point during this transition. We always + // apply updates relative to the most recently created child policy, + // even if the most recent one is still in pending_child_policy_. This + // is true both when applying the updates to an existing child policy + // and when determining whether we need to create a new policy. + // + // As a result of this, there are several cases to consider here: + // + // 1. We have no existing child policy (i.e., we have started up but + // have not yet received a serverlist from the balancer or gone + // into fallback mode; in this case, both child_policy_ and + // pending_child_policy_ are null). In this case, we create a + // new child policy and store it in child_policy_. + // + // 2. We have an existing child policy and have no pending child policy + // from a previous update (i.e., either there has not been a + // previous update that changed the policy name, or we have already + // finished swapping in the new policy; in this case, child_policy_ + // is non-null but pending_child_policy_ is null). In this case: + // a. If child_policy_->name() equals child_policy_name, then we + // update the existing child policy. + // b. If child_policy_->name() does not equal child_policy_name, + // we create a new policy. The policy will be stored in + // pending_child_policy_ and will later be swapped into + // child_policy_ by the helper when the new child transitions + // into state READY. + // + // 3. We have an existing child policy and have a pending child policy + // from a previous update (i.e., a previous update set + // pending_child_policy_ as per case 2b above and that policy has + // not yet transitioned into state READY and been swapped into + // child_policy_; in this case, both child_policy_ and + // pending_child_policy_ are non-null). In this case: + // a. If pending_child_policy_->name() equals child_policy_name, + // then we update the existing pending child policy. + // b. If pending_child_policy->name() does not equal + // child_policy_name, then we create a new policy. The new + // policy is stored in pending_child_policy_ (replacing the one + // that was there before, which will be immediately shut down) + // and will later be swapped into child_policy_ by the helper + // when the new child transitions into state READY. + const bool create_policy = + // case 1 + lb_policy_ == nullptr || + // case 2b + (pending_lb_policy_ == nullptr && + strcmp(lb_policy_->name(), lb_policy_name) != 0) || + // case 3b + (pending_lb_policy_ != nullptr && + strcmp(pending_lb_policy_->name(), lb_policy_name) != 0); + LoadBalancingPolicy* policy_to_update = nullptr; + if (create_policy) { + // Cases 1, 2b, and 3b: create a new child policy. + // If lb_policy_ is null, we set it (case 1), else we set + // pending_lb_policy_ (cases 2b and 3b). + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: Creating new %schild policy %s", this, + lb_policy_ == nullptr ? "" : "pending ", lb_policy_name); + } + auto new_policy = CreateLbPolicyLocked(lb_policy_name, trace_strings); + auto& lb_policy = lb_policy_ == nullptr ? lb_policy_ : pending_lb_policy_; + { + MutexLock lock(&lb_policy_mu_); + lb_policy = std::move(new_policy); + } + policy_to_update = lb_policy.get(); + } else { + // Cases 2a and 3a: update an existing policy. + // If we have a pending child policy, send the update to the pending + // policy (case 3a), else send it to the current policy (case 2a). + policy_to_update = pending_lb_policy_ != nullptr ? pending_lb_policy_.get() + : lb_policy_.get(); + } + GPR_ASSERT(policy_to_update != nullptr); + // Update the policy. + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: Updating %schild policy %p", this, + policy_to_update == pending_lb_policy_.get() ? "pending " : "", + policy_to_update); + } + policy_to_update->UpdateLocked(*resolver_result_, + std::move(lb_policy_config)); +} + +// Creates a new LB policy. // Updates trace_strings to indicate what was done. -void ResolvingLoadBalancingPolicy::CreateNewLbPolicyLocked( +OrphanablePtr +ResolvingLoadBalancingPolicy::CreateLbPolicyLocked( const char* lb_policy_name, TraceStringVector* trace_strings) { + ResolvingControlHelper* helper = New(Ref()); LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); lb_policy_args.channel_control_helper = - UniquePtr(New(Ref())); + UniquePtr(helper); lb_policy_args.args = resolver_result_; - OrphanablePtr new_lb_policy = + OrphanablePtr lb_policy = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( lb_policy_name, std::move(lb_policy_args)); - if (GPR_UNLIKELY(new_lb_policy == nullptr)) { + if (GPR_UNLIKELY(lb_policy == nullptr)) { gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); if (channelz_node() != nullptr) { char* str; gpr_asprintf(&str, "Could not create LB policy \"%s\"", lb_policy_name); trace_strings->push_back(str); } - } else { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: created new LB policy \"%s\" (%p)", - this, lb_policy_name, new_lb_policy.get()); - } - if (channelz_node() != nullptr) { - char* str; - gpr_asprintf(&str, "Created new LB policy \"%s\"", lb_policy_name); - trace_strings->push_back(str); - } - // Propagate channelz node. - auto* channelz = channelz_node(); - if (channelz != nullptr) { - new_lb_policy->set_channelz_node(channelz->Ref()); - } - // Swap out the LB policy and update the fds in interested_parties_. - if (lb_policy_ != nullptr) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, - lb_policy_.get()); - } - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties()); - } - lb_policy_ = std::move(new_lb_policy); - grpc_pollset_set_add_pollset_set(lb_policy_->interested_parties(), - interested_parties()); + return nullptr; } + helper->set_child(lb_policy.get()); + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: created new LB policy \"%s\" (%p)", + this, lb_policy_name, lb_policy.get()); + } + if (channelz_node() != nullptr) { + char* str; + gpr_asprintf(&str, "Created new LB policy \"%s\"", lb_policy_name); + trace_strings->push_back(str); + } + // Propagate channelz node. + auto* channelz = channelz_node(); + if (channelz != nullptr) { + lb_policy->set_channelz_node(channelz->Ref()); + } + grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(), + interested_parties()); + return lb_policy; } void ResolvingLoadBalancingPolicy::MaybeAddTraceMessagesForAddressChangesLocked( @@ -415,23 +582,8 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( lb_policy_config = self->child_lb_config_; } GPR_ASSERT(lb_policy_name != nullptr); - // If we're not already using the right LB policy name, instantiate - // a new one. - if (self->lb_policy_ == nullptr || - strcmp(self->lb_policy_->name(), lb_policy_name) != 0) { - if (self->tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: creating new LB policy \"%s\"", - self, lb_policy_name); - } - self->CreateNewLbPolicyLocked(lb_policy_name, &trace_strings); - } - // Update the LB policy with the new addresses and config. - if (self->tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: updating LB policy \"%s\" (%p)", self, - lb_policy_name, self->lb_policy_.get()); - } - self->lb_policy_->UpdateLocked(*self->resolver_result_, - std::move(lb_policy_config)); + self->CreateOrUpdateLbPolicyLocked( + lb_policy_name, std::move(lb_policy_config), &trace_strings); // Add channel trace event. if (self->channelz_node() != nullptr) { if (service_config_changed) { diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index d068a41f96f..b8f406da1b6 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -102,8 +102,11 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void StartResolvingLocked(); void OnResolverShutdownLocked(grpc_error* error); - void CreateNewLbPolicyLocked(const char* lb_policy_name, - TraceStringVector* trace_strings); + void CreateOrUpdateLbPolicyLocked(const char* lb_policy_name, + RefCountedPtr, + TraceStringVector* trace_strings); + OrphanablePtr CreateLbPolicyLocked( + const char* lb_policy_name, TraceStringVector* trace_strings); void MaybeAddTraceMessagesForAddressChangesLocked( TraceStringVector* trace_strings); void ConcatenateAndAddChannelTraceLocked( @@ -125,8 +128,12 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { bool previous_resolution_contained_addresses_ = false; grpc_closure on_resolver_result_changed_; - // Child LB policy and associated state. + // Child LB policy. OrphanablePtr lb_policy_; + OrphanablePtr pending_lb_policy_; + // Lock held when modifying the value of child_policy_ or + // pending_child_policy_. + gpr_mu lb_policy_mu_; }; } // namespace grpc_core From 8878712aebf67d366112b1f80ace2a3015d73b45 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 7 Mar 2019 13:02:04 -0800 Subject: [PATCH 618/814] Split client_channel tracer into two. --- doc/environment_variables.md | 5 +- .../filters/client_channel/client_channel.cc | 116 +++++++++--------- 2 files changed, 63 insertions(+), 58 deletions(-) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index 435edbcfdb4..635c5ee535f 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -45,8 +45,9 @@ some configuration as environment variables that can be set. - cares_address_sorting - traces operations of the c-ares based DNS resolver's resolved address sorter - channel - traces operations on the C core channel stack - - client_channel - traces client channel activity, including resolver - and load balancing policy interaction + - client_channel_call - traces client channel call batch activity + - client_channel_routing - traces client channel call routing, including + resolver and load balancing policy interaction - compression - traces compression operations - connectivity_state - traces connectivity state changes to channels - executor - traces grpc's internal thread pool ('the executor') diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 3f87438b13b..ad00855be71 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -82,7 +82,10 @@ using grpc_core::LoadBalancingPolicy; // any even moderately compelling reason to do so. #define RETRY_BACKOFF_JITTER 0.2 -grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel"); +grpc_core::TraceFlag grpc_client_channel_call_trace(false, + "client_channel_call"); +grpc_core::TraceFlag grpc_client_channel_routing_trace( + false, "client_channel_routing"); /************************************************************************* * CHANNEL-WIDE FUNCTIONS @@ -219,7 +222,7 @@ class ClientChannelControlHelper void UpdateState( grpc_connectivity_state state, grpc_error* state_error, UniquePtr picker) override { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_routing_trace.enabled()) { const char* extra = chand_->disconnect_error == GRPC_ERROR_NONE ? "" : " (ignoring -- channel shutting down)"; @@ -256,7 +259,7 @@ static bool process_resolver_result_locked( ProcessedResolverResult resolver_result(args, chand->enable_retries); grpc_core::UniquePtr service_config_json = resolver_result.service_config_json(); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", chand, service_config_json.get()); } @@ -460,8 +463,9 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, grpc_error* error = GRPC_ERROR_NONE; chand->resolving_lb_policy.reset( grpc_core::New( - std::move(lb_args), &grpc_client_channel_trace, std::move(target_uri), - process_resolver_result_locked, chand, &error)); + std::move(lb_args), &grpc_client_channel_routing_trace, + std::move(target_uri), process_resolver_result_locked, chand, + &error)); grpc_channel_args_destroy(new_args); if (error != GRPC_ERROR_NONE) { // Orphan the resolving LB policy and flush the exec_ctx to ensure @@ -480,7 +484,7 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, grpc_pollset_set_add_pollset_set( chand->resolving_lb_policy->interested_parties(), chand->interested_parties); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", chand, chand->resolving_lb_policy.get()); } @@ -856,7 +860,7 @@ static void maybe_cache_send_ops_for_batch(call_data* calld, // Frees cached send_initial_metadata. static void free_cached_send_initial_metadata(channel_data* chand, call_data* calld) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: destroying calld->send_initial_metadata", chand, calld); @@ -867,7 +871,7 @@ static void free_cached_send_initial_metadata(channel_data* chand, // Frees cached send_message at index idx. static void free_cached_send_message(channel_data* chand, call_data* calld, size_t idx) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: destroying calld->send_messages[%" PRIuPTR "]", chand, calld, idx); @@ -878,7 +882,7 @@ static void free_cached_send_message(channel_data* chand, call_data* calld, // Frees cached send_trailing_metadata. static void free_cached_send_trailing_metadata(channel_data* chand, call_data* calld) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: destroying calld->send_trailing_metadata", chand, calld); @@ -964,7 +968,7 @@ static void pending_batches_add(grpc_call_element* elem, channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); const size_t idx = get_batch_index(batch); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: adding pending batch at index %" PRIuPTR, chand, calld, idx); @@ -993,7 +997,7 @@ static void pending_batches_add(grpc_call_element* elem, } if (GPR_UNLIKELY(calld->bytes_buffered_for_retry > chand->per_rpc_retry_buffer_size)) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: exceeded retry buffer size, committing", chand, calld); @@ -1008,7 +1012,7 @@ static void pending_batches_add(grpc_call_element* elem, // If we are not going to retry and have not yet started, pretend // retries are disabled so that we don't bother with retry overhead. if (calld->num_attempts_completed == 0) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: disabling retries before first attempt", chand, calld); @@ -1066,7 +1070,7 @@ static void pending_batches_fail( YieldCallCombinerPredicate yield_call_combiner_predicate) { GPR_ASSERT(error != GRPC_ERROR_NONE); call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { size_t num_batches = 0; for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { if (calld->pending_batches[i].batch != nullptr) ++num_batches; @@ -1121,7 +1125,7 @@ static void pending_batches_resume(grpc_call_element* elem) { return; } // Retries not enabled; send down batches as-is. - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { size_t num_batches = 0; for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { if (calld->pending_batches[i].batch != nullptr) ++num_batches; @@ -1169,7 +1173,7 @@ static void maybe_clear_pending_batch(grpc_call_element* elem, (!batch->recv_trailing_metadata || batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready == nullptr)) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: clearing pending batch", chand, calld); } @@ -1189,7 +1193,7 @@ static pending_batch* pending_batch_find(grpc_call_element* elem, pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr && predicate(batch)) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: %s pending batch at index %" PRIuPTR, chand, calld, log_message, i); @@ -1211,7 +1215,7 @@ static void retry_commit(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); if (calld->retry_committed) return; calld->retry_committed = true; - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: committing retries", chand, calld); } if (retry_state != nullptr) { @@ -1250,7 +1254,7 @@ static void do_retry(grpc_call_element* elem, } next_attempt_time = calld->retry_backoff->NextAttemptTime(); } - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: retrying failed call in %" PRId64 " ms", chand, calld, next_attempt_time - grpc_core::ExecCtx::Get()->Now()); @@ -1283,7 +1287,7 @@ static bool maybe_retry(grpc_call_element* elem, retry_state = static_cast( batch_data->subchannel_call->GetParentData()); if (retry_state->retry_dispatched) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: retry already dispatched", chand, calld); } @@ -1295,14 +1299,14 @@ static bool maybe_retry(grpc_call_element* elem, if (calld->retry_throttle_data != nullptr) { calld->retry_throttle_data->RecordSuccess(); } - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: call succeeded", chand, calld); } return false; } // Status is not OK. Check whether the status is retryable. if (!retry_policy->retryable_status_codes.Contains(status)) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: status %s not configured as retryable", chand, calld, grpc_status_code_to_string(status)); @@ -1318,14 +1322,14 @@ static bool maybe_retry(grpc_call_element* elem, // checks, so that we don't fail to record failures due to other factors. if (calld->retry_throttle_data != nullptr && !calld->retry_throttle_data->RecordFailure()) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: retries throttled", chand, calld); } return false; } // Check whether the call is committed. if (calld->retry_committed) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: retries already committed", chand, calld); } @@ -1334,7 +1338,7 @@ static bool maybe_retry(grpc_call_element* elem, // Check whether we have retries remaining. ++calld->num_attempts_completed; if (calld->num_attempts_completed >= retry_policy->max_attempts) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: exceeded %d retry attempts", chand, calld, retry_policy->max_attempts); } @@ -1342,7 +1346,7 @@ static bool maybe_retry(grpc_call_element* elem, } // If the call was cancelled from the surface, don't retry. if (calld->cancel_error != GRPC_ERROR_NONE) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: call cancelled from surface, not retrying", chand, calld); @@ -1355,14 +1359,14 @@ static bool maybe_retry(grpc_call_element* elem, // If the value is "-1" or any other unparseable string, we do not retry. uint32_t ms; if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(*server_pushback_md), &ms)) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: not retrying due to server push-back", chand, calld); } return false; } else { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: server push-back: retry in %u ms", chand, calld, ms); } @@ -1484,7 +1488,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { grpc_call_element* elem = batch_data->elem; channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: got recv_initial_metadata_ready, error=%s", chand, calld, grpc_error_string(error)); @@ -1508,7 +1512,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { if (GPR_UNLIKELY((retry_state->trailing_metadata_available || error != GRPC_ERROR_NONE) && !retry_state->completed_recv_trailing_metadata)) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: deferring recv_initial_metadata_ready " "(Trailers-Only)", @@ -1574,7 +1578,7 @@ static void recv_message_ready(void* arg, grpc_error* error) { grpc_call_element* elem = batch_data->elem; channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: got recv_message_ready, error=%s", chand, calld, grpc_error_string(error)); } @@ -1596,7 +1600,7 @@ static void recv_message_ready(void* arg, grpc_error* error) { if (GPR_UNLIKELY( (retry_state->recv_message == nullptr || error != GRPC_ERROR_NONE) && !retry_state->completed_recv_trailing_metadata)) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: deferring recv_message_ready (nullptr " "message and recv_trailing_metadata pending)", @@ -1748,7 +1752,7 @@ static void add_closures_to_fail_unstarted_pending_batches( for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) { pending_batch* pending = &calld->pending_batches[i]; if (pending_batch_is_unstarted(pending, calld, retry_state)) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: failing unstarted pending batch at index " "%" PRIuPTR, @@ -1797,7 +1801,7 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { grpc_call_element* elem = batch_data->elem; channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: got recv_trailing_metadata_ready, error=%s", chand, calld, grpc_error_string(error)); @@ -1813,7 +1817,7 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata; get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, &server_pushback_md); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: call finished, status=%s", chand, calld, grpc_status_code_to_string(status)); } @@ -1899,7 +1903,7 @@ static void add_closures_for_replay_or_pending_send_ops( } } if (have_pending_send_message_ops || have_pending_send_trailing_metadata_op) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting next batch for pending send op(s)", chand, calld); @@ -1919,7 +1923,7 @@ static void on_complete(void* arg, grpc_error* error) { grpc_call_element* elem = batch_data->elem; channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { char* batch_str = grpc_transport_stream_op_batch_string(&batch_data->batch); gpr_log(GPR_INFO, "chand=%p calld=%p: got on_complete, error=%s, batch=%s", chand, calld, grpc_error_string(error), batch_str); @@ -1999,7 +2003,7 @@ static void add_closure_for_subchannel_batch( GRPC_CLOSURE_INIT(&batch->handler_private.closure, start_batch_in_call_combiner, batch, grpc_schedule_on_exec_ctx); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { char* batch_str = grpc_transport_stream_op_batch_string(batch); gpr_log(GPR_INFO, "chand=%p calld=%p: starting subchannel batch: %s", chand, calld, batch_str); @@ -2067,7 +2071,7 @@ static void add_retriable_send_message_op( subchannel_batch_data* batch_data) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting calld->send_messages[%" PRIuPTR "]", chand, calld, retry_state->started_send_message_count); @@ -2161,7 +2165,7 @@ static void add_retriable_recv_trailing_metadata_op( static void start_internal_recv_trailing_metadata(grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: call failed but recv_trailing_metadata not " "started; starting it internally", @@ -2194,7 +2198,7 @@ static subchannel_batch_data* maybe_create_subchannel_batch_for_replay( if (calld->seen_send_initial_metadata && !retry_state->started_send_initial_metadata && !calld->pending_send_initial_metadata) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: replaying previously completed " "send_initial_metadata op", @@ -2210,7 +2214,7 @@ static subchannel_batch_data* maybe_create_subchannel_batch_for_replay( retry_state->started_send_message_count == retry_state->completed_send_message_count && !calld->pending_send_message) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: replaying previously completed " "send_message op", @@ -2230,7 +2234,7 @@ static subchannel_batch_data* maybe_create_subchannel_batch_for_replay( retry_state->started_send_message_count == calld->send_messages.size() && !retry_state->started_send_trailing_metadata && !calld->pending_send_trailing_metadata) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: replaying previously completed " "send_trailing_metadata op", @@ -2380,7 +2384,7 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { grpc_call_element* elem = static_cast(arg); channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: constructing retriable batches", chand, calld); } @@ -2405,7 +2409,7 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { // Now add pending batches. add_subchannel_batches_for_pending_batches(elem, retry_state, &closures); // Start batches on subchannel call. - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting %" PRIuPTR " retriable batches on subchannel_call=%p", @@ -2439,7 +2443,7 @@ static void create_subchannel_call(grpc_call_element* elem) { grpc_error* error = GRPC_ERROR_NONE; calld->subchannel_call = calld->pick.pick.connected_subchannel->CreateCall(call_args, &error); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, calld, calld->subchannel_call.get(), grpc_error_string(error)); @@ -2461,7 +2465,7 @@ static void pick_done(void* arg, grpc_error* error) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); if (error != GRPC_ERROR_NONE) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: failed to pick subchannel: error=%s", chand, calld, grpc_error_string(error)); @@ -2493,7 +2497,7 @@ class QueuedPickCanceller { auto* self = static_cast(arg); auto* chand = static_cast(self->elem_->channel_data); auto* calld = static_cast(self->elem_->call_data); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: cancelling queued pick: " "error=%s self=%p calld->pick_canceller=%p", @@ -2525,7 +2529,7 @@ static void remove_call_from_queued_picks_locked(grpc_call_element* elem) { for (QueuedPick** pick = &chand->queued_picks; *pick != nullptr; pick = &(*pick)->next) { if (*pick == &calld->pick) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: removing from queued picks list", chand, calld); } @@ -2545,7 +2549,7 @@ static void remove_call_from_queued_picks_locked(grpc_call_element* elem) { static void add_call_to_queued_picks_locked(grpc_call_element* elem) { auto* chand = static_cast(elem->channel_data); auto* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: adding to queued picks list", chand, calld); } @@ -2567,7 +2571,7 @@ static void add_call_to_queued_picks_locked(grpc_call_element* elem) { static void apply_service_config_to_call_locked(grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call", chand, calld); } @@ -2679,7 +2683,7 @@ static void start_pick_locked(void* arg, grpc_error* error) { // Attempt pick. error = GRPC_ERROR_NONE; auto pick_result = chand->picker->Pick(&calld->pick.pick, &error); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: LB pick returned %s (connected_subchannel=%p, " "error=%s)", @@ -2748,7 +2752,7 @@ static void cc_start_transport_stream_op_batch( } // If we've previously been cancelled, immediately fail any new batches. if (GPR_UNLIKELY(calld->cancel_error != GRPC_ERROR_NONE)) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: failing batch with error: %s", chand, calld, grpc_error_string(calld->cancel_error)); } @@ -2767,7 +2771,7 @@ static void cc_start_transport_stream_op_batch( GRPC_ERROR_UNREF(calld->cancel_error); calld->cancel_error = GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error); - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: recording cancel_error=%s", chand, calld, grpc_error_string(calld->cancel_error)); } @@ -2795,7 +2799,7 @@ static void cc_start_transport_stream_op_batch( // the channel combiner, which is more efficient (especially for // streaming calls). if (calld->subchannel_call != nullptr) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: starting batch on subchannel_call=%p", chand, calld, calld->subchannel_call.get()); @@ -2807,7 +2811,7 @@ static void cc_start_transport_stream_op_batch( // For batches containing a send_initial_metadata op, enter the channel // combiner to start a pick. if (GPR_LIKELY(batch->send_initial_metadata)) { - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: entering client_channel combiner", chand, calld); } @@ -2817,7 +2821,7 @@ static void cc_start_transport_stream_op_batch( GRPC_ERROR_NONE); } else { // For all other batches, release the call combiner. - if (grpc_client_channel_trace.enabled()) { + if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: saved batch, yielding call combiner", chand, calld); From bea84d54850f362727cba50916e64a097ceba1c9 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 7 Mar 2019 14:12:14 -0800 Subject: [PATCH 619/814] Add the missing grpc_cfstream dependency --- BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD b/BUILD index 24c1fb31ced..7d26a8f5c42 100644 --- a/BUILD +++ b/BUILD @@ -307,6 +307,7 @@ grpc_cc_library( public_hdrs = GRPC_PUBLIC_HDRS + GRPC_SECURE_PUBLIC_HDRS, standalone = True, deps = [ + "grpc_cfstream", "grpc_common", "grpc_lb_policy_grpclb_secure", "grpc_lb_policy_xds_secure", From fd443c98844a6bb85143445830f7a80701b43f27 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 7 Mar 2019 14:12:14 -0800 Subject: [PATCH 620/814] Add the missing grpc_cfstream dependency --- BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD b/BUILD index 78e5e771bb0..f5f6f7714cf 100644 --- a/BUILD +++ b/BUILD @@ -297,6 +297,7 @@ grpc_cc_library( public_hdrs = GRPC_PUBLIC_HDRS + GRPC_SECURE_PUBLIC_HDRS, standalone = True, deps = [ + "grpc_cfstream", "grpc_common", "grpc_lb_policy_grpclb_secure", "grpc_lb_policy_xds_secure", From abcd5861ebd4867516aea2e12567bb8f423c18d5 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 7 Mar 2019 14:49:24 -0800 Subject: [PATCH 621/814] Nuking the poll-cv polling engine --- BUILD | 2 - CMakeLists.txt | 45 -- Makefile | 42 -- build.yaml | 21 - config.m4 | 1 - config.w32 | 1 - doc/core/grpc-polling-engines.md | 6 +- gRPC-C++.podspec | 2 - gRPC-Core.podspec | 3 - grpc.gemspec | 2 - grpc.gyp | 4 - package.xml | 2 - src/core/lib/iomgr/ev_poll_posix.cc | 484 ------------------ src/core/lib/iomgr/ev_posix.cc | 5 +- src/core/lib/iomgr/wakeup_fd_cv.cc | 107 ---- src/core/lib/iomgr/wakeup_fd_cv.h | 69 --- src/core/lib/iomgr/wakeup_fd_posix.cc | 20 +- src/python/grpcio/grpc_core_dependencies.py | 1 - test/core/end2end/generate_tests.bzl | 2 +- test/core/end2end/tests/keepalive_timeout.cc | 3 +- test/core/iomgr/BUILD | 11 - test/core/iomgr/wakeup_fd_cv_test.cc | 243 --------- test/core/util/test_config.cc | 7 - tools/doxygen/Doxyfile.c++.internal | 1 - tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 19 - tools/run_tests/generated/tests.json | 96 +--- .../run_tests/performance/scenario_config.py | 6 +- tools/run_tests/run_tests.py | 2 +- 29 files changed, 34 insertions(+), 1175 deletions(-) delete mode 100644 src/core/lib/iomgr/wakeup_fd_cv.cc delete mode 100644 src/core/lib/iomgr/wakeup_fd_cv.h delete mode 100644 test/core/iomgr/wakeup_fd_cv_test.cc diff --git a/BUILD b/BUILD index 24c1fb31ced..53afe09f449 100644 --- a/BUILD +++ b/BUILD @@ -800,7 +800,6 @@ grpc_cc_library( "src/core/lib/iomgr/udp_server.cc", "src/core/lib/iomgr/unix_sockets_posix.cc", "src/core/lib/iomgr/unix_sockets_posix_noop.cc", - "src/core/lib/iomgr/wakeup_fd_cv.cc", "src/core/lib/iomgr/wakeup_fd_eventfd.cc", "src/core/lib/iomgr/wakeup_fd_nospecial.cc", "src/core/lib/iomgr/wakeup_fd_pipe.cc", @@ -941,7 +940,6 @@ grpc_cc_library( "src/core/lib/iomgr/timer_manager.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", - "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/json/json.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index bccead24f28..7ccda85b125 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -437,9 +437,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c udp_server_test) endif() add_dependencies(buildtests_c uri_parser_test) -if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) -add_dependencies(buildtests_c wakeup_fd_cv_test) -endif() add_dependencies(buildtests_c public_headers_must_be_c89) add_dependencies(buildtests_c badreq_bad_client_test) add_dependencies(buildtests_c connection_prefix_bad_client_test) @@ -1072,7 +1069,6 @@ add_library(grpc src/core/lib/iomgr/udp_server.cc src/core/lib/iomgr/unix_sockets_posix.cc src/core/lib/iomgr/unix_sockets_posix_noop.cc - src/core/lib/iomgr/wakeup_fd_cv.cc src/core/lib/iomgr/wakeup_fd_eventfd.cc src/core/lib/iomgr/wakeup_fd_nospecial.cc src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -1497,7 +1493,6 @@ add_library(grpc_cronet src/core/lib/iomgr/udp_server.cc src/core/lib/iomgr/unix_sockets_posix.cc src/core/lib/iomgr/unix_sockets_posix_noop.cc - src/core/lib/iomgr/wakeup_fd_cv.cc src/core/lib/iomgr/wakeup_fd_eventfd.cc src/core/lib/iomgr/wakeup_fd_nospecial.cc src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -1907,7 +1902,6 @@ add_library(grpc_test_util src/core/lib/iomgr/udp_server.cc src/core/lib/iomgr/unix_sockets_posix.cc src/core/lib/iomgr/unix_sockets_posix_noop.cc - src/core/lib/iomgr/wakeup_fd_cv.cc src/core/lib/iomgr/wakeup_fd_eventfd.cc src/core/lib/iomgr/wakeup_fd_nospecial.cc src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -2232,7 +2226,6 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/udp_server.cc src/core/lib/iomgr/unix_sockets_posix.cc src/core/lib/iomgr/unix_sockets_posix_noop.cc - src/core/lib/iomgr/wakeup_fd_cv.cc src/core/lib/iomgr/wakeup_fd_eventfd.cc src/core/lib/iomgr/wakeup_fd_nospecial.cc src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -2533,7 +2526,6 @@ add_library(grpc_unsecure src/core/lib/iomgr/udp_server.cc src/core/lib/iomgr/unix_sockets_posix.cc src/core/lib/iomgr/unix_sockets_posix_noop.cc - src/core/lib/iomgr/wakeup_fd_cv.cc src/core/lib/iomgr/wakeup_fd_eventfd.cc src/core/lib/iomgr/wakeup_fd_nospecial.cc src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -3420,7 +3412,6 @@ add_library(grpc++_cronet src/core/lib/iomgr/udp_server.cc src/core/lib/iomgr/unix_sockets_posix.cc src/core/lib/iomgr/unix_sockets_posix_noop.cc - src/core/lib/iomgr/wakeup_fd_cv.cc src/core/lib/iomgr/wakeup_fd_eventfd.cc src/core/lib/iomgr/wakeup_fd_nospecial.cc src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -10453,42 +10444,6 @@ target_link_libraries(uri_parser_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) -if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - -add_executable(wakeup_fd_cv_test - test/core/iomgr/wakeup_fd_cv_test.cc -) - - -target_include_directories(wakeup_fd_cv_test - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} -) - -target_link_libraries(wakeup_fd_cv_test - ${_gRPC_ALLTARGETS_LIBRARIES} - grpc_test_util - grpc - gpr -) - - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(wakeup_fd_cv_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(wakeup_fd_cv_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() - -endif() -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) add_executable(alarm_test test/cpp/common/alarm_test.cc diff --git a/Makefile b/Makefile index 94944265d61..91516de9a27 100644 --- a/Makefile +++ b/Makefile @@ -1140,7 +1140,6 @@ transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test udp_server_test: $(BINDIR)/$(CONFIG)/udp_server_test uri_fuzzer_test: $(BINDIR)/$(CONFIG)/uri_fuzzer_test uri_parser_test: $(BINDIR)/$(CONFIG)/uri_parser_test -wakeup_fd_cv_test: $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test alarm_test: $(BINDIR)/$(CONFIG)/alarm_test alts_counter_test: $(BINDIR)/$(CONFIG)/alts_counter_test alts_crypt_test: $(BINDIR)/$(CONFIG)/alts_crypt_test @@ -1593,7 +1592,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/transport_security_test \ $(BINDIR)/$(CONFIG)/udp_server_test \ $(BINDIR)/$(CONFIG)/uri_parser_test \ - $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test \ $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \ $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ @@ -2243,8 +2241,6 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/udp_server_test || ( echo test udp_server_test failed ; exit 1 ) $(E) "[RUN] Testing uri_parser_test" $(Q) $(BINDIR)/$(CONFIG)/uri_parser_test || ( echo test uri_parser_test failed ; exit 1 ) - $(E) "[RUN] Testing wakeup_fd_cv_test" - $(Q) $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test || ( echo test wakeup_fd_cv_test failed ; exit 1 ) $(E) "[RUN] Testing public_headers_must_be_c89" $(Q) $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 || ( echo test public_headers_must_be_c89 failed ; exit 1 ) $(E) "[RUN] Testing badreq_bad_client_test" @@ -3617,7 +3613,6 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/udp_server.cc \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ - src/core/lib/iomgr/wakeup_fd_cv.cc \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ @@ -4036,7 +4031,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/udp_server.cc \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ - src/core/lib/iomgr/wakeup_fd_cv.cc \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ @@ -4439,7 +4433,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/udp_server.cc \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ - src/core/lib/iomgr/wakeup_fd_cv.cc \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ @@ -4751,7 +4744,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/udp_server.cc \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ - src/core/lib/iomgr/wakeup_fd_cv.cc \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ @@ -5026,7 +5018,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/udp_server.cc \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ - src/core/lib/iomgr/wakeup_fd_cv.cc \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ @@ -5890,7 +5881,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/udp_server.cc \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ - src/core/lib/iomgr/wakeup_fd_cv.cc \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ @@ -15405,38 +15395,6 @@ endif endif -WAKEUP_FD_CV_TEST_SRC = \ - test/core/iomgr/wakeup_fd_cv_test.cc \ - -WAKEUP_FD_CV_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(WAKEUP_FD_CV_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(WAKEUP_FD_CV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test - -endif - -$(OBJDIR)/$(CONFIG)/test/core/iomgr/wakeup_fd_cv_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_wakeup_fd_cv_test: $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(WAKEUP_FD_CV_TEST_OBJS:.o=.dep) -endif -endif - - ALARM_TEST_SRC = \ test/cpp/common/alarm_test.cc \ diff --git a/build.yaml b/build.yaml index 621b9a4de2f..02ecaa221e6 100644 --- a/build.yaml +++ b/build.yaml @@ -333,7 +333,6 @@ filegroups: - src/core/lib/iomgr/udp_server.cc - src/core/lib/iomgr/unix_sockets_posix.cc - src/core/lib/iomgr/unix_sockets_posix_noop.cc - - src/core/lib/iomgr/wakeup_fd_cv.cc - src/core/lib/iomgr/wakeup_fd_eventfd.cc - src/core/lib/iomgr/wakeup_fd_nospecial.cc - src/core/lib/iomgr/wakeup_fd_pipe.cc @@ -498,7 +497,6 @@ filegroups: - src/core/lib/iomgr/timer_manager.h - src/core/lib/iomgr/udp_server.h - src/core/lib/iomgr/unix_sockets_posix.h - - src/core/lib/iomgr/wakeup_fd_cv.h - src/core/lib/iomgr/wakeup_fd_pipe.h - src/core/lib/iomgr/wakeup_fd_posix.h - src/core/lib/json/json.h @@ -3740,21 +3738,6 @@ targets: - grpc_test_util - grpc - gpr -- name: wakeup_fd_cv_test - build: test - language: c - src: - - test/core/iomgr/wakeup_fd_cv_test.cc - deps: - - grpc_test_util - - grpc - - gpr - exclude_iomgrs: - - uv - platforms: - - mac - - linux - - posix - name: alarm_test gtest: true build: test @@ -4180,7 +4163,6 @@ targets: defaults: benchmark excluded_poll_engines: - poll - - poll-cv platforms: - mac - linux @@ -4206,7 +4188,6 @@ targets: defaults: benchmark excluded_poll_engines: - poll - - poll-cv platforms: - mac - linux @@ -4232,7 +4213,6 @@ targets: - tsan excluded_poll_engines: - poll - - poll-cv platforms: - mac - linux @@ -4258,7 +4238,6 @@ targets: defaults: benchmark excluded_poll_engines: - poll - - poll-cv platforms: - mac - linux diff --git a/config.m4 b/config.m4 index 2616803d9b0..bb23c2ed956 100644 --- a/config.m4 +++ b/config.m4 @@ -187,7 +187,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/udp_server.cc \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ - src/core/lib/iomgr/wakeup_fd_cv.cc \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ diff --git a/config.w32 b/config.w32 index 64eca2a8472..35e52e15bd0 100644 --- a/config.w32 +++ b/config.w32 @@ -162,7 +162,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\udp_server.cc " + "src\\core\\lib\\iomgr\\unix_sockets_posix.cc " + "src\\core\\lib\\iomgr\\unix_sockets_posix_noop.cc " + - "src\\core\\lib\\iomgr\\wakeup_fd_cv.cc " + "src\\core\\lib\\iomgr\\wakeup_fd_eventfd.cc " + "src\\core\\lib\\iomgr\\wakeup_fd_nospecial.cc " + "src\\core\\lib\\iomgr\\wakeup_fd_pipe.cc " + diff --git a/doc/core/grpc-polling-engines.md b/doc/core/grpc-polling-engines.md index f273913b1e4..dd5a7654852 100644 --- a/doc/core/grpc-polling-engines.md +++ b/doc/core/grpc-polling-engines.md @@ -23,11 +23,9 @@ There are multiple polling engine implementations depending on the OS and the OS - **`epollex`** (default but requires kernel version >= 4.5), - `epoll1` (If `epollex` is not available and glibc version >= 2.9) - `poll` (If kernel does not have epoll support) - - `poll-cv` (If explicitly configured) -- Mac: **`poll`** (default), `poll-cv` (If explicitly configured) +- Mac: **`poll`** (default) - Windows: (no name) - One-off polling engines: - - AppEngine platform: **`poll-cv`** (default) - NodeJS : `libuv` polling engine implementation (requires different compile `#define`s) ## Polling Engine Interface @@ -87,7 +85,7 @@ Add/Remove fd to the `grpc_pollset_set` - **grpc\_pollset\_set_[add|del]\_pollset** - Signature: `grpc_pollset_set_[add|del]_pollset(grpc_pollset_set* pss, grpc_pollset* ps)` - What does adding a pollset to a pollset_set mean ? - - It means that calling `grpc_pollset_work()` on the pollset will also poll all the fds in the pollset_set i.e semantically, it is similar to adding all the fds inside pollset_set to the pollset. + - It means that calling `grpc_pollset_work()` on the pollset will also poll all the fds in the pollset_set i.e semantically, it is similar to adding all the fds inside pollset_set to the pollset. - This guarantee is no longer true once the pollset is removed from the pollset_set - **grpc\_pollset\_set_[add|del]\_pollset\_set** diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 0f3888975c9..e755b7aa602 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -474,7 +474,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/timer_manager.h', 'src/core/lib/iomgr/udp_server.h', 'src/core/lib/iomgr/unix_sockets_posix.h', - 'src/core/lib/iomgr/wakeup_fd_cv.h', 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/json/json.h', @@ -666,7 +665,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/timer_manager.h', 'src/core/lib/iomgr/udp_server.h', 'src/core/lib/iomgr/unix_sockets_posix.h', - 'src/core/lib/iomgr/wakeup_fd_cv.h', 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/json/json.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 2e54b9d7847..7068f039870 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -468,7 +468,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/timer_manager.h', 'src/core/lib/iomgr/udp_server.h', 'src/core/lib/iomgr/unix_sockets_posix.h', - 'src/core/lib/iomgr/wakeup_fd_cv.h', 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/json/json.h', @@ -634,7 +633,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/udp_server.cc', 'src/core/lib/iomgr/unix_sockets_posix.cc', 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', - 'src/core/lib/iomgr/wakeup_fd_cv.cc', 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', 'src/core/lib/iomgr/wakeup_fd_pipe.cc', @@ -1096,7 +1094,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/timer_manager.h', 'src/core/lib/iomgr/udp_server.h', 'src/core/lib/iomgr/unix_sockets_posix.h', - 'src/core/lib/iomgr/wakeup_fd_cv.h', 'src/core/lib/iomgr/wakeup_fd_pipe.h', 'src/core/lib/iomgr/wakeup_fd_posix.h', 'src/core/lib/json/json.h', diff --git a/grpc.gemspec b/grpc.gemspec index 95de105d7af..a2a027a20d8 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -402,7 +402,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/timer_manager.h ) s.files += %w( src/core/lib/iomgr/udp_server.h ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix.h ) - s.files += %w( src/core/lib/iomgr/wakeup_fd_cv.h ) s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.h ) s.files += %w( src/core/lib/iomgr/wakeup_fd_posix.h ) s.files += %w( src/core/lib/json/json.h ) @@ -568,7 +567,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/udp_server.cc ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix.cc ) s.files += %w( src/core/lib/iomgr/unix_sockets_posix_noop.cc ) - s.files += %w( src/core/lib/iomgr/wakeup_fd_cv.cc ) s.files += %w( src/core/lib/iomgr/wakeup_fd_eventfd.cc ) s.files += %w( src/core/lib/iomgr/wakeup_fd_nospecial.cc ) s.files += %w( src/core/lib/iomgr/wakeup_fd_pipe.cc ) diff --git a/grpc.gyp b/grpc.gyp index 53e891b28dc..94a9cd2cfb8 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -369,7 +369,6 @@ 'src/core/lib/iomgr/udp_server.cc', 'src/core/lib/iomgr/unix_sockets_posix.cc', 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', - 'src/core/lib/iomgr/wakeup_fd_cv.cc', 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', 'src/core/lib/iomgr/wakeup_fd_pipe.cc', @@ -735,7 +734,6 @@ 'src/core/lib/iomgr/udp_server.cc', 'src/core/lib/iomgr/unix_sockets_posix.cc', 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', - 'src/core/lib/iomgr/wakeup_fd_cv.cc', 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', 'src/core/lib/iomgr/wakeup_fd_pipe.cc', @@ -980,7 +978,6 @@ 'src/core/lib/iomgr/udp_server.cc', 'src/core/lib/iomgr/unix_sockets_posix.cc', 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', - 'src/core/lib/iomgr/wakeup_fd_cv.cc', 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', 'src/core/lib/iomgr/wakeup_fd_pipe.cc', @@ -1201,7 +1198,6 @@ 'src/core/lib/iomgr/udp_server.cc', 'src/core/lib/iomgr/unix_sockets_posix.cc', 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', - 'src/core/lib/iomgr/wakeup_fd_cv.cc', 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', 'src/core/lib/iomgr/wakeup_fd_pipe.cc', diff --git a/package.xml b/package.xml index 34730a0c1d5..be7e258b98a 100644 --- a/package.xml +++ b/package.xml @@ -407,7 +407,6 @@ - @@ -573,7 +572,6 @@ - diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index 9350ef5a2af..4c98ffa9448 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -43,7 +43,6 @@ #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/block_annotate.h" #include "src/core/lib/iomgr/iomgr_internal.h" -#include "src/core/lib/iomgr/wakeup_fd_cv.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" #include "src/core/lib/profiling/timers.h" @@ -256,56 +255,6 @@ struct grpc_pollset_set { grpc_fd** fds; }; -/******************************************************************************* - * condition variable polling definitions - */ - -#define POLLCV_THREAD_GRACE_MS 1000 -#define CV_POLL_PERIOD_MS 1000 -#define CV_DEFAULT_TABLE_SIZE 16 - -typedef struct poll_result { - gpr_refcount refcount; - grpc_cv_node* watchers; - int watchcount; - struct pollfd* fds; - nfds_t nfds; - int retval; - int err; - int completed; -} poll_result; - -typedef struct poll_args { - grpc_core::Thread poller_thd; - gpr_cv trigger; - int trigger_set; - bool harvestable; - gpr_cv harvest; - bool joinable; - gpr_cv join; - struct pollfd* fds; - nfds_t nfds; - poll_result* result; - struct poll_args* next; - struct poll_args* prev; -} poll_args; - -// This is a 2-tiered cache, we mantain a hash table -// of active poll calls, so we can wait on the result -// of that call. We also maintain freelists of inactive -// poll args and of dead poller threads. -typedef struct poll_hash_table { - poll_args* free_pollers; - poll_args** active_pollers; - poll_args* dead_pollers; - unsigned int size; - unsigned int count; -} poll_hash_table; - -// TODO(kpayson64): Eliminate use of global non-POD variables -poll_hash_table poll_cache; -grpc_cv_fd_table g_cvfds; - /******************************************************************************* * functions to track opened fds. No-ops unless track_fds_for_fork is true. */ @@ -1363,425 +1312,6 @@ static void pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) { gpr_mu_unlock(&pollset_set->mu); } -/******************************************************************************* - * Condition Variable polling extensions - */ - -static void run_poll(void* args); -static void cache_poller_locked(poll_args* args); -static void cache_harvest_locked(); - -static void cache_insert_locked(poll_args* args) { - uint32_t key = gpr_murmur_hash3(args->fds, args->nfds * sizeof(struct pollfd), - 0xDEADBEEF); - key = key % poll_cache.size; - if (poll_cache.active_pollers[key]) { - poll_cache.active_pollers[key]->prev = args; - } - args->next = poll_cache.active_pollers[key]; - args->prev = nullptr; - poll_cache.active_pollers[key] = args; - poll_cache.count++; -} - -static void init_result(poll_args* pargs) { - pargs->result = static_cast(gpr_malloc(sizeof(poll_result))); - gpr_ref_init(&pargs->result->refcount, 1); - pargs->result->watchers = nullptr; - pargs->result->watchcount = 0; - pargs->result->fds = static_cast( - gpr_malloc(sizeof(struct pollfd) * pargs->nfds)); - memcpy(pargs->result->fds, pargs->fds, sizeof(struct pollfd) * pargs->nfds); - pargs->result->nfds = pargs->nfds; - pargs->result->retval = 0; - pargs->result->err = 0; - pargs->result->completed = 0; -} - -// Creates a poll_args object for a given arguments to poll(). -// This object may return a poll_args in the cache. -static poll_args* get_poller_locked(struct pollfd* fds, nfds_t count) { - uint32_t key = - gpr_murmur_hash3(fds, count * sizeof(struct pollfd), 0xDEADBEEF); - key = key % poll_cache.size; - poll_args* curr = poll_cache.active_pollers[key]; - while (curr) { - if (curr->nfds == count && - memcmp(curr->fds, fds, count * sizeof(struct pollfd)) == 0) { - gpr_free(fds); - return curr; - } - curr = curr->next; - } - - if (poll_cache.free_pollers) { - poll_args* pargs = poll_cache.free_pollers; - poll_cache.free_pollers = pargs->next; - if (poll_cache.free_pollers) { - poll_cache.free_pollers->prev = nullptr; - } - pargs->fds = fds; - pargs->nfds = count; - pargs->next = nullptr; - pargs->prev = nullptr; - init_result(pargs); - cache_poller_locked(pargs); - return pargs; - } - - poll_args* pargs = - static_cast(gpr_malloc(sizeof(struct poll_args))); - gpr_cv_init(&pargs->trigger); - gpr_cv_init(&pargs->harvest); - gpr_cv_init(&pargs->join); - pargs->harvestable = false; - pargs->joinable = false; - pargs->fds = fds; - pargs->nfds = count; - pargs->next = nullptr; - pargs->prev = nullptr; - pargs->trigger_set = 0; - init_result(pargs); - cache_poller_locked(pargs); - gpr_ref(&g_cvfds.pollcount); - pargs->poller_thd = grpc_core::Thread("grpc_poller", &run_poll, pargs); - pargs->poller_thd.Start(); - return pargs; -} - -static void cache_delete_locked(poll_args* args) { - if (!args->prev) { - uint32_t key = gpr_murmur_hash3( - args->fds, args->nfds * sizeof(struct pollfd), 0xDEADBEEF); - key = key % poll_cache.size; - GPR_ASSERT(poll_cache.active_pollers[key] == args); - poll_cache.active_pollers[key] = args->next; - } else { - args->prev->next = args->next; - } - - if (args->next) { - args->next->prev = args->prev; - } - - poll_cache.count--; - if (poll_cache.free_pollers) { - poll_cache.free_pollers->prev = args; - } - args->prev = nullptr; - args->next = poll_cache.free_pollers; - gpr_free(args->fds); - poll_cache.free_pollers = args; -} - -static void cache_poller_locked(poll_args* args) { - if (poll_cache.count + 1 > poll_cache.size / 2) { - poll_args** old_active_pollers = poll_cache.active_pollers; - poll_cache.size = poll_cache.size * 2; - poll_cache.count = 0; - poll_cache.active_pollers = - static_cast(gpr_malloc(sizeof(void*) * poll_cache.size)); - for (unsigned int i = 0; i < poll_cache.size; i++) { - poll_cache.active_pollers[i] = nullptr; - } - for (unsigned int i = 0; i < poll_cache.size / 2; i++) { - poll_args* curr = old_active_pollers[i]; - poll_args* next = nullptr; - while (curr) { - next = curr->next; - cache_insert_locked(curr); - curr = next; - } - } - gpr_free(old_active_pollers); - } - - cache_insert_locked(args); -} - -static void cache_destroy_locked(poll_args* args) { - if (args->next) { - args->next->prev = args->prev; - } - - if (args->prev) { - args->prev->next = args->next; - } else { - poll_cache.free_pollers = args->next; - } - - // Now move this args to the dead poller list for later join - if (poll_cache.dead_pollers != nullptr) { - poll_cache.dead_pollers->prev = args; - } - args->prev = nullptr; - args->next = poll_cache.dead_pollers; - poll_cache.dead_pollers = args; -} - -static void cache_harvest_locked() { - while (poll_cache.dead_pollers) { - poll_args* args = poll_cache.dead_pollers; - poll_cache.dead_pollers = poll_cache.dead_pollers->next; - // Keep the list consistent in case new dead pollers get added when we - // release the lock below to wait on joining - if (poll_cache.dead_pollers) { - poll_cache.dead_pollers->prev = nullptr; - } - args->harvestable = true; - gpr_cv_signal(&args->harvest); - while (!args->joinable) { - gpr_cv_wait(&args->join, &g_cvfds.mu, - gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - args->poller_thd.Join(); - gpr_cv_destroy(&args->trigger); - gpr_cv_destroy(&args->harvest); - gpr_cv_destroy(&args->join); - gpr_free(args); - } -} - -static void decref_poll_result(poll_result* res) { - if (gpr_unref(&res->refcount)) { - GPR_ASSERT(!res->watchers); - gpr_free(res->fds); - gpr_free(res); - } -} - -void remove_cvn(grpc_cv_node** head, grpc_cv_node* target) { - if (target->next) { - target->next->prev = target->prev; - } - - if (target->prev) { - target->prev->next = target->next; - } else { - *head = target->next; - } -} - -gpr_timespec thread_grace; - -// Poll in a background thread -static void run_poll(void* args) { - poll_args* pargs = static_cast(args); - while (1) { - poll_result* result = pargs->result; - int retval = g_cvfds.poll(result->fds, result->nfds, CV_POLL_PERIOD_MS); - gpr_mu_lock(&g_cvfds.mu); - cache_harvest_locked(); - if (retval != 0) { - result->completed = 1; - result->retval = retval; - result->err = errno; - grpc_cv_node* watcher = result->watchers; - while (watcher) { - gpr_cv_signal(watcher->cv); - watcher = watcher->next; - } - } - if (result->watchcount == 0 || result->completed) { - cache_delete_locked(pargs); - decref_poll_result(result); - // Leave this polling thread alive for a grace period to do another poll() - // op - gpr_timespec deadline = gpr_now(GPR_CLOCK_MONOTONIC); - deadline = gpr_time_add(deadline, thread_grace); - pargs->trigger_set = 0; - gpr_cv_wait(&pargs->trigger, &g_cvfds.mu, deadline); - cache_harvest_locked(); - if (!pargs->trigger_set) { - cache_destroy_locked(pargs); - break; - } - } - gpr_mu_unlock(&g_cvfds.mu); - } - - if (gpr_unref(&g_cvfds.pollcount)) { - gpr_cv_signal(&g_cvfds.shutdown_cv); - } - while (!pargs->harvestable) { - gpr_cv_wait(&pargs->harvest, &g_cvfds.mu, - gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - pargs->joinable = true; - gpr_cv_signal(&pargs->join); - gpr_mu_unlock(&g_cvfds.mu); -} - -// This function overrides poll() to handle condition variable wakeup fds -static int cvfd_poll(struct pollfd* fds, nfds_t nfds, int timeout) { - if (timeout == 0) { - // Don't bother using background threads for polling if timeout is 0, - // poll-cv might not wait for a poll to return otherwise. - // https://github.com/grpc/grpc/issues/13298 - return poll(fds, nfds, 0); - } - unsigned int i; - int res, idx; - grpc_cv_node* pollcv; - int skip_poll = 0; - nfds_t nsockfds = 0; - poll_result* result = nullptr; - gpr_mu_lock(&g_cvfds.mu); - cache_harvest_locked(); - pollcv = static_cast(gpr_malloc(sizeof(grpc_cv_node))); - pollcv->next = nullptr; - gpr_cv pollcv_cv; - gpr_cv_init(&pollcv_cv); - pollcv->cv = &pollcv_cv; - grpc_cv_node* fd_cvs = - static_cast(gpr_malloc(nfds * sizeof(grpc_cv_node))); - - for (i = 0; i < nfds; i++) { - fds[i].revents = 0; - if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { - idx = GRPC_FD_TO_IDX(fds[i].fd); - fd_cvs[i].cv = &pollcv_cv; - fd_cvs[i].prev = nullptr; - fd_cvs[i].next = g_cvfds.cvfds[idx].cvs; - if (g_cvfds.cvfds[idx].cvs) { - g_cvfds.cvfds[idx].cvs->prev = &(fd_cvs[i]); - } - g_cvfds.cvfds[idx].cvs = &(fd_cvs[i]); - // Don't bother polling if a wakeup fd is ready - if (g_cvfds.cvfds[idx].is_set) { - skip_poll = 1; - } - } else if (fds[i].fd >= 0) { - nsockfds++; - } - } - - gpr_timespec deadline = gpr_now(GPR_CLOCK_MONOTONIC); - if (timeout < 0) { - deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); - } else { - deadline = - gpr_time_add(deadline, gpr_time_from_millis(timeout, GPR_TIMESPAN)); - } - - res = 0; - if (!skip_poll && nsockfds > 0) { - struct pollfd* pollfds = static_cast( - gpr_malloc(sizeof(struct pollfd) * nsockfds)); - idx = 0; - for (i = 0; i < nfds; i++) { - if (fds[i].fd >= 0) { - pollfds[idx].fd = fds[i].fd; - pollfds[idx].events = fds[i].events; - pollfds[idx].revents = 0; - idx++; - } - } - poll_args* pargs = get_poller_locked(pollfds, nsockfds); - result = pargs->result; - pollcv->next = result->watchers; - pollcv->prev = nullptr; - if (result->watchers) { - result->watchers->prev = pollcv; - } - result->watchers = pollcv; - result->watchcount++; - gpr_ref(&result->refcount); - - pargs->trigger_set = 1; - gpr_cv_signal(&pargs->trigger); - gpr_cv_wait(&pollcv_cv, &g_cvfds.mu, deadline); - cache_harvest_locked(); - res = result->retval; - errno = result->err; - result->watchcount--; - remove_cvn(&result->watchers, pollcv); - } else if (!skip_poll) { - gpr_cv_wait(&pollcv_cv, &g_cvfds.mu, deadline); - cache_harvest_locked(); - } - - idx = 0; - for (i = 0; i < nfds; i++) { - if (fds[i].fd < 0 && (fds[i].events & POLLIN)) { - remove_cvn(&g_cvfds.cvfds[GRPC_FD_TO_IDX(fds[i].fd)].cvs, &(fd_cvs[i])); - if (g_cvfds.cvfds[GRPC_FD_TO_IDX(fds[i].fd)].is_set) { - fds[i].revents = POLLIN; - if (res >= 0) res++; - } - } else if (!skip_poll && fds[i].fd >= 0 && result->completed) { - fds[i].revents = result->fds[idx].revents; - idx++; - } - } - - gpr_free(fd_cvs); - gpr_cv_destroy(pollcv->cv); - gpr_free(pollcv); - if (result) { - decref_poll_result(result); - } - - gpr_mu_unlock(&g_cvfds.mu); - - return res; -} - -static void global_cv_fd_table_init() { - gpr_mu_init(&g_cvfds.mu); - gpr_mu_lock(&g_cvfds.mu); - gpr_cv_init(&g_cvfds.shutdown_cv); - gpr_ref_init(&g_cvfds.pollcount, 1); - g_cvfds.size = CV_DEFAULT_TABLE_SIZE; - g_cvfds.cvfds = static_cast( - gpr_malloc(sizeof(grpc_fd_node) * CV_DEFAULT_TABLE_SIZE)); - g_cvfds.free_fds = nullptr; - thread_grace = gpr_time_from_millis(POLLCV_THREAD_GRACE_MS, GPR_TIMESPAN); - for (int i = 0; i < CV_DEFAULT_TABLE_SIZE; i++) { - g_cvfds.cvfds[i].is_set = 0; - g_cvfds.cvfds[i].cvs = nullptr; - g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; - g_cvfds.free_fds = &g_cvfds.cvfds[i]; - } - // Override the poll function with one that supports cvfds - g_cvfds.poll = grpc_poll_function; - grpc_poll_function = &cvfd_poll; - - // Initialize the cache - poll_cache.size = 32; - poll_cache.count = 0; - poll_cache.free_pollers = nullptr; - poll_cache.active_pollers = - static_cast(gpr_malloc(sizeof(void*) * 32)); - for (unsigned int i = 0; i < poll_cache.size; i++) { - poll_cache.active_pollers[i] = nullptr; - } - poll_cache.dead_pollers = nullptr; - - gpr_mu_unlock(&g_cvfds.mu); -} - -static void global_cv_fd_table_shutdown() { - gpr_mu_lock(&g_cvfds.mu); - // Attempt to wait for all abandoned poll() threads to terminate - // Not doing so will result in reported memory leaks - if (!gpr_unref(&g_cvfds.pollcount)) { - int res = gpr_cv_wait(&g_cvfds.shutdown_cv, &g_cvfds.mu, - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(3, GPR_TIMESPAN))); - GPR_ASSERT(res == 0); - } - gpr_cv_destroy(&g_cvfds.shutdown_cv); - grpc_poll_function = g_cvfds.poll; - gpr_free(g_cvfds.cvfds); - - cache_harvest_locked(); - gpr_free(poll_cache.active_pollers); - - gpr_mu_unlock(&g_cvfds.mu); - gpr_mu_destroy(&g_cvfds.mu); -} - /******************************************************************************* * event engine binding */ @@ -1792,9 +1322,6 @@ static void shutdown_background_closure(void) {} static void shutdown_engine(void) { pollset_global_shutdown(); - if (grpc_cv_wakeup_fds_enabled()) { - global_cv_fd_table_shutdown(); - } if (track_fds_for_fork) { gpr_mu_destroy(&fork_fd_list_mu); grpc_core::Fork::SetResetChildPollingEngineFunc(nullptr); @@ -1876,15 +1403,4 @@ const grpc_event_engine_vtable* grpc_init_poll_posix(bool explicit_request) { return &vtable; } -const grpc_event_engine_vtable* grpc_init_poll_cv_posix(bool explicit_request) { - global_cv_fd_table_init(); - grpc_enable_cv_wakeup_fds(1); - if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) { - global_cv_fd_table_shutdown(); - grpc_enable_cv_wakeup_fds(0); - return nullptr; - } - return &vtable; -} - #endif /* GRPC_POSIX_SOCKET_EV_POLL */ diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index fb2e70eee49..d7aeb81c69e 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -126,10 +126,9 @@ static event_engine_factory g_factories[] = { {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, {"epollex", grpc_init_epollex_linux}, {"epoll1", grpc_init_epoll1_linux}, - {"poll", grpc_init_poll_posix}, {"poll-cv", grpc_init_poll_cv_posix}, - {"none", init_non_polling}, {ENGINE_TAIL_CUSTOM, nullptr}, + {"poll", grpc_init_poll_posix}, {"none", init_non_polling}, + {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, - {ENGINE_TAIL_CUSTOM, nullptr}, }; static void add(const char* beg, const char* end, char*** ss, size_t* ns) { diff --git a/src/core/lib/iomgr/wakeup_fd_cv.cc b/src/core/lib/iomgr/wakeup_fd_cv.cc deleted file mode 100644 index 74faa6379ef..00000000000 --- a/src/core/lib/iomgr/wakeup_fd_cv.cc +++ /dev/null @@ -1,107 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/lib/iomgr/port.h" - -#ifdef GRPC_POSIX_WAKEUP_FD - -#include "src/core/lib/iomgr/wakeup_fd_cv.h" - -#include -#include - -#include -#include -#include -#include - -#include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/thd.h" - -#define MAX_TABLE_RESIZE 256 - -extern grpc_cv_fd_table g_cvfds; - -static grpc_error* cv_fd_init(grpc_wakeup_fd* fd_info) { - unsigned int i, newsize; - int idx; - gpr_mu_lock(&g_cvfds.mu); - if (!g_cvfds.free_fds) { - newsize = GPR_MIN(g_cvfds.size * 2, g_cvfds.size + MAX_TABLE_RESIZE); - g_cvfds.cvfds = static_cast( - gpr_realloc(g_cvfds.cvfds, sizeof(grpc_fd_node) * newsize)); - for (i = g_cvfds.size; i < newsize; i++) { - g_cvfds.cvfds[i].is_set = 0; - g_cvfds.cvfds[i].cvs = nullptr; - g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; - g_cvfds.free_fds = &g_cvfds.cvfds[i]; - } - g_cvfds.size = newsize; - } - - idx = static_cast(g_cvfds.free_fds - g_cvfds.cvfds); - g_cvfds.free_fds = g_cvfds.free_fds->next_free; - g_cvfds.cvfds[idx].cvs = nullptr; - g_cvfds.cvfds[idx].is_set = 0; - fd_info->read_fd = GRPC_IDX_TO_FD(idx); - fd_info->write_fd = -1; - gpr_mu_unlock(&g_cvfds.mu); - return GRPC_ERROR_NONE; -} - -static grpc_error* cv_fd_wakeup(grpc_wakeup_fd* fd_info) { - grpc_cv_node* cvn; - gpr_mu_lock(&g_cvfds.mu); - g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].is_set = 1; - cvn = g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].cvs; - while (cvn) { - gpr_cv_signal(cvn->cv); - cvn = cvn->next; - } - gpr_mu_unlock(&g_cvfds.mu); - return GRPC_ERROR_NONE; -} - -static grpc_error* cv_fd_consume(grpc_wakeup_fd* fd_info) { - gpr_mu_lock(&g_cvfds.mu); - g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].is_set = 0; - gpr_mu_unlock(&g_cvfds.mu); - return GRPC_ERROR_NONE; -} - -static void cv_fd_destroy(grpc_wakeup_fd* fd_info) { - if (fd_info->read_fd == 0) { - return; - } - gpr_mu_lock(&g_cvfds.mu); - // Assert that there are no active pollers - GPR_ASSERT(!g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].cvs); - g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].next_free = g_cvfds.free_fds; - g_cvfds.free_fds = &g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)]; - gpr_mu_unlock(&g_cvfds.mu); -} - -static int cv_check_availability(void) { return 1; } - -const grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable = { - cv_fd_init, cv_fd_consume, cv_fd_wakeup, cv_fd_destroy, - cv_check_availability}; - -#endif /* GRPC_POSIX_WAKUP_FD */ diff --git a/src/core/lib/iomgr/wakeup_fd_cv.h b/src/core/lib/iomgr/wakeup_fd_cv.h deleted file mode 100644 index 86365f07e17..00000000000 --- a/src/core/lib/iomgr/wakeup_fd_cv.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -/* - * wakeup_fd_cv uses condition variables to implement wakeup fds. - * - * It is intended for use only in cases when eventfd() and pipe() are not - * available. It can only be used with the "poll" engine. - * - * Implementation: - * A global table of cv wakeup fds is mantained. A cv wakeup fd is a negative - * file descriptor. poll() is then run in a background thread with only the - * real socket fds while we wait on a condition variable trigged by either the - * poll() completion or a wakeup_fd() call. - * - */ - -#ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H -#define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H - -#include - -#include - -#include "src/core/lib/iomgr/ev_posix.h" - -#define GRPC_FD_TO_IDX(fd) (-(fd)-1) -#define GRPC_IDX_TO_FD(idx) (-(idx)-1) - -typedef struct grpc_cv_node { - gpr_cv* cv; - struct grpc_cv_node* next; - struct grpc_cv_node* prev; -} grpc_cv_node; - -typedef struct grpc_fd_node { - int is_set; - grpc_cv_node* cvs; - struct grpc_fd_node* next_free; -} grpc_fd_node; - -typedef struct grpc_cv_fd_table { - gpr_mu mu; - gpr_refcount pollcount; - gpr_cv shutdown_cv; - grpc_fd_node* cvfds; - grpc_fd_node* free_fds; - unsigned int size; - grpc_poll_function_type poll; -} grpc_cv_fd_table; - -extern const grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable; - -#endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H */ diff --git a/src/core/lib/iomgr/wakeup_fd_posix.cc b/src/core/lib/iomgr/wakeup_fd_posix.cc index b5b8b37a9af..3b66d6f34de 100644 --- a/src/core/lib/iomgr/wakeup_fd_posix.cc +++ b/src/core/lib/iomgr/wakeup_fd_posix.cc @@ -23,7 +23,6 @@ #ifdef GRPC_POSIX_WAKEUP_FD #include -#include "src/core/lib/iomgr/wakeup_fd_cv.h" #include "src/core/lib/iomgr/wakeup_fd_pipe.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" @@ -51,37 +50,20 @@ void grpc_wakeup_fd_global_destroy(void) { wakeup_fd_vtable = nullptr; } int grpc_has_wakeup_fd(void) { return has_real_wakeup_fd; } -int grpc_cv_wakeup_fds_enabled(void) { return cv_wakeup_fds_enabled; } - -void grpc_enable_cv_wakeup_fds(int enable) { cv_wakeup_fds_enabled = enable; } - grpc_error* grpc_wakeup_fd_init(grpc_wakeup_fd* fd_info) { - if (cv_wakeup_fds_enabled) { - return grpc_cv_wakeup_fd_vtable.init(fd_info); - } return wakeup_fd_vtable->init(fd_info); } grpc_error* grpc_wakeup_fd_consume_wakeup(grpc_wakeup_fd* fd_info) { - if (cv_wakeup_fds_enabled) { - return grpc_cv_wakeup_fd_vtable.consume(fd_info); - } return wakeup_fd_vtable->consume(fd_info); } grpc_error* grpc_wakeup_fd_wakeup(grpc_wakeup_fd* fd_info) { - if (cv_wakeup_fds_enabled) { - return grpc_cv_wakeup_fd_vtable.wakeup(fd_info); - } return wakeup_fd_vtable->wakeup(fd_info); } void grpc_wakeup_fd_destroy(grpc_wakeup_fd* fd_info) { - if (cv_wakeup_fds_enabled) { - grpc_cv_wakeup_fd_vtable.destroy(fd_info); - } else { - wakeup_fd_vtable->destroy(fd_info); - } + wakeup_fd_vtable->destroy(fd_info); } #endif /* GRPC_POSIX_WAKEUP_FD */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index a9d045281ec..8f7da3a5b04 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -161,7 +161,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/udp_server.cc', 'src/core/lib/iomgr/unix_sockets_posix.cc', 'src/core/lib/iomgr/unix_sockets_posix_noop.cc', - 'src/core/lib/iomgr/wakeup_fd_cv.cc', 'src/core/lib/iomgr/wakeup_fd_eventfd.cc', 'src/core/lib/iomgr/wakeup_fd_nospecial.cc', 'src/core/lib/iomgr/wakeup_fd_pipe.cc', diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 5174a7e5af5..7bb246b6067 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -17,7 +17,7 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library") -POLLERS = ["epollex", "epoll1", "poll", "poll-cv"] +POLLERS = ["epollex", "epoll1", "poll"] def _fixture_options( fullstack = True, diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index c4025e93b82..2c992848b95 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -228,8 +228,7 @@ static void test_read_delays_keepalive(grpc_end2end_test_config config) { char* poller = gpr_getenv("GRPC_POLL_STRATEGY"); /* It is hard to get the timing right for the polling engines poll and poll-cv */ - if (poller != nullptr && - (0 == strcmp(poller, "poll-cv") || 0 == strcmp(poller, "poll"))) { + if (poller != nullptr && (0 == strcmp(poller, "poll"))) { gpr_free(poller); return; } diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 7daabd50527..5e4338aee37 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -304,14 +304,3 @@ grpc_cc_test( "//test/core/util:grpc_test_util", ], ) - -grpc_cc_test( - name = "wakeup_fd_cv_test", - srcs = ["wakeup_fd_cv_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//:grpc", - "//test/core/util:grpc_test_util", - ], -) diff --git a/test/core/iomgr/wakeup_fd_cv_test.cc b/test/core/iomgr/wakeup_fd_cv_test.cc deleted file mode 100644 index f297a569d2d..00000000000 --- a/test/core/iomgr/wakeup_fd_cv_test.cc +++ /dev/null @@ -1,243 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "src/core/lib/iomgr/port.h" - -#ifdef GRPC_POSIX_SOCKET - -#include - -#include -#include - -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/gprpp/thd.h" -#include "src/core/lib/iomgr/ev_posix.h" -#include "src/core/lib/iomgr/iomgr_posix.h" - -typedef struct poll_args { - struct pollfd* fds; - nfds_t nfds; - int timeout; - int result; -} poll_args; - -gpr_cv poll_cv; -gpr_mu poll_mu; -static int socket_event = 0; - -// Trigger a "socket" POLLIN in mock_poll() -void trigger_socket_event() { - gpr_mu_lock(&poll_mu); - socket_event = 1; - gpr_cv_broadcast(&poll_cv); - gpr_mu_unlock(&poll_mu); -} - -void reset_socket_event() { - gpr_mu_lock(&poll_mu); - socket_event = 0; - gpr_mu_unlock(&poll_mu); -} - -// Mocks posix poll() function -int mock_poll(struct pollfd* fds, nfds_t nfds, int timeout) { - int res = 0; - gpr_timespec poll_time; - gpr_mu_lock(&poll_mu); - GPR_ASSERT(nfds == 3); - GPR_ASSERT(fds[0].fd == 20); - GPR_ASSERT(fds[1].fd == 30); - GPR_ASSERT(fds[2].fd == 50); - GPR_ASSERT(fds[0].events == (POLLIN | POLLHUP)); - GPR_ASSERT(fds[1].events == (POLLIN | POLLHUP)); - GPR_ASSERT(fds[2].events == POLLIN); - - if (timeout < 0) { - poll_time = gpr_inf_future(GPR_CLOCK_REALTIME); - } else { - poll_time = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis(timeout, GPR_TIMESPAN)); - } - - if (socket_event || !gpr_cv_wait(&poll_cv, &poll_mu, poll_time)) { - fds[0].revents = POLLIN; - res = 1; - } - gpr_mu_unlock(&poll_mu); - return res; -} - -void background_poll(void* args) { - poll_args* pargs = static_cast(args); - pargs->result = grpc_poll_function(pargs->fds, pargs->nfds, pargs->timeout); -} - -void test_many_fds(void) { - int i; - grpc_wakeup_fd fd[1000]; - for (i = 0; i < 1000; i++) { - GPR_ASSERT(grpc_wakeup_fd_init(&fd[i]) == GRPC_ERROR_NONE); - } - for (i = 0; i < 1000; i++) { - grpc_wakeup_fd_destroy(&fd[i]); - } -} - -void test_poll_cv_trigger(void) { - grpc_wakeup_fd cvfd1, cvfd2, cvfd3; - struct pollfd pfds[6]; - poll_args pargs; - - GPR_ASSERT(grpc_wakeup_fd_init(&cvfd1) == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_wakeup_fd_init(&cvfd2) == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_wakeup_fd_init(&cvfd3) == GRPC_ERROR_NONE); - GPR_ASSERT(cvfd1.read_fd < 0); - GPR_ASSERT(cvfd2.read_fd < 0); - GPR_ASSERT(cvfd3.read_fd < 0); - GPR_ASSERT(cvfd1.read_fd != cvfd2.read_fd); - GPR_ASSERT(cvfd2.read_fd != cvfd3.read_fd); - GPR_ASSERT(cvfd1.read_fd != cvfd3.read_fd); - - pfds[0].fd = cvfd1.read_fd; - pfds[1].fd = cvfd2.read_fd; - pfds[2].fd = 20; - pfds[3].fd = 30; - pfds[4].fd = cvfd3.read_fd; - pfds[5].fd = 50; - - pfds[0].events = 0; - pfds[1].events = POLLIN; - pfds[2].events = POLLIN | POLLHUP; - pfds[3].events = POLLIN | POLLHUP; - pfds[4].events = POLLIN; - pfds[5].events = POLLIN; - - pargs.fds = pfds; - pargs.nfds = 6; - pargs.timeout = 1000; - pargs.result = -2; - - { - grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); - thd.Start(); - // Wakeup wakeup_fd not listening for events - GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd1) == GRPC_ERROR_NONE); - thd.Join(); - GPR_ASSERT(pargs.result == 0); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == 0); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - } - - { - // Pollin on socket fd - pargs.timeout = -1; - pargs.result = -2; - grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); - thd.Start(); - trigger_socket_event(); - thd.Join(); - GPR_ASSERT(pargs.result == 1); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == 0); - GPR_ASSERT(pfds[2].revents == POLLIN); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - } - - { - // Pollin on wakeup fd - reset_socket_event(); - pargs.result = -2; - grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); - thd.Start(); - GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd2) == GRPC_ERROR_NONE); - thd.Join(); - - GPR_ASSERT(pargs.result == 1); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == POLLIN); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - } - - { - // Pollin on wakeupfd before poll() - pargs.result = -2; - grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); - thd.Start(); - thd.Join(); - - GPR_ASSERT(pargs.result == 1); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == POLLIN); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - } - - { - // No Events - pargs.result = -2; - pargs.timeout = 1000; - reset_socket_event(); - GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd1) == GRPC_ERROR_NONE); - GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd2) == GRPC_ERROR_NONE); - grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs); - thd.Start(); - thd.Join(); - - GPR_ASSERT(pargs.result == 0); - GPR_ASSERT(pfds[0].revents == 0); - GPR_ASSERT(pfds[1].revents == 0); - GPR_ASSERT(pfds[2].revents == 0); - GPR_ASSERT(pfds[3].revents == 0); - GPR_ASSERT(pfds[4].revents == 0); - GPR_ASSERT(pfds[5].revents == 0); - } -} - -int main(int argc, char** argv) { - gpr_setenv("GRPC_POLL_STRATEGY", "poll-cv"); - grpc_poll_function = &mock_poll; - gpr_mu_init(&poll_mu); - gpr_cv_init(&poll_cv); - grpc_determine_iomgr_platform(); - grpc_iomgr_platform_init(); - test_many_fds(); - grpc_iomgr_platform_shutdown(); - - grpc_iomgr_platform_init(); - test_poll_cv_trigger(); - grpc_iomgr_platform_shutdown(); - return 0; -} - -#else /* GRPC_POSIX_SOCKET */ - -int main(int argc, char** argv) { return 1; } - -#endif /* GRPC_POSIX_SOCKET */ diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc index 0c0492fdbbd..476e424b1eb 100644 --- a/test/core/util/test_config.cc +++ b/test/core/util/test_config.cc @@ -382,13 +382,6 @@ gpr_timespec grpc_timeout_milliseconds_to_deadline(int64_t time_ms) { void grpc_test_init(int argc, char** argv) { install_crash_handler(); - { /* poll-cv poll strategy runs much more slowly than anything else */ - char* s = gpr_getenv("GRPC_POLL_STRATEGY"); - if (s != nullptr && 0 == strcmp(s, "poll-cv")) { - g_poller_slowdown_factor = 5; - } - gpr_free(s); - } gpr_log(GPR_DEBUG, "test slowdown factor: sanitizer=%" PRId64 ", fixture=%" PRId64 ", poller=%" PRId64 ", total=%" PRId64, diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 664a6b3acfe..c0078bf2764 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1146,7 +1146,6 @@ src/core/lib/iomgr/timer_heap.h \ src/core/lib/iomgr/timer_manager.h \ src/core/lib/iomgr/udp_server.h \ src/core/lib/iomgr/unix_sockets_posix.h \ -src/core/lib/iomgr/wakeup_fd_cv.h \ src/core/lib/iomgr/wakeup_fd_pipe.h \ src/core/lib/iomgr/wakeup_fd_posix.h \ src/core/lib/json/json.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index f01531a0078..6e4a57ba00f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1323,8 +1323,6 @@ src/core/lib/iomgr/udp_server.h \ src/core/lib/iomgr/unix_sockets_posix.cc \ src/core/lib/iomgr/unix_sockets_posix.h \ src/core/lib/iomgr/unix_sockets_posix_noop.cc \ -src/core/lib/iomgr/wakeup_fd_cv.cc \ -src/core/lib/iomgr/wakeup_fd_cv.h \ src/core/lib/iomgr/wakeup_fd_eventfd.cc \ src/core/lib/iomgr/wakeup_fd_nospecial.cc \ src/core/lib/iomgr/wakeup_fd_pipe.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 5a1eafda6c2..7a72a885336 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -2395,22 +2395,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "gpr", - "grpc", - "grpc_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "wakeup_fd_cv_test", - "src": [ - "test/core/iomgr/wakeup_fd_cv_test.cc" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "gpr", @@ -9554,7 +9538,6 @@ "src/core/lib/iomgr/udp_server.cc", "src/core/lib/iomgr/unix_sockets_posix.cc", "src/core/lib/iomgr/unix_sockets_posix_noop.cc", - "src/core/lib/iomgr/wakeup_fd_cv.cc", "src/core/lib/iomgr/wakeup_fd_eventfd.cc", "src/core/lib/iomgr/wakeup_fd_nospecial.cc", "src/core/lib/iomgr/wakeup_fd_pipe.cc", @@ -9720,7 +9703,6 @@ "src/core/lib/iomgr/timer_manager.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", - "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/json/json.h", @@ -9874,7 +9856,6 @@ "src/core/lib/iomgr/timer_manager.h", "src/core/lib/iomgr/udp_server.h", "src/core/lib/iomgr/unix_sockets_posix.h", - "src/core/lib/iomgr/wakeup_fd_cv.h", "src/core/lib/iomgr/wakeup_fd_pipe.h", "src/core/lib/iomgr/wakeup_fd_posix.h", "src/core/lib/json/json.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 9df57b5e151..c86339398b5 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -2959,30 +2959,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "gtest": false, - "language": "c", - "name": "wakeup_fd_cv_test", - "platforms": [ - "linux", - "mac", - "posix" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, @@ -3669,8 +3645,7 @@ "exclude_configs": [], "exclude_iomgrs": [], "excluded_poll_engines": [ - "poll", - "poll-cv" + "poll" ], "flaky": false, "gtest": false, @@ -3696,8 +3671,7 @@ "exclude_configs": [], "exclude_iomgrs": [], "excluded_poll_engines": [ - "poll", - "poll-cv" + "poll" ], "flaky": false, "gtest": false, @@ -3725,8 +3699,7 @@ ], "exclude_iomgrs": [], "excluded_poll_engines": [ - "poll", - "poll-cv" + "poll" ], "flaky": false, "gtest": false, @@ -3752,8 +3725,7 @@ "exclude_configs": [], "exclude_iomgrs": [], "excluded_poll_engines": [ - "poll", - "poll-cv" + "poll" ], "flaky": false, "gtest": false, @@ -60416,7 +60388,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -60429,9 +60401,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -60470,7 +60440,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -60483,9 +60453,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -61382,7 +61350,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -61395,9 +61363,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -61436,7 +61402,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -61449,9 +61415,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -62375,7 +62339,7 @@ "args": [ "--run_inproc", "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "boringssl": true, "ci_platforms": [ @@ -62387,9 +62351,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "qps_json_driver", @@ -62429,7 +62391,7 @@ "args": [ "--run_inproc", "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "boringssl": true, "ci_platforms": [ @@ -62441,9 +62403,7 @@ "tsan", "asan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "qps_json_driver", @@ -63434,7 +63394,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -63461,9 +63421,7 @@ "stapprof", "ubsan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -63516,7 +63474,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -63543,9 +63501,7 @@ "stapprof", "ubsan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -64918,7 +64874,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -64945,9 +64901,7 @@ "stapprof", "ubsan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", @@ -65000,7 +64954,7 @@ { "args": [ "--scenarios_json", - "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_servers\": 1, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" + "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"SYNC_SERVER\"}, \"num_clients\": 0, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}, {\"int_value\": 1, \"name\": \"grpc.minimal_stack\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"STREAMING\", \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], "auto_timeout_scaling": false, "boringssl": true, @@ -65027,9 +64981,7 @@ "stapprof", "ubsan" ], - "excluded_poll_engines": [ - "poll-cv" - ], + "excluded_poll_engines": [], "flaky": false, "language": "c++", "name": "json_run_localhost", diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index 481918c52e4..ac25b22d9e4 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -463,8 +463,7 @@ class CXXLanguage: secure=secure, minimal_stack=not secure, categories=smoketest_categories + inproc_categories + - [SCALABLE], - excluded_poll_engines=['poll-cv']) + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_%s' @@ -490,8 +489,7 @@ class CXXLanguage: secure=secure, minimal_stack=not secure, categories=smoketest_categories + inproc_categories + - [SCALABLE], - excluded_poll_engines=['poll-cv']) + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_unary_ping_pong_%s_1MB' % secstr, diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index ed1c41e3256..19a79ea41dd 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -61,7 +61,7 @@ _FORCE_ENVIRON_FOR_WRAPPERS = { } _POLLING_STRATEGIES = { - 'linux': ['epollex', 'epoll1', 'poll', 'poll-cv'], + 'linux': ['epollex', 'epoll1', 'poll'], 'mac': ['poll'], } From 4241edeaa45972465e707d5a2d182a3c447e2610 Mon Sep 17 00:00:00 2001 From: billfeng327 Date: Thu, 7 Mar 2019 14:52:49 -0800 Subject: [PATCH 622/814] renamed tag to no_windows in conformation with Bazel and TensorFlow --- test/core/bad_connection/BUILD | 2 +- test/core/client_channel/BUILD | 2 +- test/core/iomgr/BUILD | 20 +++++------ test/cpp/common/BUILD | 2 +- test/cpp/end2end/BUILD | 4 +-- test/cpp/interop/BUILD | 2 +- test/cpp/microbenchmarks/BUILD | 34 +++++++++---------- .../generate_resolver_component_tests.bzl | 6 ++-- test/cpp/performance/BUILD | 2 +- test/cpp/qps/qps_benchmark_script.bzl | 2 +- test/cpp/server/BUILD | 6 ++-- test/cpp/server/load_reporter/BUILD | 2 +- tools/remote_build/windows.bazelrc | 4 +-- 13 files changed, 44 insertions(+), 44 deletions(-) diff --git a/test/core/bad_connection/BUILD b/test/core/bad_connection/BUILD index 4de9c0eb2d8..82b38ccc469 100644 --- a/test/core/bad_connection/BUILD +++ b/test/core/bad_connection/BUILD @@ -29,5 +29,5 @@ grpc_cc_binary( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD index d67f326aa6d..68a71632daf 100644 --- a/test/core/client_channel/BUILD +++ b/test/core/client_channel/BUILD @@ -52,7 +52,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index f9da7f7ba73..57d8c70db1d 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -81,7 +81,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -93,7 +93,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -105,7 +105,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -142,7 +142,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -157,7 +157,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -219,7 +219,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -231,7 +231,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -244,7 +244,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -267,7 +267,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -312,7 +312,7 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD index e4ed3bc5460..b67c1995ff7 100644 --- a/test/cpp/common/BUILD +++ b/test/cpp/common/BUILD @@ -28,7 +28,7 @@ grpc_cc_test( "//:grpc++_unsecure", "//test/core/util:grpc_test_util_unsecure", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index a0c7567c2b0..56b3219ae17 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -99,7 +99,7 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -630,7 +630,7 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index d74566f56a7..6cf4719c17b 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -161,5 +161,5 @@ grpc_cc_test( "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index db37d37af6c..1ce71b1bb99 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -45,7 +45,7 @@ grpc_cc_library( "//test/core/util:grpc_test_util_unsecure", "//test/cpp/util:test_config", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -53,7 +53,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_closure.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -61,7 +61,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_alarm.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -76,7 +76,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_byte_buffer.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -84,7 +84,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_channel.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -92,7 +92,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_call_create.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -100,7 +100,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_cq.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -108,7 +108,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_cq_multiple_threads.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -116,7 +116,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_error.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_library( @@ -126,7 +126,7 @@ grpc_cc_library( "fullstack_streaming_ping_pong.h", ], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -136,7 +136,7 @@ grpc_cc_binary( "bm_fullstack_streaming_ping_pong.cc", ], deps = [":fullstack_streaming_ping_pong_h"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_library( @@ -155,7 +155,7 @@ grpc_cc_binary( "bm_fullstack_streaming_pump.cc", ], deps = [":fullstack_streaming_pump_h"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -163,7 +163,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_fullstack_trickle.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_library( @@ -182,7 +182,7 @@ grpc_cc_binary( "bm_fullstack_unary_ping_pong.cc", ], deps = [":fullstack_unary_ping_pong_h"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -190,7 +190,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_metadata.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -198,7 +198,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_chttp2_hpack.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_binary( @@ -218,5 +218,5 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_timer.cc"], deps = [":helpers"], - tags = ["exclude_windows"], + tags = ["no_windows"], ) diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl index 8e584289628..589176762e6 100755 --- a/test/cpp/naming/generate_resolver_component_tests.bzl +++ b/test/cpp/naming/generate_resolver_component_tests.bzl @@ -33,7 +33,7 @@ def generate_resolver_component_tests(): "//:gpr", "//test/cpp/util:test_config", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) # meant to be invoked only through the top-level shell script driver grpc_cc_binary( @@ -53,7 +53,7 @@ def generate_resolver_component_tests(): "//:gpr", "//test/cpp/util:test_config", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( name = "resolver_component_tests_runner_invoker%s" % unsecure_build_config_suffix, @@ -80,5 +80,5 @@ def generate_resolver_component_tests(): "--test_bin_name=resolver_component_test%s" % unsecure_build_config_suffix, "--running_under_bazel=true", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) diff --git a/test/cpp/performance/BUILD b/test/cpp/performance/BUILD index ddc41e75102..6068c33f95f 100644 --- a/test/cpp/performance/BUILD +++ b/test/cpp/performance/BUILD @@ -31,5 +31,5 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_base", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl index 23b42c02b64..b4767ec8e09 100644 --- a/test/cpp/qps/qps_benchmark_script.bzl +++ b/test/cpp/qps/qps_benchmark_script.bzl @@ -75,6 +75,6 @@ def json_run_localhost_batch(): ], tags = [ "json_run_localhost", - "exclude_windows", + "no_windows", ], ) diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD index 3c4b35af709..a4811031691 100644 --- a/test/cpp/server/BUILD +++ b/test/cpp/server/BUILD @@ -29,7 +29,7 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -43,7 +43,7 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( @@ -57,5 +57,5 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD index 2286119324b..db5c93263ad 100644 --- a/test/cpp/server/load_reporter/BUILD +++ b/test/cpp/server/load_reporter/BUILD @@ -45,7 +45,7 @@ grpc_cc_test( "//:lb_server_load_reporting_filter", "//test/core/util:grpc_test_util", ], - tags = ["exclude_windows"], + tags = ["no_windows"], ) grpc_cc_test( diff --git a/tools/remote_build/windows.bazelrc b/tools/remote_build/windows.bazelrc index 86025006e3d..11f57cac32d 100644 --- a/tools/remote_build/windows.bazelrc +++ b/tools/remote_build/windows.bazelrc @@ -1,3 +1,3 @@ # TODO(yfen): Merge with rbe_common.bazelrc and enable Windows RBE -build --test_tag_filters=-exclude_windows -build --build_tag_filters=-exclude_windows \ No newline at end of file +build --test_tag_filters=-no_windows +build --build_tag_filters=-no_windows \ No newline at end of file From 620d80d8172995706da6e9f7284008ffb56869ce Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 7 Mar 2019 15:03:31 -0800 Subject: [PATCH 623/814] Remove poll-cv references from bazel and run_tests.py --- bazel/grpc_build_system.bzl | 2 +- tools/run_tests/run_tests.py | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 3ea8e305ca5..dbcaece7a36 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -26,7 +26,7 @@ load("//bazel:cc_grpc_library.bzl", "cc_grpc_library") # The set of pollers to test against if a test exercises polling -POLLERS = ["epollex", "epoll1", "poll", "poll-cv"] +POLLERS = ["epollex", "epoll1", "poll"] def if_not_windows(a): return select({ diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 19a79ea41dd..f1e1f539ff9 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -345,15 +345,6 @@ class CLanguage(object): # Scale overall test timeout if running under various sanitizers. # scaling value is based on historical data analysis timeout_scaling *= 3 - elif polling_strategy == 'poll-cv': - # scale test timeout if running with poll-cv - # sanitizer and poll-cv scaling is not cumulative to ensure - # reasonable timeout values. - # TODO(jtattermusch): based on historical data and 5min default - # test timeout poll-cv scaling is currently not useful. - # Leaving here so it can be reintroduced if the default test timeout - # is decreased in the future. - timeout_scaling *= 1 if self.config.build_config in target['exclude_configs']: continue From 4966adaeaef20531f85c00236d4cb63aab2e30c1 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 7 Mar 2019 15:15:44 -0800 Subject: [PATCH 624/814] Disable two flaky gevent tests --- src/python/grpcio_tests/commands.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 866fb6de1f7..80f228a91d5 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -135,7 +135,8 @@ class TestGevent(setuptools.Command): # This test will stuck while running higher version of gevent 'unit._auth_context_test.AuthContextTest.testSessionResumption', # TODO(https://github.com/grpc/grpc/issues/15411) enable these tests - 'unit._metadata_flags_test', + 'unit._channel_ready_future_test.ChannelReadyFutureTest.test_immediately_connectable_channel_connectivity', + "unit._cython._channel_test.ChannelTest.test_single_channel_lonely_connectivity", 'unit._exit_test.ExitTest.test_in_flight_unary_unary_call', 'unit._exit_test.ExitTest.test_in_flight_unary_stream_call', 'unit._exit_test.ExitTest.test_in_flight_stream_unary_call', @@ -143,6 +144,7 @@ class TestGevent(setuptools.Command): 'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call', 'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call', 'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call', + 'unit._metadata_flags_test', 'health_check._health_servicer_test.HealthServicerTest.test_cancelled_watch_removed_from_watch_list', # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels', From 9e102ea8b044813036d509551996f33d953e07b2 Mon Sep 17 00:00:00 2001 From: billfeng327 Date: Thu, 7 Mar 2019 16:14:02 -0800 Subject: [PATCH 625/814] excluded non-compatible test --- test/cpp/microbenchmarks/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 1ce71b1bb99..6e844a6dc62 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -69,6 +69,7 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_arena.cc"], deps = [":helpers"], + tags = ["no_windows"], ) grpc_cc_binary( From 5c4823c17b302b92a456499e279370dcc378bada Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 7 Mar 2019 16:34:48 -0800 Subject: [PATCH 626/814] Build with bazel --- examples/python/multiprocessing/BUILD | 7 ++++++- examples/python/multiprocessing/server.py | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index e47fb654aac..5fd32597355 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -7,6 +7,7 @@ py_binary( deps = [ "//src/python/grpcio/grpc:grpcio" ], + default_python_version = "PY3", ) py_binary( @@ -15,7 +16,11 @@ py_binary( srcs = ["server.py"], deps = [ "//src/python/grpcio/grpc:grpcio" - ], + ] + select({ + "//conditions:default": [requirement("futures")], + "//:python3": [], + }), + default_python_version = "PY3", ) py_test( diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index 6801f806126..5299589bb21 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -63,7 +63,7 @@ def _wait_forever(server): def _run_server(bind_address): """Start a server in a subprocess.""" - logging.warning( '[PID {}] Starting new server.'.format( os.getpid())) + logging.warning( '[PID {}] Starting new server.'.format(os.getpid())) options = (('grpc.so_reuseport', 1),) # WARNING: This example takes advantage of SO_REUSEPORT. Due to the @@ -87,6 +87,8 @@ def _reserve_port(): """Find and reserve a port for all subprocesses to use.""" sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) != 1: + raise RuntimeError("Failed to set SO_REUSEPORT.") sock.bind(('', 0)) try: yield sock.getsockname()[1] From 3eba2e6fd4924893bd394c14274a99ccf00c601c Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Thu, 7 Mar 2019 16:40:54 -0800 Subject: [PATCH 627/814] bump ver to 1.19.1 --- BUILD | 2 +- build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD b/BUILD index f5f6f7714cf..dde52688813 100644 --- a/BUILD +++ b/BUILD @@ -68,7 +68,7 @@ g_stands_for = "gold" core_version = "7.0.0" -version = "1.19.0" +version = "1.19.1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 89f4eed7206..1a60155d6de 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 7.0.0 g_stands_for: gold - version: 1.19.0 + version: 1.19.1 filegroups: - name: alts_proto headers: From 9e9cc11d2b2ee711662bd78cbf24c069e1cc753f Mon Sep 17 00:00:00 2001 From: Srini Polavarapu Date: Thu, 7 Mar 2019 16:48:38 -0800 Subject: [PATCH 628/814] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 4 ++-- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 4 ++-- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_channelz/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_status/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 30 files changed, 34 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e2fe1f9e0f..75aa7f46164 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "grpc") -set(PACKAGE_VERSION "1.19.0") +set(PACKAGE_VERSION "1.19.1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index b45a2398922..d8a0e016b2c 100644 --- a/Makefile +++ b/Makefile @@ -438,8 +438,8 @@ Q = @ endif CORE_VERSION = 7.0.0 -CPP_VERSION = 1.19.0 -CSHARP_VERSION = 1.19.0 +CPP_VERSION = 1.19.1 +CSHARP_VERSION = 1.19.1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index a50efc6aee9..3fe52f0b0cf 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,7 +23,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.19.0' + # version = '1.19.1' version = '0.0.8' s.version = version s.summary = 'gRPC C++ library' @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.19.0' + grpc_version = '1.19.1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f2b824372f7..a2c730701dd 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.19.0' + version = '1.19.1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 80912221546..54ffb988e68 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.19.0' + version = '1.19.1' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 25d2f778464..274ad362cd4 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.19.0' + version = '1.19.1' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index 77c6f7abd8c..ec9c362c9de 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.19.0' + version = '1.19.1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 04cea9ac5fa..8f144d77a2e 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.19.0 - 1.19.0 + 1.19.1 + 1.19.1 stable diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 9fde35b0690..611e99505fe 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.19.0"; } +grpc::string Version() { return "1.19.1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 0b9aafb8278..6354a053965 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.19.0 + 1.19.1 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index f683477975d..7e8e9bdd246 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.19.0.0"; + public const string CurrentAssemblyFileVersion = "1.19.1.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.19.0"; + public const string CurrentVersion = "1.19.1"; } } diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 8874a11020e..89532f053c5 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.19.0 +set VERSION=1.19.1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index d4b836e98ff..642286ab5c7 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.19.0' + v = '1.19.1' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h index a48bd904087..f75b1f77caa 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.19.0" +#define GRPC_OBJC_VERSION_STRING @"1.19.1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index a9bb2178393..f3b4fa8dd63 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.19.0" +#define GRPC_OBJC_VERSION_STRING @"1.19.1" #define GRPC_C_VERSION_STRING @"7.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index 75fab483f14..3f005974199 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -2,7 +2,7 @@ "name": "grpc/grpc-dev", "description": "gRPC library for PHP - for Developement use only", "license": "Apache-2.0", - "version": "1.19.0", + "version": "1.19.1", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index e673da4374b..7d5a02ae4e3 100644 --- a/src/php/ext/grpc/version.h +++ b/src/php/ext/grpc/version.h @@ -20,6 +20,6 @@ #ifndef VERSION_H #define VERSION_H -#define PHP_GRPC_VERSION "1.19.0" +#define PHP_GRPC_VERSION "1.19.1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 571243bda0c..124069a81c4 100644 --- a/src/python/grpcio/grpc/_grpcio_metadata.py +++ b/src/python/grpcio/grpc/_grpcio_metadata.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!! -__version__ = """1.19.0""" +__version__ = """1.19.1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 82c8859089e..4ba48692938 100644 --- a/src/python/grpcio/grpc_version.py +++ b/src/python/grpcio/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!! -VERSION = '1.19.0' +VERSION = '1.19.1' diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py index bd30f636223..094d38a3d1f 100644 --- a/src/python/grpcio_channelz/grpc_version.py +++ b/src/python/grpcio_channelz/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!! -VERSION = '1.19.0' +VERSION = '1.19.1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index c37c99e6b63..6b4572180ab 100644 --- a/src/python/grpcio_health_checking/grpc_version.py +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! -VERSION = '1.19.0' +VERSION = '1.19.1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index f540ffe904c..c75bfcb1390 100644 --- a/src/python/grpcio_reflection/grpc_version.py +++ b/src/python/grpcio_reflection/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!! -VERSION = '1.19.0' +VERSION = '1.19.1' diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py index 89419367f2e..05db71eeffe 100644 --- a/src/python/grpcio_status/grpc_version.py +++ b/src/python/grpcio_status/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!! -VERSION = '1.19.0' +VERSION = '1.19.1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 4b92d7c28ef..85f37ea399a 100644 --- a/src/python/grpcio_testing/grpc_version.py +++ b/src/python/grpcio_testing/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!! -VERSION = '1.19.0' +VERSION = '1.19.1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 02c20a41887..4b88cb8cd16 100644 --- a/src/python/grpcio_tests/grpc_version.py +++ b/src/python/grpcio_tests/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!! -VERSION = '1.19.0' +VERSION = '1.19.1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 8c161167ec7..10885ac98d6 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -14,5 +14,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '1.19.0' + VERSION = '1.19.1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index d53d6b47bf2..4e0409bc6df 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.19.0' + VERSION = '1.19.1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 09c7466bfeb..76446b2819d 100644 --- a/tools/distrib/python/grpcio_tools/grpc_version.py +++ b/tools/distrib/python/grpcio_tools/grpc_version.py @@ -14,4 +14,4 @@ # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!! -VERSION = '1.19.0' +VERSION = '1.19.1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index db3d593b75f..0fd513d8b84 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.19.0 +PROJECT_NUMBER = 1.19.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 7b3efe72309..74bbec977a8 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.19.0 +PROJECT_NUMBER = 1.19.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From c619c49fab00c3348ee50da46f4a11d91ecee038 Mon Sep 17 00:00:00 2001 From: Jerry Date: Thu, 7 Mar 2019 17:31:34 -0800 Subject: [PATCH 629/814] fixed seg fault caused by access client after it is closed --- src/php/ext/grpc/call.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index a7942262987..668095cfbd2 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -217,6 +217,12 @@ PHP_METHOD(Call, __construct) { } wrapped_grpc_channel *channel = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel, channel_obj); + if (channel->wrapper == NULL || channel->wrapper->wrapped == NULL) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Call cannot be constructed from a closed Channel", + 1 TSRMLS_CC); + return; + } gpr_mu_lock(&channel->wrapper->mu); if (channel->wrapper == NULL || channel->wrapper->wrapped == NULL) { zend_throw_exception(spl_ce_InvalidArgumentException, From 98fc9022005126897b809c5337944afadf27c619 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 7 Mar 2019 17:34:45 -0800 Subject: [PATCH 630/814] Revert "Roll foward "Strip Python wheel binary"" --- test/distrib/python/test_packages.sh | 2 +- .../artifacts/build_package_python.sh | 21 ------------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/test/distrib/python/test_packages.sh b/test/distrib/python/test_packages.sh index 433148e6bd7..755daa10211 100755 --- a/test/distrib/python/test_packages.sh +++ b/test/distrib/python/test_packages.sh @@ -41,7 +41,7 @@ PYTHON=$VIRTUAL_ENV/bin/python function at_least_one_installs() { for file in "$@"; do - if "$PYTHON" -m pip install --require-hashes "$file"; then + if "$PYTHON" -m pip install "$file"; then return 0 fi done diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh index 29a26bc081c..29801a5b867 100755 --- a/tools/run_tests/artifacts/build_package_python.sh +++ b/tools/run_tests/artifacts/build_package_python.sh @@ -23,27 +23,6 @@ mkdir -p artifacts/ # and we only collect them here to deliver them to the distribtest phase. cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/python_*/* artifacts/ || true -apt-get install -y python-pip -python -m pip install wheel --user - -strip_binary_wheel() { - WHEEL_PATH="$1" - TEMP_WHEEL_DIR=$(mktemp -d) - python -m wheel unpack "$WHEEL_PATH" -d "$TEMP_WHEEL_DIR" - find "$TEMP_WHEEL_DIR" -name "_protoc_compiler*.so" -exec strip --strip-debug {} ";" - find "$TEMP_WHEEL_DIR" -name "cygrpc*.so" -exec strip --strip-debug {} ";" - - WHEEL_FILE=$(basename "$WHEEL_PATH") - DISTRIBUTION_NAME=$(basename "$WHEEL_PATH" | cut -d '-' -f 1) - VERSION=$(basename "$WHEEL_PATH" | cut -d '-' -f 2) - python -m wheel pack "$TEMP_WHEEL_DIR/$DISTRIBUTION_NAME-$VERSION" -d "$TEMP_WHEEL_DIR" - mv "$TEMP_WHEEL_DIR/$WHEEL_FILE" "$WHEEL_PATH" -} - -for wheel in artifacts/*.whl; do - strip_binary_wheel "$wheel" -done - # TODO: all the artifact builder configurations generate a grpcio-VERSION.tar.gz # source distribution package, and only one of them will end up # in the artifacts/ directory. They should be all equivalent though. From 6b45cea2f0fa10ab44d5446105df4dff8be2d656 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 7 Mar 2019 17:56:49 -0800 Subject: [PATCH 631/814] Remove from poll-cv comments too --- src/core/lib/iomgr/ev_poll_posix.cc | 2 +- test/core/end2end/tests/keepalive_timeout.cc | 3 +-- test/cpp/end2end/BUILD | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index 4c98ffa9448..29111dd44ed 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -125,7 +125,7 @@ struct grpc_fd { grpc_fork_fd_list* fork_fd_list; }; -/* True when GRPC_ENABLE_FORK_SUPPORT=1. We do not support fork with poll-cv */ +/* True when GRPC_ENABLE_FORK_SUPPORT=1. */ static bool track_fds_for_fork = false; /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index 2c992848b95..3c33f0419ad 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -226,8 +226,7 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { * that the keepalive ping is never sent. */ static void test_read_delays_keepalive(grpc_end2end_test_config config) { char* poller = gpr_getenv("GRPC_POLL_STRATEGY"); - /* It is hard to get the timing right for the polling engines poll and poll-cv - */ + /* It is hard to get the timing right for the polling engine poll. */ if (poller != nullptr && (0 == strcmp(poller, "poll"))) { gpr_free(poller); return; diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 43dee177e7a..26095a41607 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -242,7 +242,7 @@ grpc_cc_test( grpc_cc_test( name = "end2end_test", - size = "large", # with poll-cv this takes long, see #17493 + size = "large", deps = [ ":end2end_test_lib", ], From 37ba57ec48af127ad79efd2ccd26aa3cc0786b1a Mon Sep 17 00:00:00 2001 From: Jonas Vautherin Date: Fri, 8 Mar 2019 13:44:30 +0100 Subject: [PATCH 632/814] Bugfix: cc_install following a cc_library must use BUILD_CODEGEN, too --- CMakeLists.txt | 6 ++++++ templates/CMakeLists.txt.template | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ccda85b125..f504980e1ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3828,6 +3828,7 @@ foreach(_hdr endforeach() endif (gRPC_BUILD_CODEGEN) +if (gRPC_BUILD_CODEGEN) if (gRPC_INSTALL) install(TARGETS grpc++_error_details EXPORT gRPCTargets @@ -3837,6 +3838,7 @@ if (gRPC_INSTALL) ) endif() +endif (gRPC_BUILD_CODEGEN) if (gRPC_BUILD_TESTS) if (gRPC_BUILD_CODEGEN) @@ -3958,6 +3960,7 @@ foreach(_hdr endforeach() endif (gRPC_BUILD_CODEGEN) +if (gRPC_BUILD_CODEGEN) if (gRPC_INSTALL) install(TARGETS grpc++_reflection EXPORT gRPCTargets @@ -3967,6 +3970,7 @@ if (gRPC_INSTALL) ) endif() +endif (gRPC_BUILD_CODEGEN) if (gRPC_BUILD_TESTS) add_library(grpc++_test_config @@ -4959,6 +4963,7 @@ foreach(_hdr endforeach() endif (gRPC_BUILD_CODEGEN) +if (gRPC_BUILD_CODEGEN) if (gRPC_INSTALL) install(TARGETS grpcpp_channelz EXPORT gRPCTargets @@ -4968,6 +4973,7 @@ if (gRPC_INSTALL) ) endif() +endif (gRPC_BUILD_CODEGEN) if (gRPC_BUILD_TESTS) if (gRPC_BUILD_CODEGEN) diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index e7fdfe5de55..dd996d736ac 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -331,12 +331,24 @@ % elif lib.name in ['grpc_csharp_ext']: if (gRPC_BUILD_CSHARP_EXT) ${cc_library(lib)} + % if any(proto_re.match(src) for src in lib.src): + if (gRPC_BUILD_CODEGEN) + % endif ${cc_install(lib)} + % if any(proto_re.match(src) for src in lib.src): + endif (gRPC_BUILD_CODEGEN) + % endif endif (gRPC_BUILD_CSHARP_EXT) % else: ${cc_library(lib)} % if not lib.build in ["tool"]: + % if any(proto_re.match(src) for src in lib.src): + if (gRPC_BUILD_CODEGEN) + % endif ${cc_install(lib)} + % if any(proto_re.match(src) for src in lib.src): + endif (gRPC_BUILD_CODEGEN) + % endif % endif % endif % endif From 919dc4cd2ce557308b372636307ccff8b1d9ab29 Mon Sep 17 00:00:00 2001 From: yang-g Date: Fri, 8 Mar 2019 10:04:59 -0800 Subject: [PATCH 633/814] Add comment --- src/core/lib/gpr/cpu_posix.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/lib/gpr/cpu_posix.cc b/src/core/lib/gpr/cpu_posix.cc index 59f583e4a0d..982ccbd6ffe 100644 --- a/src/core/lib/gpr/cpu_posix.cc +++ b/src/core/lib/gpr/cpu_posix.cc @@ -70,6 +70,9 @@ unsigned gpr_cpu_current_cpu(void) { unsigned int* thread_id = static_cast(pthread_getspecific(thread_id_key)); if (thread_id == nullptr) { + // Note we cannot use gpr_malloc here because this allocation can happen in + // a main thread and will only be free'd when the main thread exits, which + // will cause our internal memory counters to believe it is a leak. thread_id = static_cast(malloc(sizeof(unsigned int))); pthread_setspecific(thread_id_key, thread_id); } From 127a6c1d9e3eb17b66929eedd1cfef73ebe72706 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 8 Mar 2019 10:29:00 -0800 Subject: [PATCH 634/814] Revert "Revert "Roll foward "Strip Python wheel binary""" This reverts commit 98fc9022005126897b809c5337944afadf27c619. --- test/distrib/python/test_packages.sh | 2 +- .../artifacts/build_package_python.sh | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/test/distrib/python/test_packages.sh b/test/distrib/python/test_packages.sh index 755daa10211..433148e6bd7 100755 --- a/test/distrib/python/test_packages.sh +++ b/test/distrib/python/test_packages.sh @@ -41,7 +41,7 @@ PYTHON=$VIRTUAL_ENV/bin/python function at_least_one_installs() { for file in "$@"; do - if "$PYTHON" -m pip install "$file"; then + if "$PYTHON" -m pip install --require-hashes "$file"; then return 0 fi done diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh index 29801a5b867..29a26bc081c 100755 --- a/tools/run_tests/artifacts/build_package_python.sh +++ b/tools/run_tests/artifacts/build_package_python.sh @@ -23,6 +23,27 @@ mkdir -p artifacts/ # and we only collect them here to deliver them to the distribtest phase. cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/python_*/* artifacts/ || true +apt-get install -y python-pip +python -m pip install wheel --user + +strip_binary_wheel() { + WHEEL_PATH="$1" + TEMP_WHEEL_DIR=$(mktemp -d) + python -m wheel unpack "$WHEEL_PATH" -d "$TEMP_WHEEL_DIR" + find "$TEMP_WHEEL_DIR" -name "_protoc_compiler*.so" -exec strip --strip-debug {} ";" + find "$TEMP_WHEEL_DIR" -name "cygrpc*.so" -exec strip --strip-debug {} ";" + + WHEEL_FILE=$(basename "$WHEEL_PATH") + DISTRIBUTION_NAME=$(basename "$WHEEL_PATH" | cut -d '-' -f 1) + VERSION=$(basename "$WHEEL_PATH" | cut -d '-' -f 2) + python -m wheel pack "$TEMP_WHEEL_DIR/$DISTRIBUTION_NAME-$VERSION" -d "$TEMP_WHEEL_DIR" + mv "$TEMP_WHEEL_DIR/$WHEEL_FILE" "$WHEEL_PATH" +} + +for wheel in artifacts/*.whl; do + strip_binary_wheel "$wheel" +done + # TODO: all the artifact builder configurations generate a grpcio-VERSION.tar.gz # source distribution package, and only one of them will end up # in the artifacts/ directory. They should be all equivalent though. From cb9cc5592e3259c60f8c7f7f3d30133a322ebaba Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 7 Mar 2019 17:59:39 -0800 Subject: [PATCH 635/814] Upgrade pip before using wheel --- tools/run_tests/artifacts/build_package_python.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh index 29a26bc081c..35c78e9a93e 100755 --- a/tools/run_tests/artifacts/build_package_python.sh +++ b/tools/run_tests/artifacts/build_package_python.sh @@ -24,7 +24,8 @@ mkdir -p artifacts/ cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/python_*/* artifacts/ || true apt-get install -y python-pip -python -m pip install wheel --user +python -m pip install -U pip +python -m pip install -U wheel strip_binary_wheel() { WHEEL_PATH="$1" From 5eb1e8d8c9e715e0b5fe30bfc80c2e2f5c3e3ed1 Mon Sep 17 00:00:00 2001 From: billfeng327 Date: Fri, 8 Mar 2019 10:39:03 -0800 Subject: [PATCH 636/814] code cleanup, removed old build file --- bazel/grpc_deps.bzl | 1 - third_party/BUILD | 1 - third_party/benchmark.BUILD | 15 --------------- tools/remote_build/windows.bazelrc | 2 +- 4 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 third_party/benchmark.BUILD diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 799e864484c..2795ce8e732 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -154,7 +154,6 @@ def grpc_deps(): if "com_github_google_benchmark" not in native.existing_rules(): http_archive( name = "com_github_google_benchmark", - #build_file = "@com_github_grpc_grpc//third_party:benchmark.BUILD", strip_prefix = "benchmark-e776aa0275e293707b6a0901e0e8d8a8a3679508", url = "https://github.com/google/benchmark/archive/e776aa0275e293707b6a0901e0e8d8a8a3679508.tar.gz", ) diff --git a/third_party/BUILD b/third_party/BUILD index 5ec919dc48d..8b43d6b8300 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -1,5 +1,4 @@ exports_files([ - "benchmark.BUILD", "gtest.BUILD", "objective_c/Cronet/bidirectional_stream_c.h", "zlib.BUILD", diff --git a/third_party/benchmark.BUILD b/third_party/benchmark.BUILD deleted file mode 100644 index 4c622f32a84..00000000000 --- a/third_party/benchmark.BUILD +++ /dev/null @@ -1,15 +0,0 @@ -cc_library( - name = "benchmark", - srcs = glob(["src/*.cc"]), - hdrs = glob(["include/**/*.h", "src/*.h"]), - includes = [ - "include", "." - ], - copts = [ - "-DHAVE_POSIX_REGEX" - ], - linkstatic = 1, - visibility = [ - "//visibility:public", - ], -) diff --git a/tools/remote_build/windows.bazelrc b/tools/remote_build/windows.bazelrc index 11f57cac32d..70575372d02 100644 --- a/tools/remote_build/windows.bazelrc +++ b/tools/remote_build/windows.bazelrc @@ -1,3 +1,3 @@ # TODO(yfen): Merge with rbe_common.bazelrc and enable Windows RBE build --test_tag_filters=-no_windows -build --build_tag_filters=-no_windows \ No newline at end of file +build --build_tag_filters=-no_windows From fa7f01079517cf7075d3830eb8a207aacaa23ec6 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 8 Mar 2019 10:47:04 -0800 Subject: [PATCH 637/814] Fix the hash checking mechanism --- test/distrib/python/test_packages.sh | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/distrib/python/test_packages.sh b/test/distrib/python/test_packages.sh index 433148e6bd7..4e1e6dbc94f 100755 --- a/test/distrib/python/test_packages.sh +++ b/test/distrib/python/test_packages.sh @@ -39,9 +39,16 @@ virtualenv "$VIRTUAL_ENV" PYTHON=$VIRTUAL_ENV/bin/python "$PYTHON" -m pip install --upgrade six pip +function validate_wheel_hashes() { + for file in "$@"; do + "$PYTHON" -m wheel unpack "$file" --dest-dir /tmp || return 1 + done + return 0 +} + function at_least_one_installs() { for file in "$@"; do - if "$PYTHON" -m pip install --require-hashes "$file"; then + if "$PYTHON" -m pip install "$file"; then return 0 fi done @@ -49,6 +56,16 @@ function at_least_one_installs() { } +# +# Validate the files in wheel matches their hashes and size in RECORD +# + +if [[ "$1" == "binary" ]]; then + validate_wheel_hashes "${ARCHIVES[@]}" + validate_wheel_hashes "${TOOLS_ARCHIVES[@]}" +fi + + # # Install our distributions in order of dependencies # From e2aef4d373089d0068666cc87502c18449358831 Mon Sep 17 00:00:00 2001 From: Jerry Date: Fri, 8 Mar 2019 10:48:56 -0800 Subject: [PATCH 638/814] fixed seg fault --- src/php/ext/grpc/call.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index 668095cfbd2..46d1e22f1f8 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -217,7 +217,7 @@ PHP_METHOD(Call, __construct) { } wrapped_grpc_channel *channel = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel, channel_obj); - if (channel->wrapper == NULL || channel->wrapper->wrapped == NULL) { + if (channel->wrapper == NULL) { zend_throw_exception(spl_ce_InvalidArgumentException, "Call cannot be constructed from a closed Channel", 1 TSRMLS_CC); From acbc095ab8f29957bec0c1da6d0a613f4378101d Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 13:40:44 -0800 Subject: [PATCH 639/814] Implement test for example --- examples/python/multiprocessing/BUILD | 5 +- examples/python/multiprocessing/README.md | 3 + examples/python/multiprocessing/client.py | 23 ++++-- examples/python/multiprocessing/server.py | 20 +++-- .../test/_multiprocessing_example_test.py | 74 +++++++++++++++++++ .../test/_multiprocessing_test.py | 0 6 files changed, 113 insertions(+), 12 deletions(-) create mode 100644 examples/python/multiprocessing/test/_multiprocessing_example_test.py delete mode 100644 examples/python/multiprocessing/test/_multiprocessing_test.py diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index 5fd32597355..48b98f3ad20 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -24,10 +24,11 @@ py_binary( ) py_test( - name = "_multiprocessing_example_test", + name = "test/_multiprocessing_example_test", srcs = ["test/_multiprocessing_example_test.py"], data = [ ":client", ":server" - ] + ], + size = "small", ) diff --git a/examples/python/multiprocessing/README.md b/examples/python/multiprocessing/README.md index e69de29bb2d..da0c411dc09 100644 --- a/examples/python/multiprocessing/README.md +++ b/examples/python/multiprocessing/README.md @@ -0,0 +1,3 @@ +TODO: Describe the example. +TODO: Describe how to run the example. +TODO: Describe how to run the test. diff --git a/examples/python/multiprocessing/client.py b/examples/python/multiprocessing/client.py index 920b5285475..10233e00bc0 100644 --- a/examples/python/multiprocessing/client.py +++ b/examples/python/multiprocessing/client.py @@ -25,6 +25,7 @@ import multiprocessing import operator import os import time +import sys import prime_pb2 import prime_pb2_grpc @@ -36,11 +37,13 @@ _MAXIMUM_CANDIDATE = 10000 _worker_channel_singleton = None _worker_stub_singleton = None +_LOGGER = logging.getLogger(__name__) + def _initialize_worker(server_address): global _worker_channel_singleton global _worker_stub_singleton - logging.warning('[PID {}] Initializing worker process.'.format( + _LOGGER.info('[PID {}] Initializing worker process.'.format( os.getpid())) _worker_channel_singleton = grpc.insecure_channel(server_address) _worker_stub_singleton = prime_pb2_grpc.PrimeCheckerStub( @@ -49,25 +52,26 @@ def _initialize_worker(server_address): def _shutdown_worker(): - logging.warning('[PID {}] Shutting worker process down.'.format( + _LOGGER.info('[PID {}] Shutting worker process down.'.format( os.getpid())) if _worker_channel_singleton is not None: _worker_channel_singleton.stop() def _run_worker_query(primality_candidate): - logging.warning('[PID {}] Checking primality of {}.'.format( + _LOGGER.info('[PID {}] Checking primality of {}.'.format( os.getpid(), primality_candidate)) return _worker_stub_singleton.check( prime_pb2.PrimeCandidate(candidate=primality_candidate)) + def _calculate_primes(server_address): worker_pool = multiprocessing.Pool(processes=_PROCESS_COUNT, initializer=_initialize_worker, initargs=(server_address,)) check_range = range(2, _MAXIMUM_CANDIDATE) primality = worker_pool.map(_run_worker_query, check_range) primes = zip(check_range, map(operator.attrgetter('isPrime'), primality)) - logging.warning(tuple(primes)) + _LOGGER.info(tuple(primes)) def main(): @@ -77,7 +81,16 @@ def main(): parser.add_argument('server_address', help='The address of the server (e.g. localhost:50051)') args = parser.parse_args() _calculate_primes(args.server_address) + sys.stdout.flush() + if __name__ == '__main__': - logging.basicConfig() + # TODO(rbellevi): Add PID to formatter + fh = logging.FileHandler('/tmp/client.log') + fh.setLevel(logging.INFO) + ch = logging.StreamHandler(sys.stdout) + ch.setLevel(logging.INFO) + _LOGGER.addHandler(fh) + _LOGGER.addHandler(ch) + _LOGGER.setLevel(logging.INFO) main() diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index 5299589bb21..c45bbadecf2 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -27,10 +27,13 @@ import multiprocessing import os import time import socket +import sys import prime_pb2 import prime_pb2_grpc +_LOGGER = logging.getLogger(__name__) + _ONE_DAY = datetime.timedelta(days=1) _PROCESS_COUNT = 8 _THREAD_CONCURRENCY = 10 @@ -47,7 +50,7 @@ def is_prime(n): class PrimeChecker(prime_pb2_grpc.PrimeCheckerServicer): def check(self, request, context): - logging.warning( + _LOGGER.info( '[PID {}] Determining primality of {}'.format( os.getpid(), request.candidate)) return prime_pb2.Primality(isPrime=is_prime(request.candidate)) @@ -63,7 +66,7 @@ def _wait_forever(server): def _run_server(bind_address): """Start a server in a subprocess.""" - logging.warning( '[PID {}] Starting new server.'.format(os.getpid())) + _LOGGER.info( '[PID {}] Starting new server.'.format(os.getpid())) options = (('grpc.so_reuseport', 1),) # WARNING: This example takes advantage of SO_REUSEPORT. Due to the @@ -99,7 +102,8 @@ def _reserve_port(): def main(): with _reserve_port() as port: bind_address = '[::]:{}'.format(port) - logging.warning("Binding to {}".format(bind_address)) + _LOGGER.info("Binding to '{}'".format(bind_address)) + sys.stdout.flush() workers = [] for _ in range(_PROCESS_COUNT): # NOTE: It is imperative that the worker subprocesses be forked before @@ -111,7 +115,13 @@ def main(): for worker in workers: worker.join() - if __name__ == '__main__': - logging.basicConfig() + # TODO(rbellevi): Add PID to formatter + fh = logging.FileHandler('/tmp/server.log') + fh.setLevel(logging.INFO) + ch = logging.StreamHandler(sys.stdout) + ch.setLevel(logging.INFO) + _LOGGER.addHandler(fh) + _LOGGER.addHandler(ch) + _LOGGER.setLevel(logging.INFO) main() diff --git a/examples/python/multiprocessing/test/_multiprocessing_example_test.py b/examples/python/multiprocessing/test/_multiprocessing_example_test.py new file mode 100644 index 00000000000..5e8b31f19c0 --- /dev/null +++ b/examples/python/multiprocessing/test/_multiprocessing_example_test.py @@ -0,0 +1,74 @@ +# Copyright 2019 the gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Test for multiprocessing example.""" + +import datetime +import logging +import math +import os +import re +import subprocess +import tempfile +import time +import unittest + +_BINARY_DIR = os.path.realpath( + os.path.join( + os.path.dirname(os.path.abspath(__file__)), '..')) +_SERVER_PATH = os.path.join(_BINARY_DIR, 'server') +_CLIENT_PATH = os.path.join(_BINARY_DIR, 'client') + + +def is_prime(n): + for i in range(2, int(math.ceil(math.sqrt(n)))): + if n % i == 0: + return False + else: + return True + + +def _get_server_address(server_stream): + while True: + server_stream.seek(0) + line = server_stream.readline() + while line: + matches = re.search('Binding to \'(.+)\'', line) + if matches is not None: + return matches.groups()[0] + line = server_stream.readline() + + +class MultiprocessingExampleTest(unittest.TestCase): + + def test_multiprocessing_example(self): + server_stdout = tempfile.TemporaryFile(mode='r') + server_process = subprocess.Popen((_SERVER_PATH,), + stdout=server_stdout) + server_address = _get_server_address(server_stdout) + client_stdout = tempfile.TemporaryFile(mode='r') + client_process = subprocess.Popen((_CLIENT_PATH, server_address,), + stdout=client_stdout) + client_process.wait() + server_process.terminate() + client_stdout.seek(0) + results = eval(client_stdout.read().strip().split('\n')[-1]) + values = tuple(result[0] for result in results) + self.assertSequenceEqual(range(2, 10000), values) + for result in results: + self.assertEqual(is_prime(result[0]), result[1]) + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/examples/python/multiprocessing/test/_multiprocessing_test.py b/examples/python/multiprocessing/test/_multiprocessing_test.py deleted file mode 100644 index e69de29bb2d..00000000000 From 0f6293e85e8a820fd3436716d41b2d13550a7c08 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 13:50:17 -0800 Subject: [PATCH 640/814] Improve logging handlers --- examples/python/multiprocessing/client.py | 29 ++++++++++------------- examples/python/multiprocessing/server.py | 17 ++++++------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/examples/python/multiprocessing/client.py b/examples/python/multiprocessing/client.py index 10233e00bc0..9c47080a1ff 100644 --- a/examples/python/multiprocessing/client.py +++ b/examples/python/multiprocessing/client.py @@ -43,8 +43,7 @@ _LOGGER = logging.getLogger(__name__) def _initialize_worker(server_address): global _worker_channel_singleton global _worker_stub_singleton - _LOGGER.info('[PID {}] Initializing worker process.'.format( - os.getpid())) + _LOGGER.info('Initializing worker process.') _worker_channel_singleton = grpc.insecure_channel(server_address) _worker_stub_singleton = prime_pb2_grpc.PrimeCheckerStub( _worker_channel_singleton) @@ -52,15 +51,14 @@ def _initialize_worker(server_address): def _shutdown_worker(): - _LOGGER.info('[PID {}] Shutting worker process down.'.format( - os.getpid())) + _LOGGER.info('Shutting worker process down.') if _worker_channel_singleton is not None: _worker_channel_singleton.stop() def _run_worker_query(primality_candidate): - _LOGGER.info('[PID {}] Checking primality of {}.'.format( - os.getpid(), primality_candidate)) + _LOGGER.info('Checking primality of {}.'.format( + primality_candidate)) return _worker_stub_singleton.check( prime_pb2.PrimeCandidate(candidate=primality_candidate)) @@ -71,26 +69,25 @@ def _calculate_primes(server_address): check_range = range(2, _MAXIMUM_CANDIDATE) primality = worker_pool.map(_run_worker_query, check_range) primes = zip(check_range, map(operator.attrgetter('isPrime'), primality)) - _LOGGER.info(tuple(primes)) + return tuple(primes) def main(): msg = 'Determine the primality of the first {} integers.'.format( _MAXIMUM_CANDIDATE) parser = argparse.ArgumentParser(description=msg) - parser.add_argument('server_address', help='The address of the server (e.g. localhost:50051)') + parser.add_argument('server_address', + help='The address of the server (e.g. localhost:50051)') args = parser.parse_args() - _calculate_primes(args.server_address) + primes = _calculate_primes(args.server_address) + print(primes) sys.stdout.flush() if __name__ == '__main__': - # TODO(rbellevi): Add PID to formatter - fh = logging.FileHandler('/tmp/client.log') - fh.setLevel(logging.INFO) - ch = logging.StreamHandler(sys.stdout) - ch.setLevel(logging.INFO) - _LOGGER.addHandler(fh) - _LOGGER.addHandler(ch) + handler = logging.StreamHandler(sys.stdout) + formatter = logging.Formatter('[PID %(process)d] %(message)s') + handler.setFormatter(formatter) + _LOGGER.addHandler(handler) _LOGGER.setLevel(logging.INFO) main() diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index c45bbadecf2..da97d5d8252 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -51,8 +51,8 @@ class PrimeChecker(prime_pb2_grpc.PrimeCheckerServicer): def check(self, request, context): _LOGGER.info( - '[PID {}] Determining primality of {}'.format( - os.getpid(), request.candidate)) + 'Determining primality of {}'.format( + request.candidate)) return prime_pb2.Primality(isPrime=is_prime(request.candidate)) @@ -66,7 +66,7 @@ def _wait_forever(server): def _run_server(bind_address): """Start a server in a subprocess.""" - _LOGGER.info( '[PID {}] Starting new server.'.format(os.getpid())) + _LOGGER.info('Starting new server.') options = (('grpc.so_reuseport', 1),) # WARNING: This example takes advantage of SO_REUSEPORT. Due to the @@ -116,12 +116,9 @@ def main(): worker.join() if __name__ == '__main__': - # TODO(rbellevi): Add PID to formatter - fh = logging.FileHandler('/tmp/server.log') - fh.setLevel(logging.INFO) - ch = logging.StreamHandler(sys.stdout) - ch.setLevel(logging.INFO) - _LOGGER.addHandler(fh) - _LOGGER.addHandler(ch) + handler = logging.StreamHandler(sys.stdout) + formatter = logging.Formatter('[PID %(process)d] %(message)s') + handler.setFormatter(formatter) + _LOGGER.addHandler(handler) _LOGGER.setLevel(logging.INFO) main() From 67ca10b4f96ddab82544e128de55b664a56a527a Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 15:06:02 -0800 Subject: [PATCH 641/814] Add README --- examples/python/multiprocessing/README.md | 54 ++++++- examples/python/multiprocessing/prime_pb2.py | 132 ------------------ .../python/multiprocessing/prime_pb2_grpc.py | 46 ------ 3 files changed, 51 insertions(+), 181 deletions(-) delete mode 100644 examples/python/multiprocessing/prime_pb2.py delete mode 100644 examples/python/multiprocessing/prime_pb2_grpc.py diff --git a/examples/python/multiprocessing/README.md b/examples/python/multiprocessing/README.md index da0c411dc09..6dcec8b2132 100644 --- a/examples/python/multiprocessing/README.md +++ b/examples/python/multiprocessing/README.md @@ -1,3 +1,51 @@ -TODO: Describe the example. -TODO: Describe how to run the example. -TODO: Describe how to run the test. +## Multiprocessing with gRPC Python + +Multiprocessing allows application developers to sidestep the Python global +interpreter lock and achieve true concurrency on multicore systems. +Unfortunately, using multiprocessing and gRPC Python is not yet as simple as +instantiating your server with a `futures.ProcessPoolExecutor`. + +The library is implemented as a C extension, maintaining much of the state that +drives the system in native code. As such, upon calling +[`fork`](http://man7.org/linux/man-pages/man2/fork.2.html), much of the +state copied into the child process is invalid, leading to hangs and crashes. + +However, calling `fork` without `exec` in your python process is supported +*before* any gRPC servers have been instantiated. Application developers can +take advantage of this to parallelize their CPU-intensive operations. + +## Running the Example + +This example calculates the first 10,000 prime numbers as an RPC. We instantiate +one server per subprocess, balancing requests between the servers using the +[`SO_REUSEPORT`](https://lwn.net/Articles/542629/) socket option. + +To run the server, +[ensure `bazel` is installed](https://docs.bazel.build/versions/master/install.html) +and run: + +``` +bazel run //examples/python/multiprocessing:server & +``` + +Note the address at which the server is running. For example, + +``` +... +[PID 107153] Binding to '[::]:33915' +[PID 107507] Starting new server. +[PID 107508] Starting new server. +... +``` + +Now, start the client by running + +``` +bazel run //examples/python/multiprocessing:client -- [SERVER_ADDRESS] +``` + +For example, + +``` +bazel run //examples/python/multiprocessing:client -- [::]:33915 +``` diff --git a/examples/python/multiprocessing/prime_pb2.py b/examples/python/multiprocessing/prime_pb2.py deleted file mode 100644 index 58e6e6a023a..00000000000 --- a/examples/python/multiprocessing/prime_pb2.py +++ /dev/null @@ -1,132 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: prime.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='prime.proto', - package='prime', - syntax='proto3', - serialized_options=None, - serialized_pb=_b('\n\x0bprime.proto\x12\x05prime\"#\n\x0ePrimeCandidate\x12\x11\n\tcandidate\x18\x01 \x01(\x03\"\x1c\n\tPrimality\x12\x0f\n\x07isPrime\x18\x01 \x01(\x08\x32\x42\n\x0cPrimeChecker\x12\x32\n\x05\x63heck\x12\x15.prime.PrimeCandidate\x1a\x10.prime.Primality\"\x00\x62\x06proto3') -) - - - - -_PRIMECANDIDATE = _descriptor.Descriptor( - name='PrimeCandidate', - full_name='prime.PrimeCandidate', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='candidate', full_name='prime.PrimeCandidate.candidate', index=0, - number=1, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=22, - serialized_end=57, -) - - -_PRIMALITY = _descriptor.Descriptor( - name='Primality', - full_name='prime.Primality', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='isPrime', full_name='prime.Primality.isPrime', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=59, - serialized_end=87, -) - -DESCRIPTOR.message_types_by_name['PrimeCandidate'] = _PRIMECANDIDATE -DESCRIPTOR.message_types_by_name['Primality'] = _PRIMALITY -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -PrimeCandidate = _reflection.GeneratedProtocolMessageType('PrimeCandidate', (_message.Message,), dict( - DESCRIPTOR = _PRIMECANDIDATE, - __module__ = 'prime_pb2' - # @@protoc_insertion_point(class_scope:prime.PrimeCandidate) - )) -_sym_db.RegisterMessage(PrimeCandidate) - -Primality = _reflection.GeneratedProtocolMessageType('Primality', (_message.Message,), dict( - DESCRIPTOR = _PRIMALITY, - __module__ = 'prime_pb2' - # @@protoc_insertion_point(class_scope:prime.Primality) - )) -_sym_db.RegisterMessage(Primality) - - - -_PRIMECHECKER = _descriptor.ServiceDescriptor( - name='PrimeChecker', - full_name='prime.PrimeChecker', - file=DESCRIPTOR, - index=0, - serialized_options=None, - serialized_start=89, - serialized_end=155, - methods=[ - _descriptor.MethodDescriptor( - name='check', - full_name='prime.PrimeChecker.check', - index=0, - containing_service=None, - input_type=_PRIMECANDIDATE, - output_type=_PRIMALITY, - serialized_options=None, - ), -]) -_sym_db.RegisterServiceDescriptor(_PRIMECHECKER) - -DESCRIPTOR.services_by_name['PrimeChecker'] = _PRIMECHECKER - -# @@protoc_insertion_point(module_scope) diff --git a/examples/python/multiprocessing/prime_pb2_grpc.py b/examples/python/multiprocessing/prime_pb2_grpc.py deleted file mode 100644 index dcc3a35706d..00000000000 --- a/examples/python/multiprocessing/prime_pb2_grpc.py +++ /dev/null @@ -1,46 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - -import prime_pb2 as prime__pb2 - - -class PrimeCheckerStub(object): - """Service to check primality. - """ - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.check = channel.unary_unary( - '/prime.PrimeChecker/check', - request_serializer=prime__pb2.PrimeCandidate.SerializeToString, - response_deserializer=prime__pb2.Primality.FromString, - ) - - -class PrimeCheckerServicer(object): - """Service to check primality. - """ - - def check(self, request, context): - """Determines the primality of an integer. - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_PrimeCheckerServicer_to_server(servicer, server): - rpc_method_handlers = { - 'check': grpc.unary_unary_rpc_method_handler( - servicer.check, - request_deserializer=prime__pb2.PrimeCandidate.FromString, - response_serializer=prime__pb2.Primality.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'prime.PrimeChecker', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) From 23c5fb8ca4d3830c6360cafb809f432d7f0c2b49 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 15:14:42 -0800 Subject: [PATCH 642/814] Add example tests to CI --- tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh index 14989648a2a..d844cff7f9a 100755 --- a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh +++ b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh @@ -25,5 +25,7 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc ${name}') cd /var/local/git/grpc/test bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... bazel clean --expunge bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... From d832738c08bb076ee27a91b7da61051e24d5e902 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 15:16:12 -0800 Subject: [PATCH 643/814] Yapf --- examples/python/multiprocessing/client.py | 20 ++++++++++--------- examples/python/multiprocessing/server.py | 13 ++++++------ .../test/_multiprocessing_example_test.py | 13 ++++++------ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/examples/python/multiprocessing/client.py b/examples/python/multiprocessing/client.py index 9c47080a1ff..fa3b394f394 100644 --- a/examples/python/multiprocessing/client.py +++ b/examples/python/multiprocessing/client.py @@ -46,7 +46,7 @@ def _initialize_worker(server_address): _LOGGER.info('Initializing worker process.') _worker_channel_singleton = grpc.insecure_channel(server_address) _worker_stub_singleton = prime_pb2_grpc.PrimeCheckerStub( - _worker_channel_singleton) + _worker_channel_singleton) atexit.register(_shutdown_worker) @@ -57,15 +57,16 @@ def _shutdown_worker(): def _run_worker_query(primality_candidate): - _LOGGER.info('Checking primality of {}.'.format( - primality_candidate)) + _LOGGER.info('Checking primality of {}.'.format(primality_candidate)) return _worker_stub_singleton.check( - prime_pb2.PrimeCandidate(candidate=primality_candidate)) + prime_pb2.PrimeCandidate(candidate=primality_candidate)) def _calculate_primes(server_address): - worker_pool = multiprocessing.Pool(processes=_PROCESS_COUNT, - initializer=_initialize_worker, initargs=(server_address,)) + worker_pool = multiprocessing.Pool( + processes=_PROCESS_COUNT, + initializer=_initialize_worker, + initargs=(server_address,)) check_range = range(2, _MAXIMUM_CANDIDATE) primality = worker_pool.map(_run_worker_query, check_range) primes = zip(check_range, map(operator.attrgetter('isPrime'), primality)) @@ -74,10 +75,11 @@ def _calculate_primes(server_address): def main(): msg = 'Determine the primality of the first {} integers.'.format( - _MAXIMUM_CANDIDATE) + _MAXIMUM_CANDIDATE) parser = argparse.ArgumentParser(description=msg) - parser.add_argument('server_address', - help='The address of the server (e.g. localhost:50051)') + parser.add_argument( + 'server_address', + help='The address of the server (e.g. localhost:50051)') args = parser.parse_args() primes = _calculate_primes(args.server_address) print(primes) diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index da97d5d8252..588cd4734e9 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -50,9 +50,7 @@ def is_prime(n): class PrimeChecker(prime_pb2_grpc.PrimeCheckerServicer): def check(self, request, context): - _LOGGER.info( - 'Determining primality of {}'.format( - request.candidate)) + _LOGGER.info('Determining primality of {}'.format(request.candidate)) return prime_pb2.Primality(isPrime=is_prime(request.candidate)) @@ -76,9 +74,8 @@ def _run_server(bind_address): # `pip install grpcio --no-binary grpcio`. server = grpc.server( - futures.ThreadPoolExecutor( - max_workers=_THREAD_CONCURRENCY,), - options=options) + futures.ThreadPoolExecutor(max_workers=_THREAD_CONCURRENCY,), + options=options) prime_pb2_grpc.add_PrimeCheckerServicer_to_server(PrimeChecker(), server) server.add_insecure_port(bind_address) server.start() @@ -109,12 +106,14 @@ def main(): # NOTE: It is imperative that the worker subprocesses be forked before # any gRPC servers start up. See # https://github.com/grpc/grpc/issues/16001 for more details. - worker = multiprocessing.Process(target=_run_server, args=(bind_address,)) + worker = multiprocessing.Process( + target=_run_server, args=(bind_address,)) worker.start() workers.append(worker) for worker in workers: worker.join() + if __name__ == '__main__': handler = logging.StreamHandler(sys.stdout) formatter = logging.Formatter('[PID %(process)d] %(message)s') diff --git a/examples/python/multiprocessing/test/_multiprocessing_example_test.py b/examples/python/multiprocessing/test/_multiprocessing_example_test.py index 5e8b31f19c0..92e7c0a4b8d 100644 --- a/examples/python/multiprocessing/test/_multiprocessing_example_test.py +++ b/examples/python/multiprocessing/test/_multiprocessing_example_test.py @@ -24,8 +24,7 @@ import time import unittest _BINARY_DIR = os.path.realpath( - os.path.join( - os.path.dirname(os.path.abspath(__file__)), '..')) + os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) _SERVER_PATH = os.path.join(_BINARY_DIR, 'server') _CLIENT_PATH = os.path.join(_BINARY_DIR, 'client') @@ -53,12 +52,14 @@ class MultiprocessingExampleTest(unittest.TestCase): def test_multiprocessing_example(self): server_stdout = tempfile.TemporaryFile(mode='r') - server_process = subprocess.Popen((_SERVER_PATH,), - stdout=server_stdout) + server_process = subprocess.Popen((_SERVER_PATH,), stdout=server_stdout) server_address = _get_server_address(server_stdout) client_stdout = tempfile.TemporaryFile(mode='r') - client_process = subprocess.Popen((_CLIENT_PATH, server_address,), - stdout=client_stdout) + client_process = subprocess.Popen( + ( + _CLIENT_PATH, + server_address, + ), stdout=client_stdout) client_process.wait() server_process.terminate() client_stdout.seek(0) From 749c52de56e4d48c495404abb966274454ab36b3 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 15:31:37 -0800 Subject: [PATCH 644/814] Refcount vtables --- src/python/grpcio/grpc/_cython/BUILD.bazel | 4 +- .../grpc/_cython/_cygrpc/arguments.pxd.pxi | 15 +------ .../grpc/_cython/_cygrpc/arguments.pyx.pxi | 34 ++-------------- .../grpcio/grpc/_cython/_cygrpc/call.pyx.pxi | 4 +- .../grpc/_cython/_cygrpc/channel.pxd.pxi | 2 +- .../grpc/_cython/_cygrpc/channel.pyx.pxi | 18 ++++----- .../grpc/_cython/_cygrpc/server.pxd.pxi | 4 +- .../grpc/_cython/_cygrpc/server.pyx.pxi | 15 ++++--- .../grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi | 1 + .../grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi | 5 ++- .../grpc/_cython/_cygrpc/vtable.pxd.pxi | 26 +++++++++++++ .../grpc/_cython/_cygrpc/vtable.pyx.pxi | 39 +++++++++++++++++++ src/python/grpcio/grpc/_cython/cygrpc.pxd | 3 +- src/python/grpcio/grpc/_cython/cygrpc.pyx | 5 ++- 14 files changed, 101 insertions(+), 74 deletions(-) create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/vtable.pxd.pxi create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/vtable.pyx.pxi diff --git a/src/python/grpcio/grpc/_cython/BUILD.bazel b/src/python/grpcio/grpc/_cython/BUILD.bazel index 42db7b87213..18b1c92b9a7 100644 --- a/src/python/grpcio/grpc/_cython/BUILD.bazel +++ b/src/python/grpcio/grpc/_cython/BUILD.bazel @@ -43,10 +43,12 @@ pyx_library( "_cygrpc/tag.pyx.pxi", "_cygrpc/time.pxd.pxi", "_cygrpc/time.pyx.pxi", + "_cygrpc/vtable.pxd.pxi", + "_cygrpc/vtable.pyx.pxi", "cygrpc.pxd", "cygrpc.pyx", ], deps = [ - "//:grpc", + "//:grpc", ], ) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi index 01b82374845..9415b16344a 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi @@ -13,15 +13,6 @@ # limitations under the License. -cdef void* _copy_pointer(void* pointer) - - -cdef void _destroy_pointer(void* pointer) - - -cdef int _compare_pointer(void* first_pointer, void* second_pointer) - - cdef tuple _wrap_grpc_arg(grpc_arg arg) @@ -32,7 +23,7 @@ cdef class _ChannelArg: cdef grpc_arg c_argument - cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references) except * + cdef void c(self, argument, _VTable vtable, references) except * cdef class _ChannelArgs: @@ -42,8 +33,4 @@ cdef class _ChannelArgs: cdef readonly list _references cdef grpc_channel_args _c_arguments - cdef void _c(self, grpc_arg_pointer_vtable *vtable) except * cdef grpc_channel_args *c_args(self) except * - - @staticmethod - cdef _ChannelArgs from_args(object arguments, grpc_arg_pointer_vtable * vtable) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi index bf12871015d..9211354b1ca 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi @@ -15,25 +15,6 @@ cimport cpython -# TODO(https://github.com/grpc/grpc/issues/15662): Reform this. -cdef void* _copy_pointer(void* pointer): - return pointer - - -# TODO(https://github.com/grpc/grpc/issues/15662): Reform this. -cdef void _destroy_pointer(void* pointer): - pass - - -cdef int _compare_pointer(void* first_pointer, void* second_pointer): - if first_pointer < second_pointer: - return -1 - elif first_pointer > second_pointer: - return 1 - else: - return 0 - - cdef class _GrpcArgWrapper: cdef grpc_arg arg @@ -52,7 +33,7 @@ cdef grpc_arg _unwrap_grpc_arg(tuple wrapped_arg): cdef class _ChannelArg: - cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references) except *: + cdef void c(self, argument, _VTable vtable, references) except *: key, value = argument cdef bytes encoded_key = _encode(key) if encoded_key is not key: @@ -75,7 +56,7 @@ cdef class _ChannelArg: # lifecycle of the pointer is fixed to the lifecycle of the # python object wrapping it. self.c_argument.type = GRPC_ARG_POINTER - self.c_argument.value.pointer.vtable = vtable + self.c_argument.value.pointer.vtable = &vtable.c_vtable self.c_argument.value.pointer.address = (int(value)) else: raise TypeError( @@ -84,13 +65,10 @@ cdef class _ChannelArg: cdef class _ChannelArgs: - def __cinit__(self, arguments): + def __cinit__(self, arguments, _VTable vtable not None): self._arguments = () if arguments is None else tuple(arguments) self._channel_args = [] self._references = [] - self._c_arguments.arguments = NULL - - cdef void _c(self, grpc_arg_pointer_vtable *vtable) except *: self._c_arguments.arguments_length = len(self._arguments) if self._c_arguments.arguments_length != 0: self._c_arguments.arguments = gpr_malloc( @@ -107,9 +85,3 @@ cdef class _ChannelArgs: def __dealloc__(self): if self._c_arguments.arguments != NULL: gpr_free(self._c_arguments.arguments) - - @staticmethod - cdef _ChannelArgs from_args(object arguments, grpc_arg_pointer_vtable * vtable): - cdef _ChannelArgs channel_args = _ChannelArgs(arguments) - channel_args._c(vtable) - return channel_args diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi index 6e4574af8d5..84934db4d60 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi @@ -17,11 +17,11 @@ cimport cpython cdef class Call: - def __cinit__(self): + def __cinit__(self, _VTable vtable not None): # Create an *empty* call fork_handlers_and_grpc_init() self.c_call = NULL - self.references = [] + self.references = [vtable] def _start_batch(self, operations, tag, retain_self): if not self.is_valid: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi index ced32abba14..13c0c02ab21 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi @@ -68,8 +68,8 @@ cdef class SegregatedCall: cdef class Channel: - cdef grpc_arg_pointer_vtable _vtable cdef _ChannelState _state + cdef _VTable _vtable # TODO(https://github.com/grpc/grpc/issues/15662): Eliminate this. cdef tuple _arguments diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index 24c11e63a6b..ca637094353 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -420,11 +420,14 @@ cdef class Channel: arguments = () if arguments is None else tuple(arguments) fork_handlers_and_grpc_init() self._state = _ChannelState() - self._vtable.copy = &_copy_pointer - self._vtable.destroy = &_destroy_pointer - self._vtable.cmp = &_compare_pointer - cdef _ChannelArgs channel_args = _ChannelArgs.from_args( - arguments, &self._vtable) + self._state.c_call_completion_queue = ( + grpc_completion_queue_create_for_next(NULL)) + self._state.c_connectivity_completion_queue = ( + grpc_completion_queue_create_for_next(NULL)) + self._arguments = arguments + self._vtable = _VTable() + cdef _ChannelArgs channel_args = _ChannelArgs( + arguments, self._vtable) if channel_credentials is None: self._state.c_channel = grpc_insecure_channel_create( target, channel_args.c_args(), NULL) @@ -433,11 +436,6 @@ cdef class Channel: self._state.c_channel = grpc_secure_channel_create( c_channel_credentials, target, channel_args.c_args(), NULL) grpc_channel_credentials_release(c_channel_credentials) - self._state.c_call_completion_queue = ( - grpc_completion_queue_create_for_next(NULL)) - self._state.c_connectivity_completion_queue = ( - grpc_completion_queue_create_for_next(NULL)) - self._arguments = arguments def target(self): cdef char *c_target diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi index 4a6fbe0f96c..b3fadcdc62d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi @@ -12,11 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. - cdef class Server: - cdef grpc_arg_pointer_vtable _vtable cdef grpc_server *c_server + + cdef _VTable _vtable cdef bint is_started # start has been called cdef bint is_shutting_down # shutdown has been called cdef bint is_shutdown # notification of complete shutdown received diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index fe55ea885e4..2369371cabe 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -20,22 +20,21 @@ import grpc _LOGGER = logging.getLogger(__name__) + cdef class Server: def __cinit__(self, object arguments): fork_handlers_and_grpc_init() self.references = [] self.registered_completion_queues = [] - self._vtable.copy = &_copy_pointer - self._vtable.destroy = &_destroy_pointer - self._vtable.cmp = &_compare_pointer - cdef _ChannelArgs channel_args = _ChannelArgs.from_args( - arguments, &self._vtable) - self.c_server = grpc_server_create(channel_args.c_args(), NULL) - self.references.append(arguments) self.is_started = False self.is_shutting_down = False self.is_shutdown = False + self.c_server = NULL + self._vtable = _VTable() + cdef _ChannelArgs channel_args = _ChannelArgs(arguments, self._vtable) + self.c_server = grpc_server_create(channel_args.c_args(), NULL) + self.references.append(arguments) def request_call( self, CompletionQueue call_queue not None, @@ -44,7 +43,7 @@ cdef class Server: raise ValueError("server must be started and not shutting down") if server_queue not in self.registered_completion_queues: raise ValueError("server_queue must be a registered completion queue") - cdef _RequestCallTag request_call_tag = _RequestCallTag(tag) + cdef _RequestCallTag request_call_tag = _RequestCallTag(tag, self._vtable) request_call_tag.prepare() cpython.Py_INCREF(request_call_tag) return grpc_server_request_call( diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi index d8ba1ea9bd5..c77beb28194 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi @@ -29,6 +29,7 @@ cdef class _RequestCallTag(_Tag): cdef readonly object _user_tag cdef Call call + cdef _VTable _vtable cdef CallDetails call_details cdef grpc_metadata_array c_invocation_metadata diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi index e80dc88767e..d1280ef4948 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi @@ -30,13 +30,14 @@ cdef class _ConnectivityTag(_Tag): cdef class _RequestCallTag(_Tag): - def __cinit__(self, user_tag): + def __cinit__(self, user_tag, _VTable vtable not None): self._user_tag = user_tag self.call = None self.call_details = None + self._vtable = vtable cdef void prepare(self) except *: - self.call = Call() + self.call = Call(self._vtable) self.call_details = CallDetails() grpc_metadata_array_init(&self.c_invocation_metadata) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pxd.pxi new file mode 100644 index 00000000000..1799b6e1f14 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pxd.pxi @@ -0,0 +1,26 @@ +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +cdef void* _copy_pointer(void* pointer) + + +cdef void _destroy_pointer(void* pointer) + + +cdef int _compare_pointer(void* first_pointer, void* second_pointer) + + +cdef class _VTable: + cdef grpc_arg_pointer_vtable c_vtable diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pyx.pxi new file mode 100644 index 00000000000..98cb60c10e3 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/vtable.pyx.pxi @@ -0,0 +1,39 @@ +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# TODO(https://github.com/grpc/grpc/issues/15662): Reform this. +cdef void* _copy_pointer(void* pointer): + return pointer + + +# TODO(https://github.com/grpc/grpc/issues/15662): Reform this. +cdef void _destroy_pointer(void* pointer): + pass + + +cdef int _compare_pointer(void* first_pointer, void* second_pointer): + if first_pointer < second_pointer: + return -1 + elif first_pointer > second_pointer: + return 1 + else: + return 0 + + +cdef class _VTable: + def __cinit__(self): + self.c_vtable.copy = &_copy_pointer + self.c_vtable.destroy = &_destroy_pointer + self.c_vtable.cmp = &_compare_pointer + diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd index 64cae6b34d6..e29f7aee97a 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pxd +++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd @@ -23,13 +23,14 @@ include "_cygrpc/completion_queue.pxd.pxi" include "_cygrpc/event.pxd.pxi" include "_cygrpc/metadata.pxd.pxi" include "_cygrpc/operation.pxd.pxi" +include "_cygrpc/propagation_bits.pxd.pxi" include "_cygrpc/records.pxd.pxi" include "_cygrpc/security.pxd.pxi" include "_cygrpc/server.pxd.pxi" include "_cygrpc/tag.pxd.pxi" include "_cygrpc/time.pxd.pxi" +include "_cygrpc/vtable.pxd.pxi" include "_cygrpc/_hooks.pxd.pxi" -include "_cygrpc/propagation_bits.pxd.pxi" include "_cygrpc/grpc_gevent.pxd.pxi" diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index ce98fa3a8e6..f2dd0df89d4 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -24,19 +24,20 @@ include "_cygrpc/grpc_string.pyx.pxi" include "_cygrpc/arguments.pyx.pxi" include "_cygrpc/call.pyx.pxi" include "_cygrpc/channel.pyx.pxi" +include "_cygrpc/channelz.pyx.pxi" include "_cygrpc/credentials.pyx.pxi" include "_cygrpc/completion_queue.pyx.pxi" include "_cygrpc/event.pyx.pxi" include "_cygrpc/metadata.pyx.pxi" include "_cygrpc/operation.pyx.pxi" +include "_cygrpc/propagation_bits.pyx.pxi" include "_cygrpc/records.pyx.pxi" include "_cygrpc/security.pyx.pxi" include "_cygrpc/server.pyx.pxi" include "_cygrpc/tag.pyx.pxi" include "_cygrpc/time.pyx.pxi" +include "_cygrpc/vtable.pyx.pxi" include "_cygrpc/_hooks.pyx.pxi" -include "_cygrpc/channelz.pyx.pxi" -include "_cygrpc/propagation_bits.pyx.pxi" include "_cygrpc/grpc_gevent.pyx.pxi" From 34aa71464482b4b93b81ff430e942b9aa2517b49 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 8 Mar 2019 15:37:09 -0800 Subject: [PATCH 645/814] Remove pollset_set when resetting LB policies --- .../filters/client_channel/lb_policy/grpclb/grpclb.cc | 11 +++++++++++ .../ext/filters/client_channel/lb_policy/xds/xds.cc | 11 +++++++++++ .../ext/filters/client_channel/resolving_lb_policy.cc | 3 +++ 3 files changed, 25 insertions(+) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 184215a3da9..34fe88215fe 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -625,6 +625,9 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, GRPC_ERROR_UNREF(state_error); return; } + grpc_pollset_set_del_pollset_set( + parent_->child_policy_->interested_parties(), + parent_->interested_parties()); MutexLock lock(&parent_->child_policy_mu_); parent_->child_policy_ = std::move(parent_->pending_child_policy_); } else if (!CalledByCurrentChild()) { @@ -1272,6 +1275,14 @@ void GrpcLb::ShutdownLocked() { if (fallback_timer_callback_pending_) { grpc_timer_cancel(&lb_fallback_timer_); } + if (child_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(), + interested_parties()); + } + if (pending_child_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set( + pending_child_policy_->interested_parties(), interested_parties()); + } { MutexLock lock(&child_policy_mu_); child_policy_.reset(); diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 4b386d37797..eca41bf3a2e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -430,6 +430,9 @@ void XdsLb::Helper::UpdateState(grpc_connectivity_state state, GRPC_ERROR_UNREF(state_error); return; } + grpc_pollset_set_del_pollset_set( + parent_->child_policy_->interested_parties(), + parent_->interested_parties()); MutexLock lock(&parent_->child_policy_mu_); parent_->child_policy_ = std::move(parent_->pending_child_policy_); } else if (!CalledByCurrentChild()) { @@ -1154,6 +1157,14 @@ void XdsLb::ShutdownLocked() { if (fallback_timer_callback_pending_) { grpc_timer_cancel(&lb_fallback_timer_); } + if (child_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(), + interested_parties()); + } + if (pending_child_policy_ != nullptr) { + grpc_pollset_set_del_pollset_set( + pending_child_policy_->interested_parties(), interested_parties()); + } { MutexLock lock(&child_policy_mu_); child_policy_.reset(); diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 0dd51e8bc4c..52b14dcc7de 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -110,6 +110,9 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper GRPC_ERROR_UNREF(state_error); return; } + grpc_pollset_set_del_pollset_set( + parent_->lb_policy_->interested_parties(), + parent_->interested_parties()); MutexLock lock(&parent_->lb_policy_mu_); parent_->lb_policy_ = std::move(parent_->pending_lb_policy_); } else if (!CalledByCurrentChild()) { From 307044c6aff8f51fc3496e34e7a72deb65f41658 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 16:18:45 -0800 Subject: [PATCH 646/814] Fix linting --- tools/distrib/pylint_code.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh index abb37dde0ed..75aed1c4814 100755 --- a/tools/distrib/pylint_code.sh +++ b/tools/distrib/pylint_code.sh @@ -32,7 +32,7 @@ TEST_DIRS=( ) VIRTUALENV=python_pylint_venv -python3 -m virtualenv $VIRTUALENV +python3 -m virtualenv $VIRTUALENV -p $(which python3) PYTHON=$VIRTUALENV/bin/python From 81c3b0bfb6ac4813ff96373eb8d9a0c702a6f0c2 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 16:18:57 -0800 Subject: [PATCH 647/814] Fix lint errors --- examples/python/multiprocessing/client.py | 29 ++++++++++--------- examples/python/multiprocessing/server.py | 8 ++--- .../test/_multiprocessing_example_test.py | 5 ++-- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/examples/python/multiprocessing/client.py b/examples/python/multiprocessing/client.py index fa3b394f394..6c583964fde 100644 --- a/examples/python/multiprocessing/client.py +++ b/examples/python/multiprocessing/client.py @@ -19,14 +19,13 @@ from __future__ import print_function import argparse import atexit -import grpc import logging import multiprocessing import operator -import os -import time import sys +import grpc + import prime_pb2 import prime_pb2_grpc @@ -34,30 +33,32 @@ _PROCESS_COUNT = 8 _MAXIMUM_CANDIDATE = 10000 # Each worker process initializes a single channel after forking. +# It's regrettable, but to ensure that each subprocess only has to instantiate +# a single channel to be reused across all RPCs, we use globals. _worker_channel_singleton = None _worker_stub_singleton = None _LOGGER = logging.getLogger(__name__) -def _initialize_worker(server_address): - global _worker_channel_singleton - global _worker_stub_singleton - _LOGGER.info('Initializing worker process.') - _worker_channel_singleton = grpc.insecure_channel(server_address) - _worker_stub_singleton = prime_pb2_grpc.PrimeCheckerStub( - _worker_channel_singleton) - atexit.register(_shutdown_worker) - - def _shutdown_worker(): _LOGGER.info('Shutting worker process down.') if _worker_channel_singleton is not None: _worker_channel_singleton.stop() +def _initialize_worker(server_address): + global _worker_channel_singleton # pylint: disable=global-statement + global _worker_stub_singleton # pylint: disable=global-statement + _LOGGER.info('Initializing worker process.') + _worker_channel_singleton = grpc.insecure_channel(server_address) + _worker_stub_singleton = prime_pb2_grpc.PrimeCheckerStub( + _worker_channel_singleton) + atexit.register(_shutdown_worker) + + def _run_worker_query(primality_candidate): - _LOGGER.info('Checking primality of {}.'.format(primality_candidate)) + _LOGGER.info('Checking primality of %s.', primality_candidate) return _worker_stub_singleton.check( prime_pb2.PrimeCandidate(candidate=primality_candidate)) diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index 588cd4734e9..d686d90559a 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -20,15 +20,15 @@ from __future__ import print_function from concurrent import futures import contextlib import datetime -import grpc import logging import math import multiprocessing -import os import time import socket import sys +import grpc + import prime_pb2 import prime_pb2_grpc @@ -50,7 +50,7 @@ def is_prime(n): class PrimeChecker(prime_pb2_grpc.PrimeCheckerServicer): def check(self, request, context): - _LOGGER.info('Determining primality of {}'.format(request.candidate)) + _LOGGER.info('Determining primality of %s', request.candidate) return prime_pb2.Primality(isPrime=is_prime(request.candidate)) @@ -99,7 +99,7 @@ def _reserve_port(): def main(): with _reserve_port() as port: bind_address = '[::]:{}'.format(port) - _LOGGER.info("Binding to '{}'".format(bind_address)) + _LOGGER.info("Binding to '%s'", bind_address) sys.stdout.flush() workers = [] for _ in range(_PROCESS_COUNT): diff --git a/examples/python/multiprocessing/test/_multiprocessing_example_test.py b/examples/python/multiprocessing/test/_multiprocessing_example_test.py index 92e7c0a4b8d..2d8f8d49db4 100644 --- a/examples/python/multiprocessing/test/_multiprocessing_example_test.py +++ b/examples/python/multiprocessing/test/_multiprocessing_example_test.py @@ -13,14 +13,13 @@ # limitations under the License. """Test for multiprocessing example.""" -import datetime +import ast import logging import math import os import re import subprocess import tempfile -import time import unittest _BINARY_DIR = os.path.realpath( @@ -63,7 +62,7 @@ class MultiprocessingExampleTest(unittest.TestCase): client_process.wait() server_process.terminate() client_stdout.seek(0) - results = eval(client_stdout.read().strip().split('\n')[-1]) + results = ast.literal_eval(client_stdout.read().strip().split('\n')[-1]) values = tuple(result[0] for result in results) self.assertSequenceEqual(range(2, 10000), values) for result in results: From d359dbe44d24685d07a1e621404d6c497769b33f Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 16:21:49 -0800 Subject: [PATCH 648/814] Remove unnecessary flush --- examples/python/multiprocessing/client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/python/multiprocessing/client.py b/examples/python/multiprocessing/client.py index 6c583964fde..c3da4ba2b99 100644 --- a/examples/python/multiprocessing/client.py +++ b/examples/python/multiprocessing/client.py @@ -84,7 +84,6 @@ def main(): args = parser.parse_args() primes = _calculate_primes(args.server_address) print(primes) - sys.stdout.flush() if __name__ == '__main__': From 69b5476429f883f15e6438f4de43da9504217434 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 16:38:58 -0800 Subject: [PATCH 649/814] Expand the readme --- examples/python/multiprocessing/README.md | 21 +++++++++++++++++++-- examples/python/multiprocessing/server.py | 4 ++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/examples/python/multiprocessing/README.md b/examples/python/multiprocessing/README.md index 6dcec8b2132..c0e296924ee 100644 --- a/examples/python/multiprocessing/README.md +++ b/examples/python/multiprocessing/README.md @@ -14,11 +14,26 @@ However, calling `fork` without `exec` in your python process is supported *before* any gRPC servers have been instantiated. Application developers can take advantage of this to parallelize their CPU-intensive operations. -## Running the Example +## Calculating Prime Numbers with Multiple Processes This example calculates the first 10,000 prime numbers as an RPC. We instantiate one server per subprocess, balancing requests between the servers using the -[`SO_REUSEPORT`](https://lwn.net/Articles/542629/) socket option. +[`SO_REUSEPORT`](https://lwn.net/Articles/542629/) socket option. Note that this +option is not available in `manylinux1` distributions, which are, as of the time +of writing, the only gRPC Python wheels available on PyPi. To take advantage of this +feature, you'll need to build from source, either using bazel (as we do for +these examples) or via pip, using `pip install grpcio --no-binary grpcio`. + +```python +_PROCESS_COUNT = multiprocessing.cpu_count() +``` + +On the server side, we detect the number of CPUs available on the system and +spawn exactly that many child processes. If we spin up fewer, we won't be taking +full advantage of the hardware resources available. If we spin up more, then the +kernel will have to multiplex the processes on the available CPUs. + +## Running the Example To run the server, [ensure `bazel` is installed](https://docs.bazel.build/versions/master/install.html) @@ -38,6 +53,8 @@ Note the address at which the server is running. For example, ... ``` +Note that several servers have been started, each with its own PID. + Now, start the client by running ``` diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index d686d90559a..27a0758d224 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -35,8 +35,8 @@ import prime_pb2_grpc _LOGGER = logging.getLogger(__name__) _ONE_DAY = datetime.timedelta(days=1) -_PROCESS_COUNT = 8 -_THREAD_CONCURRENCY = 10 +_PROCESS_COUNT = multiprocessing.cpu_count() +_THREAD_CONCURRENCY = _PROCESS_COUNT def is_prime(n): From 4c8c8e36d241d6f526665619fa142c91fc8f9538 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 16:52:33 -0800 Subject: [PATCH 650/814] Show some respect --- examples/python/multiprocessing/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/multiprocessing/README.md b/examples/python/multiprocessing/README.md index c0e296924ee..b752d85a9ae 100644 --- a/examples/python/multiprocessing/README.md +++ b/examples/python/multiprocessing/README.md @@ -20,7 +20,7 @@ This example calculates the first 10,000 prime numbers as an RPC. We instantiate one server per subprocess, balancing requests between the servers using the [`SO_REUSEPORT`](https://lwn.net/Articles/542629/) socket option. Note that this option is not available in `manylinux1` distributions, which are, as of the time -of writing, the only gRPC Python wheels available on PyPi. To take advantage of this +of writing, the only gRPC Python wheels available on PyPI. To take advantage of this feature, you'll need to build from source, either using bazel (as we do for these examples) or via pip, using `pip install grpcio --no-binary grpcio`. From 2640822c2d65adca9f15410e03f2e4be0b32e0f3 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 8 Mar 2019 17:24:59 -0800 Subject: [PATCH 651/814] Remove a statement proven wrong by science --- examples/python/multiprocessing/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/python/multiprocessing/README.md b/examples/python/multiprocessing/README.md index b752d85a9ae..709a815aca5 100644 --- a/examples/python/multiprocessing/README.md +++ b/examples/python/multiprocessing/README.md @@ -30,8 +30,7 @@ _PROCESS_COUNT = multiprocessing.cpu_count() On the server side, we detect the number of CPUs available on the system and spawn exactly that many child processes. If we spin up fewer, we won't be taking -full advantage of the hardware resources available. If we spin up more, then the -kernel will have to multiplex the processes on the available CPUs. +full advantage of the hardware resources available. ## Running the Example From 9f9c03d0f5023ff10058713de0dd4593676801c8 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Sat, 9 Mar 2019 12:14:02 -0800 Subject: [PATCH 652/814] Prevent merging if PR marked DO NOT MERGE --- .github/mergeable.yml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/mergeable.yml b/.github/mergeable.yml index 30692095c46..a10ae9b7589 100644 --- a/.github/mergeable.yml +++ b/.github/mergeable.yml @@ -1,14 +1,18 @@ mergeable: pull_requests: label: - or: - - and: + and: + - must_exclude: + regex: '^disposition/DO NOT MERGE' + message: 'Pull request marked not mergeable' + - or: + - and: + - must_include: + regex: 'release notes: yes' + message: 'Please include release note: yes' + - must_include: + regex: '^lang\/' + message: 'Please include a language label' - must_include: - regex: 'release notes: yes' - message: 'Please include release note: yes' - - must_include: - regex: '^lang\/' - message: 'Please include a language label' - - must_include: - regex: 'release notes: no' - message: 'Please include release note: no' + regex: 'release notes: no' + message: 'Please include release note: no' From b93d4842cc076eb3a26f0c4a6ccb1021354a9dcf Mon Sep 17 00:00:00 2001 From: Tyler Southard Date: Mon, 11 Mar 2019 06:53:49 -0400 Subject: [PATCH 653/814] Add armv7 support for Xamarin.iOS native libraries --- src/csharp/experimental/build_native_ext_for_ios.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/csharp/experimental/build_native_ext_for_ios.sh b/src/csharp/experimental/build_native_ext_for_ios.sh index 69c9cdf021c..130f4c51e96 100755 --- a/src/csharp/experimental/build_native_ext_for_ios.sh +++ b/src/csharp/experimental/build_native_ext_for_ios.sh @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Helper script to crosscompile grpc_csharp_ext native extension for Android. +# Helper script to crosscompile grpc_csharp_ext native extension for iOS. set -ex @@ -28,9 +28,8 @@ function build { PATH_CC="$(xcrun --sdk $SDK --find clang)" PATH_CXX="$(xcrun --sdk $SDK --find clang++)" - # TODO(jtattermusch): add -mios-version-min=6.0 and -Wl,ios_version_min=6.0 - CPPFLAGS="-O2 -Wframe-larger-than=16384 -arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path) -DPB_NO_PACKED_STRUCTS=1" - LDFLAGS="-arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path)" + CPPFLAGS="-O2 -Wframe-larger-than=16384 -arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path) -mios-version-min=6.0 -DPB_NO_PACKED_STRUCTS=1" + LDFLAGS="-arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path) -Wl,ios_version_min=6.0" # TODO(jtattermusch): revisit the build arguments make -j4 static_csharp \ @@ -51,10 +50,12 @@ function fatten { mkdir -p libs/ios lipo -create -output libs/ios/lib$LIB_NAME.a \ + libs/ios_armv7/lib$LIB_NAME.a \ libs/ios_arm64/lib$LIB_NAME.a \ libs/ios_x86_64/lib$LIB_NAME.a } +build iphoneos armv7 build iphoneos arm64 build iphonesimulator x86_64 From 5779e0c9afbc2c228e9132ff43b7ccb309675a80 Mon Sep 17 00:00:00 2001 From: Tyler Southard Date: Mon, 11 Mar 2019 07:11:23 -0400 Subject: [PATCH 654/814] Updated experimental README --- src/csharp/experimental/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/experimental/README.md b/src/csharp/experimental/README.md index 64515075ce0..b5c106e320c 100644 --- a/src/csharp/experimental/README.md +++ b/src/csharp/experimental/README.md @@ -14,7 +14,7 @@ Xamarin.Android `arm64-v8a` (some newer Android devices), `x86` (for emulator) Xamarin.iOS -- supported architectures: arm64 (iPhone 6+) and x86_64 (iPhone simulator) +- supported architectures: armv7, arm64 (iPhone 6+) and x86_64 (iPhone simulator) # Unity From 3291154db08d5f32de96991d3048a9e4954865e5 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 21 Nov 2018 13:28:09 +0100 Subject: [PATCH 655/814] update all executables to netcoreapp2.1 --- src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj | 2 +- .../Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj | 2 +- .../Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj | 2 +- src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj | 2 +- src/csharp/Grpc.Examples/Grpc.Examples.csproj | 2 +- src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj | 2 +- .../Grpc.IntegrationTesting.Client.csproj | 2 +- .../Grpc.IntegrationTesting.QpsWorker.csproj | 2 +- .../Grpc.IntegrationTesting.Server.csproj | 2 +- .../Grpc.IntegrationTesting.StressClient.csproj | 2 +- .../Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj | 2 +- src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj | 2 +- src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj | 2 +- src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index 2a3e30174c0..8de9b675a7d 100755 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true diff --git a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj index 557f4639bd5..1011ebce0f0 100755 --- a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj +++ b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj index 557f4639bd5..1011ebce0f0 100755 --- a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj +++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index e2d988a8662..26ae2776446 100755 --- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj +++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj index 5e532b11982..65ca87ed121 100755 --- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj +++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 true diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj index 6b9e37b3e6c..2c759124689 100755 --- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj +++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj index 5b29bf0a72f..30991cd0b57 100755 --- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj index c8bd3e3f186..8c682beb396 100755 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true true diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj index 5b29bf0a72f..30991cd0b57 100755 --- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj index 5b29bf0a72f..30991cd0b57 100755 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index 6bf5d220e4b..fd90e19c843 100755 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index f30b90b5130..71f970f09cd 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj index 0fb0726d7aa..6436058d4e2 100755 --- a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj +++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj @@ -4,7 +4,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe true diff --git a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj index cfb40f44ae1..402d860e382 100644 --- a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj +++ b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj @@ -3,7 +3,7 @@ - net45;netcoreapp1.1 + net45;netcoreapp2.1 Exe From c586eea27ef6118ede0a07cdf25512d7350529e7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 21 Nov 2018 16:24:01 +0100 Subject: [PATCH 656/814] adjust run_*tests.py --- tools/run_tests/performance/run_worker_csharp.sh | 2 +- tools/run_tests/run_interop_tests.py | 4 ++-- tools/run_tests/run_tests.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/run_tests/performance/run_worker_csharp.sh b/tools/run_tests/performance/run_worker_csharp.sh index bfa59b5d9e6..af944f9fefa 100755 --- a/tools/run_tests/performance/run_worker_csharp.sh +++ b/tools/run_tests/performance/run_worker_csharp.sh @@ -18,6 +18,6 @@ set -ex cd "$(dirname "$0")/../../.." # needed to correctly locate testca -cd src/csharp/Grpc.IntegrationTesting.QpsWorker/bin/Release/netcoreapp1.1 +cd src/csharp/Grpc.IntegrationTesting.QpsWorker/bin/Release/netcoreapp2.1 dotnet exec Grpc.IntegrationTesting.QpsWorker.dll "$@" diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 448b53a7207..d35dccd8d03 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -147,8 +147,8 @@ class CSharpLanguage: class CSharpCoreCLRLanguage: def __init__(self): - self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1' - self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/netcoreapp1.1' + self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp2.1' + self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/netcoreapp2.1' self.safename = str(self) def client_cmd(self, args): diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index f1e1f539ff9..1c4d20ef6da 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -946,7 +946,7 @@ class CSharpLanguage(object): assembly_extension = '.exe' if self.args.compiler == 'coreclr': - assembly_subdir += '/netcoreapp1.1' + assembly_subdir += '/netcoreapp2.1' runtime_cmd = ['dotnet', 'exec'] assembly_extension = '.dll' else: From 38ecd3831b6b8355a673437bb42df5b30b6130fb Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Mar 2019 07:58:58 -0400 Subject: [PATCH 657/814] install dotnet SDK before starting Windows build --- src/csharp/install_dotnet_sdk.ps1 | 16 ++++++++++++++++ .../helper_scripts/prepare_build_windows.bat | 4 ++++ 2 files changed, 20 insertions(+) create mode 100644 src/csharp/install_dotnet_sdk.ps1 diff --git a/src/csharp/install_dotnet_sdk.ps1 b/src/csharp/install_dotnet_sdk.ps1 new file mode 100644 index 00000000000..57328fa9981 --- /dev/null +++ b/src/csharp/install_dotnet_sdk.ps1 @@ -0,0 +1,16 @@ +#!/usr/bin/env powershell +# Install dotnet SDK needed to build C# projects on Windows + +Set-StrictMode -Version 2 +$ErrorActionPreference = 'Stop' + +# avoid "Unknown error on a send" in Invoke-WebRequest +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +$InstallScriptUrl = 'https://dot.net/v1/dotnet-install.ps1' +$InstallScriptPath = Join-Path "$env:TEMP" 'dotnet-install.ps1' + +# Download install script +Write-Host "Downloading install script: $InstallScriptUrl => $InstallScriptPath" +Invoke-WebRequest -Uri $InstallScriptUrl -OutFile $InstallScriptPath +&$InstallScriptPath -Version 2.1.504 diff --git a/tools/internal_ci/helper_scripts/prepare_build_windows.bat b/tools/internal_ci/helper_scripts/prepare_build_windows.bat index f987f8a8cb5..bee59159331 100644 --- a/tools/internal_ci/helper_scripts/prepare_build_windows.bat +++ b/tools/internal_ci/helper_scripts/prepare_build_windows.bat @@ -34,6 +34,10 @@ netsh interface ip add dnsservers "Local Area Connection 8" 8.8.4.4 index=3 @rem Needed for big_query_utils python -m pip install google-api-python-client +@rem C# prerequisites: Install dotnet SDK +powershell -File src\csharp\install_dotnet_sdk.ps1 +set PATH=%LOCALAPPDATA%\Microsoft\dotnet;%PATH% + @rem Disable some unwanted dotnet options set NUGET_XMLDOC_MODE=skip set DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true From 5a65985bf88dcbfdd3310caff677ccc8fccc6332 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Mar 2019 18:36:01 +0100 Subject: [PATCH 658/814] add NativeCallbackDispatcher --- .../Internal/NativeCallbackDispatcher.cs | 120 ++++++++++++++++++ .../Grpc.Core/Internal/NativeExtension.cs | 3 + .../NativeMetadataCredentialsPlugin.cs | 21 ++- .../Internal/NativeMethods.Generated.cs | 17 ++- src/csharp/ext/grpc_csharp_ext.c | 32 ++--- .../runtimes/grpc_csharp_ext_dummy_stubs.c | 4 + .../Grpc.Core/Internal/native_methods.include | 3 +- 7 files changed, 170 insertions(+), 30 deletions(-) create mode 100644 src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs diff --git a/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs new file mode 100644 index 00000000000..53f8b7c6489 --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs @@ -0,0 +1,120 @@ +#region Copyright notice and license + +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Collections.Generic; +using Grpc.Core.Logging; + +namespace Grpc.Core.Internal +{ + internal delegate void UniversalNativeCallback(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5); + + internal delegate void NativeCallbackDispatcherCallback(IntPtr tag, IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5); + + internal class NativeCallbackDispatcher + { + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); + static readonly object staticLock = new object(); + static readonly AtomicCounter atomicCounter = new AtomicCounter(); + static readonly ConcurrentDictionary registry = new ConcurrentDictionary(); + + static NativeCallbackDispatcherCallback dispatcherCallback; + + public static void Init(NativeMethods native) + { + lock (staticLock) + { + if (dispatcherCallback == null) + { + dispatcherCallback = new NativeCallbackDispatcherCallback(HandleDispatcherCallback); + native.grpcsharp_native_callback_dispatcher_init(dispatcherCallback); + } + } + } + + public static NativeCallbackRegistration RegisterCallback(UniversalNativeCallback callback) + { + while (true) + { + // TODO: retries might not work well on 32-bit + var tag = NextTag(); + if (registry.TryAdd(tag, callback)) + { + return new NativeCallbackRegistration(tag); + } + } + } + + public static void UnregisterCallback(IntPtr tag) + { + registry.TryRemove(tag, out UniversalNativeCallback callback); + } + + private static bool TryGetCallback(IntPtr tag, out UniversalNativeCallback callback) + { + return registry.TryGetValue(tag, out callback); + } + + private static IntPtr NextTag() + { + return (IntPtr) atomicCounter.Increment(); + } + + [MonoPInvokeCallback(typeof(NativeCallbackDispatcherCallback))] + private static void HandleDispatcherCallback(IntPtr tag, IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5) + { + try + { + UniversalNativeCallback callback; + if (!TryGetCallback(tag, out callback)) + { + Logger.Error("No native callback handler registered for tag {0}.", tag); + } + callback(arg0, arg1, arg2, arg3, arg4, arg5); + } + catch (Exception e) + { + // eat the exception, we must not throw when inside callback from native code. + Logger.Error(e, "Caught exception inside callback from native callback."); + } + } + } + + internal class NativeCallbackRegistration : IDisposable + { + readonly IntPtr tag; + readonly Action disposeAction; + + public NativeCallbackRegistration(IntPtr tag, Action disposeAction) + { + this.tag = tag; + } + + public IntPtr Tag => tag; + + public void Dispose() + { + NativeCallbackDispatcher.UnregisterCallback(tag); + } + } +} diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs index 5177b69fd90..6d9cbaf97f0 100644 --- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs +++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs @@ -43,6 +43,9 @@ namespace Grpc.Core.Internal // to make sure we don't lose any logs. NativeLogRedirector.Redirect(this.nativeMethods); + // Initialize + NativeCallbackDispatcher.Init(this.nativeMethods); + DefaultSslRootsOverride.Override(this.nativeMethods); Logger.Debug("gRPC native library loaded successfully."); diff --git a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs index faeb51e6f7a..d01d4ef287a 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs @@ -23,8 +23,6 @@ using Grpc.Core.Utils; namespace Grpc.Core.Internal { - internal delegate void NativeMetadataInterceptor(IntPtr statePtr, IntPtr serviceUrlPtr, IntPtr methodNamePtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy); - internal class NativeMetadataCredentialsPlugin { const string GetMetadataExceptionStatusMsg = "Exception occurred in metadata credentials plugin."; @@ -33,18 +31,14 @@ namespace Grpc.Core.Internal static readonly NativeMethods Native = NativeMethods.Get(); AsyncAuthInterceptor interceptor; - GCHandle gcHandle; - NativeMetadataInterceptor nativeInterceptor; CallCredentialsSafeHandle credentials; + NativeCallbackRegistration callbackRegistration; public NativeMetadataCredentialsPlugin(AsyncAuthInterceptor interceptor) { this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, "interceptor"); - this.nativeInterceptor = NativeMetadataInterceptorHandler; - - // Make sure the callback doesn't get garbage collected until it is destroyed. - this.gcHandle = GCHandle.Alloc(this.nativeInterceptor, GCHandleType.Normal); - this.credentials = Native.grpcsharp_metadata_credentials_create_from_plugin(nativeInterceptor); + this.callbackRegistration = NativeCallbackDispatcher.RegisterCallback(HandleUniversalCallback); + this.credentials = Native.grpcsharp_metadata_credentials_create_from_plugin(this.callbackRegistration.Tag); } public CallCredentialsSafeHandle Credentials @@ -52,11 +46,16 @@ namespace Grpc.Core.Internal get { return credentials; } } - private void NativeMetadataInterceptorHandler(IntPtr statePtr, IntPtr serviceUrlPtr, IntPtr methodNamePtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy) + private void HandleUniversalCallback(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5) + { + NativeMetadataInterceptorHandler(arg0, arg1, arg2, arg3, arg4 != IntPtr.Zero); + } + + private void NativeMetadataInterceptorHandler(IntPtr serviceUrlPtr, IntPtr methodNamePtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy) { if (isDestroy) { - gcHandle.Free(); + this.callbackRegistration.Dispose(); return; } diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs index a45cbe4107d..b7b9a12d8a3 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs @@ -103,6 +103,7 @@ namespace Grpc.Core.Internal public readonly Delegates.grpcsharp_metadata_array_get_value_delegate grpcsharp_metadata_array_get_value; public readonly Delegates.grpcsharp_metadata_array_destroy_full_delegate grpcsharp_metadata_array_destroy_full; public readonly Delegates.grpcsharp_redirect_log_delegate grpcsharp_redirect_log; + public readonly Delegates.grpcsharp_native_callback_dispatcher_init_delegate grpcsharp_native_callback_dispatcher_init; public readonly Delegates.grpcsharp_metadata_credentials_create_from_plugin_delegate grpcsharp_metadata_credentials_create_from_plugin; public readonly Delegates.grpcsharp_metadata_credentials_notify_from_plugin_delegate grpcsharp_metadata_credentials_notify_from_plugin; public readonly Delegates.grpcsharp_ssl_server_credentials_create_delegate grpcsharp_ssl_server_credentials_create; @@ -203,6 +204,7 @@ namespace Grpc.Core.Internal this.grpcsharp_metadata_array_get_value = GetMethodDelegate(library); this.grpcsharp_metadata_array_destroy_full = GetMethodDelegate(library); this.grpcsharp_redirect_log = GetMethodDelegate(library); + this.grpcsharp_native_callback_dispatcher_init = GetMethodDelegate(library); this.grpcsharp_metadata_credentials_create_from_plugin = GetMethodDelegate(library); this.grpcsharp_metadata_credentials_notify_from_plugin = GetMethodDelegate(library); this.grpcsharp_ssl_server_credentials_create = GetMethodDelegate(library); @@ -302,6 +304,7 @@ namespace Grpc.Core.Internal this.grpcsharp_metadata_array_get_value = DllImportsFromStaticLib.grpcsharp_metadata_array_get_value; this.grpcsharp_metadata_array_destroy_full = DllImportsFromStaticLib.grpcsharp_metadata_array_destroy_full; this.grpcsharp_redirect_log = DllImportsFromStaticLib.grpcsharp_redirect_log; + this.grpcsharp_native_callback_dispatcher_init = DllImportsFromStaticLib.grpcsharp_native_callback_dispatcher_init; this.grpcsharp_metadata_credentials_create_from_plugin = DllImportsFromStaticLib.grpcsharp_metadata_credentials_create_from_plugin; this.grpcsharp_metadata_credentials_notify_from_plugin = DllImportsFromStaticLib.grpcsharp_metadata_credentials_notify_from_plugin; this.grpcsharp_ssl_server_credentials_create = DllImportsFromStaticLib.grpcsharp_ssl_server_credentials_create; @@ -401,6 +404,7 @@ namespace Grpc.Core.Internal this.grpcsharp_metadata_array_get_value = DllImportsFromSharedLib.grpcsharp_metadata_array_get_value; this.grpcsharp_metadata_array_destroy_full = DllImportsFromSharedLib.grpcsharp_metadata_array_destroy_full; this.grpcsharp_redirect_log = DllImportsFromSharedLib.grpcsharp_redirect_log; + this.grpcsharp_native_callback_dispatcher_init = DllImportsFromSharedLib.grpcsharp_native_callback_dispatcher_init; this.grpcsharp_metadata_credentials_create_from_plugin = DllImportsFromSharedLib.grpcsharp_metadata_credentials_create_from_plugin; this.grpcsharp_metadata_credentials_notify_from_plugin = DllImportsFromSharedLib.grpcsharp_metadata_credentials_notify_from_plugin; this.grpcsharp_ssl_server_credentials_create = DllImportsFromSharedLib.grpcsharp_ssl_server_credentials_create; @@ -503,7 +507,8 @@ namespace Grpc.Core.Internal public delegate IntPtr grpcsharp_metadata_array_get_value_delegate(IntPtr metadataArray, UIntPtr index, out UIntPtr valueLength); public delegate void grpcsharp_metadata_array_destroy_full_delegate(IntPtr array); public delegate void grpcsharp_redirect_log_delegate(GprLogDelegate callback); - public delegate CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin_delegate(NativeMetadataInterceptor interceptor); + public delegate void grpcsharp_native_callback_dispatcher_init_delegate(NativeCallbackDispatcherCallback dispatcher); + public delegate CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin_delegate(IntPtr nativeCallbackTag); public delegate void grpcsharp_metadata_credentials_notify_from_plugin_delegate(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails); public delegate ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create_delegate(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, SslClientCertificateRequestType clientCertificateRequest); public delegate void grpcsharp_server_credentials_release_delegate(IntPtr credentials); @@ -746,7 +751,10 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_redirect_log(GprLogDelegate callback); [DllImport(ImportName)] - public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor); + public static extern void grpcsharp_native_callback_dispatcher_init(NativeCallbackDispatcherCallback dispatcher); + + [DllImport(ImportName)] + public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(IntPtr nativeCallbackTag); [DllImport(ImportName)] public static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails); @@ -1039,7 +1047,10 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_redirect_log(GprLogDelegate callback); [DllImport(ImportName)] - public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor); + public static extern void grpcsharp_native_callback_dispatcher_init(NativeCallbackDispatcherCallback dispatcher); + + [DllImport(ImportName)] + public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(IntPtr nativeCallbackTag); [DllImport(ImportName)] public static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails); diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index ed002ae1fff..b034bafe86c 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -1010,6 +1010,18 @@ grpcsharp_composite_call_credentials_create(grpc_call_credentials* creds1, return grpc_composite_call_credentials_create(creds1, creds2, NULL); } +/* Native callback dispatcher */ + +typedef void(GPR_CALLTYPE* grpcsharp_native_callback_dispatcher_func)( + void* tag, void* arg0, void* arg1, void* arg2, void* arg3, void* arg4, void *arg5); + +static grpcsharp_native_callback_dispatcher_func native_callback_dispatcher = NULL; + +GPR_EXPORT void GPR_CALLTYPE grpcsharp_native_callback_dispatcher_init(grpcsharp_native_callback_dispatcher_func func) { + GPR_ASSERT(func); + native_callback_dispatcher = func; +} + /* Metadata credentials plugin */ GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_credentials_notify_from_plugin( @@ -1023,37 +1035,27 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_credentials_notify_from_plugin( } } -typedef void(GPR_CALLTYPE* grpcsharp_metadata_interceptor_func)( - void* state, const char* service_url, const char* method_name, - grpc_credentials_plugin_metadata_cb cb, void* user_data, - int32_t is_destroy); - static int grpcsharp_get_metadata_handler( void* state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data, grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], size_t* num_creds_md, grpc_status_code* status, const char** error_details) { - grpcsharp_metadata_interceptor_func interceptor = - (grpcsharp_metadata_interceptor_func)(intptr_t)state; - interceptor(state, context.service_url, context.method_name, cb, user_data, - 0); + native_callback_dispatcher(state, context.service_url, context.method_name, cb, user_data, + 0, NULL); return 0; /* Asynchronous return. */ } static void grpcsharp_metadata_credentials_destroy_handler(void* state) { - grpcsharp_metadata_interceptor_func interceptor = - (grpcsharp_metadata_interceptor_func)(intptr_t)state; - interceptor(state, NULL, NULL, NULL, NULL, 1); + native_callback_dispatcher(state, NULL, NULL, NULL, NULL, 1, NULL); } GPR_EXPORT grpc_call_credentials* GPR_CALLTYPE -grpcsharp_metadata_credentials_create_from_plugin( - grpcsharp_metadata_interceptor_func metadata_interceptor) { +grpcsharp_metadata_credentials_create_from_plugin(void *callback_tag) { grpc_metadata_credentials_plugin plugin; plugin.get_metadata = grpcsharp_get_metadata_handler; plugin.destroy = grpcsharp_metadata_credentials_destroy_handler; - plugin.state = (void*)(intptr_t)metadata_interceptor; + plugin.state = callback_tag; plugin.type = ""; return grpc_metadata_credentials_create_from_plugin(plugin, NULL); } diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c index 200dd022bf8..0e9d56f5bdf 100644 --- a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c +++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/grpc_csharp_ext_dummy_stubs.c @@ -298,6 +298,10 @@ void grpcsharp_redirect_log() { fprintf(stderr, "Should never reach here"); abort(); } +void grpcsharp_native_callback_dispatcher_init() { + fprintf(stderr, "Should never reach here"); + abort(); +} void grpcsharp_metadata_credentials_create_from_plugin() { fprintf(stderr, "Should never reach here"); abort(); diff --git a/templates/src/csharp/Grpc.Core/Internal/native_methods.include b/templates/src/csharp/Grpc.Core/Internal/native_methods.include index 2afffd03720..b7a8e285488 100644 --- a/templates/src/csharp/Grpc.Core/Internal/native_methods.include +++ b/templates/src/csharp/Grpc.Core/Internal/native_methods.include @@ -69,7 +69,8 @@ native_method_signatures = [ 'IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index, out UIntPtr valueLength)', 'void grpcsharp_metadata_array_destroy_full(IntPtr array)', 'void grpcsharp_redirect_log(GprLogDelegate callback)', - 'CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor)', + 'void grpcsharp_native_callback_dispatcher_init(NativeCallbackDispatcherCallback dispatcher)', + 'CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(IntPtr nativeCallbackTag)', 'void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails)', 'ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, SslClientCertificateRequestType clientCertificateRequest)', 'void grpcsharp_server_credentials_release(IntPtr credentials)', From 83b6a98872212863d5d4f3c2fe80a0a96a01c1cd Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Mar 2019 18:51:49 +0100 Subject: [PATCH 659/814] allow return value from native callbacks --- .../Grpc.Core/Internal/NativeCallbackDispatcher.cs | 13 +++++++------ .../Internal/NativeMetadataCredentialsPlugin.cs | 3 ++- src/csharp/ext/grpc_csharp_ext.c | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs index 53f8b7c6489..36df8a5ede1 100644 --- a/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs +++ b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs @@ -27,9 +27,9 @@ using Grpc.Core.Logging; namespace Grpc.Core.Internal { - internal delegate void UniversalNativeCallback(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5); + internal delegate int UniversalNativeCallback(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5); - internal delegate void NativeCallbackDispatcherCallback(IntPtr tag, IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5); + internal delegate int NativeCallbackDispatcherCallback(IntPtr tag, IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5); internal class NativeCallbackDispatcher { @@ -81,7 +81,7 @@ namespace Grpc.Core.Internal } [MonoPInvokeCallback(typeof(NativeCallbackDispatcherCallback))] - private static void HandleDispatcherCallback(IntPtr tag, IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5) + private static int HandleDispatcherCallback(IntPtr tag, IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5) { try { @@ -89,13 +89,15 @@ namespace Grpc.Core.Internal if (!TryGetCallback(tag, out callback)) { Logger.Error("No native callback handler registered for tag {0}.", tag); + return 0; } - callback(arg0, arg1, arg2, arg3, arg4, arg5); + return callback(arg0, arg1, arg2, arg3, arg4, arg5); } catch (Exception e) { // eat the exception, we must not throw when inside callback from native code. Logger.Error(e, "Caught exception inside callback from native callback."); + return 0; } } } @@ -103,9 +105,8 @@ namespace Grpc.Core.Internal internal class NativeCallbackRegistration : IDisposable { readonly IntPtr tag; - readonly Action disposeAction; - public NativeCallbackRegistration(IntPtr tag, Action disposeAction) + public NativeCallbackRegistration(IntPtr tag) { this.tag = tag; } diff --git a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs index d01d4ef287a..f47988f7f76 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs @@ -46,9 +46,10 @@ namespace Grpc.Core.Internal get { return credentials; } } - private void HandleUniversalCallback(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5) + private int HandleUniversalCallback(IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5) { NativeMetadataInterceptorHandler(arg0, arg1, arg2, arg3, arg4 != IntPtr.Zero); + return 0; } private void NativeMetadataInterceptorHandler(IntPtr serviceUrlPtr, IntPtr methodNamePtr, IntPtr callbackPtr, IntPtr userDataPtr, bool isDestroy) diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index b034bafe86c..fcd4caf5f49 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -1012,7 +1012,7 @@ grpcsharp_composite_call_credentials_create(grpc_call_credentials* creds1, /* Native callback dispatcher */ -typedef void(GPR_CALLTYPE* grpcsharp_native_callback_dispatcher_func)( +typedef int(GPR_CALLTYPE* grpcsharp_native_callback_dispatcher_func)( void* tag, void* arg0, void* arg1, void* arg2, void* arg3, void* arg4, void *arg5); static grpcsharp_native_callback_dispatcher_func native_callback_dispatcher = NULL; From 0c8c4c6dd50b57871e504377e0375207d5ace16d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Mar 2019 14:47:28 -0400 Subject: [PATCH 660/814] update third_party/protobuf to v3.7.0 --- third_party/protobuf | 2 +- tools/run_tests/sanity/check_submodules.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/protobuf b/third_party/protobuf index 48cb18e5c41..582743bf40c 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit 48cb18e5c419ddd23d9badcfe4e9df7bde1979b2 +Subproject commit 582743bf40c5d3639a70f98f183914a2c0cd0680 diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index f1103596d51..2c447f887ee 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -38,7 +38,7 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules" ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0) 6599cac0965be8e5a835ab7a5684bbef033d5ad0 third_party/libcxx (heads/release_60) 9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60) - 48cb18e5c419ddd23d9badcfe4e9df7bde1979b2 third_party/protobuf (v3.6.0.1-37-g48cb18e5) + 582743bf40c5d3639a70f98f183914a2c0cd0680 third_party/protobuf (v3.7.0-rc.2-20-g582743bf) e143189bf6f37b3957fb31743df6a1bcf4a8c685 third_party/protoc-gen-validate (v0.0.10) 9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3 third_party/upb (heads/upbc-cpp) cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11) From e3c024591b8910d6239ef98c1213506bc04e6faa Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Mar 2019 14:49:08 -0400 Subject: [PATCH 661/814] update bazel build to protobuf v3.7.0 --- bazel/grpc_deps.bzl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 2795ce8e732..d97e8368ed7 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -124,8 +124,8 @@ def grpc_deps(): if "com_google_protobuf" not in native.existing_rules(): http_archive( name = "com_google_protobuf", - strip_prefix = "protobuf-66dc42d891a4fc8e9190c524fd67961688a37bbe", - url = "https://github.com/google/protobuf/archive/66dc42d891a4fc8e9190c524fd67961688a37bbe.tar.gz", + strip_prefix = "protobuf-582743bf40c5d3639a70f98f183914a2c0cd0680", + url = "https://github.com/google/protobuf/archive/582743bf40c5d3639a70f98f183914a2c0cd0680.tar.gz", ) if "com_github_nanopb_nanopb" not in native.existing_rules(): From 1c6040162e55e264acb4f55747eeecbff05632b9 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Mar 2019 14:59:45 -0400 Subject: [PATCH 662/814] regenerate C# protos --- src/csharp/Grpc.Examples/MathGrpc.cs | 6 +- src/csharp/Grpc.HealthCheck/Health.cs | 2 +- src/csharp/Grpc.HealthCheck/HealthGrpc.cs | 6 +- .../BenchmarkServiceGrpc.cs | 6 +- src/csharp/Grpc.IntegrationTesting/Control.cs | 84 +++++++++---------- .../Grpc.IntegrationTesting/EchoMessages.cs | 24 +++--- src/csharp/Grpc.IntegrationTesting/Empty.cs | 1 - .../EmptyServiceGrpc.cs | 6 +- .../Grpc.IntegrationTesting/Messages.cs | 72 ++++++++-------- .../Grpc.IntegrationTesting/MetricsGrpc.cs | 8 +- .../ReportQpsScenarioServiceGrpc.cs | 6 +- src/csharp/Grpc.IntegrationTesting/Stats.cs | 18 ++-- .../Grpc.IntegrationTesting/TestGrpc.cs | 6 +- .../WorkerServiceGrpc.cs | 6 +- src/csharp/Grpc.Reflection/Reflection.cs | 6 +- src/csharp/Grpc.Reflection/ReflectionGrpc.cs | 6 +- 16 files changed, 131 insertions(+), 132 deletions(-) diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs index acd70b3714d..ba6824dd8e2 100644 --- a/src/csharp/Grpc.Examples/MathGrpc.cs +++ b/src/csharp/Grpc.Examples/MathGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs index 2c3bb45c3cf..82e42febedd 100644 --- a/src/csharp/Grpc.HealthCheck/Health.cs +++ b/src/csharp/Grpc.HealthCheck/Health.cs @@ -296,7 +296,7 @@ namespace Grpc.Health.V1 { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { - status_ = (global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus) input.ReadEnum(); + Status = (global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus) input.ReadEnum(); break; } } diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs index e13b1147cf8..3edec5a37f8 100644 --- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs +++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015 The gRPC Authors -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs index 5f18ba7accf..09691d28716 100644 --- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs index 2e80dac074c..3cac3b9d759 100644 --- a/src/csharp/Grpc.IntegrationTesting/Control.cs +++ b/src/csharp/Grpc.IntegrationTesting/Control.cs @@ -1502,7 +1502,7 @@ namespace Grpc.Testing { } if (other.securityParams_ != null) { if (securityParams_ == null) { - securityParams_ = new global::Grpc.Testing.SecurityParams(); + SecurityParams = new global::Grpc.Testing.SecurityParams(); } SecurityParams.MergeFrom(other.SecurityParams); } @@ -1520,19 +1520,19 @@ namespace Grpc.Testing { } if (other.loadParams_ != null) { if (loadParams_ == null) { - loadParams_ = new global::Grpc.Testing.LoadParams(); + LoadParams = new global::Grpc.Testing.LoadParams(); } LoadParams.MergeFrom(other.LoadParams); } if (other.payloadConfig_ != null) { if (payloadConfig_ == null) { - payloadConfig_ = new global::Grpc.Testing.PayloadConfig(); + PayloadConfig = new global::Grpc.Testing.PayloadConfig(); } PayloadConfig.MergeFrom(other.PayloadConfig); } if (other.histogramParams_ != null) { if (histogramParams_ == null) { - histogramParams_ = new global::Grpc.Testing.HistogramParams(); + HistogramParams = new global::Grpc.Testing.HistogramParams(); } HistogramParams.MergeFrom(other.HistogramParams); } @@ -1572,14 +1572,14 @@ namespace Grpc.Testing { break; } case 16: { - clientType_ = (global::Grpc.Testing.ClientType) input.ReadEnum(); + ClientType = (global::Grpc.Testing.ClientType) input.ReadEnum(); break; } case 26: { if (securityParams_ == null) { - securityParams_ = new global::Grpc.Testing.SecurityParams(); + SecurityParams = new global::Grpc.Testing.SecurityParams(); } - input.ReadMessage(securityParams_); + input.ReadMessage(SecurityParams); break; } case 32: { @@ -1595,28 +1595,28 @@ namespace Grpc.Testing { break; } case 64: { - rpcType_ = (global::Grpc.Testing.RpcType) input.ReadEnum(); + RpcType = (global::Grpc.Testing.RpcType) input.ReadEnum(); break; } case 82: { if (loadParams_ == null) { - loadParams_ = new global::Grpc.Testing.LoadParams(); + LoadParams = new global::Grpc.Testing.LoadParams(); } - input.ReadMessage(loadParams_); + input.ReadMessage(LoadParams); break; } case 90: { if (payloadConfig_ == null) { - payloadConfig_ = new global::Grpc.Testing.PayloadConfig(); + PayloadConfig = new global::Grpc.Testing.PayloadConfig(); } - input.ReadMessage(payloadConfig_); + input.ReadMessage(PayloadConfig); break; } case 98: { if (histogramParams_ == null) { - histogramParams_ = new global::Grpc.Testing.HistogramParams(); + HistogramParams = new global::Grpc.Testing.HistogramParams(); } - input.ReadMessage(histogramParams_); + input.ReadMessage(HistogramParams); break; } case 106: @@ -1765,7 +1765,7 @@ namespace Grpc.Testing { } if (other.stats_ != null) { if (stats_ == null) { - stats_ = new global::Grpc.Testing.ClientStats(); + Stats = new global::Grpc.Testing.ClientStats(); } Stats.MergeFrom(other.Stats); } @@ -1782,9 +1782,9 @@ namespace Grpc.Testing { break; case 10: { if (stats_ == null) { - stats_ = new global::Grpc.Testing.ClientStats(); + Stats = new global::Grpc.Testing.ClientStats(); } - input.ReadMessage(stats_); + input.ReadMessage(Stats); break; } } @@ -2467,7 +2467,7 @@ namespace Grpc.Testing { } if (other.securityParams_ != null) { if (securityParams_ == null) { - securityParams_ = new global::Grpc.Testing.SecurityParams(); + SecurityParams = new global::Grpc.Testing.SecurityParams(); } SecurityParams.MergeFrom(other.SecurityParams); } @@ -2482,7 +2482,7 @@ namespace Grpc.Testing { } if (other.payloadConfig_ != null) { if (payloadConfig_ == null) { - payloadConfig_ = new global::Grpc.Testing.PayloadConfig(); + PayloadConfig = new global::Grpc.Testing.PayloadConfig(); } PayloadConfig.MergeFrom(other.PayloadConfig); } @@ -2509,14 +2509,14 @@ namespace Grpc.Testing { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { - serverType_ = (global::Grpc.Testing.ServerType) input.ReadEnum(); + ServerType = (global::Grpc.Testing.ServerType) input.ReadEnum(); break; } case 18: { if (securityParams_ == null) { - securityParams_ = new global::Grpc.Testing.SecurityParams(); + SecurityParams = new global::Grpc.Testing.SecurityParams(); } - input.ReadMessage(securityParams_); + input.ReadMessage(SecurityParams); break; } case 32: { @@ -2533,9 +2533,9 @@ namespace Grpc.Testing { } case 74: { if (payloadConfig_ == null) { - payloadConfig_ = new global::Grpc.Testing.PayloadConfig(); + PayloadConfig = new global::Grpc.Testing.PayloadConfig(); } - input.ReadMessage(payloadConfig_); + input.ReadMessage(PayloadConfig); break; } case 82: @@ -2924,7 +2924,7 @@ namespace Grpc.Testing { } if (other.stats_ != null) { if (stats_ == null) { - stats_ = new global::Grpc.Testing.ServerStats(); + Stats = new global::Grpc.Testing.ServerStats(); } Stats.MergeFrom(other.Stats); } @@ -2947,9 +2947,9 @@ namespace Grpc.Testing { break; case 10: { if (stats_ == null) { - stats_ = new global::Grpc.Testing.ServerStats(); + Stats = new global::Grpc.Testing.ServerStats(); } - input.ReadMessage(stats_); + input.ReadMessage(Stats); break; } case 16: { @@ -3584,7 +3584,7 @@ namespace Grpc.Testing { } if (other.clientConfig_ != null) { if (clientConfig_ == null) { - clientConfig_ = new global::Grpc.Testing.ClientConfig(); + ClientConfig = new global::Grpc.Testing.ClientConfig(); } ClientConfig.MergeFrom(other.ClientConfig); } @@ -3593,7 +3593,7 @@ namespace Grpc.Testing { } if (other.serverConfig_ != null) { if (serverConfig_ == null) { - serverConfig_ = new global::Grpc.Testing.ServerConfig(); + ServerConfig = new global::Grpc.Testing.ServerConfig(); } ServerConfig.MergeFrom(other.ServerConfig); } @@ -3626,9 +3626,9 @@ namespace Grpc.Testing { } case 18: { if (clientConfig_ == null) { - clientConfig_ = new global::Grpc.Testing.ClientConfig(); + ClientConfig = new global::Grpc.Testing.ClientConfig(); } - input.ReadMessage(clientConfig_); + input.ReadMessage(ClientConfig); break; } case 24: { @@ -3637,9 +3637,9 @@ namespace Grpc.Testing { } case 34: { if (serverConfig_ == null) { - serverConfig_ = new global::Grpc.Testing.ServerConfig(); + ServerConfig = new global::Grpc.Testing.ServerConfig(); } - input.ReadMessage(serverConfig_); + input.ReadMessage(ServerConfig); break; } case 40: { @@ -4696,13 +4696,13 @@ namespace Grpc.Testing { } if (other.scenario_ != null) { if (scenario_ == null) { - scenario_ = new global::Grpc.Testing.Scenario(); + Scenario = new global::Grpc.Testing.Scenario(); } Scenario.MergeFrom(other.Scenario); } if (other.latencies_ != null) { if (latencies_ == null) { - latencies_ = new global::Grpc.Testing.HistogramData(); + Latencies = new global::Grpc.Testing.HistogramData(); } Latencies.MergeFrom(other.Latencies); } @@ -4711,7 +4711,7 @@ namespace Grpc.Testing { serverCores_.Add(other.serverCores_); if (other.summary_ != null) { if (summary_ == null) { - summary_ = new global::Grpc.Testing.ScenarioResultSummary(); + Summary = new global::Grpc.Testing.ScenarioResultSummary(); } Summary.MergeFrom(other.Summary); } @@ -4731,16 +4731,16 @@ namespace Grpc.Testing { break; case 10: { if (scenario_ == null) { - scenario_ = new global::Grpc.Testing.Scenario(); + Scenario = new global::Grpc.Testing.Scenario(); } - input.ReadMessage(scenario_); + input.ReadMessage(Scenario); break; } case 18: { if (latencies_ == null) { - latencies_ = new global::Grpc.Testing.HistogramData(); + Latencies = new global::Grpc.Testing.HistogramData(); } - input.ReadMessage(latencies_); + input.ReadMessage(Latencies); break; } case 26: { @@ -4758,9 +4758,9 @@ namespace Grpc.Testing { } case 50: { if (summary_ == null) { - summary_ = new global::Grpc.Testing.ScenarioResultSummary(); + Summary = new global::Grpc.Testing.ScenarioResultSummary(); } - input.ReadMessage(summary_); + input.ReadMessage(Summary); break; } case 58: diff --git a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs index 80a1007e9a5..e5af4a93e99 100644 --- a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs +++ b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs @@ -864,7 +864,7 @@ namespace Grpc.Testing { } if (other.debugInfo_ != null) { if (debugInfo_ == null) { - debugInfo_ = new global::Grpc.Testing.DebugInfo(); + DebugInfo = new global::Grpc.Testing.DebugInfo(); } DebugInfo.MergeFrom(other.DebugInfo); } @@ -876,7 +876,7 @@ namespace Grpc.Testing { } if (other.expectedError_ != null) { if (expectedError_ == null) { - expectedError_ = new global::Grpc.Testing.ErrorStatus(); + ExpectedError = new global::Grpc.Testing.ErrorStatus(); } ExpectedError.MergeFrom(other.ExpectedError); } @@ -939,9 +939,9 @@ namespace Grpc.Testing { } case 90: { if (debugInfo_ == null) { - debugInfo_ = new global::Grpc.Testing.DebugInfo(); + DebugInfo = new global::Grpc.Testing.DebugInfo(); } - input.ReadMessage(debugInfo_); + input.ReadMessage(DebugInfo); break; } case 96: { @@ -954,9 +954,9 @@ namespace Grpc.Testing { } case 114: { if (expectedError_ == null) { - expectedError_ = new global::Grpc.Testing.ErrorStatus(); + ExpectedError = new global::Grpc.Testing.ErrorStatus(); } - input.ReadMessage(expectedError_); + input.ReadMessage(ExpectedError); break; } case 120: { @@ -1104,7 +1104,7 @@ namespace Grpc.Testing { } if (other.param_ != null) { if (param_ == null) { - param_ = new global::Grpc.Testing.RequestParams(); + Param = new global::Grpc.Testing.RequestParams(); } Param.MergeFrom(other.Param); } @@ -1125,9 +1125,9 @@ namespace Grpc.Testing { } case 18: { if (param_ == null) { - param_ = new global::Grpc.Testing.RequestParams(); + Param = new global::Grpc.Testing.RequestParams(); } - input.ReadMessage(param_); + input.ReadMessage(Param); break; } } @@ -1452,7 +1452,7 @@ namespace Grpc.Testing { } if (other.param_ != null) { if (param_ == null) { - param_ = new global::Grpc.Testing.ResponseParams(); + Param = new global::Grpc.Testing.ResponseParams(); } Param.MergeFrom(other.Param); } @@ -1473,9 +1473,9 @@ namespace Grpc.Testing { } case 18: { if (param_ == null) { - param_ = new global::Grpc.Testing.ResponseParams(); + Param = new global::Grpc.Testing.ResponseParams(); } - input.ReadMessage(param_); + input.ReadMessage(Param); break; } } diff --git a/src/csharp/Grpc.IntegrationTesting/Empty.cs b/src/csharp/Grpc.IntegrationTesting/Empty.cs index 389fe433755..0d4c28bf7fc 100644 --- a/src/csharp/Grpc.IntegrationTesting/Empty.cs +++ b/src/csharp/Grpc.IntegrationTesting/Empty.cs @@ -44,7 +44,6 @@ namespace Grpc.Testing { /// service Foo { /// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { }; /// }; - /// /// public sealed partial class Empty : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Empty()); diff --git a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs index 01af6c24f41..bfa3348f6a0 100644 --- a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2018 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/src/csharp/Grpc.IntegrationTesting/Messages.cs b/src/csharp/Grpc.IntegrationTesting/Messages.cs index 35546f1b671..3b6c0010222 100644 --- a/src/csharp/Grpc.IntegrationTesting/Messages.cs +++ b/src/csharp/Grpc.IntegrationTesting/Messages.cs @@ -379,7 +379,7 @@ namespace Grpc.Testing { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { - type_ = (global::Grpc.Testing.PayloadType) input.ReadEnum(); + Type = (global::Grpc.Testing.PayloadType) input.ReadEnum(); break; } case 18: { @@ -844,7 +844,7 @@ namespace Grpc.Testing { } if (other.payload_ != null) { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } Payload.MergeFrom(other.Payload); } @@ -856,19 +856,19 @@ namespace Grpc.Testing { } if (other.responseCompressed_ != null) { if (responseCompressed_ == null) { - responseCompressed_ = new global::Grpc.Testing.BoolValue(); + ResponseCompressed = new global::Grpc.Testing.BoolValue(); } ResponseCompressed.MergeFrom(other.ResponseCompressed); } if (other.responseStatus_ != null) { if (responseStatus_ == null) { - responseStatus_ = new global::Grpc.Testing.EchoStatus(); + ResponseStatus = new global::Grpc.Testing.EchoStatus(); } ResponseStatus.MergeFrom(other.ResponseStatus); } if (other.expectCompressed_ != null) { if (expectCompressed_ == null) { - expectCompressed_ = new global::Grpc.Testing.BoolValue(); + ExpectCompressed = new global::Grpc.Testing.BoolValue(); } ExpectCompressed.MergeFrom(other.ExpectCompressed); } @@ -884,7 +884,7 @@ namespace Grpc.Testing { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { - responseType_ = (global::Grpc.Testing.PayloadType) input.ReadEnum(); + ResponseType = (global::Grpc.Testing.PayloadType) input.ReadEnum(); break; } case 16: { @@ -893,9 +893,9 @@ namespace Grpc.Testing { } case 26: { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } - input.ReadMessage(payload_); + input.ReadMessage(Payload); break; } case 32: { @@ -908,23 +908,23 @@ namespace Grpc.Testing { } case 50: { if (responseCompressed_ == null) { - responseCompressed_ = new global::Grpc.Testing.BoolValue(); + ResponseCompressed = new global::Grpc.Testing.BoolValue(); } - input.ReadMessage(responseCompressed_); + input.ReadMessage(ResponseCompressed); break; } case 58: { if (responseStatus_ == null) { - responseStatus_ = new global::Grpc.Testing.EchoStatus(); + ResponseStatus = new global::Grpc.Testing.EchoStatus(); } - input.ReadMessage(responseStatus_); + input.ReadMessage(ResponseStatus); break; } case 66: { if (expectCompressed_ == null) { - expectCompressed_ = new global::Grpc.Testing.BoolValue(); + ExpectCompressed = new global::Grpc.Testing.BoolValue(); } - input.ReadMessage(expectCompressed_); + input.ReadMessage(ExpectCompressed); break; } } @@ -1095,7 +1095,7 @@ namespace Grpc.Testing { } if (other.payload_ != null) { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } Payload.MergeFrom(other.Payload); } @@ -1118,9 +1118,9 @@ namespace Grpc.Testing { break; case 10: { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } - input.ReadMessage(payload_); + input.ReadMessage(Payload); break; } case 18: { @@ -1277,13 +1277,13 @@ namespace Grpc.Testing { } if (other.payload_ != null) { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } Payload.MergeFrom(other.Payload); } if (other.expectCompressed_ != null) { if (expectCompressed_ == null) { - expectCompressed_ = new global::Grpc.Testing.BoolValue(); + ExpectCompressed = new global::Grpc.Testing.BoolValue(); } ExpectCompressed.MergeFrom(other.ExpectCompressed); } @@ -1300,16 +1300,16 @@ namespace Grpc.Testing { break; case 10: { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } - input.ReadMessage(payload_); + input.ReadMessage(Payload); break; } case 18: { if (expectCompressed_ == null) { - expectCompressed_ = new global::Grpc.Testing.BoolValue(); + ExpectCompressed = new global::Grpc.Testing.BoolValue(); } - input.ReadMessage(expectCompressed_); + input.ReadMessage(ExpectCompressed); break; } } @@ -1624,7 +1624,7 @@ namespace Grpc.Testing { } if (other.compressed_ != null) { if (compressed_ == null) { - compressed_ = new global::Grpc.Testing.BoolValue(); + Compressed = new global::Grpc.Testing.BoolValue(); } Compressed.MergeFrom(other.Compressed); } @@ -1649,9 +1649,9 @@ namespace Grpc.Testing { } case 26: { if (compressed_ == null) { - compressed_ = new global::Grpc.Testing.BoolValue(); + Compressed = new global::Grpc.Testing.BoolValue(); } - input.ReadMessage(compressed_); + input.ReadMessage(Compressed); break; } } @@ -1846,13 +1846,13 @@ namespace Grpc.Testing { responseParameters_.Add(other.responseParameters_); if (other.payload_ != null) { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } Payload.MergeFrom(other.Payload); } if (other.responseStatus_ != null) { if (responseStatus_ == null) { - responseStatus_ = new global::Grpc.Testing.EchoStatus(); + ResponseStatus = new global::Grpc.Testing.EchoStatus(); } ResponseStatus.MergeFrom(other.ResponseStatus); } @@ -1868,7 +1868,7 @@ namespace Grpc.Testing { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { - responseType_ = (global::Grpc.Testing.PayloadType) input.ReadEnum(); + ResponseType = (global::Grpc.Testing.PayloadType) input.ReadEnum(); break; } case 18: { @@ -1877,16 +1877,16 @@ namespace Grpc.Testing { } case 26: { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } - input.ReadMessage(payload_); + input.ReadMessage(Payload); break; } case 58: { if (responseStatus_ == null) { - responseStatus_ = new global::Grpc.Testing.EchoStatus(); + ResponseStatus = new global::Grpc.Testing.EchoStatus(); } - input.ReadMessage(responseStatus_); + input.ReadMessage(ResponseStatus); break; } } @@ -2008,7 +2008,7 @@ namespace Grpc.Testing { } if (other.payload_ != null) { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } Payload.MergeFrom(other.Payload); } @@ -2025,9 +2025,9 @@ namespace Grpc.Testing { break; case 10: { if (payload_ == null) { - payload_ = new global::Grpc.Testing.Payload(); + Payload = new global::Grpc.Testing.Payload(); } - input.ReadMessage(payload_); + input.ReadMessage(Payload); break; } } diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs index 7b5b1a3aa7f..27746c07641 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015-2016 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,7 +19,7 @@ // // Contains the definitions for a metrics service and the type of metrics // exposed by the service. -// +// // Currently, 'Gauge' (i.e a metric that represents the measured value of // something at an instant of time) is the only metric type supported by the // service. diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs index 04bb9c29d63..f92ae8e974b 100644 --- a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/src/csharp/Grpc.IntegrationTesting/Stats.cs b/src/csharp/Grpc.IntegrationTesting/Stats.cs index af83eef7ba8..c3e5664e11a 100644 --- a/src/csharp/Grpc.IntegrationTesting/Stats.cs +++ b/src/csharp/Grpc.IntegrationTesting/Stats.cs @@ -328,7 +328,7 @@ namespace Grpc.Testing { } if (other.coreStats_ != null) { if (coreStats_ == null) { - coreStats_ = new global::Grpc.Core.Stats(); + CoreStats = new global::Grpc.Core.Stats(); } CoreStats.MergeFrom(other.CoreStats); } @@ -369,9 +369,9 @@ namespace Grpc.Testing { } case 58: { if (coreStats_ == null) { - coreStats_ = new global::Grpc.Core.Stats(); + CoreStats = new global::Grpc.Core.Stats(); } - input.ReadMessage(coreStats_); + input.ReadMessage(CoreStats); break; } } @@ -1210,7 +1210,7 @@ namespace Grpc.Testing { } if (other.latencies_ != null) { if (latencies_ == null) { - latencies_ = new global::Grpc.Testing.HistogramData(); + Latencies = new global::Grpc.Testing.HistogramData(); } Latencies.MergeFrom(other.Latencies); } @@ -1229,7 +1229,7 @@ namespace Grpc.Testing { } if (other.coreStats_ != null) { if (coreStats_ == null) { - coreStats_ = new global::Grpc.Core.Stats(); + CoreStats = new global::Grpc.Core.Stats(); } CoreStats.MergeFrom(other.CoreStats); } @@ -1246,9 +1246,9 @@ namespace Grpc.Testing { break; case 10: { if (latencies_ == null) { - latencies_ = new global::Grpc.Testing.HistogramData(); + Latencies = new global::Grpc.Testing.HistogramData(); } - input.ReadMessage(latencies_); + input.ReadMessage(Latencies); break; } case 17: { @@ -1273,9 +1273,9 @@ namespace Grpc.Testing { } case 58: { if (coreStats_ == null) { - coreStats_ = new global::Grpc.Core.Stats(); + CoreStats = new global::Grpc.Core.Stats(); } - input.ReadMessage(coreStats_); + input.ReadMessage(CoreStats); break; } } diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs index 05e1e3ccc7d..d47b5fe0d4b 100644 --- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015-2016 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs index a36f1d7a356..f7dd2eecf2e 100644 --- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs +++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2015 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/src/csharp/Grpc.Reflection/Reflection.cs b/src/csharp/Grpc.Reflection/Reflection.cs index e319be5bff7..a1b99dff431 100644 --- a/src/csharp/Grpc.Reflection/Reflection.cs +++ b/src/csharp/Grpc.Reflection/Reflection.cs @@ -850,7 +850,7 @@ namespace Grpc.Reflection.V1Alpha { } if (other.originalRequest_ != null) { if (originalRequest_ == null) { - originalRequest_ = new global::Grpc.Reflection.V1Alpha.ServerReflectionRequest(); + OriginalRequest = new global::Grpc.Reflection.V1Alpha.ServerReflectionRequest(); } OriginalRequest.MergeFrom(other.OriginalRequest); } @@ -898,9 +898,9 @@ namespace Grpc.Reflection.V1Alpha { } case 18: { if (originalRequest_ == null) { - originalRequest_ = new global::Grpc.Reflection.V1Alpha.ServerReflectionRequest(); + OriginalRequest = new global::Grpc.Reflection.V1Alpha.ServerReflectionRequest(); } - input.ReadMessage(originalRequest_); + input.ReadMessage(OriginalRequest); break; } case 34: { diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs index 0b2bb2341b9..500738205a7 100644 --- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs +++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs @@ -4,13 +4,13 @@ // // Original file comments: // Copyright 2016 gRPC authors. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. From b667c2f72ffecb1de672f5a7fb837737bf9ee405 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Mar 2019 15:00:56 -0400 Subject: [PATCH 663/814] regenerate ruby protos --- src/ruby/bin/math_pb.rb | 34 ++- src/ruby/pb/grpc/health/v1/health_pb.rb | 23 +- .../pb/grpc/health/v1/health_services_pb.rb | 18 ++ .../pb/src/proto/grpc/testing/empty_pb.rb | 4 +- .../pb/src/proto/grpc/testing/messages_pb.rb | 114 +++---- src/ruby/pb/src/proto/grpc/testing/test_pb.rb | 2 + src/ruby/qps/src/proto/grpc/core/stats_pb.rb | 32 +- .../grpc/testing/benchmark_service_pb.rb | 2 + .../qps/src/proto/grpc/testing/control_pb.rb | 289 +++++++++--------- .../qps/src/proto/grpc/testing/messages_pb.rb | 114 +++---- .../qps/src/proto/grpc/testing/payloads_pb.rb | 32 +- .../testing/report_qps_scenario_service_pb.rb | 2 + .../qps/src/proto/grpc/testing/stats_pb.rb | 68 +++-- .../proto/grpc/testing/worker_service_pb.rb | 2 + 14 files changed, 392 insertions(+), 344 deletions(-) diff --git a/src/ruby/bin/math_pb.rb b/src/ruby/bin/math_pb.rb index 60429a15052..ac287c81bcd 100644 --- a/src/ruby/bin/math_pb.rb +++ b/src/ruby/bin/math_pb.rb @@ -4,22 +4,24 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "math.DivArgs" do - optional :dividend, :int64, 1 - optional :divisor, :int64, 2 - end - add_message "math.DivReply" do - optional :quotient, :int64, 1 - optional :remainder, :int64, 2 - end - add_message "math.FibArgs" do - optional :limit, :int64, 1 - end - add_message "math.Num" do - optional :num, :int64, 1 - end - add_message "math.FibReply" do - optional :count, :int64, 1 + add_file("math.proto", :syntax => :proto3) do + add_message "math.DivArgs" do + optional :dividend, :int64, 1 + optional :divisor, :int64, 2 + end + add_message "math.DivReply" do + optional :quotient, :int64, 1 + optional :remainder, :int64, 2 + end + add_message "math.FibArgs" do + optional :limit, :int64, 1 + end + add_message "math.Num" do + optional :num, :int64, 1 + end + add_message "math.FibReply" do + optional :count, :int64, 1 + end end end diff --git a/src/ruby/pb/grpc/health/v1/health_pb.rb b/src/ruby/pb/grpc/health/v1/health_pb.rb index aa87a93918b..c11dbf48418 100644 --- a/src/ruby/pb/grpc/health/v1/health_pb.rb +++ b/src/ruby/pb/grpc/health/v1/health_pb.rb @@ -4,16 +4,19 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.health.v1.HealthCheckRequest" do - optional :service, :string, 1 - end - add_message "grpc.health.v1.HealthCheckResponse" do - optional :status, :enum, 1, "grpc.health.v1.HealthCheckResponse.ServingStatus" - end - add_enum "grpc.health.v1.HealthCheckResponse.ServingStatus" do - value :UNKNOWN, 0 - value :SERVING, 1 - value :NOT_SERVING, 2 + add_file("grpc/health/v1/health.proto", :syntax => :proto3) do + add_message "grpc.health.v1.HealthCheckRequest" do + optional :service, :string, 1 + end + add_message "grpc.health.v1.HealthCheckResponse" do + optional :status, :enum, 1, "grpc.health.v1.HealthCheckResponse.ServingStatus" + end + add_enum "grpc.health.v1.HealthCheckResponse.ServingStatus" do + value :UNKNOWN, 0 + value :SERVING, 1 + value :NOT_SERVING, 2 + value :SERVICE_UNKNOWN, 3 + end end end diff --git a/src/ruby/pb/grpc/health/v1/health_services_pb.rb b/src/ruby/pb/grpc/health/v1/health_services_pb.rb index 169e160f90f..5992f1c403d 100644 --- a/src/ruby/pb/grpc/health/v1/health_services_pb.rb +++ b/src/ruby/pb/grpc/health/v1/health_services_pb.rb @@ -34,7 +34,25 @@ module Grpc self.unmarshal_class_method = :decode self.service_name = 'grpc.health.v1.Health' + # If the requested service is unknown, the call will fail with status + # NOT_FOUND. rpc :Check, HealthCheckRequest, HealthCheckResponse + # Performs a watch for the serving status of the requested service. + # The server will immediately send back a message indicating the current + # serving status. It will then subsequently send a new message whenever + # the service's serving status changes. + # + # If the requested service is unknown when the call is received, the + # server will send a message setting the serving status to + # SERVICE_UNKNOWN but will *not* terminate the call. If at some + # future point, the serving status of the service becomes known, the + # server will send a new message with the service's serving status. + # + # If the call terminates with status UNIMPLEMENTED, then clients + # should assume this method is not supported and should not retry the + # call. If the call terminates with any other status (including OK), + # clients should retry the call with appropriate exponential backoff. + rpc :Watch, HealthCheckRequest, stream(HealthCheckResponse) end Stub = Service.rpc_stub_class diff --git a/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb b/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb index 9c2568d6053..3e46d8525ed 100644 --- a/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +++ b/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb @@ -4,7 +4,9 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.testing.Empty" do + add_file("src/proto/grpc/testing/empty.proto", :syntax => :proto3) do + add_message "grpc.testing.Empty" do + end end end diff --git a/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb b/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb index e27ccd0dc04..796d4bb9ae2 100644 --- a/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +++ b/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb @@ -4,62 +4,64 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.testing.BoolValue" do - optional :value, :bool, 1 - end - add_message "grpc.testing.Payload" do - optional :type, :enum, 1, "grpc.testing.PayloadType" - optional :body, :bytes, 2 - end - add_message "grpc.testing.EchoStatus" do - optional :code, :int32, 1 - optional :message, :string, 2 - end - add_message "grpc.testing.SimpleRequest" do - optional :response_type, :enum, 1, "grpc.testing.PayloadType" - optional :response_size, :int32, 2 - optional :payload, :message, 3, "grpc.testing.Payload" - optional :fill_username, :bool, 4 - optional :fill_oauth_scope, :bool, 5 - optional :response_compressed, :message, 6, "grpc.testing.BoolValue" - optional :response_status, :message, 7, "grpc.testing.EchoStatus" - optional :expect_compressed, :message, 8, "grpc.testing.BoolValue" - end - add_message "grpc.testing.SimpleResponse" do - optional :payload, :message, 1, "grpc.testing.Payload" - optional :username, :string, 2 - optional :oauth_scope, :string, 3 - end - add_message "grpc.testing.StreamingInputCallRequest" do - optional :payload, :message, 1, "grpc.testing.Payload" - optional :expect_compressed, :message, 2, "grpc.testing.BoolValue" - end - add_message "grpc.testing.StreamingInputCallResponse" do - optional :aggregated_payload_size, :int32, 1 - end - add_message "grpc.testing.ResponseParameters" do - optional :size, :int32, 1 - optional :interval_us, :int32, 2 - optional :compressed, :message, 3, "grpc.testing.BoolValue" - end - add_message "grpc.testing.StreamingOutputCallRequest" do - optional :response_type, :enum, 1, "grpc.testing.PayloadType" - repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters" - optional :payload, :message, 3, "grpc.testing.Payload" - optional :response_status, :message, 7, "grpc.testing.EchoStatus" - end - add_message "grpc.testing.StreamingOutputCallResponse" do - optional :payload, :message, 1, "grpc.testing.Payload" - end - add_message "grpc.testing.ReconnectParams" do - optional :max_reconnect_backoff_ms, :int32, 1 - end - add_message "grpc.testing.ReconnectInfo" do - optional :passed, :bool, 1 - repeated :backoff_ms, :int32, 2 - end - add_enum "grpc.testing.PayloadType" do - value :COMPRESSABLE, 0 + add_file("src/proto/grpc/testing/messages.proto", :syntax => :proto3) do + add_message "grpc.testing.BoolValue" do + optional :value, :bool, 1 + end + add_message "grpc.testing.Payload" do + optional :type, :enum, 1, "grpc.testing.PayloadType" + optional :body, :bytes, 2 + end + add_message "grpc.testing.EchoStatus" do + optional :code, :int32, 1 + optional :message, :string, 2 + end + add_message "grpc.testing.SimpleRequest" do + optional :response_type, :enum, 1, "grpc.testing.PayloadType" + optional :response_size, :int32, 2 + optional :payload, :message, 3, "grpc.testing.Payload" + optional :fill_username, :bool, 4 + optional :fill_oauth_scope, :bool, 5 + optional :response_compressed, :message, 6, "grpc.testing.BoolValue" + optional :response_status, :message, 7, "grpc.testing.EchoStatus" + optional :expect_compressed, :message, 8, "grpc.testing.BoolValue" + end + add_message "grpc.testing.SimpleResponse" do + optional :payload, :message, 1, "grpc.testing.Payload" + optional :username, :string, 2 + optional :oauth_scope, :string, 3 + end + add_message "grpc.testing.StreamingInputCallRequest" do + optional :payload, :message, 1, "grpc.testing.Payload" + optional :expect_compressed, :message, 2, "grpc.testing.BoolValue" + end + add_message "grpc.testing.StreamingInputCallResponse" do + optional :aggregated_payload_size, :int32, 1 + end + add_message "grpc.testing.ResponseParameters" do + optional :size, :int32, 1 + optional :interval_us, :int32, 2 + optional :compressed, :message, 3, "grpc.testing.BoolValue" + end + add_message "grpc.testing.StreamingOutputCallRequest" do + optional :response_type, :enum, 1, "grpc.testing.PayloadType" + repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters" + optional :payload, :message, 3, "grpc.testing.Payload" + optional :response_status, :message, 7, "grpc.testing.EchoStatus" + end + add_message "grpc.testing.StreamingOutputCallResponse" do + optional :payload, :message, 1, "grpc.testing.Payload" + end + add_message "grpc.testing.ReconnectParams" do + optional :max_reconnect_backoff_ms, :int32, 1 + end + add_message "grpc.testing.ReconnectInfo" do + optional :passed, :bool, 1 + repeated :backoff_ms, :int32, 2 + end + add_enum "grpc.testing.PayloadType" do + value :COMPRESSABLE, 0 + end end end diff --git a/src/ruby/pb/src/proto/grpc/testing/test_pb.rb b/src/ruby/pb/src/proto/grpc/testing/test_pb.rb index 2cc98630314..ed4b5b5e1e7 100644 --- a/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +++ b/src/ruby/pb/src/proto/grpc/testing/test_pb.rb @@ -6,6 +6,8 @@ require 'google/protobuf' require 'src/proto/grpc/testing/empty_pb' require 'src/proto/grpc/testing/messages_pb' Google::Protobuf::DescriptorPool.generated_pool.build do + add_file("src/proto/grpc/testing/test.proto", :syntax => :proto3) do + end end module Grpc diff --git a/src/ruby/qps/src/proto/grpc/core/stats_pb.rb b/src/ruby/qps/src/proto/grpc/core/stats_pb.rb index 59c057820bf..b75ce043fbb 100644 --- a/src/ruby/qps/src/proto/grpc/core/stats_pb.rb +++ b/src/ruby/qps/src/proto/grpc/core/stats_pb.rb @@ -4,22 +4,24 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.core.Bucket" do - optional :start, :double, 1 - optional :count, :uint64, 2 - end - add_message "grpc.core.Histogram" do - repeated :buckets, :message, 1, "grpc.core.Bucket" - end - add_message "grpc.core.Metric" do - optional :name, :string, 1 - oneof :value do - optional :count, :uint64, 10 - optional :histogram, :message, 11, "grpc.core.Histogram" + add_file("src/proto/grpc/core/stats.proto", :syntax => :proto3) do + add_message "grpc.core.Bucket" do + optional :start, :double, 1 + optional :count, :uint64, 2 + end + add_message "grpc.core.Histogram" do + repeated :buckets, :message, 1, "grpc.core.Bucket" + end + add_message "grpc.core.Metric" do + optional :name, :string, 1 + oneof :value do + optional :count, :uint64, 10 + optional :histogram, :message, 11, "grpc.core.Histogram" + end + end + add_message "grpc.core.Stats" do + repeated :metrics, :message, 1, "grpc.core.Metric" end - end - add_message "grpc.core.Stats" do - repeated :metrics, :message, 1, "grpc.core.Metric" end end diff --git a/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb index 0bd3625f3d4..3f14f441730 100644 --- a/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/benchmark_service_pb.rb @@ -5,6 +5,8 @@ require 'google/protobuf' require 'src/proto/grpc/testing/messages_pb' Google::Protobuf::DescriptorPool.generated_pool.build do + add_file("src/proto/grpc/testing/benchmark_service.proto", :syntax => :proto3) do + end end module Grpc diff --git a/src/ruby/qps/src/proto/grpc/testing/control_pb.rb b/src/ruby/qps/src/proto/grpc/testing/control_pb.rb index 5acc7fc0c6b..1053e504621 100644 --- a/src/ruby/qps/src/proto/grpc/testing/control_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/control_pb.rb @@ -6,152 +6,157 @@ require 'google/protobuf' require 'src/proto/grpc/testing/payloads_pb' require 'src/proto/grpc/testing/stats_pb' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.testing.PoissonParams" do - optional :offered_load, :double, 1 - end - add_message "grpc.testing.ClosedLoopParams" do - end - add_message "grpc.testing.LoadParams" do - oneof :load do - optional :closed_loop, :message, 1, "grpc.testing.ClosedLoopParams" - optional :poisson, :message, 2, "grpc.testing.PoissonParams" + add_file("src/proto/grpc/testing/control.proto", :syntax => :proto3) do + add_message "grpc.testing.PoissonParams" do + optional :offered_load, :double, 1 end - end - add_message "grpc.testing.SecurityParams" do - optional :use_test_ca, :bool, 1 - optional :server_host_override, :string, 2 - optional :cred_type, :string, 3 - end - add_message "grpc.testing.ChannelArg" do - optional :name, :string, 1 - oneof :value do - optional :str_value, :string, 2 - optional :int_value, :int32, 3 + add_message "grpc.testing.ClosedLoopParams" do end - end - add_message "grpc.testing.ClientConfig" do - repeated :server_targets, :string, 1 - optional :client_type, :enum, 2, "grpc.testing.ClientType" - optional :security_params, :message, 3, "grpc.testing.SecurityParams" - optional :outstanding_rpcs_per_channel, :int32, 4 - optional :client_channels, :int32, 5 - optional :async_client_threads, :int32, 7 - optional :rpc_type, :enum, 8, "grpc.testing.RpcType" - optional :load_params, :message, 10, "grpc.testing.LoadParams" - optional :payload_config, :message, 11, "grpc.testing.PayloadConfig" - optional :histogram_params, :message, 12, "grpc.testing.HistogramParams" - repeated :core_list, :int32, 13 - optional :core_limit, :int32, 14 - optional :other_client_api, :string, 15 - repeated :channel_args, :message, 16, "grpc.testing.ChannelArg" - optional :threads_per_cq, :int32, 17 - optional :messages_per_stream, :int32, 18 - optional :use_coalesce_api, :bool, 19 - end - add_message "grpc.testing.ClientStatus" do - optional :stats, :message, 1, "grpc.testing.ClientStats" - end - add_message "grpc.testing.Mark" do - optional :reset, :bool, 1 - end - add_message "grpc.testing.ClientArgs" do - oneof :argtype do - optional :setup, :message, 1, "grpc.testing.ClientConfig" - optional :mark, :message, 2, "grpc.testing.Mark" + add_message "grpc.testing.LoadParams" do + oneof :load do + optional :closed_loop, :message, 1, "grpc.testing.ClosedLoopParams" + optional :poisson, :message, 2, "grpc.testing.PoissonParams" + end end - end - add_message "grpc.testing.ServerConfig" do - optional :server_type, :enum, 1, "grpc.testing.ServerType" - optional :security_params, :message, 2, "grpc.testing.SecurityParams" - optional :port, :int32, 4 - optional :async_server_threads, :int32, 7 - optional :core_limit, :int32, 8 - optional :payload_config, :message, 9, "grpc.testing.PayloadConfig" - repeated :core_list, :int32, 10 - optional :other_server_api, :string, 11 - optional :threads_per_cq, :int32, 12 - optional :resource_quota_size, :int32, 1001 - repeated :channel_args, :message, 1002, "grpc.testing.ChannelArg" - end - add_message "grpc.testing.ServerArgs" do - oneof :argtype do - optional :setup, :message, 1, "grpc.testing.ServerConfig" - optional :mark, :message, 2, "grpc.testing.Mark" + add_message "grpc.testing.SecurityParams" do + optional :use_test_ca, :bool, 1 + optional :server_host_override, :string, 2 + optional :cred_type, :string, 3 + end + add_message "grpc.testing.ChannelArg" do + optional :name, :string, 1 + oneof :value do + optional :str_value, :string, 2 + optional :int_value, :int32, 3 + end + end + add_message "grpc.testing.ClientConfig" do + repeated :server_targets, :string, 1 + optional :client_type, :enum, 2, "grpc.testing.ClientType" + optional :security_params, :message, 3, "grpc.testing.SecurityParams" + optional :outstanding_rpcs_per_channel, :int32, 4 + optional :client_channels, :int32, 5 + optional :async_client_threads, :int32, 7 + optional :rpc_type, :enum, 8, "grpc.testing.RpcType" + optional :load_params, :message, 10, "grpc.testing.LoadParams" + optional :payload_config, :message, 11, "grpc.testing.PayloadConfig" + optional :histogram_params, :message, 12, "grpc.testing.HistogramParams" + repeated :core_list, :int32, 13 + optional :core_limit, :int32, 14 + optional :other_client_api, :string, 15 + repeated :channel_args, :message, 16, "grpc.testing.ChannelArg" + optional :threads_per_cq, :int32, 17 + optional :messages_per_stream, :int32, 18 + optional :use_coalesce_api, :bool, 19 + optional :median_latency_collection_interval_millis, :int32, 20 + end + add_message "grpc.testing.ClientStatus" do + optional :stats, :message, 1, "grpc.testing.ClientStats" + end + add_message "grpc.testing.Mark" do + optional :reset, :bool, 1 + end + add_message "grpc.testing.ClientArgs" do + oneof :argtype do + optional :setup, :message, 1, "grpc.testing.ClientConfig" + optional :mark, :message, 2, "grpc.testing.Mark" + end + end + add_message "grpc.testing.ServerConfig" do + optional :server_type, :enum, 1, "grpc.testing.ServerType" + optional :security_params, :message, 2, "grpc.testing.SecurityParams" + optional :port, :int32, 4 + optional :async_server_threads, :int32, 7 + optional :core_limit, :int32, 8 + optional :payload_config, :message, 9, "grpc.testing.PayloadConfig" + repeated :core_list, :int32, 10 + optional :other_server_api, :string, 11 + optional :threads_per_cq, :int32, 12 + optional :resource_quota_size, :int32, 1001 + repeated :channel_args, :message, 1002, "grpc.testing.ChannelArg" + end + add_message "grpc.testing.ServerArgs" do + oneof :argtype do + optional :setup, :message, 1, "grpc.testing.ServerConfig" + optional :mark, :message, 2, "grpc.testing.Mark" + end + end + add_message "grpc.testing.ServerStatus" do + optional :stats, :message, 1, "grpc.testing.ServerStats" + optional :port, :int32, 2 + optional :cores, :int32, 3 + end + add_message "grpc.testing.CoreRequest" do + end + add_message "grpc.testing.CoreResponse" do + optional :cores, :int32, 1 + end + add_message "grpc.testing.Void" do + end + add_message "grpc.testing.Scenario" do + optional :name, :string, 1 + optional :client_config, :message, 2, "grpc.testing.ClientConfig" + optional :num_clients, :int32, 3 + optional :server_config, :message, 4, "grpc.testing.ServerConfig" + optional :num_servers, :int32, 5 + optional :warmup_seconds, :int32, 6 + optional :benchmark_seconds, :int32, 7 + optional :spawn_local_worker_count, :int32, 8 + end + add_message "grpc.testing.Scenarios" do + repeated :scenarios, :message, 1, "grpc.testing.Scenario" + end + add_message "grpc.testing.ScenarioResultSummary" do + optional :qps, :double, 1 + optional :qps_per_server_core, :double, 2 + optional :server_system_time, :double, 3 + optional :server_user_time, :double, 4 + optional :client_system_time, :double, 5 + optional :client_user_time, :double, 6 + optional :latency_50, :double, 7 + optional :latency_90, :double, 8 + optional :latency_95, :double, 9 + optional :latency_99, :double, 10 + optional :latency_999, :double, 11 + optional :server_cpu_usage, :double, 12 + optional :successful_requests_per_second, :double, 13 + optional :failed_requests_per_second, :double, 14 + optional :client_polls_per_request, :double, 15 + optional :server_polls_per_request, :double, 16 + optional :server_queries_per_cpu_sec, :double, 17 + optional :client_queries_per_cpu_sec, :double, 18 + end + add_message "grpc.testing.ScenarioResult" do + optional :scenario, :message, 1, "grpc.testing.Scenario" + optional :latencies, :message, 2, "grpc.testing.HistogramData" + repeated :client_stats, :message, 3, "grpc.testing.ClientStats" + repeated :server_stats, :message, 4, "grpc.testing.ServerStats" + repeated :server_cores, :int32, 5 + optional :summary, :message, 6, "grpc.testing.ScenarioResultSummary" + repeated :client_success, :bool, 7 + repeated :server_success, :bool, 8 + repeated :request_results, :message, 9, "grpc.testing.RequestResultCount" + end + add_enum "grpc.testing.ClientType" do + value :SYNC_CLIENT, 0 + value :ASYNC_CLIENT, 1 + value :OTHER_CLIENT, 2 + value :CALLBACK_CLIENT, 3 + end + add_enum "grpc.testing.ServerType" do + value :SYNC_SERVER, 0 + value :ASYNC_SERVER, 1 + value :ASYNC_GENERIC_SERVER, 2 + value :OTHER_SERVER, 3 + value :CALLBACK_SERVER, 4 + end + add_enum "grpc.testing.RpcType" do + value :UNARY, 0 + value :STREAMING, 1 + value :STREAMING_FROM_CLIENT, 2 + value :STREAMING_FROM_SERVER, 3 + value :STREAMING_BOTH_WAYS, 4 end - end - add_message "grpc.testing.ServerStatus" do - optional :stats, :message, 1, "grpc.testing.ServerStats" - optional :port, :int32, 2 - optional :cores, :int32, 3 - end - add_message "grpc.testing.CoreRequest" do - end - add_message "grpc.testing.CoreResponse" do - optional :cores, :int32, 1 - end - add_message "grpc.testing.Void" do - end - add_message "grpc.testing.Scenario" do - optional :name, :string, 1 - optional :client_config, :message, 2, "grpc.testing.ClientConfig" - optional :num_clients, :int32, 3 - optional :server_config, :message, 4, "grpc.testing.ServerConfig" - optional :num_servers, :int32, 5 - optional :warmup_seconds, :int32, 6 - optional :benchmark_seconds, :int32, 7 - optional :spawn_local_worker_count, :int32, 8 - end - add_message "grpc.testing.Scenarios" do - repeated :scenarios, :message, 1, "grpc.testing.Scenario" - end - add_message "grpc.testing.ScenarioResultSummary" do - optional :qps, :double, 1 - optional :qps_per_server_core, :double, 2 - optional :server_system_time, :double, 3 - optional :server_user_time, :double, 4 - optional :client_system_time, :double, 5 - optional :client_user_time, :double, 6 - optional :latency_50, :double, 7 - optional :latency_90, :double, 8 - optional :latency_95, :double, 9 - optional :latency_99, :double, 10 - optional :latency_999, :double, 11 - optional :server_cpu_usage, :double, 12 - optional :successful_requests_per_second, :double, 13 - optional :failed_requests_per_second, :double, 14 - optional :client_polls_per_request, :double, 15 - optional :server_polls_per_request, :double, 16 - optional :server_queries_per_cpu_sec, :double, 17 - optional :client_queries_per_cpu_sec, :double, 18 - end - add_message "grpc.testing.ScenarioResult" do - optional :scenario, :message, 1, "grpc.testing.Scenario" - optional :latencies, :message, 2, "grpc.testing.HistogramData" - repeated :client_stats, :message, 3, "grpc.testing.ClientStats" - repeated :server_stats, :message, 4, "grpc.testing.ServerStats" - repeated :server_cores, :int32, 5 - optional :summary, :message, 6, "grpc.testing.ScenarioResultSummary" - repeated :client_success, :bool, 7 - repeated :server_success, :bool, 8 - repeated :request_results, :message, 9, "grpc.testing.RequestResultCount" - end - add_enum "grpc.testing.ClientType" do - value :SYNC_CLIENT, 0 - value :ASYNC_CLIENT, 1 - value :OTHER_CLIENT, 2 - end - add_enum "grpc.testing.ServerType" do - value :SYNC_SERVER, 0 - value :ASYNC_SERVER, 1 - value :ASYNC_GENERIC_SERVER, 2 - value :OTHER_SERVER, 3 - end - add_enum "grpc.testing.RpcType" do - value :UNARY, 0 - value :STREAMING, 1 - value :STREAMING_FROM_CLIENT, 2 - value :STREAMING_FROM_SERVER, 3 - value :STREAMING_BOTH_WAYS, 4 end end diff --git a/src/ruby/qps/src/proto/grpc/testing/messages_pb.rb b/src/ruby/qps/src/proto/grpc/testing/messages_pb.rb index e27ccd0dc04..796d4bb9ae2 100644 --- a/src/ruby/qps/src/proto/grpc/testing/messages_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/messages_pb.rb @@ -4,62 +4,64 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.testing.BoolValue" do - optional :value, :bool, 1 - end - add_message "grpc.testing.Payload" do - optional :type, :enum, 1, "grpc.testing.PayloadType" - optional :body, :bytes, 2 - end - add_message "grpc.testing.EchoStatus" do - optional :code, :int32, 1 - optional :message, :string, 2 - end - add_message "grpc.testing.SimpleRequest" do - optional :response_type, :enum, 1, "grpc.testing.PayloadType" - optional :response_size, :int32, 2 - optional :payload, :message, 3, "grpc.testing.Payload" - optional :fill_username, :bool, 4 - optional :fill_oauth_scope, :bool, 5 - optional :response_compressed, :message, 6, "grpc.testing.BoolValue" - optional :response_status, :message, 7, "grpc.testing.EchoStatus" - optional :expect_compressed, :message, 8, "grpc.testing.BoolValue" - end - add_message "grpc.testing.SimpleResponse" do - optional :payload, :message, 1, "grpc.testing.Payload" - optional :username, :string, 2 - optional :oauth_scope, :string, 3 - end - add_message "grpc.testing.StreamingInputCallRequest" do - optional :payload, :message, 1, "grpc.testing.Payload" - optional :expect_compressed, :message, 2, "grpc.testing.BoolValue" - end - add_message "grpc.testing.StreamingInputCallResponse" do - optional :aggregated_payload_size, :int32, 1 - end - add_message "grpc.testing.ResponseParameters" do - optional :size, :int32, 1 - optional :interval_us, :int32, 2 - optional :compressed, :message, 3, "grpc.testing.BoolValue" - end - add_message "grpc.testing.StreamingOutputCallRequest" do - optional :response_type, :enum, 1, "grpc.testing.PayloadType" - repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters" - optional :payload, :message, 3, "grpc.testing.Payload" - optional :response_status, :message, 7, "grpc.testing.EchoStatus" - end - add_message "grpc.testing.StreamingOutputCallResponse" do - optional :payload, :message, 1, "grpc.testing.Payload" - end - add_message "grpc.testing.ReconnectParams" do - optional :max_reconnect_backoff_ms, :int32, 1 - end - add_message "grpc.testing.ReconnectInfo" do - optional :passed, :bool, 1 - repeated :backoff_ms, :int32, 2 - end - add_enum "grpc.testing.PayloadType" do - value :COMPRESSABLE, 0 + add_file("src/proto/grpc/testing/messages.proto", :syntax => :proto3) do + add_message "grpc.testing.BoolValue" do + optional :value, :bool, 1 + end + add_message "grpc.testing.Payload" do + optional :type, :enum, 1, "grpc.testing.PayloadType" + optional :body, :bytes, 2 + end + add_message "grpc.testing.EchoStatus" do + optional :code, :int32, 1 + optional :message, :string, 2 + end + add_message "grpc.testing.SimpleRequest" do + optional :response_type, :enum, 1, "grpc.testing.PayloadType" + optional :response_size, :int32, 2 + optional :payload, :message, 3, "grpc.testing.Payload" + optional :fill_username, :bool, 4 + optional :fill_oauth_scope, :bool, 5 + optional :response_compressed, :message, 6, "grpc.testing.BoolValue" + optional :response_status, :message, 7, "grpc.testing.EchoStatus" + optional :expect_compressed, :message, 8, "grpc.testing.BoolValue" + end + add_message "grpc.testing.SimpleResponse" do + optional :payload, :message, 1, "grpc.testing.Payload" + optional :username, :string, 2 + optional :oauth_scope, :string, 3 + end + add_message "grpc.testing.StreamingInputCallRequest" do + optional :payload, :message, 1, "grpc.testing.Payload" + optional :expect_compressed, :message, 2, "grpc.testing.BoolValue" + end + add_message "grpc.testing.StreamingInputCallResponse" do + optional :aggregated_payload_size, :int32, 1 + end + add_message "grpc.testing.ResponseParameters" do + optional :size, :int32, 1 + optional :interval_us, :int32, 2 + optional :compressed, :message, 3, "grpc.testing.BoolValue" + end + add_message "grpc.testing.StreamingOutputCallRequest" do + optional :response_type, :enum, 1, "grpc.testing.PayloadType" + repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters" + optional :payload, :message, 3, "grpc.testing.Payload" + optional :response_status, :message, 7, "grpc.testing.EchoStatus" + end + add_message "grpc.testing.StreamingOutputCallResponse" do + optional :payload, :message, 1, "grpc.testing.Payload" + end + add_message "grpc.testing.ReconnectParams" do + optional :max_reconnect_backoff_ms, :int32, 1 + end + add_message "grpc.testing.ReconnectInfo" do + optional :passed, :bool, 1 + repeated :backoff_ms, :int32, 2 + end + add_enum "grpc.testing.PayloadType" do + value :COMPRESSABLE, 0 + end end end diff --git a/src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb b/src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb index ae8855f6850..6d55793fba4 100644 --- a/src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb @@ -4,21 +4,23 @@ require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.testing.ByteBufferParams" do - optional :req_size, :int32, 1 - optional :resp_size, :int32, 2 - end - add_message "grpc.testing.SimpleProtoParams" do - optional :req_size, :int32, 1 - optional :resp_size, :int32, 2 - end - add_message "grpc.testing.ComplexProtoParams" do - end - add_message "grpc.testing.PayloadConfig" do - oneof :payload do - optional :bytebuf_params, :message, 1, "grpc.testing.ByteBufferParams" - optional :simple_params, :message, 2, "grpc.testing.SimpleProtoParams" - optional :complex_params, :message, 3, "grpc.testing.ComplexProtoParams" + add_file("src/proto/grpc/testing/payloads.proto", :syntax => :proto3) do + add_message "grpc.testing.ByteBufferParams" do + optional :req_size, :int32, 1 + optional :resp_size, :int32, 2 + end + add_message "grpc.testing.SimpleProtoParams" do + optional :req_size, :int32, 1 + optional :resp_size, :int32, 2 + end + add_message "grpc.testing.ComplexProtoParams" do + end + add_message "grpc.testing.PayloadConfig" do + oneof :payload do + optional :bytebuf_params, :message, 1, "grpc.testing.ByteBufferParams" + optional :simple_params, :message, 2, "grpc.testing.SimpleProtoParams" + optional :complex_params, :message, 3, "grpc.testing.ComplexProtoParams" + end end end end diff --git a/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb index 1b43e372997..03461a4c556 100644 --- a/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/report_qps_scenario_service_pb.rb @@ -5,6 +5,8 @@ require 'google/protobuf' require 'src/proto/grpc/testing/control_pb' Google::Protobuf::DescriptorPool.generated_pool.build do + add_file("src/proto/grpc/testing/report_qps_scenario_service.proto", :syntax => :proto3) do + end end module Grpc diff --git a/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb b/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb index 2069840168a..dd25d3159f3 100644 --- a/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb @@ -5,39 +5,41 @@ require 'google/protobuf' require 'src/proto/grpc/core/stats_pb' Google::Protobuf::DescriptorPool.generated_pool.build do - add_message "grpc.testing.ServerStats" do - optional :time_elapsed, :double, 1 - optional :time_user, :double, 2 - optional :time_system, :double, 3 - optional :total_cpu_time, :uint64, 4 - optional :idle_cpu_time, :uint64, 5 - optional :cq_poll_count, :uint64, 6 - optional :core_stats, :message, 7, "grpc.core.Stats" - end - add_message "grpc.testing.HistogramParams" do - optional :resolution, :double, 1 - optional :max_possible, :double, 2 - end - add_message "grpc.testing.HistogramData" do - repeated :bucket, :uint32, 1 - optional :min_seen, :double, 2 - optional :max_seen, :double, 3 - optional :sum, :double, 4 - optional :sum_of_squares, :double, 5 - optional :count, :double, 6 - end - add_message "grpc.testing.RequestResultCount" do - optional :status_code, :int32, 1 - optional :count, :int64, 2 - end - add_message "grpc.testing.ClientStats" do - optional :latencies, :message, 1, "grpc.testing.HistogramData" - optional :time_elapsed, :double, 2 - optional :time_user, :double, 3 - optional :time_system, :double, 4 - repeated :request_results, :message, 5, "grpc.testing.RequestResultCount" - optional :cq_poll_count, :uint64, 6 - optional :core_stats, :message, 7, "grpc.core.Stats" + add_file("src/proto/grpc/testing/stats.proto", :syntax => :proto3) do + add_message "grpc.testing.ServerStats" do + optional :time_elapsed, :double, 1 + optional :time_user, :double, 2 + optional :time_system, :double, 3 + optional :total_cpu_time, :uint64, 4 + optional :idle_cpu_time, :uint64, 5 + optional :cq_poll_count, :uint64, 6 + optional :core_stats, :message, 7, "grpc.core.Stats" + end + add_message "grpc.testing.HistogramParams" do + optional :resolution, :double, 1 + optional :max_possible, :double, 2 + end + add_message "grpc.testing.HistogramData" do + repeated :bucket, :uint32, 1 + optional :min_seen, :double, 2 + optional :max_seen, :double, 3 + optional :sum, :double, 4 + optional :sum_of_squares, :double, 5 + optional :count, :double, 6 + end + add_message "grpc.testing.RequestResultCount" do + optional :status_code, :int32, 1 + optional :count, :int64, 2 + end + add_message "grpc.testing.ClientStats" do + optional :latencies, :message, 1, "grpc.testing.HistogramData" + optional :time_elapsed, :double, 2 + optional :time_user, :double, 3 + optional :time_system, :double, 4 + repeated :request_results, :message, 5, "grpc.testing.RequestResultCount" + optional :cq_poll_count, :uint64, 6 + optional :core_stats, :message, 7, "grpc.core.Stats" + end end end diff --git a/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb b/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb index 18b63452b6e..2fdef48e933 100644 --- a/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb +++ b/src/ruby/qps/src/proto/grpc/testing/worker_service_pb.rb @@ -5,6 +5,8 @@ require 'google/protobuf' require 'src/proto/grpc/testing/control_pb' Google::Protobuf::DescriptorPool.generated_pool.build do + add_file("src/proto/grpc/testing/worker_service.proto", :syntax => :proto3) do + end end module Grpc From ce22e246d71cc13493a4396b7f9cd4f8cfccd721 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Mar 2019 15:02:31 -0400 Subject: [PATCH 664/814] run tools/distrib/python/make_grpcio_tools.py --- tools/distrib/python/grpcio_tools/protoc_lib_deps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py index 7d10db0329c..e7e4ba307ec 100644 --- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py +++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py @@ -14,10 +14,10 @@ # limitations under the License. # AUTO-GENERATED BY make_grpcio_tools.py! -CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_padding_optimizer.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/util/delimited_message_util.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_table_driven.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/io_win32.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/implicit_weak_message.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/generated_message_table_driven_lite.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc'] +CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_padding_optimizer.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/util/delimited_message_util.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_table_driven.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/io_win32.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/implicit_weak_message.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/generated_message_table_driven_lite.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arena.cc'] PROTO_FILES=['google/protobuf/wrappers.proto', 'google/protobuf/type.proto', 'google/protobuf/timestamp.proto', 'google/protobuf/struct.proto', 'google/protobuf/source_context.proto', 'google/protobuf/field_mask.proto', 'google/protobuf/empty.proto', 'google/protobuf/duration.proto', 'google/protobuf/descriptor.proto', 'google/protobuf/compiler/plugin.proto', 'google/protobuf/api.proto', 'google/protobuf/any.proto'] CC_INCLUDE='third_party/protobuf/src' PROTO_INCLUDE='third_party/protobuf/src' -PROTOBUF_SUBMODULE_VERSION="48cb18e5c419ddd23d9badcfe4e9df7bde1979b2" +PROTOBUF_SUBMODULE_VERSION="582743bf40c5d3639a70f98f183914a2c0cd0680" From f601afae144a66b040fce6149d2d154b2a5c6ba1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Mar 2019 15:05:03 -0400 Subject: [PATCH 665/814] bump ruby google-protobuf dependency --- grpc.gemspec | 2 +- templates/grpc.gemspec.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/grpc.gemspec b/grpc.gemspec index a2a027a20d8..5c749dd285d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -29,7 +29,7 @@ Gem::Specification.new do |s| s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.1' + s.add_dependency 'google-protobuf', '~> 3.7' s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0' s.add_development_dependency 'bundler', '~> 1.9' diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template index 1498a280b0e..0e321717c99 100644 --- a/templates/grpc.gemspec.template +++ b/templates/grpc.gemspec.template @@ -31,7 +31,7 @@ s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.1' + s.add_dependency 'google-protobuf', '~> 3.7' s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0' s.add_development_dependency 'bundler', '~> 1.9' From 96fd87169476309cb0934617365101113abda8b9 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 11 Mar 2019 15:07:47 -0400 Subject: [PATCH 666/814] bump C# protobuf dependency --- src/csharp/Grpc.Core/Version.csproj.include | 2 +- templates/src/csharp/Grpc.Core/Version.csproj.include.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index de933448b96..f3d484643d7 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -2,6 +2,6 @@ 1.20.0-dev - 3.6.1 + 3.7.0 diff --git a/templates/src/csharp/Grpc.Core/Version.csproj.include.template b/templates/src/csharp/Grpc.Core/Version.csproj.include.template index 0ec0a08c499..0ed9018a49e 100755 --- a/templates/src/csharp/Grpc.Core/Version.csproj.include.template +++ b/templates/src/csharp/Grpc.Core/Version.csproj.include.template @@ -4,6 +4,6 @@ ${settings.csharp_version} - 3.6.1 + 3.7.0 From c820cfc1589f8a7be148e9d6279ea3f2aa812a44 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 12 Mar 2019 06:19:37 -0400 Subject: [PATCH 667/814] activate sourcelink when building packages --- src/csharp/build_packages_dotnetcli.bat | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index f500310865b..58520f2f497 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -32,13 +32,13 @@ expand_dev_version.sh @rem To be able to build, we also need to put grpc_csharp_ext to its normal location xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\build\x64\Release\ -%DOTNET% pack --configuration Release Grpc.Core.Api --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.Core --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.Core.Testing --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.Auth --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.HealthCheck --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.Reflection --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.Tools --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Core.Api /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Core /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Core.Testing /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Auth /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.HealthCheck /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Reflection /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Tools /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error @rem build auxiliary packages %DOTNET% pack --configuration Release Grpc --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Core.NativeDebug --output ..\..\..\artifacts || goto :error From 478377ff70b771ef6084f31dbd464511987517e3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 12 Mar 2019 08:42:47 -0400 Subject: [PATCH 668/814] PDBs will get included automatically --- src/csharp/Grpc.Core/SourceLink.csproj.include | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/csharp/Grpc.Core/SourceLink.csproj.include b/src/csharp/Grpc.Core/SourceLink.csproj.include index 0ec273f57e6..526db954540 100755 --- a/src/csharp/Grpc.Core/SourceLink.csproj.include +++ b/src/csharp/Grpc.Core/SourceLink.csproj.include @@ -1,17 +1,6 @@ - - - true - lib/netstandard1.5 - - - true - lib/net45 - - - From 2a50960b4c874e90d9d32c53e9a642c0869e1b80 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 12 Mar 2019 08:37:07 -0700 Subject: [PATCH 669/814] Add copyright to BUILD file --- examples/python/multiprocessing/BUILD | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index 48b98f3ad20..81bd67feeb6 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -1,3 +1,19 @@ +# gRPC Bazel BUILD file. +# +# Copyright 2019 The gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + load("@grpc_python_dependencies//:requirements.bzl", "requirement") py_binary( From b9659d58da915f64abf73eb146947d805476f4c5 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 12 Mar 2019 09:16:30 -0700 Subject: [PATCH 670/814] Actually generate proto --- examples/python/multiprocessing/BUILD | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index 81bd67feeb6..b72edfa6d04 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -15,13 +15,20 @@ # limitations under the License. load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") + +py_proto_library( + name = "prime_proto", + protos = ["prime.proto",], +) py_binary( name = "client", testonly = 1, srcs = ["client.py"], deps = [ - "//src/python/grpcio/grpc:grpcio" + "//src/python/grpcio/grpc:grpcio", + ":prime_proto", ], default_python_version = "PY3", ) @@ -31,7 +38,8 @@ py_binary( testonly = 1, srcs = ["server.py"], deps = [ - "//src/python/grpcio/grpc:grpcio" + "//src/python/grpcio/grpc:grpcio", + ":prime_proto" ] + select({ "//conditions:default": [requirement("futures")], "//:python3": [], From f3b57e35ec127e2e19b72d27660402fbac7054ed Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 12 Mar 2019 10:15:19 -0700 Subject: [PATCH 671/814] Properly import protos --- examples/python/multiprocessing/BUILD | 1 + examples/python/multiprocessing/client.py | 4 ++-- examples/python/multiprocessing/server.py | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index b72edfa6d04..6de1e947d85 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -20,6 +20,7 @@ load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") py_proto_library( name = "prime_proto", protos = ["prime.proto",], + deps = [requirement("protobuf")], ) py_binary( diff --git a/examples/python/multiprocessing/client.py b/examples/python/multiprocessing/client.py index c3da4ba2b99..6d3bf5d825a 100644 --- a/examples/python/multiprocessing/client.py +++ b/examples/python/multiprocessing/client.py @@ -26,8 +26,8 @@ import sys import grpc -import prime_pb2 -import prime_pb2_grpc +from examples.python.multiprocessing import prime_pb2 +from examples.python.multiprocessing import prime_pb2_grpc _PROCESS_COUNT = 8 _MAXIMUM_CANDIDATE = 10000 diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index 27a0758d224..267019731f2 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -29,8 +29,8 @@ import sys import grpc -import prime_pb2 -import prime_pb2_grpc +from examples.python.multiprocessing import prime_pb2 +from examples.python.multiprocessing import prime_pb2_grpc _LOGGER = logging.getLogger(__name__) From dde238cb5dbf3347bedccf73e3fadb59e5da5d47 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 12 Mar 2019 10:44:05 -0700 Subject: [PATCH 672/814] Apparently no ipv6 on kokoro --- examples/python/multiprocessing/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/multiprocessing/server.py b/examples/python/multiprocessing/server.py index 267019731f2..a05eb9edda0 100644 --- a/examples/python/multiprocessing/server.py +++ b/examples/python/multiprocessing/server.py @@ -98,7 +98,7 @@ def _reserve_port(): def main(): with _reserve_port() as port: - bind_address = '[::]:{}'.format(port) + bind_address = 'localhost:{}'.format(port) _LOGGER.info("Binding to '%s'", bind_address) sys.stdout.flush() workers = [] From b3889585a1f9f0a7600be92788d81ec73fca1941 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 12 Mar 2019 12:25:38 -0700 Subject: [PATCH 673/814] Revert "Moving ::grpc::ResourceQuota to ::grpc_impl::ResouceQuota" --- BUILD | 3 +- CMakeLists.txt | 3 - Makefile | 3 - build.yaml | 1 - gRPC-C++.podspec | 1 - include/grpcpp/resource_quota.h | 45 +++++++++++- include/grpcpp/resource_quota_impl.h | 68 ------------------- include/grpcpp/server_builder.h | 9 +-- include/grpcpp/support/channel_arguments.h | 9 +-- src/cpp/common/channel_arguments.cc | 2 +- src/cpp/common/resource_quota_cc.cc | 4 +- src/cpp/server/server_builder.cc | 7 +- test/cpp/end2end/end2end_test.cc | 5 -- test/cpp/end2end/thread_stress_test.cc | 5 -- test/cpp/qps/server.h | 5 -- test/cpp/qps/server_async.cc | 1 + tools/doxygen/Doxyfile.c++ | 1 - tools/doxygen/Doxyfile.c++.internal | 1 - .../generated/sources_and_headers.json | 2 - 19 files changed, 53 insertions(+), 122 deletions(-) delete mode 100644 include/grpcpp/resource_quota_impl.h diff --git a/BUILD b/BUILD index 191661fdd9a..4bf387cec3a 100644 --- a/BUILD +++ b/BUILD @@ -192,8 +192,8 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpc++/impl/service_type.h", "include/grpc++/impl/sync_cxx11.h", "include/grpc++/impl/sync_no_cxx11.h", - "include/grpc++/security/auth_context.h", "include/grpc++/resource_quota.h", + "include/grpc++/security/auth_context.h", "include/grpc++/security/auth_metadata_processor.h", "include/grpc++/security/credentials.h", "include/grpc++/security/server_credentials.h", @@ -241,7 +241,6 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/impl/sync_cxx11.h", "include/grpcpp/impl/sync_no_cxx11.h", "include/grpcpp/resource_quota.h", - "include/grpcpp/resource_quota_impl.h", "include/grpcpp/security/auth_context.h", "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/credentials.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 40719422aa8..7ccda85b125 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3014,7 +3014,6 @@ foreach(_hdr include/grpcpp/impl/server_initializer.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h - include/grpcpp/resource_quota_impl.h include/grpcpp/security/auth_context.h include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/credentials.h @@ -3605,7 +3604,6 @@ foreach(_hdr include/grpcpp/impl/server_initializer.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h - include/grpcpp/resource_quota_impl.h include/grpcpp/security/auth_context.h include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/credentials.h @@ -4561,7 +4559,6 @@ foreach(_hdr include/grpcpp/impl/server_initializer.h include/grpcpp/impl/service_type.h include/grpcpp/resource_quota.h - include/grpcpp/resource_quota_impl.h include/grpcpp/security/auth_context.h include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/credentials.h diff --git a/Makefile b/Makefile index f47184b3436..91516de9a27 100644 --- a/Makefile +++ b/Makefile @@ -5438,7 +5438,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ - include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/credentials.h \ @@ -6038,7 +6037,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ - include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/credentials.h \ @@ -6951,7 +6949,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ - include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/credentials.h \ diff --git a/build.yaml b/build.yaml index cfd6cdb18a4..02ecaa221e6 100644 --- a/build.yaml +++ b/build.yaml @@ -1360,7 +1360,6 @@ filegroups: - include/grpcpp/impl/server_initializer.h - include/grpcpp/impl/service_type.h - include/grpcpp/resource_quota.h - - include/grpcpp/resource_quota_impl.h - include/grpcpp/security/auth_context.h - include/grpcpp/security/auth_metadata_processor.h - include/grpcpp/security/credentials.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 2d50f28ff2a..e755b7aa602 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -105,7 +105,6 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/server_initializer.h', 'include/grpcpp/impl/service_type.h', 'include/grpcpp/resource_quota.h', - 'include/grpcpp/resource_quota_impl.h', 'include/grpcpp/security/auth_context.h', 'include/grpcpp/security/auth_metadata_processor.h', 'include/grpcpp/security/credentials.h', diff --git a/include/grpcpp/resource_quota.h b/include/grpcpp/resource_quota.h index 333767b95c5..50bd1cb849a 100644 --- a/include/grpcpp/resource_quota.h +++ b/include/grpcpp/resource_quota.h @@ -1,6 +1,6 @@ /* * - * Copyright 2019 gRPC authors. + * Copyright 2016 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,50 @@ #ifndef GRPCPP_RESOURCE_QUOTA_H #define GRPCPP_RESOURCE_QUOTA_H -#include +struct grpc_resource_quota; + +#include +#include namespace grpc { -typedef ::grpc_impl::ResourceQuota ResourceQuota; +/// ResourceQuota represents a bound on memory and thread usage by the gRPC +/// library. A ResourceQuota can be attached to a server (via \a ServerBuilder), +/// or a client channel (via \a ChannelArguments). +/// gRPC will attempt to keep memory and threads used by all attached entities +/// below the ResourceQuota bound. +class ResourceQuota final : private GrpcLibraryCodegen { + public: + /// \param name - a unique name for this ResourceQuota. + explicit ResourceQuota(const grpc::string& name); + ResourceQuota(); + ~ResourceQuota(); + + /// Resize this \a ResourceQuota to a new size. If \a new_size is smaller + /// than the current size of the pool, memory usage will be monotonically + /// decreased until it falls under \a new_size. + /// No time bound is given for this to occur however. + ResourceQuota& Resize(size_t new_size); + + /// Set the max number of threads that can be allocated from this + /// ResourceQuota object. + /// + /// If the new_max_threads value is smaller than the current value, no new + /// threads are allocated until the number of active threads fall below + /// new_max_threads. There is no time bound on when this may happen i.e none + /// of the current threads are forcefully destroyed and all threads run their + /// normal course. + ResourceQuota& SetMaxThreads(int new_max_threads); + + grpc_resource_quota* c_resource_quota() const { return impl_; } + + private: + ResourceQuota(const ResourceQuota& rhs); + ResourceQuota& operator=(const ResourceQuota& rhs); + + grpc_resource_quota* const impl_; +}; + } // namespace grpc #endif // GRPCPP_RESOURCE_QUOTA_H diff --git a/include/grpcpp/resource_quota_impl.h b/include/grpcpp/resource_quota_impl.h deleted file mode 100644 index 16c0e35385b..00000000000 --- a/include/grpcpp/resource_quota_impl.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPCPP_RESOURCE_QUOTA_IMPL_H -#define GRPCPP_RESOURCE_QUOTA_IMPL_H - -struct grpc_resource_quota; - -#include -#include - -namespace grpc_impl { - -/// ResourceQuota represents a bound on memory and thread usage by the gRPC -/// library. A ResourceQuota can be attached to a server (via \a ServerBuilder), -/// or a client channel (via \a ChannelArguments). -/// gRPC will attempt to keep memory and threads used by all attached entities -/// below the ResourceQuota bound. -class ResourceQuota final : private ::grpc::GrpcLibraryCodegen { - public: - /// \param name - a unique name for this ResourceQuota. - explicit ResourceQuota(const grpc::string& name); - ResourceQuota(); - ~ResourceQuota(); - - /// Resize this \a ResourceQuota to a new size. If \a new_size is smaller - /// than the current size of the pool, memory usage will be monotonically - /// decreased until it falls under \a new_size. - /// No time bound is given for this to occur however. - ResourceQuota& Resize(size_t new_size); - - /// Set the max number of threads that can be allocated from this - /// ResourceQuota object. - /// - /// If the new_max_threads value is smaller than the current value, no new - /// threads are allocated until the number of active threads fall below - /// new_max_threads. There is no time bound on when this may happen i.e none - /// of the current threads are forcefully destroyed and all threads run their - /// normal course. - ResourceQuota& SetMaxThreads(int new_max_threads); - - grpc_resource_quota* c_resource_quota() const { return impl_; } - - private: - ResourceQuota(const ResourceQuota& rhs); - ResourceQuota& operator=(const ResourceQuota& rhs); - - grpc_resource_quota* const impl_; -}; - -} // namespace grpc_impl - -#endif // GRPCPP_RESOURCE_QUOTA_IMPL_H diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 4c00f021d11..498e5b7bb31 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -35,14 +35,10 @@ struct grpc_resource_quota; -namespace grpc_impl { - -class ResourceQuota; -} - namespace grpc { class AsyncGenericService; +class ResourceQuota; class CompletionQueue; class Server; class ServerCompletionQueue; @@ -190,8 +186,7 @@ class ServerBuilder { grpc_compression_algorithm algorithm); /// Set the attached buffer pool for this server - ServerBuilder& SetResourceQuota( - const ::grpc_impl::ResourceQuota& resource_quota); + ServerBuilder& SetResourceQuota(const ResourceQuota& resource_quota); ServerBuilder& SetOption(std::unique_ptr option); diff --git a/include/grpcpp/support/channel_arguments.h b/include/grpcpp/support/channel_arguments.h index 48ae4246462..217929d4aca 100644 --- a/include/grpcpp/support/channel_arguments.h +++ b/include/grpcpp/support/channel_arguments.h @@ -26,16 +26,13 @@ #include #include -namespace grpc_impl { - -class ResourceQuota; -} - namespace grpc { namespace testing { class ChannelArgumentsTest; } // namespace testing +class ResourceQuota; + /// Options for channel creation. The user can use generic setters to pass /// key value pairs down to C channel creation code. For gRPC related options, /// concrete setters are provided. @@ -86,7 +83,7 @@ class ChannelArguments { void SetUserAgentPrefix(const grpc::string& user_agent_prefix); /// Set the buffer pool to be attached to the constructed channel. - void SetResourceQuota(const ::grpc_impl::ResourceQuota& resource_quota); + void SetResourceQuota(const ResourceQuota& resource_quota); /// Set the max receive and send message sizes. void SetMaxReceiveMessageSize(int size); diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index c3d75054b9b..214d72f853f 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -143,7 +143,7 @@ void ChannelArguments::SetUserAgentPrefix( } void ChannelArguments::SetResourceQuota( - const grpc_impl::ResourceQuota& resource_quota) { + const grpc::ResourceQuota& resource_quota) { SetPointerWithVtable(GRPC_ARG_RESOURCE_QUOTA, resource_quota.c_resource_quota(), grpc_resource_quota_arg_vtable()); diff --git a/src/cpp/common/resource_quota_cc.cc b/src/cpp/common/resource_quota_cc.cc index 4fab2975d89..276e5f79548 100644 --- a/src/cpp/common/resource_quota_cc.cc +++ b/src/cpp/common/resource_quota_cc.cc @@ -19,7 +19,7 @@ #include #include -namespace grpc_impl { +namespace grpc { ResourceQuota::ResourceQuota() : impl_(grpc_resource_quota_create(nullptr)) {} @@ -37,4 +37,4 @@ ResourceQuota& ResourceQuota::SetMaxThreads(int new_max_threads) { grpc_resource_quota_set_max_threads(impl_, new_max_threads); return *this; } -} // namespace grpc_impl +} // namespace grpc diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index f60c77dc8d6..cd0e516d9a3 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -29,11 +29,6 @@ #include "src/core/lib/gpr/useful.h" #include "src/cpp/server/thread_pool_interface.h" -namespace grpc_impl { - -class ResourceQuota; -} - namespace grpc { static std::vector (*)()>* @@ -169,7 +164,7 @@ ServerBuilder& ServerBuilder::SetDefaultCompressionAlgorithm( } ServerBuilder& ServerBuilder::SetResourceQuota( - const grpc_impl::ResourceQuota& resource_quota) { + const grpc::ResourceQuota& resource_quota) { if (resource_quota_ != nullptr) { grpc_resource_quota_unref(resource_quota_); } diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index f7b9ee4b0b0..f58a472bfaf 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -64,11 +64,6 @@ using std::chrono::system_clock; } \ } while (0) -namespace grpc_impl { - -class ResourceQuota; -} - namespace grpc { namespace testing { namespace { diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index e308e591d1a..e30ce0dbcbf 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -48,11 +48,6 @@ const int kNumAsyncReceiveThreads = 50; const int kNumAsyncServerThreads = 50; const int kNumRpcs = 1000; // Number of RPCs per thread -namespace grpc_impl { - -class ResourceQuota; -} - namespace grpc { namespace testing { diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h index 3aec8644a94..89b0e3af4b2 100644 --- a/test/cpp/qps/server.h +++ b/test/cpp/qps/server.h @@ -34,11 +34,6 @@ #include "test/cpp/qps/usage_timer.h" #include "test/cpp/util/test_credentials_provider.h" -namespace grpc_impl { - -class ResourceQuota; -} - namespace grpc { namespace testing { diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index 9343fd311e1..a5f8347c269 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 367160a0ca9..9f17a25298a 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -995,7 +995,6 @@ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ -include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/credentials.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 4c1ba9d4f9d..c0078bf2764 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -997,7 +997,6 @@ include/grpcpp/impl/server_builder_plugin.h \ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/resource_quota.h \ -include/grpcpp/resource_quota_impl.h \ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/credentials.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 96fa00e387e..7a72a885336 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11391,7 +11391,6 @@ "include/grpcpp/impl/server_initializer.h", "include/grpcpp/impl/service_type.h", "include/grpcpp/resource_quota.h", - "include/grpcpp/resource_quota_impl.h", "include/grpcpp/security/auth_context.h", "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/credentials.h", @@ -11501,7 +11500,6 @@ "include/grpcpp/impl/server_initializer.h", "include/grpcpp/impl/service_type.h", "include/grpcpp/resource_quota.h", - "include/grpcpp/resource_quota_impl.h", "include/grpcpp/security/auth_context.h", "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/credentials.h", From 33ebf719a55fd601f9b01f21c367fbc60c4d0af5 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 12 Mar 2019 08:43:57 -0700 Subject: [PATCH 674/814] use cached grpc ssl credential --- include/grpc/grpc_security.h | 9 ++++++ .../private/GRPCSecureChannelFactory.h | 5 +++ .../private/GRPCSecureChannelFactory.m | 32 +++---------------- 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index f0323eb16a1..9b7822627e0 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -191,6 +191,15 @@ typedef struct { try to get the roots set by grpc_override_ssl_default_roots. Eventually, if all these fail, it will try to get the roots from a well-known place on disk (in the grpc install directory). + + gRPC has implemented root cache if the underlying OpenSSL library supports + it. The gRPC root certificates cache is only applicable on the default + root certificates, which is used when this parameter is nullptr. If user + provides their own pem_root_certs, when creating an SSL credential object, + gRPC would not be able to cache it, and each subchannel will generate a + copy of the root store. So it is recommended to avoid providing large room + pem with pem_root_certs parameter to avoid excessive memory consumption, + particularly on mobile platforms such as iOS. - pem_key_cert_pair is a pointer on the object containing client's private key and certificate chain. This parameter can be NULL if the client does not have such a key/cert pair. diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h index 588239b7064..572f20d341f 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h @@ -23,6 +23,11 @@ NS_ASSUME_NONNULL_BEGIN @interface GRPCSecureChannelFactory : NSObject +/** + * Creates a secure channel factory which uses provided root certificates and client authentication + * credentials. If rootCerts is nil, gRPC will use its default root certificates. If rootCerts is + * provided, it must only contain the server's CA to avoid memory issue. + */ + (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts privateKey:(nullable NSString *)privateKey certChain:(nullable NSString *)certChain diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m index 96998895364..b1a6797b9e3 100644 --- a/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m +++ b/src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m @@ -52,44 +52,20 @@ privateKey:(NSString *)privateKey certChain:(NSString *)certChain error:(NSError **)errorPtr { - static NSData *defaultRootsASCII; - static NSError *defaultRootsError; static dispatch_once_t loading; dispatch_once(&loading, ^{ NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem // Do not use NSBundle.mainBundle, as it's nil for tests of library projects. NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"]; - NSError *error; - // Files in PEM format can have non-ASCII characters in their comments (e.g. for the name of the - // issuer). Load them as UTF8 and produce an ASCII equivalent. - NSString *contentInUTF8 = - [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; - if (contentInUTF8 == nil) { - defaultRootsError = error; - return; - } - defaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8]; + setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, + [path cStringUsingEncoding:NSUTF8StringEncoding], 1); }); - NSData *rootsASCII; + NSData *rootsASCII = nil; + // if rootCerts is not provided, gRPC will use its own default certs if (rootCerts != nil) { rootsASCII = [self nullTerminatedDataWithString:rootCerts]; - } else { - if (defaultRootsASCII == nil) { - if (errorPtr) { - *errorPtr = defaultRootsError; - } - NSAssert( - defaultRootsASCII, NSObjectNotAvailableException, - @"Could not read gRPCCertificates.bundle/roots.pem. This file, " - "with the root certificates, is needed to establish secure (TLS) connections. " - "Because the file is distributed with the gRPC library, this error is usually a sign " - "that the library wasn't configured correctly for your project. Error: %@", - defaultRootsError); - return nil; - } - rootsASCII = defaultRootsASCII; } grpc_channel_credentials *creds = NULL; From c9421eeb8518cdf4abe2960a87a89f9f2f9f49b5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 12 Mar 2019 13:15:45 -0700 Subject: [PATCH 675/814] Fix state reported by pick_first when we receive a GOAWAY with a pending subchannel list. --- .../lb_policy/pick_first/pick_first.cc | 61 +++++++++++++------ .../chttp2/transport/chttp2_transport.cc | 6 +- test/cpp/end2end/BUILD | 1 + test/cpp/end2end/client_lb_end2end_test.cc | 54 +++++++++++++++- 4 files changed, 100 insertions(+), 22 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 0ac0f41d4ef..15d953cd92f 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -102,6 +102,14 @@ class PickFirst : public LoadBalancingPolicy { PickFirst* p = static_cast(policy()); p->Unref(DEBUG_LOCATION, "subchannel_list"); } + + bool in_transient_failure() const { return in_transient_failure_; } + void set_in_transient_failure(bool in_transient_failure) { + in_transient_failure_ = in_transient_failure; + } + + private: + bool in_transient_failure_ = false; }; class Picker : public SubchannelPicker { @@ -368,12 +376,21 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->selected_ = nullptr; StopConnectivityWatchLocked(); p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); - grpc_error* new_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "selected subchannel not ready; switching to pending update", &error, - 1); - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), - UniquePtr(New(new_error))); + // Set our state to that of the pending subchannel list. + if (p->subchannel_list_->in_transient_failure()) { + grpc_error* new_error = + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "selected subchannel failed; switching to pending update", + &error, 1); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), + UniquePtr( + New(new_error))); + } else { + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + UniquePtr(New(p->Ref()))); + } } else { if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { // If the selected subchannel goes bad, request a re-resolution. We @@ -382,7 +399,6 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // to connect to the re-resolved backends until we leave IDLE state. p->idle_ = true; p->channel_control_helper()->RequestReresolution(); - // In transient failure. Rely on re-resolution to recover. p->selected_ = nullptr; StopConnectivityWatchLocked(); p->channel_control_helper()->UpdateState( @@ -418,6 +434,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // for a subchannel in p->latest_pending_subchannel_list_. The // goal here is to find a subchannel from the update that we can // select in place of the current one. + subchannel_list()->set_in_transient_failure(false); switch (connectivity_state) { case GRPC_CHANNEL_READY: { // Renew notification. @@ -431,17 +448,25 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( size_t next_index = (sd->Index() + 1) % subchannel_list()->num_subchannels(); sd = subchannel_list()->subchannel(next_index); - // Case 1: Only set state to TRANSIENT_FAILURE if we've tried - // all subchannels. - if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) { - p->channel_control_helper()->RequestReresolution(); - grpc_error* new_error = - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "failed to connect to all addresses", &error, 1); - p->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), - UniquePtr( - New(new_error))); + // If we're tried all subchannels, set state to TRANSIENT_FAILURE. + if (sd->Index() == 0) { + // Re-resolve if this is the most recent subchannel list. + if (subchannel_list() == (p->latest_pending_subchannel_list_ != nullptr + ? p->latest_pending_subchannel_list_.get() + : p->subchannel_list_.get())) { + p->channel_control_helper()->RequestReresolution(); + } + subchannel_list()->set_in_transient_failure(true); + // Only report new state in case 1. + if (subchannel_list() == p->subchannel_list_.get()) { + grpc_error* new_error = + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "failed to connect to all addresses", &error, 1); + p->channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(new_error), + UniquePtr( + New(new_error))); + } } sd->CheckConnectivityStateAndStartWatchingLocked(); break; diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 888c1757be1..829bee6bedd 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1136,8 +1136,10 @@ void grpc_chttp2_add_incoming_goaway(grpc_chttp2_transport* t, } t->goaway_error = grpc_error_set_str( grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("GOAWAY received"), - GRPC_ERROR_INT_HTTP2_ERROR, static_cast(goaway_error)), + grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("GOAWAY received"), + GRPC_ERROR_INT_HTTP2_ERROR, static_cast(goaway_error)), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), GRPC_ERROR_STR_RAW_BYTES, goaway_text); /* We want to log this irrespective of whether http tracing is enabled */ diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 12258a64e00..68e0ec3cef1 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -402,6 +402,7 @@ grpc_cc_test( name = "client_lb_end2end_test", srcs = ["client_lb_end2end_test.cc"], external_deps = [ + "gmock", "gtest", ], deps = [ diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 996ba0edbbe..3cd06e9e28c 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -56,6 +56,7 @@ #include "test/core/util/test_lb_policies.h" #include "test/cpp/end2end/test_service_impl.h" +#include #include using grpc::testing::EchoRequest; @@ -221,9 +222,11 @@ class ClientLbEnd2endTest : public ::testing::Test { response_generator_->SetFailureOnReresolution(); } - std::vector GetServersPorts() { + std::vector GetServersPorts(size_t start_index = 0) { std::vector ports; - for (const auto& server : servers_) ports.push_back(server->port_); + for (size_t i = start_index; i < servers_.size(); ++i) { + ports.push_back(servers_[i]->port_); + } return ports; } @@ -897,6 +900,53 @@ TEST_F(ClientLbEnd2endTest, PickFirstIdleOnDisconnect) { servers_.clear(); } +TEST_F(ClientLbEnd2endTest, PickFirstPendingUpdateAndSelectedSubchannelFails) { + auto channel = BuildChannel(""); // pick_first is the default. + auto stub = BuildStub(channel); + // Create a number of servers, but only start 1 of them. + CreateServers(10); + StartServer(0); + // Initially resolve to first server and make sure it connects. + gpr_log(GPR_INFO, "Phase 1: Connect to first server."); + SetNextResolution({servers_[0]->port_}); + CheckRpcSendOk(stub, DEBUG_LOCATION, true /* wait_for_ready */); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + // Send a resolution update with the remaining servers, none of which are + // running yet, so the update will stay pending. Note that it's important + // to have multiple servers here, or else the test will be flaky; with only + // one server, the pending subchannel list has already gone into + // TRANSIENT_FAILURE due to hitting the end of the list by the time we + // check the state. + gpr_log(GPR_INFO, + "Phase 2: Resolver update pointing to remaining " + "(not started) servers."); + SetNextResolution(GetServersPorts(1 /* start_index */)); + // RPCs will continue to be sent to the first server. + CheckRpcSendOk(stub, DEBUG_LOCATION); + // Now stop the first server, so that the current subchannel list + // fails. This should cause us to immediately swap over to the + // pending list, even though it's not yet connected. The state should + // be set to CONNECTING, since that's what the pending subchannel list + // was doing when we swapped over. + gpr_log(GPR_INFO, "Phase 3: Stopping first server."); + servers_[0]->Shutdown(); + WaitForChannelNotReady(channel.get()); + // TODO(roth): This should always return CONNECTING, but it's flaky + // between that and TRANSIENT_FAILURE. I suspect that this problem + // will go away once we move the backoff code out of the subchannel + // and into the LB policies. + EXPECT_THAT(channel->GetState(false), + ::testing::AnyOf(GRPC_CHANNEL_CONNECTING, + GRPC_CHANNEL_TRANSIENT_FAILURE)); + // Now start the second server. + gpr_log(GPR_INFO, "Phase 4: Starting second server."); + StartServer(1); + // The channel should go to READY state and RPCs should go to the + // second server. + WaitForChannelReady(channel.get()); + WaitForServer(stub, 1, DEBUG_LOCATION, true /* ignore_failure */); +} + TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; From fac3ec2563fc1174e9c9f3ade4c2d10a9878020d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 13 Mar 2019 11:53:06 +0100 Subject: [PATCH 676/814] add netstandard2.0 target for Grpc.* packages --- src/csharp/Grpc.Auth/Grpc.Auth.csproj | 2 +- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 2 +- src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj | 2 +- src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj | 2 +- src/csharp/Grpc.Core/Grpc.Core.csproj | 2 +- src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj | 2 +- src/csharp/Grpc.Reflection/Grpc.Reflection.csproj | 2 +- src/csharp/Grpc/Grpc.csproj | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj index e9a6d2cc198..e8974f7221f 100755 --- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj +++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj @@ -15,7 +15,7 @@ - net45;netstandard1.5 + net45;netstandard1.5;netstandard2.0 $(DefineConstants);SIGNED true true diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index 4b772f6276a..556f65f4b32 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -15,7 +15,7 @@ - net45;netstandard1.5 + net45;netstandard1.5;netstandard2.0 true true diff --git a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj index df4f31dc421..3cd5ba4fa6f 100644 --- a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj +++ b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj @@ -15,7 +15,7 @@ - net45;netstandard1.5 + net45;netstandard1.5;netstandard2.0 false true diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj index 90ed88201d0..3727639f44a 100755 --- a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj +++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj @@ -15,7 +15,7 @@ - net45;netstandard1.5 + net45;netstandard1.5;netstandard2.0 true true diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index e6ccff823a4..5a73ac3deb8 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -15,7 +15,7 @@ - net45;netstandard1.5 + net45;netstandard1.5;netstandard2.0 true true diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index 4f3862deeb7..338c9c2c0d8 100755 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -15,7 +15,7 @@ - net45;netstandard1.5 + net45;netstandard1.5;netstandard2.0 true true diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj index c5362252d00..f080e2085dd 100755 --- a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj +++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj @@ -15,7 +15,7 @@ - net45;netstandard1.5 + net45;netstandard1.5;netstandard2.0 true true diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj index c529c38e989..5174b97086e 100644 --- a/src/csharp/Grpc/Grpc.csproj +++ b/src/csharp/Grpc/Grpc.csproj @@ -15,7 +15,7 @@ - net45;netstandard1.5 + net45;netstandard1.5;netstandard2.0 false true From cfe021a3b39072ea0fa58ef778fbd96a1705581f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 13 Mar 2019 11:54:13 +0100 Subject: [PATCH 677/814] netstandard2.0 tweaks --- src/csharp/Grpc.Core/GrpcEnvironment.cs | 2 +- src/csharp/Grpc.Core/Internal/NativeExtension.cs | 4 ++-- src/csharp/Grpc.Core/Internal/PlatformApis.cs | 4 ++-- src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs | 2 +- src/csharp/Grpc.Core/Utils/TaskUtils.cs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs index 6ca694e0e46..3c83b03cc1f 100644 --- a/src/csharp/Grpc.Core/GrpcEnvironment.cs +++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs @@ -448,7 +448,7 @@ namespace Grpc.Core // the gRPC channels and servers before the application exits. The following // hooks provide some extra handling for cases when this is not the case, // in the effort to achieve a reasonable behavior on shutdown. -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 // No action required at shutdown on .NET Core // - In-progress P/Invoke calls (such as grpc_completion_queue_next) don't seem // to prevent a .NET core application from terminating, so no special handling diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs index 5177b69fd90..9935ef109c8 100644 --- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs +++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs @@ -153,7 +153,7 @@ namespace Grpc.Core.Internal private static string GetAssemblyPath() { var assembly = typeof(NativeExtension).GetTypeInfo().Assembly; -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 // Assembly.EscapedCodeBase does not exist under CoreCLR, but assemblies imported from a nuget package // don't seem to be shadowed by DNX-based projects at all. return assembly.Location; @@ -172,7 +172,7 @@ namespace Grpc.Core.Internal #endif } -#if !NETSTANDARD1_5 +#if !NETSTANDARD1_5 && !NETSTANDARD2_0 private static bool IsFileUri(string uri) { return uri.ToLowerInvariant().StartsWith(Uri.UriSchemeFile); diff --git a/src/csharp/Grpc.Core/Internal/PlatformApis.cs b/src/csharp/Grpc.Core/Internal/PlatformApis.cs index a8f147545b4..8d7e8c2acb5 100644 --- a/src/csharp/Grpc.Core/Internal/PlatformApis.cs +++ b/src/csharp/Grpc.Core/Internal/PlatformApis.cs @@ -49,7 +49,7 @@ namespace Grpc.Core.Internal static PlatformApis() { -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); isMacOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); @@ -171,7 +171,7 @@ namespace Grpc.Core.Internal public static string GetUnityRuntimePlatform() { GrpcPreconditions.CheckState(IsUnity, "Not running on Unity."); -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 return Type.GetType(UnityEngineApplicationClassName).GetTypeInfo().GetProperty("platform").GetValue(null).ToString(); #else return Type.GetType(UnityEngineApplicationClassName).GetProperty("platform").GetValue(null).ToString(); diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs index 1786fc2e3f6..056758df8ca 100644 --- a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs +++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs @@ -120,7 +120,7 @@ namespace Grpc.Core.Internal { throw new MissingMethodException(string.Format("The native method \"{0}\" does not exist", methodName)); } -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 return Marshal.GetDelegateForFunctionPointer(ptr); // non-generic version is obsolete #else return Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T; // generic version not available in .NET45 diff --git a/src/csharp/Grpc.Core/Utils/TaskUtils.cs b/src/csharp/Grpc.Core/Utils/TaskUtils.cs index f25106f8dd8..21cd63336dc 100644 --- a/src/csharp/Grpc.Core/Utils/TaskUtils.cs +++ b/src/csharp/Grpc.Core/Utils/TaskUtils.cs @@ -33,7 +33,7 @@ namespace Grpc.Core.Utils { get { -#if NETSTANDARD1_5 +#if NETSTANDARD1_5 || NETSTANDARD2_0 return Task.CompletedTask; #else return Task.FromResult(null); // for .NET45, emulate the functionality From 91da9380534121ff6b90dc0f2f7543ca3e5dc63c Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 13 Mar 2019 09:29:52 -0400 Subject: [PATCH 678/814] Make the TCP_INQ log a debug entry. Users reported they see a lot of these logs in their runs. --- src/core/lib/iomgr/tcp_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 960a45b7b26..30305a94f37 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -1255,7 +1255,7 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, if (setsockopt(tcp->fd, SOL_TCP, TCP_INQ, &one, sizeof(one)) == 0) { tcp->inq_capable = true; } else { - gpr_log(GPR_INFO, "cannot set inq fd=%d errno=%d", tcp->fd, errno); + gpr_log(GPR_DEBUG, "cannot set inq fd=%d errno=%d", tcp->fd, errno); tcp->inq_capable = false; } #else From 687580fe046f6166a58bd12c3d1836405e74acc4 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 12 Mar 2019 14:19:10 -0700 Subject: [PATCH 679/814] Add ResultHandler to Resolver API. --- .../ext/filters/client_channel/resolver.cc | 4 +- .../ext/filters/client_channel/resolver.h | 54 +++-- .../resolver/dns/c_ares/dns_resolver_ares.cc | 97 +++----- .../resolver/dns/native/dns_resolver.cc | 104 +++------ .../resolver/fake/fake_resolver.cc | 88 +++---- .../resolver/fake/fake_resolver.h | 3 +- .../resolver/sockaddr/sockaddr_resolver.cc | 89 +++---- .../filters/client_channel/resolver_factory.h | 4 +- .../client_channel/resolver_registry.cc | 7 +- .../client_channel/resolver_registry.h | 8 +- .../client_channel/resolving_lb_policy.cc | 218 +++++++----------- .../client_channel/resolving_lb_policy.h | 14 +- src/core/lib/channel/channel_args.h | 3 + .../dns_resolver_connectivity_test.cc | 109 +++++---- .../resolvers/dns_resolver_cooldown_test.cc | 84 ++++--- .../resolvers/dns_resolver_test.cc | 8 +- .../resolvers/fake_resolver_test.cc | 172 +++++++------- .../resolvers/sockaddr_resolver_test.cc | 34 ++- test/cpp/naming/cancel_ares_query_test.cc | 39 ++-- test/cpp/naming/resolver_component_test.cc | 138 ++++++----- 20 files changed, 610 insertions(+), 667 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver.cc b/src/core/ext/filters/client_channel/resolver.cc index 601b08be246..5d14d51d011 100644 --- a/src/core/ext/filters/client_channel/resolver.cc +++ b/src/core/ext/filters/client_channel/resolver.cc @@ -26,8 +26,10 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount(false, namespace grpc_core { -Resolver::Resolver(grpc_combiner* combiner) +Resolver::Resolver(grpc_combiner* combiner, + UniquePtr result_handler) : InternallyRefCounted(&grpc_trace_resolver_refcount), + result_handler_(std::move(result_handler)), combiner_(GRPC_COMBINER_REF(combiner, "resolver")) {} Resolver::~Resolver() { GRPC_COMBINER_UNREF(combiner_, "resolver"); } diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h index 9da849a1017..790779cfe75 100644 --- a/src/core/ext/filters/client_channel/resolver.h +++ b/src/core/ext/filters/client_channel/resolver.h @@ -46,27 +46,34 @@ namespace grpc_core { /// combiner passed to the constructor. class Resolver : public InternallyRefCounted { public: + /// A proxy object used by the resolver to return results to the + /// client channel. + class ResultHandler { + public: + virtual ~ResultHandler() {} + + /// Returns a result to the channel. + /// The list of addresses will be in GRPC_ARG_SERVER_ADDRESS_LIST. + /// The service config (if any) will be in GRPC_ARG_SERVICE_CONFIG. + /// Takes ownership of \a result. + // TODO(roth): Change this API so that addresses and service config are + // passed explicitly instead of being in channel args. + virtual void ReturnResult(const grpc_channel_args* result) GRPC_ABSTRACT; + + /// Returns a transient error to the channel. + /// If the resolver does not set the GRPC_ERROR_INT_GRPC_STATUS + /// attribute on the error, calls will be failed with status UNKNOWN. + virtual void ReturnError(grpc_error* error) GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS + }; + // Not copyable nor movable. Resolver(const Resolver&) = delete; Resolver& operator=(const Resolver&) = delete; - /// Requests a callback when a new result becomes available. - /// When the new result is available, sets \a *result to the new result - /// and schedules \a on_complete for execution. - /// Upon transient failure, sets \a *result to nullptr and schedules - /// \a on_complete with no error. - /// If resolution is fatally broken, sets \a *result to nullptr and - /// schedules \a on_complete with an error. - /// TODO(roth): When we have time, improve the way this API represents - /// transient failure vs. shutdown. - /// - /// Note that the client channel will almost always have a request - /// to \a NextLocked() pending. When it gets the callback, it will - /// process the new result and then immediately make another call to - /// \a NextLocked(). This allows push-based resolvers to provide new - /// data as soon as it becomes available. - virtual void NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) GRPC_ABSTRACT; + /// Starts resolving. + virtual void StartLocked() GRPC_ABSTRACT; /// Asks the resolver to obtain an updated resolver result, if /// applicable. @@ -79,8 +86,8 @@ class Resolver : public InternallyRefCounted { /// /// For push-based implementations, this may be a no-op. /// - /// If this causes new data to become available, then the currently - /// pending call to \a NextLocked() will return the new result. + /// Note: Implementations must not invoke any method on the + /// ResultHandler from within this call. virtual void RequestReresolutionLocked() {} /// Resets the re-resolution backoff, if any. @@ -108,16 +115,18 @@ class Resolver : public InternallyRefCounted { // TODO(roth): Once we have a C++-like interface for combiners, this // API should change to take a RefCountedPtr<>, so that we always take // ownership of a new ref. - explicit Resolver(grpc_combiner* combiner); + explicit Resolver(grpc_combiner* combiner, + UniquePtr result_handler); virtual ~Resolver(); - /// Shuts down the resolver. If there is a pending call to - /// NextLocked(), the callback will be scheduled with an error. + /// Shuts down the resolver. virtual void ShutdownLocked() GRPC_ABSTRACT; grpc_combiner* combiner() const { return combiner_; } + ResultHandler* result_handler() const { return result_handler_.get(); } + private: static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) { Resolver* resolver = static_cast(arg); @@ -125,6 +134,7 @@ class Resolver : public InternallyRefCounted { resolver->Unref(); } + UniquePtr result_handler_; grpc_combiner* combiner_; }; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index c99943ab2f1..249b9e3958c 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -60,10 +60,9 @@ const char kDefaultPort[] = "https"; class AresDnsResolver : public Resolver { public: - explicit AresDnsResolver(const ResolverArgs& args); + explicit AresDnsResolver(ResolverArgs args); - void NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) override; + void StartLocked() override; void RequestReresolutionLocked() override; @@ -76,7 +75,6 @@ class AresDnsResolver : public Resolver { void MaybeStartResolvingLocked(); void StartResolvingLocked(); - void MaybeFinishNextLocked(); static void OnNextResolutionLocked(void* arg, grpc_error* error); static void OnResolvedLocked(void* arg, grpc_error* error); @@ -98,16 +96,6 @@ class AresDnsResolver : public Resolver { bool resolving_ = false; /// the pending resolving request grpc_ares_request* pending_request_ = nullptr; - /// which version of the result have we published? - int published_version_ = 0; - /// which version of the result is current? - int resolved_version_ = 0; - /// pending next completion, or NULL - grpc_closure* next_completion_ = nullptr; - /// target result address for next completion - grpc_channel_args** target_result_ = nullptr; - /// current (fully resolved) result - grpc_channel_args* resolved_result_ = nullptr; /// next resolution timer bool have_next_resolution_timer_ = false; grpc_timer next_resolution_timer_; @@ -129,8 +117,8 @@ class AresDnsResolver : public Resolver { bool enable_srv_queries_; }; -AresDnsResolver::AresDnsResolver(const ResolverArgs& args) - : Resolver(args.combiner), +AresDnsResolver::AresDnsResolver(ResolverArgs args) + : Resolver(args.combiner, std::move(args.result_handler)), backoff_( BackOff::Options() .set_initial_backoff(GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS * @@ -177,27 +165,16 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args) AresDnsResolver::~AresDnsResolver() { GRPC_CARES_TRACE_LOG("resolver:%p destroying AresDnsResolver", this); - if (resolved_result_ != nullptr) { - grpc_channel_args_destroy(resolved_result_); - } grpc_pollset_set_destroy(interested_parties_); gpr_free(dns_server_); gpr_free(name_to_resolve_); grpc_channel_args_destroy(channel_args_); } -void AresDnsResolver::NextLocked(grpc_channel_args** target_result, - grpc_closure* on_complete) { - GRPC_CARES_TRACE_LOG("resolver:%p AresDnsResolver::NextLocked() is called.", +void AresDnsResolver::StartLocked() { + GRPC_CARES_TRACE_LOG("resolver:%p AresDnsResolver::StartLocked() is called.", this); - GPR_ASSERT(next_completion_ == nullptr); - next_completion_ = on_complete; - target_result_ = target_result; - if (resolved_version_ == 0 && !resolving_) { - MaybeStartResolvingLocked(); - } else { - MaybeFinishNextLocked(); - } + MaybeStartResolvingLocked(); } void AresDnsResolver::RequestReresolutionLocked() { @@ -221,12 +198,6 @@ void AresDnsResolver::ShutdownLocked() { if (pending_request_ != nullptr) { grpc_cancel_ares_request_locked(pending_request_); } - if (next_completion_ != nullptr) { - *target_result_ = nullptr; - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Resolver Shutdown")); - next_completion_ = nullptr; - } } void AresDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) { @@ -319,11 +290,14 @@ char* ChooseServiceConfig(char* service_config_choice_json) { void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { AresDnsResolver* r = static_cast(arg); - grpc_channel_args* result = nullptr; GPR_ASSERT(r->resolving_); r->resolving_ = false; gpr_free(r->pending_request_); r->pending_request_ = nullptr; + if (r->shutdown_initiated_) { + r->Unref(DEBUG_LOCATION, "OnResolvedLocked() shutdown"); + return; + } if (r->addresses_ != nullptr) { static const char* args_to_remove[1]; size_t num_args_to_remove = 0; @@ -343,17 +317,22 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { (char*)GRPC_ARG_SERVICE_CONFIG, service_config_string); } } - result = grpc_channel_args_copy_and_add_and_remove( + r->result_handler()->ReturnResult(grpc_channel_args_copy_and_add_and_remove( r->channel_args_, args_to_remove, num_args_to_remove, args_to_add, - num_args_to_add); + num_args_to_add)); gpr_free(service_config_string); r->addresses_.reset(); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); - } else if (!r->shutdown_initiated_) { - const char* msg = grpc_error_string(error); - GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed: %s", r, msg); + } else { + GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed: %s", r, + grpc_error_string(error)); + r->result_handler()->ReturnError(grpc_error_set_int( + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "DNS resolution failed", &error, 1), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); + // Set retry timer. grpc_millis next_try = r->backoff_.NextAttemptTime(); grpc_millis timeout = next_try - ExecCtx::Get()->Now(); GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed (will retry): %s", @@ -363,8 +342,7 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { // TODO(roth): We currently deal with this ref manually. Once the // new closure API is done, find a way to track this ref with the timer // callback as part of the type system. - RefCountedPtr self = r->Ref(DEBUG_LOCATION, "retry-timer"); - self.release(); + r->Ref(DEBUG_LOCATION, "retry-timer").release(); if (timeout > 0) { GRPC_CARES_TRACE_LOG("resolver:%p retrying in %" PRId64 " milliseconds", r, timeout); @@ -374,12 +352,6 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { grpc_timer_init(&r->next_resolution_timer_, next_try, &r->on_next_resolution_); } - if (r->resolved_result_ != nullptr) { - grpc_channel_args_destroy(r->resolved_result_); - } - r->resolved_result_ = result; - ++r->resolved_version_; - r->MaybeFinishNextLocked(); r->Unref(DEBUG_LOCATION, "dns-resolving"); } @@ -403,9 +375,7 @@ void AresDnsResolver::MaybeStartResolvingLocked() { // TODO(roth): We currently deal with this ref manually. Once the // new closure API is done, find a way to track this ref with the timer // callback as part of the type system. - RefCountedPtr self = - Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown"); - self.release(); + Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release(); grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution, &on_next_resolution_); return; @@ -418,8 +388,7 @@ void AresDnsResolver::StartResolvingLocked() { // TODO(roth): We currently deal with this ref manually. Once the // new closure API is done, find a way to track this ref with the timer // callback as part of the type system. - RefCountedPtr self = Ref(DEBUG_LOCATION, "dns-resolving"); - self.release(); + Ref(DEBUG_LOCATION, "dns-resolving").release(); GPR_ASSERT(!resolving_); resolving_ = true; service_config_json_ = nullptr; @@ -433,28 +402,14 @@ void AresDnsResolver::StartResolvingLocked() { this, pending_request_); } -void AresDnsResolver::MaybeFinishNextLocked() { - if (next_completion_ != nullptr && resolved_version_ != published_version_) { - *target_result_ = resolved_result_ == nullptr - ? nullptr - : grpc_channel_args_copy(resolved_result_); - GRPC_CARES_TRACE_LOG("resolver:%p AresDnsResolver::MaybeFinishNextLocked()", - this); - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); - next_completion_ = nullptr; - published_version_ = resolved_version_; - } -} - // // Factory // class AresDnsResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { - return OrphanablePtr(New(args)); + OrphanablePtr CreateResolver(ResolverArgs args) const override { + return OrphanablePtr(New(std::move(args))); } const char* scheme() const override { return "dns"; } diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index c365f1abfd8..1c0fe1c6717 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -51,10 +51,9 @@ const char kDefaultPort[] = "https"; class NativeDnsResolver : public Resolver { public: - explicit NativeDnsResolver(const ResolverArgs& args); + explicit NativeDnsResolver(ResolverArgs args); - void NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) override; + void StartLocked() override; void RequestReresolutionLocked() override; @@ -67,7 +66,6 @@ class NativeDnsResolver : public Resolver { void MaybeStartResolvingLocked(); void StartResolvingLocked(); - void MaybeFinishNextLocked(); static void OnNextResolutionLocked(void* arg, grpc_error* error); static void OnResolvedLocked(void* arg, grpc_error* error); @@ -78,19 +76,11 @@ class NativeDnsResolver : public Resolver { grpc_channel_args* channel_args_ = nullptr; /// pollset_set to drive the name resolution process grpc_pollset_set* interested_parties_ = nullptr; + /// are we shutting down? + bool shutdown_ = false; /// are we currently resolving? bool resolving_ = false; grpc_closure on_resolved_; - /// which version of the result have we published? - int published_version_ = 0; - /// which version of the result is current? - int resolved_version_ = 0; - /// pending next completion, or nullptr - grpc_closure* next_completion_ = nullptr; - /// target result address for next completion - grpc_channel_args** target_result_ = nullptr; - /// current (fully resolved) result - grpc_channel_args* resolved_result_ = nullptr; /// next resolution timer bool have_next_resolution_timer_ = false; grpc_timer next_resolution_timer_; @@ -105,8 +95,8 @@ class NativeDnsResolver : public Resolver { grpc_resolved_addresses* addresses_ = nullptr; }; -NativeDnsResolver::NativeDnsResolver(const ResolverArgs& args) - : Resolver(args.combiner), +NativeDnsResolver::NativeDnsResolver(ResolverArgs args) + : Resolver(args.combiner, std::move(args.result_handler)), backoff_( BackOff::Options() .set_initial_backoff(GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS * @@ -134,25 +124,12 @@ NativeDnsResolver::NativeDnsResolver(const ResolverArgs& args) } NativeDnsResolver::~NativeDnsResolver() { - if (resolved_result_ != nullptr) { - grpc_channel_args_destroy(resolved_result_); - } + grpc_channel_args_destroy(channel_args_); grpc_pollset_set_destroy(interested_parties_); gpr_free(name_to_resolve_); - grpc_channel_args_destroy(channel_args_); } -void NativeDnsResolver::NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) { - GPR_ASSERT(next_completion_ == nullptr); - next_completion_ = on_complete; - target_result_ = result; - if (resolved_version_ == 0 && !resolving_) { - MaybeStartResolvingLocked(); - } else { - MaybeFinishNextLocked(); - } -} +void NativeDnsResolver::StartLocked() { MaybeStartResolvingLocked(); } void NativeDnsResolver::RequestReresolutionLocked() { if (!resolving_) { @@ -168,15 +145,10 @@ void NativeDnsResolver::ResetBackoffLocked() { } void NativeDnsResolver::ShutdownLocked() { + shutdown_ = true; if (have_next_resolution_timer_) { grpc_timer_cancel(&next_resolution_timer_); } - if (next_completion_ != nullptr) { - *target_result_ = nullptr; - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Resolver Shutdown")); - next_completion_ = nullptr; - } } void NativeDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) { @@ -190,38 +162,42 @@ void NativeDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) { void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { NativeDnsResolver* r = static_cast(arg); - grpc_channel_args* result = nullptr; GPR_ASSERT(r->resolving_); r->resolving_ = false; - GRPC_ERROR_REF(error); - error = - grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, - grpc_slice_from_copied_string(r->name_to_resolve_)); + if (r->shutdown_) { + r->Unref(DEBUG_LOCATION, "dns-resolving"); + return; + } if (r->addresses_ != nullptr) { ServerAddressList addresses; for (size_t i = 0; i < r->addresses_->naddrs; ++i) { addresses.emplace_back(&r->addresses_->addrs[i].addr, r->addresses_->addrs[i].len, nullptr /* args */); } - grpc_arg new_arg = CreateServerAddressListChannelArg(&addresses); - result = grpc_channel_args_copy_and_add(r->channel_args_, &new_arg, 1); grpc_resolved_addresses_destroy(r->addresses_); + grpc_arg new_arg = CreateServerAddressListChannelArg(&addresses); + r->result_handler()->ReturnResult( + grpc_channel_args_copy_and_add(r->channel_args_, &new_arg, 1)); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); } else { - grpc_millis next_try = r->backoff_.NextAttemptTime(); - grpc_millis timeout = next_try - ExecCtx::Get()->Now(); gpr_log(GPR_INFO, "dns resolution failed (will retry): %s", grpc_error_string(error)); + // Return transient error. + r->result_handler()->ReturnError(grpc_error_set_int( + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "DNS resolution failed", &error, 1), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); + // Set up for retry. + grpc_millis next_try = r->backoff_.NextAttemptTime(); + grpc_millis timeout = next_try - ExecCtx::Get()->Now(); GPR_ASSERT(!r->have_next_resolution_timer_); r->have_next_resolution_timer_ = true; // TODO(roth): We currently deal with this ref manually. Once the // new closure API is done, find a way to track this ref with the timer // callback as part of the type system. - RefCountedPtr self = - r->Ref(DEBUG_LOCATION, "next_resolution_timer"); - self.release(); + r->Ref(DEBUG_LOCATION, "next_resolution_timer").release(); if (timeout > 0) { gpr_log(GPR_DEBUG, "retrying in %" PRId64 " milliseconds", timeout); } else { @@ -230,13 +206,6 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { grpc_timer_init(&r->next_resolution_timer_, next_try, &r->on_next_resolution_); } - if (r->resolved_result_ != nullptr) { - grpc_channel_args_destroy(r->resolved_result_); - } - r->resolved_result_ = result; - ++r->resolved_version_; - r->MaybeFinishNextLocked(); - GRPC_ERROR_UNREF(error); r->Unref(DEBUG_LOCATION, "dns-resolving"); } @@ -260,9 +229,7 @@ void NativeDnsResolver::MaybeStartResolvingLocked() { // TODO(roth): We currently deal with this ref manually. Once the // new closure API is done, find a way to track this ref with the timer // callback as part of the type system. - RefCountedPtr self = - Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown"); - self.release(); + Ref(DEBUG_LOCATION, "next_resolution_timer_cooldown").release(); grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution, &on_next_resolution_); return; @@ -276,8 +243,7 @@ void NativeDnsResolver::StartResolvingLocked() { // TODO(roth): We currently deal with this ref manually. Once the // new closure API is done, find a way to track this ref with the timer // callback as part of the type system. - RefCountedPtr self = Ref(DEBUG_LOCATION, "dns-resolving"); - self.release(); + Ref(DEBUG_LOCATION, "dns-resolving").release(); GPR_ASSERT(!resolving_); resolving_ = true; addresses_ = nullptr; @@ -286,30 +252,18 @@ void NativeDnsResolver::StartResolvingLocked() { last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); } -void NativeDnsResolver::MaybeFinishNextLocked() { - if (next_completion_ != nullptr && resolved_version_ != published_version_) { - *target_result_ = resolved_result_ == nullptr - ? nullptr - : grpc_channel_args_copy(resolved_result_); - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); - next_completion_ = nullptr; - published_version_ = resolved_version_; - } -} - // // Factory // class NativeDnsResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { + OrphanablePtr CreateResolver(ResolverArgs args) const override { if (GPR_UNLIKELY(0 != strcmp(args.uri->authority, ""))) { gpr_log(GPR_ERROR, "authority based dns uri's not supported"); return OrphanablePtr(nullptr); } - return OrphanablePtr(New(args)); + return OrphanablePtr(New(std::move(args))); } const char* scheme() const override { return "dns"; } diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index 3489f3d491b..153279e323e 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -50,10 +50,9 @@ namespace grpc_core { // FakeResolverResponseGenerator. class FakeResolver : public Resolver { public: - explicit FakeResolver(const ResolverArgs& args); + explicit FakeResolver(ResolverArgs args); - void NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) override; + void StartLocked() override; void RequestReresolutionLocked() override; @@ -62,27 +61,32 @@ class FakeResolver : public Resolver { virtual ~FakeResolver(); - void MaybeFinishNextLocked(); + void ShutdownLocked() override { active_ = false; } - void ShutdownLocked() override; + void MaybeSendResultLocked(); + + static void ReturnReresolutionResult(void* arg, grpc_error* error); // passed-in parameters grpc_channel_args* channel_args_ = nullptr; - // If not NULL, the next set of resolution results to be returned to - // NextLocked()'s closure. + // If not NULL, the next set of resolution results to be returned. grpc_channel_args* next_results_ = nullptr; // Results to use for the pretended re-resolution in // RequestReresolutionLocked(). grpc_channel_args* reresolution_results_ = nullptr; - // pending next completion, or NULL - grpc_closure* next_completion_ = nullptr; - // target result address for next completion - grpc_channel_args** target_result_ = nullptr; + // True between the calls to StartLocked() ShutdownLocked(). + bool active_ = false; // if true, return failure bool return_failure_ = false; + // pending re-resolution + grpc_closure reresolution_closure_; + bool reresolution_closure_pending_ = false; }; -FakeResolver::FakeResolver(const ResolverArgs& args) : Resolver(args.combiner) { +FakeResolver::FakeResolver(ResolverArgs args) + : Resolver(args.combiner, std::move(args.result_handler)) { + GRPC_CLOSURE_INIT(&reresolution_closure_, ReturnReresolutionResult, this, + grpc_combiner_scheduler(combiner())); channel_args_ = grpc_channel_args_copy(args.args); FakeResolverResponseGenerator* response_generator = FakeResolverResponseGenerator::GetFromArgs(args.args); @@ -102,46 +106,51 @@ FakeResolver::~FakeResolver() { grpc_channel_args_destroy(channel_args_); } -void FakeResolver::NextLocked(grpc_channel_args** target_result, - grpc_closure* on_complete) { - GPR_ASSERT(next_completion_ == nullptr); - next_completion_ = on_complete; - target_result_ = target_result; - MaybeFinishNextLocked(); +void FakeResolver::StartLocked() { + active_ = true; + MaybeSendResultLocked(); } void FakeResolver::RequestReresolutionLocked() { if (reresolution_results_ != nullptr || return_failure_) { grpc_channel_args_destroy(next_results_); next_results_ = grpc_channel_args_copy(reresolution_results_); - MaybeFinishNextLocked(); + // Return the result in a different closure, so that we don't call + // back into the LB policy while it's still processing the previous + // update. + if (!reresolution_closure_pending_) { + reresolution_closure_pending_ = true; + Ref().release(); // ref held by closure + GRPC_CLOSURE_SCHED(&reresolution_closure_, GRPC_ERROR_NONE); + } } } -void FakeResolver::MaybeFinishNextLocked() { - if (next_completion_ != nullptr && - (next_results_ != nullptr || return_failure_)) { +void FakeResolver::MaybeSendResultLocked() { + if (!active_) return; + if (return_failure_) { + // TODO(roth): Change resolver result generator to be able to inject + // the error to be returned. + result_handler()->ReturnError(grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver transient failure"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); + return_failure_ = false; + } else if (next_results_ != nullptr) { // When both next_results_ and channel_args_ contain an arg with the same // name, only the one in next_results_ will be kept since next_results_ is // before channel_args_. - *target_result_ = - return_failure_ ? nullptr - : grpc_channel_args_union(next_results_, channel_args_); + result_handler()->ReturnResult( + grpc_channel_args_union(next_results_, channel_args_)); grpc_channel_args_destroy(next_results_); next_results_ = nullptr; - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); - next_completion_ = nullptr; - return_failure_ = false; } } -void FakeResolver::ShutdownLocked() { - if (next_completion_ != nullptr) { - *target_result_ = nullptr; - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Resolver Shutdown")); - next_completion_ = nullptr; - } +void FakeResolver::ReturnReresolutionResult(void* arg, grpc_error* error) { + FakeResolver* self = static_cast(arg); + self->reresolution_closure_pending_ = false; + self->MaybeSendResultLocked(); + self->Unref(); } // @@ -161,7 +170,7 @@ void FakeResolverResponseGenerator::SetResponseLocked(void* arg, FakeResolver* resolver = closure_arg->generator->resolver_; grpc_channel_args_destroy(resolver->next_results_); resolver->next_results_ = closure_arg->response; - resolver->MaybeFinishNextLocked(); + resolver->MaybeSendResultLocked(); Delete(closure_arg); } @@ -210,7 +219,7 @@ void FakeResolverResponseGenerator::SetFailureLocked(void* arg, SetResponseClosureArg* closure_arg = static_cast(arg); FakeResolver* resolver = closure_arg->generator->resolver_; resolver->return_failure_ = true; - if (closure_arg->immediate) resolver->MaybeFinishNextLocked(); + if (closure_arg->immediate) resolver->MaybeSendResultLocked(); Delete(closure_arg); } @@ -290,9 +299,8 @@ namespace { class FakeResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { - return OrphanablePtr(New(args)); + OrphanablePtr CreateResolver(ResolverArgs args) const override { + return OrphanablePtr(New(std::move(args))); } const char* scheme() const override { return "fake"; } diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h index f423e6d46db..9e3ec1fb7cb 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h @@ -58,8 +58,7 @@ class FakeResolverResponseGenerator // is called. void SetReresolutionResponse(grpc_channel_args* response); - // Tells the resolver to return a transient failure (signalled by - // returning a null result with no error). + // Tells the resolver to return a transient failure. void SetFailure(); // Same as SetFailure(), but instead of returning the error diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc index 1654747a79f..df93c76399d 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -45,66 +45,29 @@ namespace { class SockaddrResolver : public Resolver { public: /// Takes ownership of \a addresses. - SockaddrResolver(const ResolverArgs& args, - UniquePtr addresses); + explicit SockaddrResolver(ResolverArgs args); + ~SockaddrResolver() override; - void NextLocked(grpc_channel_args** result, - grpc_closure* on_complete) override; + void StartLocked() override; - void ShutdownLocked() override; + void ShutdownLocked() override {} private: - virtual ~SockaddrResolver(); - - void MaybeFinishNextLocked(); - - /// the addresses that we've "resolved" - UniquePtr addresses_; /// channel args - grpc_channel_args* channel_args_ = nullptr; - /// have we published? - bool published_ = false; - /// pending next completion, or NULL - grpc_closure* next_completion_ = nullptr; - /// target result address for next completion - grpc_channel_args** target_result_ = nullptr; + const grpc_channel_args* channel_args_ = nullptr; }; -SockaddrResolver::SockaddrResolver(const ResolverArgs& args, - UniquePtr addresses) - : Resolver(args.combiner), - addresses_(std::move(addresses)), - channel_args_(grpc_channel_args_copy(args.args)) {} +SockaddrResolver::SockaddrResolver(ResolverArgs args) + : Resolver(args.combiner, std::move(args.result_handler)), + channel_args_(args.args) {} SockaddrResolver::~SockaddrResolver() { grpc_channel_args_destroy(channel_args_); } -void SockaddrResolver::NextLocked(grpc_channel_args** target_result, - grpc_closure* on_complete) { - GPR_ASSERT(!next_completion_); - next_completion_ = on_complete; - target_result_ = target_result; - MaybeFinishNextLocked(); -} - -void SockaddrResolver::ShutdownLocked() { - if (next_completion_ != nullptr) { - *target_result_ = nullptr; - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Resolver Shutdown")); - next_completion_ = nullptr; - } -} - -void SockaddrResolver::MaybeFinishNextLocked() { - if (next_completion_ != nullptr && !published_) { - published_ = true; - grpc_arg arg = CreateServerAddressListChannelArg(addresses_.get()); - *target_result_ = grpc_channel_args_copy_and_add(channel_args_, &arg, 1); - GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE); - next_completion_ = nullptr; - } +void SockaddrResolver::StartLocked() { + result_handler()->ReturnResult(channel_args_); + channel_args_ = nullptr; } // @@ -114,7 +77,7 @@ void SockaddrResolver::MaybeFinishNextLocked() { void DoNothing(void* ignored) {} OrphanablePtr CreateSockaddrResolver( - const ResolverArgs& args, + ResolverArgs args, bool parse(const grpc_uri* uri, grpc_resolved_address* dst)) { if (0 != strcmp(args.uri->authority, "")) { gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme", @@ -127,7 +90,7 @@ OrphanablePtr CreateSockaddrResolver( grpc_slice_buffer path_parts; grpc_slice_buffer_init(&path_parts); grpc_slice_split(path_slice, ",", &path_parts); - auto addresses = MakeUnique(); + ServerAddressList addresses; bool errors_found = false; for (size_t i = 0; i < path_parts.count; i++) { grpc_uri ith_uri = *args.uri; @@ -135,26 +98,28 @@ OrphanablePtr CreateSockaddrResolver( ith_uri.path = part_str.get(); grpc_resolved_address addr; if (!parse(&ith_uri, &addr)) { - errors_found = true; /* GPR_TRUE */ + errors_found = true; break; } - addresses->emplace_back(addr, nullptr /* args */); + addresses.emplace_back(addr, nullptr /* args */); } grpc_slice_buffer_destroy_internal(&path_parts); grpc_slice_unref_internal(path_slice); if (errors_found) { return OrphanablePtr(nullptr); } + // Add addresses to channel args. + // Note: SockaddrResolver takes ownership of channel args. + grpc_arg arg = CreateServerAddressListChannelArg(&addresses); + args.args = grpc_channel_args_copy_and_add(args.args, &arg, 1); // Instantiate resolver. - return OrphanablePtr( - New(args, std::move(addresses))); + return OrphanablePtr(New(std::move(args))); } class IPv4ResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { - return CreateSockaddrResolver(args, grpc_parse_ipv4); + OrphanablePtr CreateResolver(ResolverArgs args) const override { + return CreateSockaddrResolver(std::move(args), grpc_parse_ipv4); } const char* scheme() const override { return "ipv4"; } @@ -162,9 +127,8 @@ class IPv4ResolverFactory : public ResolverFactory { class IPv6ResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { - return CreateSockaddrResolver(args, grpc_parse_ipv6); + OrphanablePtr CreateResolver(ResolverArgs args) const override { + return CreateSockaddrResolver(std::move(args), grpc_parse_ipv6); } const char* scheme() const override { return "ipv6"; } @@ -173,9 +137,8 @@ class IPv6ResolverFactory : public ResolverFactory { #ifdef GRPC_HAVE_UNIX_SOCKET class UnixResolverFactory : public ResolverFactory { public: - OrphanablePtr CreateResolver( - const ResolverArgs& args) const override { - return CreateSockaddrResolver(args, grpc_parse_unix); + OrphanablePtr CreateResolver(ResolverArgs args) const override { + return CreateSockaddrResolver(std::move(args), grpc_parse_unix); } UniquePtr GetDefaultAuthority(grpc_uri* uri) const override { diff --git a/src/core/ext/filters/client_channel/resolver_factory.h b/src/core/ext/filters/client_channel/resolver_factory.h index d891ef62e1d..273fd8d24f0 100644 --- a/src/core/ext/filters/client_channel/resolver_factory.h +++ b/src/core/ext/filters/client_channel/resolver_factory.h @@ -41,12 +41,14 @@ struct ResolverArgs { grpc_pollset_set* pollset_set = nullptr; /// The combiner under which all resolver calls will be run. grpc_combiner* combiner = nullptr; + /// The result handler to be used by the resolver. + UniquePtr result_handler; }; class ResolverFactory { public: /// Returns a new resolver instance. - virtual OrphanablePtr CreateResolver(const ResolverArgs& args) const + virtual OrphanablePtr CreateResolver(ResolverArgs args) const GRPC_ABSTRACT; /// Returns a string representing the default authority to use for this diff --git a/src/core/ext/filters/client_channel/resolver_registry.cc b/src/core/ext/filters/client_channel/resolver_registry.cc index 91c0267f95e..5b00eab341e 100644 --- a/src/core/ext/filters/client_channel/resolver_registry.cc +++ b/src/core/ext/filters/client_channel/resolver_registry.cc @@ -134,7 +134,8 @@ ResolverFactory* ResolverRegistry::LookupResolverFactory(const char* scheme) { OrphanablePtr ResolverRegistry::CreateResolver( const char* target, const grpc_channel_args* args, - grpc_pollset_set* pollset_set, grpc_combiner* combiner) { + grpc_pollset_set* pollset_set, grpc_combiner* combiner, + UniquePtr result_handler) { GPR_ASSERT(g_state != nullptr); grpc_uri* uri = nullptr; char* canonical_target = nullptr; @@ -145,8 +146,10 @@ OrphanablePtr ResolverRegistry::CreateResolver( resolver_args.args = args; resolver_args.pollset_set = pollset_set; resolver_args.combiner = combiner; + resolver_args.result_handler = std::move(result_handler); OrphanablePtr resolver = - factory == nullptr ? nullptr : factory->CreateResolver(resolver_args); + factory == nullptr ? nullptr + : factory->CreateResolver(std::move(resolver_args)); grpc_uri_destroy(uri); gpr_free(canonical_target); return resolver; diff --git a/src/core/ext/filters/client_channel/resolver_registry.h b/src/core/ext/filters/client_channel/resolver_registry.h index d6ec6811bd7..1fbe01aabc2 100644 --- a/src/core/ext/filters/client_channel/resolver_registry.h +++ b/src/core/ext/filters/client_channel/resolver_registry.h @@ -62,10 +62,10 @@ class ResolverRegistry { /// \a args are the channel args to be included in resolver results. /// \a pollset_set is used to drive I/O in the name resolution process. /// \a combiner is the combiner under which all resolver calls will be run. - static OrphanablePtr CreateResolver(const char* target, - const grpc_channel_args* args, - grpc_pollset_set* pollset_set, - grpc_combiner* combiner); + static OrphanablePtr CreateResolver( + const char* target, const grpc_channel_args* args, + grpc_pollset_set* pollset_set, grpc_combiner* combiner, + UniquePtr result_handler); /// Returns the default authority to pass from a client for \a target. static UniquePtr GetDefaultAuthority(const char* target); diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 52b14dcc7de..63cf56b1a44 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -65,6 +65,36 @@ namespace grpc_core { +// +// ResolvingLoadBalancingPolicy::ResolverResultHandler +// + +class ResolvingLoadBalancingPolicy::ResolverResultHandler + : public Resolver::ResultHandler { + public: + explicit ResolverResultHandler( + RefCountedPtr parent) + : parent_(std::move(parent)) {} + + ~ResolverResultHandler() { + if (parent_->tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: resolver shutdown complete", + parent_.get()); + } + } + + void ReturnResult(const grpc_channel_args* result) override { + parent_->OnResolverResultChangedLocked(result); + } + + void ReturnError(grpc_error* error) override { + parent_->OnResolverError(error); + } + + private: + RefCountedPtr parent_; +}; + // // ResolvingLoadBalancingPolicy::ResolvingControlHelper // @@ -196,12 +226,9 @@ ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( } grpc_error* ResolvingLoadBalancingPolicy::Init(const grpc_channel_args& args) { - GRPC_CLOSURE_INIT( - &on_resolver_result_changed_, - &ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked, this, - grpc_combiner_scheduler(combiner())); resolver_ = ResolverRegistry::CreateResolver( - target_uri_.get(), &args, interested_parties(), combiner()); + target_uri_.get(), &args, interested_parties(), combiner(), + UniquePtr(New(Ref()))); if (resolver_ == nullptr) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed"); } @@ -288,62 +315,34 @@ void ResolvingLoadBalancingPolicy::StartResolvingLocked() { channel_control_helper()->UpdateState( GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, UniquePtr(New(Ref()))); - Ref().release(); - resolver_->NextLocked(&resolver_result_, &on_resolver_result_changed_); + resolver_->StartLocked(); } -// Invoked from the resolver NextLocked() callback when the resolver -// is shutting down. -void ResolvingLoadBalancingPolicy::OnResolverShutdownLocked(grpc_error* error) { +void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { + if (resolver_ == nullptr) { + GRPC_ERROR_UNREF(error); + return; + } if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: shutting down", this); + gpr_log(GPR_INFO, "resolving_lb=%p: resolver transient failure: %s", this, + grpc_error_string(error)); } - { - MutexLock lock(&lb_policy_mu_); - if (lb_policy_ != nullptr) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this, - lb_policy_.get()); - } - grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(), - interested_parties()); - lb_policy_.reset(); - } - if (pending_lb_policy_ != nullptr) { - if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: shutting down pending lb_policy=%p", - this, pending_lb_policy_.get()); - } - grpc_pollset_set_del_pollset_set(pending_lb_policy_->interested_parties(), - interested_parties()); - pending_lb_policy_.reset(); - } - } - if (resolver_ != nullptr) { - // This should never happen; it can only be triggered by a resolver - // implementation spotaneously deciding to report shutdown without - // being orphaned. This code is included just to be defensive. - if (tracer_->enabled()) { - gpr_log(GPR_INFO, - "resolving_lb=%p: spontaneous shutdown from resolver %p", this, - resolver_.get()); - } - resolver_.reset(); - grpc_error* error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Resolver spontaneous shutdown", &error, 1); + // If we already have an LB policy from a previous resolution + // result, then we continue to let it set the connectivity state. + // Otherwise, we go into TRANSIENT_FAILURE. + if (lb_policy_ == nullptr) { + grpc_error* state_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Resolver transient failure", &error, 1); channel_control_helper()->UpdateState( - GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error), - UniquePtr(New(error))); + GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(state_error), + UniquePtr(New(state_error))); } - grpc_channel_args_destroy(resolver_result_); - resolver_result_ = nullptr; GRPC_ERROR_UNREF(error); - Unref(); } void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, RefCountedPtr lb_policy_config, - TraceStringVector* trace_strings) { + const grpc_channel_args& args, TraceStringVector* trace_strings) { // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store // the new child policy in pending_child_policy_. Once the new child @@ -411,7 +410,7 @@ void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( gpr_log(GPR_INFO, "resolving_lb=%p: Creating new %schild policy %s", this, lb_policy_ == nullptr ? "" : "pending ", lb_policy_name); } - auto new_policy = CreateLbPolicyLocked(lb_policy_name, trace_strings); + auto new_policy = CreateLbPolicyLocked(lb_policy_name, args, trace_strings); auto& lb_policy = lb_policy_ == nullptr ? lb_policy_ : pending_lb_policy_; { MutexLock lock(&lb_policy_mu_); @@ -432,21 +431,21 @@ void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( policy_to_update == pending_lb_policy_.get() ? "pending " : "", policy_to_update); } - policy_to_update->UpdateLocked(*resolver_result_, - std::move(lb_policy_config)); + policy_to_update->UpdateLocked(args, std::move(lb_policy_config)); } // Creates a new LB policy. // Updates trace_strings to indicate what was done. OrphanablePtr ResolvingLoadBalancingPolicy::CreateLbPolicyLocked( - const char* lb_policy_name, TraceStringVector* trace_strings) { + const char* lb_policy_name, const grpc_channel_args& args, + TraceStringVector* trace_strings) { ResolvingControlHelper* helper = New(Ref()); LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = combiner(); lb_policy_args.channel_control_helper = UniquePtr(helper); - lb_policy_args.args = resolver_result_; + lb_policy_args.args = &args; OrphanablePtr lb_policy = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( lb_policy_name, std::move(lb_policy_args)); @@ -480,9 +479,10 @@ ResolvingLoadBalancingPolicy::CreateLbPolicyLocked( } void ResolvingLoadBalancingPolicy::MaybeAddTraceMessagesForAddressChangesLocked( + const grpc_channel_args& resolver_result, TraceStringVector* trace_strings) { const ServerAddressList* addresses = - FindServerAddressListChannelArg(resolver_result_); + FindServerAddressListChannelArg(&resolver_result); const bool resolution_contains_addresses = addresses != nullptr && addresses->size() > 0; if (!resolution_contains_addresses && @@ -516,27 +516,16 @@ void ResolvingLoadBalancingPolicy::ConcatenateAndAddChannelTraceLocked( } } -// Callback invoked when a resolver result is available. void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( - void* arg, grpc_error* error) { - auto* self = static_cast(arg); - if (self->tracer_->enabled()) { - const char* disposition = - self->resolver_result_ != nullptr - ? "" - : (error == GRPC_ERROR_NONE ? " (transient error)" - : " (resolver shutdown)"); - gpr_log(GPR_INFO, - "resolving_lb=%p: got resolver result: resolver_result=%p " - "error=%s%s", - self, self->resolver_result_, grpc_error_string(error), - disposition); - } - // Handle shutdown. - if (error != GRPC_ERROR_NONE || self->resolver_ == nullptr) { - self->OnResolverShutdownLocked(GRPC_ERROR_REF(error)); + const grpc_channel_args* result) { + // Handle race conditions. + if (resolver_ == nullptr) { + grpc_channel_args_destroy(result); return; } + if (tracer_->enabled()) { + gpr_log(GPR_INFO, "resolving_lb=%p: got resolver result %p", this, result); + } // We only want to trace the address resolution in the follow cases: // (a) Address resolution resulted in service config change. // (b) Address resolution that causes number of backends to go from @@ -547,63 +536,34 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( // // we track a list of strings to eventually be concatenated and traced. TraceStringVector trace_strings; - // resolver_result_ will be null in the case of a transient - // resolution error. In that case, we don't have any new result to - // process, which means that we keep using the previous result (if any). - if (self->resolver_result_ == nullptr) { - if (self->tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: resolver transient failure", self); - } - // If we already have an LB policy from a previous resolution - // result, then we continue to let it set the connectivity state. - // Otherwise, we go into TRANSIENT_FAILURE. - if (self->lb_policy_ == nullptr) { - // TODO(roth): When we change the resolver API to be able to - // return transient errors in a cleaner way, we should make it the - // resolver's responsibility to attach a status to the error, - // rather than doing it centrally here. - grpc_error* state_error = grpc_error_set_int( - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Resolver transient failure", &error, 1), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); - self->channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(state_error), - UniquePtr( - New(state_error))); - } + // Parse the resolver result. + const char* lb_policy_name = nullptr; + RefCountedPtr lb_policy_config; + bool service_config_changed = false; + if (process_resolver_result_ != nullptr) { + service_config_changed = + process_resolver_result_(process_resolver_result_user_data_, *result, + &lb_policy_name, &lb_policy_config); } else { - // Parse the resolver result. - const char* lb_policy_name = nullptr; - RefCountedPtr lb_policy_config; - bool service_config_changed = false; - if (self->process_resolver_result_ != nullptr) { - service_config_changed = self->process_resolver_result_( - self->process_resolver_result_user_data_, *self->resolver_result_, - &lb_policy_name, &lb_policy_config); - } else { - lb_policy_name = self->child_policy_name_.get(); - lb_policy_config = self->child_lb_config_; - } - GPR_ASSERT(lb_policy_name != nullptr); - self->CreateOrUpdateLbPolicyLocked( - lb_policy_name, std::move(lb_policy_config), &trace_strings); - // Add channel trace event. - if (self->channelz_node() != nullptr) { - if (service_config_changed) { - // TODO(ncteisen): might be worth somehow including a snippet of the - // config in the trace, at the risk of bloating the trace logs. - trace_strings.push_back(gpr_strdup("Service config changed")); - } - self->MaybeAddTraceMessagesForAddressChangesLocked(&trace_strings); - self->ConcatenateAndAddChannelTraceLocked(&trace_strings); - } - // Clean up. - grpc_channel_args_destroy(self->resolver_result_); - self->resolver_result_ = nullptr; + lb_policy_name = child_policy_name_.get(); + lb_policy_config = child_lb_config_; } - // Renew resolver callback. - self->resolver_->NextLocked(&self->resolver_result_, - &self->on_resolver_result_changed_); + GPR_ASSERT(lb_policy_name != nullptr); + // Create or update LB policy, as needed. + CreateOrUpdateLbPolicyLocked(lb_policy_name, std::move(lb_policy_config), + *result, &trace_strings); + // Add channel trace event. + if (channelz_node() != nullptr) { + if (service_config_changed) { + // TODO(ncteisen): might be worth somehow including a snippet of the + // config in the trace, at the risk of bloating the trace logs. + trace_strings.push_back(gpr_strdup("Service config changed")); + } + MaybeAddTraceMessagesForAddressChangesLocked(*result, &trace_strings); + ConcatenateAndAddChannelTraceLocked(&trace_strings); + } + // Clean up. + grpc_channel_args_destroy(result); } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index b8f406da1b6..fa34611c979 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -93,6 +93,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { private: using TraceStringVector = InlinedVector; + class ResolverResultHandler; class ResolvingControlHelper; ~ResolvingLoadBalancingPolicy(); @@ -101,17 +102,20 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void ShutdownLocked() override; void StartResolvingLocked(); - void OnResolverShutdownLocked(grpc_error* error); + void OnResolverError(grpc_error* error); void CreateOrUpdateLbPolicyLocked(const char* lb_policy_name, - RefCountedPtr, + RefCountedPtr lb_policy_config, + const grpc_channel_args& args, TraceStringVector* trace_strings); OrphanablePtr CreateLbPolicyLocked( - const char* lb_policy_name, TraceStringVector* trace_strings); + const char* lb_policy_name, const grpc_channel_args& args, + TraceStringVector* trace_strings); void MaybeAddTraceMessagesForAddressChangesLocked( + const grpc_channel_args& resolver_result, TraceStringVector* trace_strings); void ConcatenateAndAddChannelTraceLocked( TraceStringVector* trace_strings) const; - static void OnResolverResultChangedLocked(void* arg, grpc_error* error); + void OnResolverResultChangedLocked(const grpc_channel_args* result); // Passed in from caller at construction time. TraceFlag* tracer_; @@ -124,9 +128,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // Resolver and associated state. OrphanablePtr resolver_; bool started_resolving_ = false; - grpc_channel_args* resolver_result_ = nullptr; bool previous_resolution_contained_addresses_ = false; - grpc_closure on_resolver_result_changed_; // Child LB policy. OrphanablePtr lb_policy_; diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h index 5ff303a9dc6..c47c027b379 100644 --- a/src/core/lib/channel/channel_args.h +++ b/src/core/lib/channel/channel_args.h @@ -56,6 +56,9 @@ grpc_channel_args* grpc_channel_args_union(const grpc_channel_args* a, /** Destroy arguments created by \a grpc_channel_args_copy */ void grpc_channel_args_destroy(grpc_channel_args* a); +inline void grpc_channel_args_destroy(const grpc_channel_args* a) { + grpc_channel_args_destroy(const_cast(a)); +} /** Returns the compression algorithm set in \a a. */ grpc_compression_algorithm grpc_channel_args_get_compression_algorithm( diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc index 0cf549d01da..76ac585fb4c 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -90,7 +90,8 @@ static void my_cancel_ares_request_locked(grpc_ares_request* request) { } static grpc_core::OrphanablePtr create_resolver( - const char* name) { + const char* name, + grpc_core::UniquePtr result_handler) { grpc_core::ResolverFactory* factory = grpc_core::ResolverRegistry::LookupResolverFactory("dns"); grpc_uri* uri = grpc_uri_parse(name, 0); @@ -98,15 +99,52 @@ static grpc_core::OrphanablePtr create_resolver( grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = std::move(result_handler); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); grpc_uri_destroy(uri); return resolver; } -static void on_done(void* ev, grpc_error* error) { - gpr_event_set(static_cast(ev), (void*)1); -} +class ResultHandler : public grpc_core::Resolver::ResultHandler { + public: + struct ResolverOutput { + const grpc_channel_args* result = nullptr; + grpc_error* error = nullptr; + gpr_event ev; + + ResolverOutput() { gpr_event_init(&ev); } + ~ResolverOutput() { + grpc_channel_args_destroy(result); + GRPC_ERROR_UNREF(error); + } + }; + + void SetOutput(ResolverOutput* output) { + gpr_atm_rel_store(&output_, reinterpret_cast(output)); + } + + void ReturnResult(const grpc_channel_args* args) override { + ResolverOutput* output = + reinterpret_cast(gpr_atm_acq_load(&output_)); + GPR_ASSERT(output != nullptr); + output->result = args; + output->error = GRPC_ERROR_NONE; + gpr_event_set(&output->ev, (void*)1); + } + + void ReturnError(grpc_error* error) override { + ResolverOutput* output = + reinterpret_cast(gpr_atm_acq_load(&output_)); + GPR_ASSERT(output != nullptr); + output->result = nullptr; + output->error = error; + gpr_event_set(&output->ev, (void*)1); + } + + private: + gpr_atm output_ = 0; // ResolverOutput* +}; // interleave waiting for an event with a timer check static bool wait_loop(int deadline_seconds, gpr_event* ev) { @@ -121,32 +159,6 @@ static bool wait_loop(int deadline_seconds, gpr_event* ev) { return false; } -typedef struct next_args { - grpc_core::Resolver* resolver; - grpc_channel_args** result; - grpc_closure* on_complete; -} next_args; - -static void call_resolver_next_now_lock_taken(void* arg, - grpc_error* error_unused) { - next_args* a = static_cast(arg); - a->resolver->NextLocked(a->result, a->on_complete); - gpr_free(a); -} - -static void call_resolver_next_after_locking(grpc_core::Resolver* resolver, - grpc_channel_args** result, - grpc_closure* on_complete, - grpc_combiner* combiner) { - next_args* a = static_cast(gpr_malloc(sizeof(*a))); - a->resolver = resolver; - a->result = result; - a->on_complete = on_complete; - GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(call_resolver_next_now_lock_taken, a, - grpc_combiner_scheduler(combiner)), - GRPC_ERROR_NONE); -} - int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); @@ -156,33 +168,28 @@ int main(int argc, char** argv) { grpc_set_resolver_impl(&test_resolver); grpc_dns_lookup_ares_locked = my_dns_lookup_ares_locked; grpc_cancel_ares_request_locked = my_cancel_ares_request_locked; - grpc_channel_args* result = (grpc_channel_args*)1; { grpc_core::ExecCtx exec_ctx; - grpc_core::OrphanablePtr resolver = - create_resolver("dns:test"); - gpr_event ev1; - gpr_event_init(&ev1); - call_resolver_next_after_locking( - resolver.get(), &result, - GRPC_CLOSURE_CREATE(on_done, &ev1, grpc_schedule_on_exec_ctx), - g_combiner); + ResultHandler* result_handler = grpc_core::New(); + grpc_core::OrphanablePtr resolver = create_resolver( + "dns:test", grpc_core::UniquePtr( + result_handler)); + ResultHandler::ResolverOutput output1; + result_handler->SetOutput(&output1); + resolver->StartLocked(); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(wait_loop(5, &ev1)); - GPR_ASSERT(result == nullptr); + GPR_ASSERT(wait_loop(5, &output1.ev)); + GPR_ASSERT(output1.result == nullptr); + GPR_ASSERT(output1.error != GRPC_ERROR_NONE); - gpr_event ev2; - gpr_event_init(&ev2); - call_resolver_next_after_locking( - resolver.get(), &result, - GRPC_CLOSURE_CREATE(on_done, &ev2, grpc_schedule_on_exec_ctx), - g_combiner); + ResultHandler::ResolverOutput output2; + result_handler->SetOutput(&output2); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(wait_loop(30, &ev2)); - GPR_ASSERT(result != nullptr); + GPR_ASSERT(wait_loop(30, &output2.ev)); + GPR_ASSERT(output2.result != nullptr); + GPR_ASSERT(output2.error == GRPC_ERROR_NONE); - grpc_channel_args_destroy(result); GRPC_COMBINER_UNREF(g_combiner, "test"); } diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index 3157d6019f3..82ff5b04fe0 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -170,19 +170,52 @@ static void poll_pollset_until_request_done(iomgr_args* args) { gpr_event_set(&args->ev, (void*)1); } +struct OnResolutionCallbackArg; + +class ResultHandler : public grpc_core::Resolver::ResultHandler { + public: + using ResultCallback = void (*)(const grpc_channel_args* result, + OnResolutionCallbackArg* state); + + void SetCallback(ResultCallback result_cb, OnResolutionCallbackArg* state) { + GPR_ASSERT(result_cb_ == nullptr); + result_cb_ = result_cb; + GPR_ASSERT(state_ == nullptr); + state_ = state; + } + + void ReturnResult(const grpc_channel_args* args) override { + GPR_ASSERT(result_cb_ != nullptr); + GPR_ASSERT(state_ != nullptr); + ResultCallback cb = result_cb_; + OnResolutionCallbackArg* state = state_; + result_cb_ = nullptr; + state_ = nullptr; + cb(args, state); + } + + void ReturnError(grpc_error* error) override { + gpr_log(GPR_ERROR, "resolver returned error: %s", grpc_error_string(error)); + GPR_ASSERT(false); + } + + private: + ResultCallback result_cb_ = nullptr; + OnResolutionCallbackArg* state_ = nullptr; +}; + struct OnResolutionCallbackArg { const char* uri_str = nullptr; grpc_core::OrphanablePtr resolver; - grpc_channel_args* result = nullptr; + ResultHandler* result_handler; }; // Set to true by the last callback in the resolution chain. static bool g_all_callbacks_invoked; -static void on_second_resolution(void* arg, grpc_error* error) { - OnResolutionCallbackArg* cb_arg = static_cast(arg); - grpc_channel_args_destroy(cb_arg->result); - GPR_ASSERT(error == GRPC_ERROR_NONE); +static void on_second_resolution(const grpc_channel_args* result, + OnResolutionCallbackArg* cb_arg) { + grpc_channel_args_destroy(result); gpr_log(GPR_INFO, "2nd: g_resolution_count: %d", g_resolution_count); // The resolution callback was not invoked until new data was // available, which was delayed until after the cooldown period. @@ -197,18 +230,14 @@ static void on_second_resolution(void* arg, grpc_error* error) { g_all_callbacks_invoked = true; } -static void on_first_resolution(void* arg, grpc_error* error) { - OnResolutionCallbackArg* cb_arg = static_cast(arg); - grpc_channel_args_destroy(cb_arg->result); - GPR_ASSERT(error == GRPC_ERROR_NONE); +static void on_first_resolution(const grpc_channel_args* result, + OnResolutionCallbackArg* cb_arg) { + grpc_channel_args_destroy(result); gpr_log(GPR_INFO, "1st: g_resolution_count: %d", g_resolution_count); // There's one initial system-level resolution and one invocation of a // notification callback (the current function). GPR_ASSERT(g_resolution_count == 1); - cb_arg->resolver->NextLocked( - &cb_arg->result, - GRPC_CLOSURE_CREATE(on_second_resolution, arg, - grpc_combiner_scheduler(g_combiner))); + cb_arg->result_handler->SetCallback(on_second_resolution, cb_arg); cb_arg->resolver->RequestReresolutionLocked(); gpr_mu_lock(g_iomgr_args.mu); GRPC_LOG_IF_ERROR("pollset_kick", @@ -220,6 +249,8 @@ static void start_test_under_combiner(void* arg, grpc_error* error) { OnResolutionCallbackArg* res_cb_arg = static_cast(arg); + res_cb_arg->result_handler = grpc_core::New(); + grpc_core::ResolverFactory* factory = grpc_core::ResolverRegistry::LookupResolverFactory("dns"); grpc_uri* uri = grpc_uri_parse(res_cb_arg->uri_str, 0); @@ -229,25 +260,22 @@ static void start_test_under_combiner(void* arg, grpc_error* error) { grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = + grpc_core::UniquePtr( + res_cb_arg->result_handler); g_resolution_count = 0; - grpc_arg cooldown_arg; - cooldown_arg.key = - const_cast(GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS); - cooldown_arg.type = GRPC_ARG_INTEGER; - cooldown_arg.value.integer = kMinResolutionPeriodMs; - auto* cooldown_channel_args = - grpc_channel_args_copy_and_add(nullptr, &cooldown_arg, 1); - args.args = cooldown_channel_args; - res_cb_arg->resolver = factory->CreateResolver(args); - grpc_channel_args_destroy(cooldown_channel_args); + grpc_arg cooldown_arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS), + kMinResolutionPeriodMs); + grpc_channel_args cooldown_args = {1, &cooldown_arg}; + args.args = &cooldown_args; + res_cb_arg->resolver = factory->CreateResolver(std::move(args)); GPR_ASSERT(res_cb_arg->resolver != nullptr); - // First resolution, would incur in system-level resolution. - res_cb_arg->resolver->NextLocked( - &res_cb_arg->result, - GRPC_CLOSURE_CREATE(on_first_resolution, res_cb_arg, - grpc_combiner_scheduler(g_combiner))); grpc_uri_destroy(uri); + // First resolution, would incur in system-level resolution. + res_cb_arg->result_handler->SetCallback(on_first_resolution, res_cb_arg); + res_cb_arg->resolver->StartLocked(); } static void test_cooldown() { diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc index 6f153cc9bf6..ed3b4e66472 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_test.cc @@ -39,8 +39,10 @@ static void test_succeeds(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = + grpc_core::MakeUnique(); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver != nullptr); grpc_uri_destroy(uri); } @@ -55,8 +57,10 @@ static void test_fails(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = + grpc_core::MakeUnique(); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver == nullptr); grpc_uri_destroy(uri); } diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index 3b06fe063ae..9927404fc10 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -33,9 +33,49 @@ #include "test/core/util/test_config.h" +class ResultHandler : public grpc_core::Resolver::ResultHandler { + public: + ~ResultHandler() override { grpc_channel_args_destroy(expected_); } + + void SetExpectedAndEvent(grpc_channel_args* expected, gpr_event* ev) { + GPR_ASSERT(expected_ == nullptr); + GPR_ASSERT(ev_ == nullptr); + expected_ = grpc_channel_args_copy(expected); + ev_ = ev; + } + + void ReturnResult(const grpc_channel_args* args) override { + GPR_ASSERT(expected_ != nullptr); + GPR_ASSERT(ev_ != nullptr); + // We only check the addresses channel arg because that's the only one + // explicitly set by the test via + // FakeResolverResponseGenerator::SetResponse(). + const grpc_core::ServerAddressList* actual_addresses = + grpc_core::FindServerAddressListChannelArg(args); + const grpc_core::ServerAddressList* expected_addresses = + grpc_core::FindServerAddressListChannelArg(expected_); + GPR_ASSERT(actual_addresses->size() == expected_addresses->size()); + for (size_t i = 0; i < expected_addresses->size(); ++i) { + GPR_ASSERT((*actual_addresses)[i] == (*expected_addresses)[i]); + } + grpc_channel_args_destroy(args); + grpc_channel_args_destroy(expected_); + expected_ = nullptr; + gpr_event_set(ev_, (void*)1); + ev_ = nullptr; + } + + void ReturnError(grpc_error* error) override {} + + private: + grpc_channel_args* expected_ = nullptr; + gpr_event* ev_ = nullptr; +}; + static grpc_core::OrphanablePtr build_fake_resolver( grpc_combiner* combiner, - grpc_core::FakeResolverResponseGenerator* response_generator) { + grpc_core::FakeResolverResponseGenerator* response_generator, + grpc_core::UniquePtr result_handler) { grpc_core::ResolverFactory* factory = grpc_core::ResolverRegistry::LookupResolverFactory("fake"); grpc_arg generator_arg = @@ -45,37 +85,12 @@ static grpc_core::OrphanablePtr build_fake_resolver( grpc_core::ResolverArgs args; args.args = &channel_args; args.combiner = combiner; + args.result_handler = std::move(result_handler); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); return resolver; } -typedef struct on_resolution_arg { - grpc_channel_args* resolver_result; - grpc_channel_args* expected_resolver_result; - gpr_event ev; -} on_resolution_arg; - -// Callback to check the resolution result is as expected. -void on_resolution_cb(void* arg, grpc_error* error) { - if (error != GRPC_ERROR_NONE) return; - on_resolution_arg* res = static_cast(arg); - // We only check the addresses channel arg because that's the only one - // explicitly set by the test via - // FakeResolverResponseGenerator::SetResponse(). - const grpc_core::ServerAddressList* actual_addresses = - grpc_core::FindServerAddressListChannelArg(res->resolver_result); - const grpc_core::ServerAddressList* expected_addresses = - grpc_core::FindServerAddressListChannelArg(res->expected_resolver_result); - GPR_ASSERT(actual_addresses->size() == expected_addresses->size()); - for (size_t i = 0; i < expected_addresses->size(); ++i) { - GPR_ASSERT((*actual_addresses)[i] == (*expected_addresses)[i]); - } - grpc_channel_args_destroy(res->resolver_result); - grpc_channel_args_destroy(res->expected_resolver_result); - gpr_event_set(&res->ev, (void*)1); -} - // Create a new resolution containing 2 addresses. static grpc_channel_args* create_new_resolver_result() { static size_t test_counter = 0; @@ -115,110 +130,99 @@ static grpc_channel_args* create_new_resolver_result() { return results; } -static on_resolution_arg create_on_resolution_arg(grpc_channel_args* results) { - on_resolution_arg on_res_arg; - memset(&on_res_arg, 0, sizeof(on_res_arg)); - on_res_arg.expected_resolver_result = results; - gpr_event_init(&on_res_arg.ev); - return on_res_arg; -} - static void test_fake_resolver() { grpc_core::ExecCtx exec_ctx; grpc_combiner* combiner = grpc_combiner_create(); // Create resolver. + ResultHandler* result_handler = grpc_core::New(); grpc_core::RefCountedPtr response_generator = grpc_core::MakeRefCounted(); - grpc_core::OrphanablePtr resolver = - build_fake_resolver(combiner, response_generator.get()); + grpc_core::OrphanablePtr resolver = build_fake_resolver( + combiner, response_generator.get(), + grpc_core::UniquePtr(result_handler)); GPR_ASSERT(resolver.get() != nullptr); + resolver->StartLocked(); // Test 1: normal resolution. // next_results != NULL, reresolution_results == NULL. // Expected response is next_results. + gpr_log(GPR_INFO, "TEST 1"); grpc_channel_args* results = create_new_resolver_result(); - on_resolution_arg on_res_arg = create_on_resolution_arg(results); - grpc_closure* on_resolution = GRPC_CLOSURE_CREATE( - on_resolution_cb, &on_res_arg, grpc_combiner_scheduler(combiner)); - // Resolution won't be triggered until next_results is set. - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + gpr_event ev1; + gpr_event_init(&ev1); + result_handler->SetExpectedAndEvent(results, &ev1); response_generator->SetResponse(results); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); + GPR_ASSERT(gpr_event_wait(&ev1, grpc_timeout_seconds_to_deadline(5)) != + nullptr); + grpc_channel_args_destroy(results); // Test 2: update resolution. // next_results != NULL, reresolution_results == NULL. // Expected response is next_results. + gpr_log(GPR_INFO, "TEST 2"); results = create_new_resolver_result(); - on_res_arg = create_on_resolution_arg(results); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - // Resolution won't be triggered until next_results is set. - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + gpr_event ev2; + gpr_event_init(&ev2); + result_handler->SetExpectedAndEvent(results, &ev2); response_generator->SetResponse(results); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); + GPR_ASSERT(gpr_event_wait(&ev2, grpc_timeout_seconds_to_deadline(5)) != + nullptr); + grpc_channel_args_destroy(results); // Test 3: normal re-resolution. // next_results == NULL, reresolution_results != NULL. // Expected response is reresolution_results. + gpr_log(GPR_INFO, "TEST 3"); grpc_channel_args* reresolution_results = create_new_resolver_result(); - on_res_arg = - create_on_resolution_arg(grpc_channel_args_copy(reresolution_results)); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + gpr_event ev3; + gpr_event_init(&ev3); + result_handler->SetExpectedAndEvent(reresolution_results, &ev3); // Set reresolution_results. + // No result will be returned until re-resolution is requested. response_generator->SetReresolutionResponse(reresolution_results); - // Flush here to guarantee that the response has been set. grpc_core::ExecCtx::Get()->Flush(); // Trigger a re-resolution. resolver->RequestReresolutionLocked(); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); + GPR_ASSERT(gpr_event_wait(&ev3, grpc_timeout_seconds_to_deadline(5)) != + nullptr); // Test 4: repeat re-resolution. // next_results == NULL, reresolution_results != NULL. // Expected response is reresolution_results. - on_res_arg = create_on_resolution_arg(reresolution_results); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + gpr_log(GPR_INFO, "TEST 4"); + gpr_event ev4; + gpr_event_init(&ev4); + result_handler->SetExpectedAndEvent(reresolution_results, &ev4); // Trigger a re-resolution. resolver->RequestReresolutionLocked(); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); + GPR_ASSERT(gpr_event_wait(&ev4, grpc_timeout_seconds_to_deadline(5)) != + nullptr); + grpc_channel_args_destroy(reresolution_results); // Test 5: normal resolution. // next_results != NULL, reresolution_results != NULL. // Expected response is next_results. + gpr_log(GPR_INFO, "TEST 5"); results = create_new_resolver_result(); - on_res_arg = create_on_resolution_arg(results); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - // Resolution won't be triggered until next_results is set. - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); + gpr_event ev5; + gpr_event_init(&ev5); + result_handler->SetExpectedAndEvent(results, &ev5); response_generator->SetResponse(results); grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); + GPR_ASSERT(gpr_event_wait(&ev5, grpc_timeout_seconds_to_deadline(5)) != + nullptr); + grpc_channel_args_destroy(results); // Test 6: no-op. // Requesting a new resolution without setting the response shouldn't trigger // the resolution callback. - memset(&on_res_arg, 0, sizeof(on_res_arg)); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_milliseconds_to_deadline(100)) == + gpr_log(GPR_INFO, "TEST 6"); + gpr_event ev6; + gpr_event_init(&ev6); + result_handler->SetExpectedAndEvent(nullptr, &ev6); + GPR_ASSERT(gpr_event_wait(&ev6, grpc_timeout_milliseconds_to_deadline(100)) == nullptr); // Clean up. - // Note: Need to explicitly unref the resolver and flush the exec_ctx - // to make sure that the final resolver callback (with error set to - // "Resolver Shutdown") is invoked before on_res_arg goes out of scope. resolver.reset(); - grpc_core::ExecCtx::Get()->Flush(); GRPC_COMBINER_UNREF(combiner, "test_fake_resolver"); } diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc index ff7db6046d7..37abe20fe8d 100644 --- a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc +++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc @@ -30,15 +30,14 @@ static grpc_combiner* g_combiner; -typedef struct on_resolution_arg { - char* expected_server_name; - grpc_channel_args* resolver_result; -} on_resolution_arg; +class ResultHandler : public grpc_core::Resolver::ResultHandler { + public: + void ReturnResult(const grpc_channel_args* args) override { + grpc_channel_args_destroy(args); + } -void on_resolution_cb(void* arg, grpc_error* error) { - on_resolution_arg* res = static_cast(arg); - grpc_channel_args_destroy(res->resolver_result); -} + void ReturnError(grpc_error* error) override { GRPC_ERROR_UNREF(error); } +}; static void test_succeeds(grpc_core::ResolverFactory* factory, const char* string) { @@ -50,18 +49,14 @@ static void test_succeeds(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = + grpc_core::UniquePtr( + grpc_core::New()); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver != nullptr); - - on_resolution_arg on_res_arg; - memset(&on_res_arg, 0, sizeof(on_res_arg)); - on_res_arg.expected_server_name = uri->path; - grpc_closure* on_resolution = GRPC_CLOSURE_CREATE( - on_resolution_cb, &on_res_arg, grpc_schedule_on_exec_ctx); - - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); grpc_uri_destroy(uri); + resolver->StartLocked(); /* Flush ExecCtx to avoid stack-use-after-scope on on_res_arg which is * accessed in the closure on_resolution_cb */ grpc_core::ExecCtx::Get()->Flush(); @@ -77,8 +72,11 @@ static void test_fails(grpc_core::ResolverFactory* factory, grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; + args.result_handler = + grpc_core::UniquePtr( + grpc_core::New()); grpc_core::OrphanablePtr resolver = - factory->CreateResolver(args); + factory->CreateResolver(std::move(args)); GPR_ASSERT(resolver == nullptr); grpc_uri_destroy(uri); } diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index 3e789f0b149..74da4380be5 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -160,14 +160,27 @@ void PollPollsetUntilRequestDone(ArgsStruct* args) { } } -void CheckResolverResultAssertFailureLocked(void* arg, grpc_error* error) { - EXPECT_NE(error, GRPC_ERROR_NONE); - ArgsStruct* args = static_cast(arg); - gpr_atm_rel_store(&args->done_atm, 1); - gpr_mu_lock(args->mu); - GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); - gpr_mu_unlock(args->mu); -} +class AssertFailureResultHandler : public grpc_core::Resolver::ResultHandler { + public: + explicit AssertFailureResultHandler(ArgsStruct* args) : args_(args) {} + + ~AssertFailureResultHandler() override { + gpr_atm_rel_store(&args_->done_atm, 1); + gpr_mu_lock(args_->mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(args_->pollset, nullptr)); + gpr_mu_unlock(args_->mu); + } + + void ReturnResult(const grpc_channel_args* args) override { + GPR_ASSERT(false); + } + + void ReturnError(grpc_error* error) override { GPR_ASSERT(false); } + + private: + ArgsStruct* args_; +}; void TestCancelActiveDNSQuery(ArgsStruct* args) { int fake_dns_port = grpc_pick_unused_port_or_die(); @@ -180,13 +193,11 @@ void TestCancelActiveDNSQuery(ArgsStruct* args) { // create resolver and resolve grpc_core::OrphanablePtr resolver = grpc_core::ResolverRegistry::CreateResolver( - client_target, nullptr, args->pollset_set, args->lock); + client_target, nullptr, args->pollset_set, args->lock, + grpc_core::UniquePtr( + grpc_core::New(args))); gpr_free(client_target); - grpc_closure on_resolver_result_changed; - GRPC_CLOSURE_INIT(&on_resolver_result_changed, - CheckResolverResultAssertFailureLocked, (void*)args, - grpc_combiner_scheduler(args->lock)); - resolver->NextLocked(&args->channel_args, &on_resolver_result_changed); + resolver->StartLocked(); // Without resetting and causing resolver shutdown, the // PollPollsetUntilRequestDone call should never finish. resolver.reset(); diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 9532529e45d..abf27cdd058 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -239,7 +239,7 @@ void PollPollsetUntilRequestDone(ArgsStruct* args) { gpr_event_set(&args->ev, (void*)1); } -void CheckServiceConfigResultLocked(grpc_channel_args* channel_args, +void CheckServiceConfigResultLocked(const grpc_channel_args* channel_args, ArgsStruct* args) { const grpc_arg* service_config_arg = grpc_channel_args_find(channel_args, GRPC_ARG_SERVICE_CONFIG); @@ -253,7 +253,7 @@ void CheckServiceConfigResultLocked(grpc_channel_args* channel_args, } } -void CheckLBPolicyResultLocked(grpc_channel_args* channel_args, +void CheckLBPolicyResultLocked(const grpc_channel_args* channel_args, ArgsStruct* args) { const grpc_arg* lb_policy_arg = grpc_channel_args_find(channel_args, GRPC_ARG_LB_POLICY_NAME); @@ -394,54 +394,86 @@ void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) { } #endif -void CheckResolverResultLocked(void* argsp, grpc_error* err) { - EXPECT_EQ(err, GRPC_ERROR_NONE); - ArgsStruct* args = (ArgsStruct*)argsp; - grpc_channel_args* channel_args = args->channel_args; - grpc_core::ServerAddressList* addresses = - grpc_core::FindServerAddressListChannelArg(channel_args); - gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR, - addresses->size(), args->expected_addrs.size()); - GPR_ASSERT(addresses->size() == args->expected_addrs.size()); - std::vector found_lb_addrs; - for (size_t i = 0; i < addresses->size(); i++) { - grpc_core::ServerAddress& addr = (*addresses)[i]; - char* str; - grpc_sockaddr_to_string(&str, &addr.address(), 1 /* normalize */); - gpr_log(GPR_INFO, "%s", str); - found_lb_addrs.emplace_back( - GrpcLBAddress(std::string(str), addr.IsBalancer())); - gpr_free(str); +class ResultHandler : public grpc_core::Resolver::ResultHandler { + public: + static grpc_core::UniquePtr Create( + ArgsStruct* args) { + return grpc_core::UniquePtr( + grpc_core::New(args)); } - if (args->expected_addrs.size() != found_lb_addrs.size()) { - gpr_log(GPR_DEBUG, - "found lb addrs size is: %" PRIdPTR - ". expected addrs size is %" PRIdPTR, - found_lb_addrs.size(), args->expected_addrs.size()); - abort(); - } - EXPECT_THAT(args->expected_addrs, UnorderedElementsAreArray(found_lb_addrs)); - CheckServiceConfigResultLocked(channel_args, args); - if (args->expected_service_config_string == "") { - CheckLBPolicyResultLocked(channel_args, args); - } - gpr_atm_rel_store(&args->done_atm, 1); - gpr_mu_lock(args->mu); - GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); - gpr_mu_unlock(args->mu); -} -void CheckResolvedWithoutErrorLocked(void* argsp, grpc_error* err) { - EXPECT_EQ(err, GRPC_ERROR_NONE); - ArgsStruct* args = (ArgsStruct*)argsp; - gpr_atm_rel_store(&args->done_atm, 1); - gpr_mu_lock(args->mu); - GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr)); - gpr_mu_unlock(args->mu); -} + explicit ResultHandler(ArgsStruct* args) : args_(args) {} -void RunResolvesRelevantRecordsTest(void (*OnDoneLocked)(void* arg, - grpc_error* error)) { + void ReturnResult(const grpc_channel_args* result) override { + CheckResult(result); + gpr_atm_rel_store(&args_->done_atm, 1); + gpr_mu_lock(args_->mu); + GRPC_LOG_IF_ERROR("pollset_kick", + grpc_pollset_kick(args_->pollset, nullptr)); + gpr_mu_unlock(args_->mu); + grpc_channel_args_destroy(result); + } + + void ReturnError(grpc_error* error) override { + gpr_log(GPR_ERROR, "resolver returned error: %s", grpc_error_string(error)); + GPR_ASSERT(false); + } + + virtual void CheckResult(const grpc_channel_args* channel_args) {} + + protected: + ArgsStruct* args_struct() const { return args_; } + + private: + ArgsStruct* args_; +}; + +class CheckingResultHandler : public ResultHandler { + public: + static grpc_core::UniquePtr Create( + ArgsStruct* args) { + return grpc_core::UniquePtr( + grpc_core::New(args)); + } + + explicit CheckingResultHandler(ArgsStruct* args) : ResultHandler(args) {} + + void CheckResult(const grpc_channel_args* channel_args) override { + ArgsStruct* args = args_struct(); + grpc_core::ServerAddressList* addresses = + grpc_core::FindServerAddressListChannelArg(channel_args); + gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR, + addresses->size(), args->expected_addrs.size()); + GPR_ASSERT(addresses->size() == args->expected_addrs.size()); + std::vector found_lb_addrs; + for (size_t i = 0; i < addresses->size(); i++) { + grpc_core::ServerAddress& addr = (*addresses)[i]; + char* str; + grpc_sockaddr_to_string(&str, &addr.address(), 1 /* normalize */); + gpr_log(GPR_INFO, "%s", str); + found_lb_addrs.emplace_back( + GrpcLBAddress(std::string(str), addr.IsBalancer())); + gpr_free(str); + } + if (args->expected_addrs.size() != found_lb_addrs.size()) { + gpr_log(GPR_DEBUG, + "found lb addrs size is: %" PRIdPTR + ". expected addrs size is %" PRIdPTR, + found_lb_addrs.size(), args->expected_addrs.size()); + abort(); + } + EXPECT_THAT(args->expected_addrs, + UnorderedElementsAreArray(found_lb_addrs)); + CheckServiceConfigResultLocked(channel_args, args); + if (args->expected_service_config_string == "") { + CheckLBPolicyResultLocked(channel_args, args); + } + } +}; + +void RunResolvesRelevantRecordsTest( + grpc_core::UniquePtr ( + *CreateResultHandler)(ArgsStruct* args)) { grpc_core::ExecCtx exec_ctx; ArgsStruct args; ArgsInit(&args); @@ -491,20 +523,18 @@ void RunResolvesRelevantRecordsTest(void (*OnDoneLocked)(void* arg, // create resolver and resolve grpc_core::OrphanablePtr resolver = grpc_core::ResolverRegistry::CreateResolver(whole_uri, resolver_args, - args.pollset_set, args.lock); + args.pollset_set, args.lock, + CreateResultHandler(&args)); grpc_channel_args_destroy(resolver_args); gpr_free(whole_uri); - grpc_closure on_resolver_result_changed; - GRPC_CLOSURE_INIT(&on_resolver_result_changed, OnDoneLocked, (void*)&args, - grpc_combiner_scheduler(args.lock)); - resolver->NextLocked(&args.channel_args, &on_resolver_result_changed); + resolver->StartLocked(); grpc_core::ExecCtx::Get()->Flush(); PollPollsetUntilRequestDone(&args); ArgsFinish(&args); } TEST(ResolverComponentTest, TestResolvesRelevantRecords) { - RunResolvesRelevantRecordsTest(CheckResolverResultLocked); + RunResolvesRelevantRecordsTest(CheckingResultHandler::Create); } TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) { @@ -515,7 +545,7 @@ TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) { std::thread socket_stress_thread(OpenAndCloseSocketsStressLoop, dummy_port, &done_ev); // Run the resolver test - RunResolvesRelevantRecordsTest(CheckResolvedWithoutErrorLocked); + RunResolvesRelevantRecordsTest(ResultHandler::Create); // Shutdown and join stress thread gpr_event_set(&done_ev, (void*)1); socket_stress_thread.join(); From 64b29fba5de6cd49183e9b486174623744c5890d Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 13 Mar 2019 09:58:54 -0700 Subject: [PATCH 680/814] An attempt to fix distrib test --- test/distrib/python/test_packages.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/distrib/python/test_packages.sh b/test/distrib/python/test_packages.sh index 4e1e6dbc94f..0ed6a2965e6 100755 --- a/test/distrib/python/test_packages.sh +++ b/test/distrib/python/test_packages.sh @@ -37,7 +37,7 @@ TESTING_ARCHIVES=("$EXTERNAL_GIT_ROOT"/input_artifacts/grpcio-testing-[0-9]*.tar VIRTUAL_ENV=$(mktemp -d) virtualenv "$VIRTUAL_ENV" PYTHON=$VIRTUAL_ENV/bin/python -"$PYTHON" -m pip install --upgrade six pip +"$PYTHON" -m pip install --upgrade six pip wheel function validate_wheel_hashes() { for file in "$@"; do From 33dbbb98d8728b334326b2e4ea5bdb2b43eefd70 Mon Sep 17 00:00:00 2001 From: John Luo Date: Wed, 13 Mar 2019 11:13:48 -0700 Subject: [PATCH 681/814] Update tools to ensure error details appear in VS --- src/csharp/Grpc.Tools/ProtoCompile.cs | 1 + .../Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets | 1 + 2 files changed, 2 insertions(+) diff --git a/src/csharp/Grpc.Tools/ProtoCompile.cs b/src/csharp/Grpc.Tools/ProtoCompile.cs index 93608e1ac02..f6964205d2b 100644 --- a/src/csharp/Grpc.Tools/ProtoCompile.cs +++ b/src/csharp/Grpc.Tools/ProtoCompile.cs @@ -322,6 +322,7 @@ namespace Grpc.Tools { cmd.AddArg(proto.ItemSpec); } + cmd.AddSwitchMaybe("error_format", "msvs"); return cmd.ToString(); } diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets index 26f9efb5a84..1fa6ca1eb36 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -271,6 +271,7 @@ GrpcPluginExe="%(_Protobuf_OutOfDateProto.GrpcPluginExe)" GrpcOutputDir="%(_Protobuf_OutOfDateProto.GrpcOutputDir)" GrpcOutputOptions="%(_Protobuf_OutOfDateProto._GrpcOutputOptions)" + LogStandardErrorAsError="true" > From f42ad52c44f5d06b3418676611d5758e5061f3d5 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 13 Mar 2019 12:40:10 -0700 Subject: [PATCH 682/814] Update `--dest-dir` to `-d` --- test/distrib/python/test_packages.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/distrib/python/test_packages.sh b/test/distrib/python/test_packages.sh index 0ed6a2965e6..e9f494310d6 100755 --- a/test/distrib/python/test_packages.sh +++ b/test/distrib/python/test_packages.sh @@ -41,7 +41,7 @@ PYTHON=$VIRTUAL_ENV/bin/python function validate_wheel_hashes() { for file in "$@"; do - "$PYTHON" -m wheel unpack "$file" --dest-dir /tmp || return 1 + "$PYTHON" -m wheel unpack "$file" -d /tmp || return 1 done return 0 } From 319fcdf26ed46fd244521552645d33e17e65ef88 Mon Sep 17 00:00:00 2001 From: Vishal Powar Date: Fri, 1 Mar 2019 13:30:14 -0800 Subject: [PATCH 683/814] Add a script for generating C code and build rule for protobuf protos. All these changes need to go together to make sense - changes to use new version of upb in bazel - allowing includes in build target option - script for generating c code (upb) for protos - generated code for example protos - adding changes for non-bazel builds - change sanity tests to ignore the generated files. --- BUILD | 25 + CMakeLists.txt | 52 + Makefile | 37 +- bazel/grpc_build_system.bzl | 1 + bazel/grpc_deps.bzl | 6 +- build.yaml | 3 + grpc.gyp | 18 + .../upb-generated/google/protobuf/any.upb.c | 27 + .../upb-generated/google/protobuf/any.upb.h | 59 + .../google/protobuf/descriptor.upb.c | 485 +++++ .../google/protobuf/descriptor.upb.h | 1691 +++++++++++++++++ .../google/protobuf/duration.upb.c | 27 + .../google/protobuf/duration.upb.h | 59 + .../google/protobuf/struct.upb.c | 79 + .../google/protobuf/struct.upb.h | 216 +++ .../google/protobuf/timestamp.upb.c | 27 + .../google/protobuf/timestamp.upb.h | 59 + .../google/protobuf/wrappers.upb.c | 106 ++ .../google/protobuf/wrappers.upb.h | 239 +++ src/upb/gen_build_yaml.py | 66 + third_party/upb | 2 +- tools/buildgen/generate_build_additions.sh | 1 + tools/codegen/core/gen_upb_api.sh | 38 + tools/distrib/check_copyright.py | 14 + tools/distrib/check_include_guards.py | 14 + .../clang_format_all_the_things.sh | 2 +- .../generated/sources_and_headers.json | 20 + tools/run_tests/sanity/check_port_platform.py | 3 + tools/run_tests/sanity/check_submodules.sh | 2 +- 29 files changed, 3371 insertions(+), 7 deletions(-) create mode 100644 src/core/ext/upb-generated/google/protobuf/any.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/any.upb.h create mode 100644 src/core/ext/upb-generated/google/protobuf/descriptor.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/descriptor.upb.h create mode 100644 src/core/ext/upb-generated/google/protobuf/duration.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/duration.upb.h create mode 100644 src/core/ext/upb-generated/google/protobuf/struct.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/struct.upb.h create mode 100644 src/core/ext/upb-generated/google/protobuf/timestamp.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/timestamp.upb.h create mode 100644 src/core/ext/upb-generated/google/protobuf/wrappers.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/wrappers.upb.h create mode 100755 src/upb/gen_build_yaml.py create mode 100755 tools/codegen/core/gen_upb_api.sh diff --git a/BUILD b/BUILD index 4bf387cec3a..0b6fff354f4 100644 --- a/BUILD +++ b/BUILD @@ -2308,4 +2308,29 @@ grpc_cc_library( ], ) +#TODO: Get this into build.yaml once we start using it. +grpc_cc_library( + name = "google_protobuf_upb", + srcs = [ + "src/core/ext/upb-generated/google/protobuf/any.upb.c", + "src/core/ext/upb-generated/google/protobuf/descriptor.upb.c", + "src/core/ext/upb-generated/google/protobuf/duration.upb.c", + "src/core/ext/upb-generated/google/protobuf/struct.upb.c", + "src/core/ext/upb-generated/google/protobuf/timestamp.upb.c", + "src/core/ext/upb-generated/google/protobuf/wrappers.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/google/protobuf/any.upb.h", + "src/core/ext/upb-generated/google/protobuf/descriptor.upb.h", + "src/core/ext/upb-generated/google/protobuf/duration.upb.h", + "src/core/ext/upb-generated/google/protobuf/struct.upb.h", + "src/core/ext/upb-generated/google/protobuf/timestamp.upb.h", + "src/core/ext/upb-generated/google/protobuf/wrappers.upb.h", + ], + language = "c++", + external_deps = [ + "upb_lib", + ], +) + grpc_generate_one_off_targets() diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ccda85b125..b7c770ccd24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5494,6 +5494,58 @@ endif() endif (gRPC_BUILD_CSHARP_EXT) if (gRPC_BUILD_TESTS) +add_library(upb + third_party/upb/google/protobuf/descriptor.upb.c + third_party/upb/upb/decode.c + third_party/upb/upb/def.c + third_party/upb/upb/encode.c + third_party/upb/upb/handlers.c + third_party/upb/upb/msg.c + third_party/upb/upb/msgfactory.c + third_party/upb/upb/sink.c + third_party/upb/upb/table.c + third_party/upb/upb/upb.c +) + +if(WIN32 AND MSVC) + set_target_properties(upb PROPERTIES COMPILE_PDB_NAME "upb" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + if (gRPC_INSTALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/upb.pdb + DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL + ) + endif() +endif() + + +target_include_directories(upb + PUBLIC $ $ + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(upb PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(upb PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() +target_link_libraries(upb + ${_gRPC_SSL_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_library(bad_client_test test/core/bad_client/bad_client.cc ) diff --git a/Makefile b/Makefile index 91516de9a27..5a31d648b32 100644 --- a/Makefile +++ b/Makefile @@ -1443,7 +1443,7 @@ plugins: $(PROTOC_PLUGINS) privatelibs: privatelibs_c privatelibs_cxx -privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a +privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libupb.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc @@ -10188,6 +10188,41 @@ ifneq ($(NO_DEPS),true) endif +LIBUPB_SRC = \ + third_party/upb/google/protobuf/descriptor.upb.c \ + third_party/upb/upb/decode.c \ + third_party/upb/upb/def.c \ + third_party/upb/upb/encode.c \ + third_party/upb/upb/handlers.c \ + third_party/upb/upb/msg.c \ + third_party/upb/upb/msgfactory.c \ + third_party/upb/upb/sink.c \ + third_party/upb/upb/table.c \ + third_party/upb/upb/upb.c \ + +PUBLIC_HEADERS_C += \ + +LIBUPB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBUPB_SRC)))) + +$(LIBUPB_OBJS): CFLAGS += -Ithird_party/upb -Wno-sign-conversion -Wno-shadow -Wno-conversion -Wno-implicit-fallthrough -Wno-sign-compare -Wno-missing-field-initializers + +$(LIBDIR)/$(CONFIG)/libupb.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(LIBUPB_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libupb.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libupb.a $(LIBUPB_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libupb.a +endif + + + + +ifneq ($(NO_DEPS),true) +-include $(LIBUPB_OBJS:.o=.dep) +endif + + LIBZ_SRC = \ third_party/zlib/adler32.c \ third_party/zlib/compress.c \ diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 513efac7509..59e9c46e0a3 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -120,6 +120,7 @@ def grpc_cc_library( linkopts = linkopts, includes = [ "include", + "src/core/ext/upb-generated", ], alwayslink = alwayslink, data = data, diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index d97e8368ed7..9b6aaacbd58 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -12,7 +12,7 @@ def grpc_deps(): ) native.bind( - name = "upblib", + name = "upb_lib", actual = "@upb//:upb", ) @@ -202,8 +202,8 @@ def grpc_deps(): if "upb" not in native.existing_rules(): http_archive( name = "upb", - strip_prefix = "upb-9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3", - url = "https://github.com/google/upb/archive/9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3.tar.gz", + strip_prefix = "upb-ed9faae0993704b033c594b072d65e1bf19207fa", + url = "https://github.com/google/upb/archive/ed9faae0993704b033c594b072d65e1bf19207fa.tar.gz", ) # TODO: move some dependencies from "grpc_deps" here? diff --git a/build.yaml b/build.yaml index 02ecaa221e6..d8322b176b7 100644 --- a/build.yaml +++ b/build.yaml @@ -5837,6 +5837,9 @@ defaults: -Wno-deprecated-declarations -Ithird_party/nanopb -DPB_FIELD_32BIT CXXFLAGS: -Wnon-virtual-dtor LDFLAGS: -g + upb: + CFLAGS: -Ithird_party/upb -Wno-sign-conversion -Wno-shadow -Wno-conversion -Wno-implicit-fallthrough + -Wno-sign-compare -Wno-missing-field-initializers zlib: CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration -Wno-implicit-fallthrough $(W_NO_SHIFT_NEGATIVE_VALUE) -fvisibility=hidden diff --git a/grpc.gyp b/grpc.gyp index 94a9cd2cfb8..cce9f738fbd 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -2639,6 +2639,24 @@ 'third_party/benchmark/src/timers.cc', ], }, + { + 'target_name': 'upb', + 'type': 'static_library', + 'dependencies': [ + ], + 'sources': [ + 'third_party/upb/google/protobuf/descriptor.upb.c', + 'third_party/upb/upb/decode.c', + 'third_party/upb/upb/def.c', + 'third_party/upb/upb/encode.c', + 'third_party/upb/upb/handlers.c', + 'third_party/upb/upb/msg.c', + 'third_party/upb/upb/msgfactory.c', + 'third_party/upb/upb/sink.c', + 'third_party/upb/upb/table.c', + 'third_party/upb/upb/upb.c', + ], + }, { 'target_name': 'z', 'type': 'static_library', diff --git a/src/core/ext/upb-generated/google/protobuf/any.upb.c b/src/core/ext/upb-generated/google/protobuf/any.upb.c new file mode 100644 index 00000000000..14badf797c1 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/any.upb.c @@ -0,0 +1,27 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/any.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/any.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_Any__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 12, 1}, +}; + +const upb_msglayout google_protobuf_Any_msginit = { + NULL, + &google_protobuf_Any__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/any.upb.h b/src/core/ext/upb-generated/google/protobuf/any.upb.h new file mode 100644 index 00000000000..386916c7ca8 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/any.upb.h @@ -0,0 +1,59 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/any.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_Any; +typedef struct google_protobuf_Any google_protobuf_Any; +extern const upb_msglayout google_protobuf_Any_msginit; + +/* Enums */ + +/* google.protobuf.Any */ + +UPB_INLINE google_protobuf_Any *google_protobuf_Any_new(upb_arena *arena) { + return (google_protobuf_Any *)upb_msg_new(&google_protobuf_Any_msginit, arena); +} +UPB_INLINE google_protobuf_Any *google_protobuf_Any_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Any *ret = google_protobuf_Any_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Any_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Any_serialize(const google_protobuf_Any *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Any_msginit, arena, len); +} + +UPB_INLINE upb_strview google_protobuf_Any_type_url(const google_protobuf_Any *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview google_protobuf_Any_value(const google_protobuf_Any *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } + +UPB_INLINE void google_protobuf_Any_set_type_url(google_protobuf_Any *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Any_set_value(google_protobuf_Any *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c new file mode 100644 index 00000000000..61b9299bb43 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c @@ -0,0 +1,485 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/descriptor.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] = { + &google_protobuf_FileDescriptorProto_msginit, +}; + +static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FileDescriptorSet_msginit = { + &google_protobuf_FileDescriptorSet_submsgs[0], + &google_protobuf_FileDescriptorSet__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = { + &google_protobuf_DescriptorProto_msginit, + &google_protobuf_EnumDescriptorProto_msginit, + &google_protobuf_FieldDescriptorProto_msginit, + &google_protobuf_FileOptions_msginit, + &google_protobuf_ServiceDescriptorProto_msginit, + &google_protobuf_SourceCodeInfo_msginit, +}; + +static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = { + {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {2, UPB_SIZE(12, 24), 2, 0, 9, 1}, + {3, UPB_SIZE(36, 72), 0, 0, 9, 3}, + {4, UPB_SIZE(40, 80), 0, 0, 11, 3}, + {5, UPB_SIZE(44, 88), 0, 1, 11, 3}, + {6, UPB_SIZE(48, 96), 0, 4, 11, 3}, + {7, UPB_SIZE(52, 104), 0, 2, 11, 3}, + {8, UPB_SIZE(28, 56), 4, 3, 11, 1}, + {9, UPB_SIZE(32, 64), 5, 5, 11, 1}, + {10, UPB_SIZE(56, 112), 0, 0, 5, 3}, + {11, UPB_SIZE(60, 120), 0, 0, 5, 3}, + {12, UPB_SIZE(20, 40), 3, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_FileDescriptorProto_msginit = { + &google_protobuf_FileDescriptorProto_submsgs[0], + &google_protobuf_FileDescriptorProto__fields[0], + UPB_SIZE(64, 128), 12, false, +}; + +static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8] = { + &google_protobuf_DescriptorProto_msginit, + &google_protobuf_DescriptorProto_ExtensionRange_msginit, + &google_protobuf_DescriptorProto_ReservedRange_msginit, + &google_protobuf_EnumDescriptorProto_msginit, + &google_protobuf_FieldDescriptorProto_msginit, + &google_protobuf_MessageOptions_msginit, + &google_protobuf_OneofDescriptorProto_msginit, +}; + +static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = { + {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 0, 4, 11, 3}, + {3, UPB_SIZE(20, 40), 0, 0, 11, 3}, + {4, UPB_SIZE(24, 48), 0, 3, 11, 3}, + {5, UPB_SIZE(28, 56), 0, 1, 11, 3}, + {6, UPB_SIZE(32, 64), 0, 4, 11, 3}, + {7, UPB_SIZE(12, 24), 2, 5, 11, 1}, + {8, UPB_SIZE(36, 72), 0, 6, 11, 3}, + {9, UPB_SIZE(40, 80), 0, 2, 11, 3}, + {10, UPB_SIZE(44, 88), 0, 0, 9, 3}, +}; + +const upb_msglayout google_protobuf_DescriptorProto_msginit = { + &google_protobuf_DescriptorProto_submsgs[0], + &google_protobuf_DescriptorProto__fields[0], + UPB_SIZE(48, 96), 10, false, +}; + +static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = { + &google_protobuf_ExtensionRangeOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, + {3, UPB_SIZE(12, 16), 3, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = { + &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0], + &google_protobuf_DescriptorProto_ExtensionRange__fields[0], + UPB_SIZE(16, 24), 3, false, +}; + +static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = { + NULL, + &google_protobuf_DescriptorProto_ReservedRange__fields[0], + UPB_SIZE(12, 12), 2, false, +}; + +static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = { + {999, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = { + &google_protobuf_ExtensionRangeOptions_submsgs[0], + &google_protobuf_ExtensionRangeOptions__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = { + &google_protobuf_FieldOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[10] = { + {1, UPB_SIZE(32, 32), 5, 0, 9, 1}, + {2, UPB_SIZE(40, 48), 6, 0, 9, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 5, 1}, + {4, UPB_SIZE(8, 8), 1, 0, 14, 1}, + {5, UPB_SIZE(16, 16), 2, 0, 14, 1}, + {6, UPB_SIZE(48, 64), 7, 0, 9, 1}, + {7, UPB_SIZE(56, 80), 8, 0, 9, 1}, + {8, UPB_SIZE(72, 112), 10, 0, 11, 1}, + {9, UPB_SIZE(28, 28), 4, 0, 5, 1}, + {10, UPB_SIZE(64, 96), 9, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { + &google_protobuf_FieldDescriptorProto_submsgs[0], + &google_protobuf_FieldDescriptorProto__fields[0], + UPB_SIZE(80, 128), 10, false, +}; + +static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = { + &google_protobuf_OneofOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = { + {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {2, UPB_SIZE(12, 24), 2, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = { + &google_protobuf_OneofDescriptorProto_submsgs[0], + &google_protobuf_OneofDescriptorProto__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = { + &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, + &google_protobuf_EnumOptions_msginit, + &google_protobuf_EnumValueDescriptorProto_msginit, +}; + +static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = { + {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 0, 2, 11, 3}, + {3, UPB_SIZE(12, 24), 2, 1, 11, 1}, + {4, UPB_SIZE(20, 40), 0, 0, 11, 3}, + {5, UPB_SIZE(24, 48), 0, 0, 9, 3}, +}; + +const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = { + &google_protobuf_EnumDescriptorProto_submsgs[0], + &google_protobuf_EnumDescriptorProto__fields[0], + UPB_SIZE(32, 64), 5, false, +}; + +static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = { + NULL, + &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0], + UPB_SIZE(12, 12), 2, false, +}; + +static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = { + &google_protobuf_EnumValueOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = { + {1, UPB_SIZE(8, 8), 2, 0, 9, 1}, + {2, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {3, UPB_SIZE(16, 24), 3, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = { + &google_protobuf_EnumValueDescriptorProto_submsgs[0], + &google_protobuf_EnumValueDescriptorProto__fields[0], + UPB_SIZE(24, 32), 3, false, +}; + +static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = { + &google_protobuf_MethodDescriptorProto_msginit, + &google_protobuf_ServiceOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = { + {1, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 0, 0, 11, 3}, + {3, UPB_SIZE(12, 24), 2, 1, 11, 1}, +}; + +const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = { + &google_protobuf_ServiceDescriptorProto_submsgs[0], + &google_protobuf_ServiceDescriptorProto__fields[0], + UPB_SIZE(24, 48), 3, false, +}; + +static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = { + &google_protobuf_MethodOptions_msginit, +}; + +static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = { + {1, UPB_SIZE(4, 8), 3, 0, 9, 1}, + {2, UPB_SIZE(12, 24), 4, 0, 9, 1}, + {3, UPB_SIZE(20, 40), 5, 0, 9, 1}, + {4, UPB_SIZE(28, 56), 6, 0, 11, 1}, + {5, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {6, UPB_SIZE(2, 2), 2, 0, 8, 1}, +}; + +const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = { + &google_protobuf_MethodDescriptorProto_submsgs[0], + &google_protobuf_MethodDescriptorProto__fields[0], + UPB_SIZE(32, 64), 6, false, +}; + +static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = { + {1, UPB_SIZE(28, 32), 11, 0, 9, 1}, + {8, UPB_SIZE(36, 48), 12, 0, 9, 1}, + {9, UPB_SIZE(8, 8), 1, 0, 14, 1}, + {10, UPB_SIZE(16, 16), 2, 0, 8, 1}, + {11, UPB_SIZE(44, 64), 13, 0, 9, 1}, + {16, UPB_SIZE(17, 17), 3, 0, 8, 1}, + {17, UPB_SIZE(18, 18), 4, 0, 8, 1}, + {18, UPB_SIZE(19, 19), 5, 0, 8, 1}, + {20, UPB_SIZE(20, 20), 6, 0, 8, 1}, + {23, UPB_SIZE(21, 21), 7, 0, 8, 1}, + {27, UPB_SIZE(22, 22), 8, 0, 8, 1}, + {31, UPB_SIZE(23, 23), 9, 0, 8, 1}, + {36, UPB_SIZE(52, 80), 14, 0, 9, 1}, + {37, UPB_SIZE(60, 96), 15, 0, 9, 1}, + {39, UPB_SIZE(68, 112), 16, 0, 9, 1}, + {40, UPB_SIZE(76, 128), 17, 0, 9, 1}, + {41, UPB_SIZE(84, 144), 18, 0, 9, 1}, + {42, UPB_SIZE(24, 24), 10, 0, 8, 1}, + {44, UPB_SIZE(92, 160), 19, 0, 9, 1}, + {45, UPB_SIZE(100, 176), 20, 0, 9, 1}, + {999, UPB_SIZE(108, 192), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FileOptions_msginit = { + &google_protobuf_FileOptions_submsgs[0], + &google_protobuf_FileOptions__fields[0], + UPB_SIZE(112, 208), 21, false, +}; + +static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {2, UPB_SIZE(2, 2), 2, 0, 8, 1}, + {3, UPB_SIZE(3, 3), 3, 0, 8, 1}, + {7, UPB_SIZE(4, 4), 4, 0, 8, 1}, + {999, UPB_SIZE(8, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_MessageOptions_msginit = { + &google_protobuf_MessageOptions_submsgs[0], + &google_protobuf_MessageOptions__fields[0], + UPB_SIZE(12, 16), 5, false, +}; + +static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 14, 1}, + {2, UPB_SIZE(24, 24), 3, 0, 8, 1}, + {3, UPB_SIZE(25, 25), 4, 0, 8, 1}, + {5, UPB_SIZE(26, 26), 5, 0, 8, 1}, + {6, UPB_SIZE(16, 16), 2, 0, 14, 1}, + {10, UPB_SIZE(27, 27), 6, 0, 8, 1}, + {999, UPB_SIZE(28, 32), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FieldOptions_msginit = { + &google_protobuf_FieldOptions_submsgs[0], + &google_protobuf_FieldOptions__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = { + {999, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_OneofOptions_msginit = { + &google_protobuf_OneofOptions_submsgs[0], + &google_protobuf_OneofOptions__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = { + {2, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {3, UPB_SIZE(2, 2), 2, 0, 8, 1}, + {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_EnumOptions_msginit = { + &google_protobuf_EnumOptions_submsgs[0], + &google_protobuf_EnumOptions__fields[0], + UPB_SIZE(8, 16), 3, false, +}; + +static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_EnumValueOptions_msginit = { + &google_protobuf_EnumValueOptions_submsgs[0], + &google_protobuf_EnumValueOptions__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = { + {33, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {999, UPB_SIZE(4, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_ServiceOptions_msginit = { + &google_protobuf_ServiceOptions_submsgs[0], + &google_protobuf_ServiceOptions__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = { + &google_protobuf_UninterpretedOption_msginit, +}; + +static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = { + {33, UPB_SIZE(16, 16), 2, 0, 8, 1}, + {34, UPB_SIZE(8, 8), 1, 0, 14, 1}, + {999, UPB_SIZE(20, 24), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_MethodOptions_msginit = { + &google_protobuf_MethodOptions_submsgs[0], + &google_protobuf_MethodOptions__fields[0], + UPB_SIZE(24, 32), 3, false, +}; + +static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = { + &google_protobuf_UninterpretedOption_NamePart_msginit, +}; + +static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = { + {2, UPB_SIZE(56, 80), 0, 0, 11, 3}, + {3, UPB_SIZE(32, 32), 4, 0, 9, 1}, + {4, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {5, UPB_SIZE(16, 16), 2, 0, 3, 1}, + {6, UPB_SIZE(24, 24), 3, 0, 1, 1}, + {7, UPB_SIZE(40, 48), 5, 0, 12, 1}, + {8, UPB_SIZE(48, 64), 6, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_UninterpretedOption_msginit = { + &google_protobuf_UninterpretedOption_submsgs[0], + &google_protobuf_UninterpretedOption__fields[0], + UPB_SIZE(64, 96), 7, false, +}; + +static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = { + {1, UPB_SIZE(4, 8), 2, 0, 9, 2}, + {2, UPB_SIZE(1, 1), 1, 0, 8, 2}, +}; + +const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = { + NULL, + &google_protobuf_UninterpretedOption_NamePart__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = { + &google_protobuf_SourceCodeInfo_Location_msginit, +}; + +static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_SourceCodeInfo_msginit = { + &google_protobuf_SourceCodeInfo_submsgs[0], + &google_protobuf_SourceCodeInfo__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = { + {1, UPB_SIZE(20, 40), 0, 0, 5, 3}, + {2, UPB_SIZE(24, 48), 0, 0, 5, 3}, + {3, UPB_SIZE(4, 8), 1, 0, 9, 1}, + {4, UPB_SIZE(12, 24), 2, 0, 9, 1}, + {6, UPB_SIZE(28, 56), 0, 0, 9, 3}, +}; + +const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = { + NULL, + &google_protobuf_SourceCodeInfo_Location__fields[0], + UPB_SIZE(32, 64), 5, false, +}; + +static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = { + &google_protobuf_GeneratedCodeInfo_Annotation_msginit, +}; + +static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = { + &google_protobuf_GeneratedCodeInfo_submsgs[0], + &google_protobuf_GeneratedCodeInfo__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = { + {1, UPB_SIZE(20, 32), 0, 0, 5, 3}, + {2, UPB_SIZE(12, 16), 3, 0, 9, 1}, + {3, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {4, UPB_SIZE(8, 8), 2, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = { + NULL, + &google_protobuf_GeneratedCodeInfo_Annotation__fields[0], + UPB_SIZE(24, 48), 4, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h new file mode 100644 index 00000000000..89e24a6c976 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h @@ -0,0 +1,1691 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_FileDescriptorSet; +struct google_protobuf_FileDescriptorProto; +struct google_protobuf_DescriptorProto; +struct google_protobuf_DescriptorProto_ExtensionRange; +struct google_protobuf_DescriptorProto_ReservedRange; +struct google_protobuf_ExtensionRangeOptions; +struct google_protobuf_FieldDescriptorProto; +struct google_protobuf_OneofDescriptorProto; +struct google_protobuf_EnumDescriptorProto; +struct google_protobuf_EnumDescriptorProto_EnumReservedRange; +struct google_protobuf_EnumValueDescriptorProto; +struct google_protobuf_ServiceDescriptorProto; +struct google_protobuf_MethodDescriptorProto; +struct google_protobuf_FileOptions; +struct google_protobuf_MessageOptions; +struct google_protobuf_FieldOptions; +struct google_protobuf_OneofOptions; +struct google_protobuf_EnumOptions; +struct google_protobuf_EnumValueOptions; +struct google_protobuf_ServiceOptions; +struct google_protobuf_MethodOptions; +struct google_protobuf_UninterpretedOption; +struct google_protobuf_UninterpretedOption_NamePart; +struct google_protobuf_SourceCodeInfo; +struct google_protobuf_SourceCodeInfo_Location; +struct google_protobuf_GeneratedCodeInfo; +struct google_protobuf_GeneratedCodeInfo_Annotation; +typedef struct google_protobuf_FileDescriptorSet google_protobuf_FileDescriptorSet; +typedef struct google_protobuf_FileDescriptorProto google_protobuf_FileDescriptorProto; +typedef struct google_protobuf_DescriptorProto google_protobuf_DescriptorProto; +typedef struct google_protobuf_DescriptorProto_ExtensionRange google_protobuf_DescriptorProto_ExtensionRange; +typedef struct google_protobuf_DescriptorProto_ReservedRange google_protobuf_DescriptorProto_ReservedRange; +typedef struct google_protobuf_ExtensionRangeOptions google_protobuf_ExtensionRangeOptions; +typedef struct google_protobuf_FieldDescriptorProto google_protobuf_FieldDescriptorProto; +typedef struct google_protobuf_OneofDescriptorProto google_protobuf_OneofDescriptorProto; +typedef struct google_protobuf_EnumDescriptorProto google_protobuf_EnumDescriptorProto; +typedef struct google_protobuf_EnumDescriptorProto_EnumReservedRange google_protobuf_EnumDescriptorProto_EnumReservedRange; +typedef struct google_protobuf_EnumValueDescriptorProto google_protobuf_EnumValueDescriptorProto; +typedef struct google_protobuf_ServiceDescriptorProto google_protobuf_ServiceDescriptorProto; +typedef struct google_protobuf_MethodDescriptorProto google_protobuf_MethodDescriptorProto; +typedef struct google_protobuf_FileOptions google_protobuf_FileOptions; +typedef struct google_protobuf_MessageOptions google_protobuf_MessageOptions; +typedef struct google_protobuf_FieldOptions google_protobuf_FieldOptions; +typedef struct google_protobuf_OneofOptions google_protobuf_OneofOptions; +typedef struct google_protobuf_EnumOptions google_protobuf_EnumOptions; +typedef struct google_protobuf_EnumValueOptions google_protobuf_EnumValueOptions; +typedef struct google_protobuf_ServiceOptions google_protobuf_ServiceOptions; +typedef struct google_protobuf_MethodOptions google_protobuf_MethodOptions; +typedef struct google_protobuf_UninterpretedOption google_protobuf_UninterpretedOption; +typedef struct google_protobuf_UninterpretedOption_NamePart google_protobuf_UninterpretedOption_NamePart; +typedef struct google_protobuf_SourceCodeInfo google_protobuf_SourceCodeInfo; +typedef struct google_protobuf_SourceCodeInfo_Location google_protobuf_SourceCodeInfo_Location; +typedef struct google_protobuf_GeneratedCodeInfo google_protobuf_GeneratedCodeInfo; +typedef struct google_protobuf_GeneratedCodeInfo_Annotation google_protobuf_GeneratedCodeInfo_Annotation; +extern const upb_msglayout google_protobuf_FileDescriptorSet_msginit; +extern const upb_msglayout google_protobuf_FileDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_DescriptorProto_msginit; +extern const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit; +extern const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit; +extern const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit; +extern const upb_msglayout google_protobuf_FieldDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_OneofDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_EnumDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit; +extern const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_MethodDescriptorProto_msginit; +extern const upb_msglayout google_protobuf_FileOptions_msginit; +extern const upb_msglayout google_protobuf_MessageOptions_msginit; +extern const upb_msglayout google_protobuf_FieldOptions_msginit; +extern const upb_msglayout google_protobuf_OneofOptions_msginit; +extern const upb_msglayout google_protobuf_EnumOptions_msginit; +extern const upb_msglayout google_protobuf_EnumValueOptions_msginit; +extern const upb_msglayout google_protobuf_ServiceOptions_msginit; +extern const upb_msglayout google_protobuf_MethodOptions_msginit; +extern const upb_msglayout google_protobuf_UninterpretedOption_msginit; +extern const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit; +extern const upb_msglayout google_protobuf_SourceCodeInfo_msginit; +extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit; +extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit; +extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit; + +/* Enums */ + +typedef enum { + google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, + google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, + google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 +} google_protobuf_FieldDescriptorProto_Label; + +typedef enum { + google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1, + google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2, + google_protobuf_FieldDescriptorProto_TYPE_INT64 = 3, + google_protobuf_FieldDescriptorProto_TYPE_UINT64 = 4, + google_protobuf_FieldDescriptorProto_TYPE_INT32 = 5, + google_protobuf_FieldDescriptorProto_TYPE_FIXED64 = 6, + google_protobuf_FieldDescriptorProto_TYPE_FIXED32 = 7, + google_protobuf_FieldDescriptorProto_TYPE_BOOL = 8, + google_protobuf_FieldDescriptorProto_TYPE_STRING = 9, + google_protobuf_FieldDescriptorProto_TYPE_GROUP = 10, + google_protobuf_FieldDescriptorProto_TYPE_MESSAGE = 11, + google_protobuf_FieldDescriptorProto_TYPE_BYTES = 12, + google_protobuf_FieldDescriptorProto_TYPE_UINT32 = 13, + google_protobuf_FieldDescriptorProto_TYPE_ENUM = 14, + google_protobuf_FieldDescriptorProto_TYPE_SFIXED32 = 15, + google_protobuf_FieldDescriptorProto_TYPE_SFIXED64 = 16, + google_protobuf_FieldDescriptorProto_TYPE_SINT32 = 17, + google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18 +} google_protobuf_FieldDescriptorProto_Type; + +typedef enum { + google_protobuf_FieldOptions_STRING = 0, + google_protobuf_FieldOptions_CORD = 1, + google_protobuf_FieldOptions_STRING_PIECE = 2 +} google_protobuf_FieldOptions_CType; + +typedef enum { + google_protobuf_FieldOptions_JS_NORMAL = 0, + google_protobuf_FieldOptions_JS_STRING = 1, + google_protobuf_FieldOptions_JS_NUMBER = 2 +} google_protobuf_FieldOptions_JSType; + +typedef enum { + google_protobuf_FileOptions_SPEED = 1, + google_protobuf_FileOptions_CODE_SIZE = 2, + google_protobuf_FileOptions_LITE_RUNTIME = 3 +} google_protobuf_FileOptions_OptimizeMode; + +typedef enum { + google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0, + google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1, + google_protobuf_MethodOptions_IDEMPOTENT = 2 +} google_protobuf_MethodOptions_IdempotencyLevel; + +/* google.protobuf.FileDescriptorSet */ + +UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_new(upb_arena *arena) { + return (google_protobuf_FileDescriptorSet *)upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena); +} +UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FileDescriptorSet_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FileDescriptorSet_serialize(const google_protobuf_FileDescriptorSet *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_FileDescriptorProto* const* google_protobuf_FileDescriptorSet_file(const google_protobuf_FileDescriptorSet *msg, size_t *len) { return (const google_protobuf_FileDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_mutable_file(google_protobuf_FileDescriptorSet *msg, size_t *len) { + return (google_protobuf_FileDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_resize_file(google_protobuf_FileDescriptorSet *msg, size_t len, upb_arena *arena) { + return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorSet_add_file(google_protobuf_FileDescriptorSet *msg, upb_arena *arena) { + struct google_protobuf_FileDescriptorProto* sub = (struct google_protobuf_FileDescriptorProto*)upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.FileDescriptorProto */ + +UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_FileDescriptorProto *)upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FileDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FileDescriptorProto_serialize(const google_protobuf_FileDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_name(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE upb_strview const* google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } +UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_FileDescriptorProto_message_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } +UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); } +UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_ServiceDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(48, 96), len); } +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(52, 104), len); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FileOptions*, UPB_SIZE(28, 56)); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_SourceCodeInfo*, UPB_SIZE(32, 64)); } +UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_public_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(56, 112), len); } +UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_weak_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(60, 120), len); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); } + +UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_package(google_protobuf_FileDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_mutable_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len); +} +UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_resize_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_mutable_message_type(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len); +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_resize_message_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescriptorProto_add_message_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_mutable_enum_type(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len); +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_resize_enum_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescriptorProto_add_enum_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(44, 88), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_mutable_service(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (google_protobuf_ServiceDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 96), len); +} +UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_resize_service(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDescriptorProto_add_service(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_ServiceDescriptorProto* sub = (struct google_protobuf_ServiceDescriptorProto*)upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(48, 96), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_mutable_extension(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 104), len); +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_resize_extension(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 104), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDescriptorProto_add_extension(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(52, 104), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto *msg, google_protobuf_FileOptions* value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, google_protobuf_FileOptions*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_mutable_options(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_FileOptions* sub = (struct google_protobuf_FileOptions*)google_protobuf_FileDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FileOptions*)upb_msg_new(&google_protobuf_FileOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_FileDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_protobuf_FileDescriptorProto *msg, google_protobuf_SourceCodeInfo* value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, google_protobuf_SourceCodeInfo*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE struct google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_mutable_source_code_info(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_SourceCodeInfo* sub = (struct google_protobuf_SourceCodeInfo*)google_protobuf_FileDescriptorProto_source_code_info(msg); + if (sub == NULL) { + sub = (struct google_protobuf_SourceCodeInfo*)upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); + if (!sub) return NULL; + google_protobuf_FileDescriptorProto_set_source_code_info(msg, sub); + } + return sub; +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 112), len); +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(56, 112), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(56, 112), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(60, 120), len); +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(60, 120), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(60, 120), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value; +} + + +/* google.protobuf.DescriptorProto */ + +UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_new(upb_arena *arena) { + return (google_protobuf_DescriptorProto *)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_DescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_DescriptorProto_serialize(const google_protobuf_DescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_DescriptorProto_has_name(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } +UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } +UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE const google_protobuf_DescriptorProto_ExtensionRange* const* google_protobuf_DescriptorProto_extension_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ExtensionRange* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_options(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MessageOptions*, UPB_SIZE(12, 24)); } +UPB_INLINE const google_protobuf_OneofDescriptorProto* const* google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_OneofDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } +UPB_INLINE const google_protobuf_DescriptorProto_ReservedRange* const* google_protobuf_DescriptorProto_reserved_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } +UPB_INLINE upb_strview const* google_protobuf_DescriptorProto_reserved_name(const google_protobuf_DescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); } + +UPB_INLINE void google_protobuf_DescriptorProto_set_name(google_protobuf_DescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_field(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_field(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_field(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mutable_nested_type(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_resize_nested_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_add_nested_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_mutable_enum_type(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_resize_enum_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_DescriptorProto_add_enum_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_mutable_extension_range(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_resize_extension_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_add_extension_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_DescriptorProto_ExtensionRange* sub = (struct google_protobuf_DescriptorProto_ExtensionRange*)upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_extension(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len); +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_extension(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_extension(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_options(google_protobuf_DescriptorProto *msg, google_protobuf_MessageOptions* value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, google_protobuf_MessageOptions*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_MessageOptions* google_protobuf_DescriptorProto_mutable_options(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_MessageOptions* sub = (struct google_protobuf_MessageOptions*)google_protobuf_DescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_MessageOptions*)upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_DescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_mutable_oneof_decl(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_OneofDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len); +} +UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_resize_oneof_decl(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_DescriptorProto_add_oneof_decl(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_OneofDescriptorProto* sub = (struct google_protobuf_OneofDescriptorProto*)upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_mutable_reserved_range(google_protobuf_DescriptorProto *msg, size_t *len) { + return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len); +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_resize_reserved_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_add_reserved_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_DescriptorProto_ReservedRange* sub = (struct google_protobuf_DescriptorProto_ReservedRange*)upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE upb_strview* google_protobuf_DescriptorProto_mutable_reserved_name(google_protobuf_DescriptorProto *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len); +} +UPB_INLINE upb_strview* google_protobuf_DescriptorProto_resize_reserved_name(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(44, 88), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* google.protobuf.DescriptorProto.ExtensionRange */ + +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_new(upb_arena *arena) { + return (google_protobuf_DescriptorProto_ExtensionRange *)upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_DescriptorProto_ExtensionRange_serialize(const google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)); } + +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_end(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options(google_protobuf_DescriptorProto_ExtensionRange *msg, google_protobuf_ExtensionRangeOptions* value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_mutable_options(google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena) { + struct google_protobuf_ExtensionRangeOptions* sub = (struct google_protobuf_ExtensionRangeOptions*)google_protobuf_DescriptorProto_ExtensionRange_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_ExtensionRangeOptions*)upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_DescriptorProto_ExtensionRange_set_options(msg, sub); + } + return sub; +} + + +/* google.protobuf.DescriptorProto.ReservedRange */ + +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_new(upb_arena *arena) { + return (google_protobuf_DescriptorProto_ReservedRange *)upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_DescriptorProto_ReservedRange_serialize(const google_protobuf_DescriptorProto_ReservedRange *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } + +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + + +/* google.protobuf.ExtensionRangeOptions */ + +UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_new(upb_arena *arena) { + return (google_protobuf_ExtensionRangeOptions *)upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena); +} +UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_ExtensionRangeOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_ExtensionRangeOptions_serialize(const google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ExtensionRangeOptions_uninterpreted_option(const google_protobuf_ExtensionRangeOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_mutable_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_resize_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ExtensionRangeOptions_add_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.FieldDescriptorProto */ + +UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_FieldDescriptorProto *)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FieldDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_protobuf_FieldDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE google_protobuf_FieldDescriptorProto_Label google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Label, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE google_protobuf_FieldDescriptorProto_Type google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Type, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 10); } +UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FieldOptions*, UPB_SIZE(72, 112)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)); } + +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldDescriptorProto_Label value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Label, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldDescriptorProto_Type value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Type, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 7); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 8); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) { + _upb_sethas(msg, 10); + UPB_FIELD_AT(msg, google_protobuf_FieldOptions*, UPB_SIZE(72, 112)) = value; +} +UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options(google_protobuf_FieldDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_FieldOptions* sub = (struct google_protobuf_FieldOptions*)google_protobuf_FieldDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FieldOptions*)upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_FieldDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 9); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)) = value; +} + + +/* google.protobuf.OneofDescriptorProto */ + +UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_OneofDescriptorProto *)upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_OneofDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_OneofDescriptorProto_serialize(const google_protobuf_OneofDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_name(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_options(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_OneofOptions*, UPB_SIZE(12, 24)); } + +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options(google_protobuf_OneofDescriptorProto *msg, google_protobuf_OneofOptions* value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, google_protobuf_OneofOptions*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_mutable_options(google_protobuf_OneofDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_OneofOptions* sub = (struct google_protobuf_OneofOptions*)google_protobuf_OneofDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_OneofOptions*)upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_OneofDescriptorProto_set_options(msg, sub); + } + return sub; +} + + +/* google.protobuf.EnumDescriptorProto */ + +UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_EnumDescriptorProto *)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_EnumDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_EnumDescriptorProto_serialize(const google_protobuf_EnumDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_name(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE const google_protobuf_EnumValueDescriptorProto* const* google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumValueDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_options(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumOptions*, UPB_SIZE(12, 24)); } +UPB_INLINE const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* google_protobuf_EnumDescriptorProto_reserved_range(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto_EnumReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } +UPB_INLINE upb_strview const* google_protobuf_EnumDescriptorProto_reserved_name(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } + +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name(google_protobuf_EnumDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_mutable_value(google_protobuf_EnumDescriptorProto *msg, size_t *len) { + return (google_protobuf_EnumValueDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_resize_value(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumDescriptorProto_add_value(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumValueDescriptorProto* sub = (struct google_protobuf_EnumValueDescriptorProto*)upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_EnumDescriptorProto *msg, google_protobuf_EnumOptions* value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, google_protobuf_EnumOptions*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_mutable_options(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumOptions* sub = (struct google_protobuf_EnumOptions*)google_protobuf_EnumDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_EnumOptions*)upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_EnumDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_mutable_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t *len) { + return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_resize_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_add_reserved_range(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_mutable_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_resize_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* google.protobuf.EnumDescriptorProto.EnumReservedRange */ + +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_arena *arena) { + return (google_protobuf_EnumDescriptorProto_EnumReservedRange *)upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } + +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + + +/* google.protobuf.EnumValueDescriptorProto */ + +UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_EnumValueDescriptorProto *)upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_EnumValueDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_EnumValueDescriptorProto_serialize(const google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE upb_strview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumValueOptions*, UPB_SIZE(16, 24)); } + +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_protobuf_EnumValueDescriptorProto *msg, google_protobuf_EnumValueOptions* value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, google_protobuf_EnumValueOptions*, UPB_SIZE(16, 24)) = value; +} +UPB_INLINE struct google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_mutable_options(google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_EnumValueOptions* sub = (struct google_protobuf_EnumValueOptions*)google_protobuf_EnumValueDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_EnumValueOptions*)upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_EnumValueDescriptorProto_set_options(msg, sub); + } + return sub; +} + + +/* google.protobuf.ServiceDescriptorProto */ + +UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_ServiceDescriptorProto *)upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_ServiceDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_ServiceDescriptorProto_serialize(const google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_name(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE const google_protobuf_MethodDescriptorProto* const* google_protobuf_ServiceDescriptorProto_method(const google_protobuf_ServiceDescriptorProto *msg, size_t *len) { return (const google_protobuf_MethodDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_options(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ServiceOptions*, UPB_SIZE(12, 24)); } + +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_mutable_method(google_protobuf_ServiceDescriptorProto *msg, size_t *len) { + return (google_protobuf_MethodDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); +} +UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_resize_method(google_protobuf_ServiceDescriptorProto *msg, size_t len, upb_arena *arena) { + return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_ServiceDescriptorProto_add_method(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_MethodDescriptorProto* sub = (struct google_protobuf_MethodDescriptorProto*)upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options(google_protobuf_ServiceDescriptorProto *msg, google_protobuf_ServiceOptions* value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, google_protobuf_ServiceOptions*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_mutable_options(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_ServiceOptions* sub = (struct google_protobuf_ServiceOptions*)google_protobuf_ServiceDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_ServiceOptions*)upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_ServiceDescriptorProto_set_options(msg, sub); + } + return sub; +} + + +/* google.protobuf.MethodDescriptorProto */ + +UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_new(upb_arena *arena) { + return (google_protobuf_MethodDescriptorProto *)upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena); +} +UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_MethodDescriptorProto_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_MethodDescriptorProto_serialize(const google_protobuf_MethodDescriptorProto *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MethodOptions*, UPB_SIZE(28, 56)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } + +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto *msg, google_protobuf_MethodOptions* value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, google_protobuf_MethodOptions*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_mutable_options(google_protobuf_MethodDescriptorProto *msg, upb_arena *arena) { + struct google_protobuf_MethodOptions* sub = (struct google_protobuf_MethodOptions*)google_protobuf_MethodDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_MethodOptions*)upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); + if (!sub) return NULL; + google_protobuf_MethodDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} + + +/* google.protobuf.FileOptions */ + +UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_new(upb_arena *arena) { + return (google_protobuf_FileOptions *)upb_msg_new(&google_protobuf_FileOptions_msginit, arena); +} +UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FileOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_FileOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FileOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 11); } +UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(28, 32)); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 12); } +UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 48)); } +UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE google_protobuf_FileOptions_OptimizeMode google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FileOptions_OptimizeMode, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 13); } +UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 64)); } +UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)); } +UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)); } +UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)); } +UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)); } +UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 14); } +UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(52, 80)); } +UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 15); } +UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(60, 96)); } +UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 16); } +UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(68, 112)); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 17); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(76, 128)); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 18); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(84, 144)); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 10); } +UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 19); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(92, 160)); } +UPB_INLINE bool google_protobuf_FileOptions_has_ruby_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 20); } +UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(100, 176)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(108, 192), len); } + +UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 11); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(28, 32)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 12); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 48)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, google_protobuf_FileOptions_OptimizeMode value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, google_protobuf_FileOptions_OptimizeMode, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 13); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 64)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 7); + UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 8); + UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 9); + UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 14); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(52, 80)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 15); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(60, 96)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 16); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(68, 112)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 17); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(76, 128)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 18); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(84, 144)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 10); + UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 19); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(92, 160)) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 20); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(100, 176)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_mutable_uninterpreted_option(google_protobuf_FileOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(108, 192), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_resize_uninterpreted_option(google_protobuf_FileOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(108, 192), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptions_add_uninterpreted_option(google_protobuf_FileOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(108, 192), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.MessageOptions */ + +UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_new(upb_arena *arena) { + return (google_protobuf_MessageOptions *)upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); +} +UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_MessageOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_MessageOptions_serialize(const google_protobuf_MessageOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_MessageOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_MessageOptions_has_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_MessageOptions_has_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } +UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); } +UPB_INLINE bool google_protobuf_MessageOptions_has_map_entry(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MessageOptions_uninterpreted_option(const google_protobuf_MessageOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(8, 8), len); } + +UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format(google_protobuf_MessageOptions *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_no_standard_descriptor_accessor(google_protobuf_MessageOptions *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_deprecated(google_protobuf_MessageOptions *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_map_entry(google_protobuf_MessageOptions *msg, bool value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_mutable_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 8), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_resize_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOptions_add_uninterpreted_option(google_protobuf_MessageOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(8, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.FieldOptions */ + +UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_new(upb_arena *arena) { + return (google_protobuf_FieldOptions *)upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); +} +UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FieldOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_FieldOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FieldOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE google_protobuf_FieldOptions_CType google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_CType, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } +UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)); } +UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)); } +UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE google_protobuf_FieldOptions_JSType google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_JSType, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, google_protobuf_FieldOptions_CType value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, google_protobuf_FieldOptions_CType, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, google_protobuf_FieldOptions_JSType value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, google_protobuf_FieldOptions_JSType, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_mutable_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_resize_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.OneofOptions */ + +UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_new(upb_arena *arena) { + return (google_protobuf_OneofOptions *)upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); +} +UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_OneofOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_OneofOptions_serialize(const google_protobuf_OneofOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_OneofOptions_uninterpreted_option(const google_protobuf_OneofOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_mutable_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_resize_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOptions_add_uninterpreted_option(google_protobuf_OneofOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.EnumOptions */ + +UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_new(upb_arena *arena) { + return (google_protobuf_EnumOptions *)upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); +} +UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_EnumOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_EnumOptions_serialize(const google_protobuf_EnumOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_EnumOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumOptions_has_allow_alias(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumOptions_uninterpreted_option(const google_protobuf_EnumOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } + +UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias(google_protobuf_EnumOptions *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void google_protobuf_EnumOptions_set_deprecated(google_protobuf_EnumOptions *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_mutable_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_resize_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptions_add_uninterpreted_option(google_protobuf_EnumOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.EnumValueOptions */ + +UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_new(upb_arena *arena) { + return (google_protobuf_EnumValueOptions *)upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); +} +UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_EnumValueOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_EnumValueOptions_serialize(const google_protobuf_EnumValueOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_EnumValueOptions_has_deprecated(const google_protobuf_EnumValueOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumValueOptions_uninterpreted_option(const google_protobuf_EnumValueOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } + +UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated(google_protobuf_EnumValueOptions *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_mutable_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_resize_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValueOptions_add_uninterpreted_option(google_protobuf_EnumValueOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.ServiceOptions */ + +UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_new(upb_arena *arena) { + return (google_protobuf_ServiceOptions *)upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); +} +UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_ServiceOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_ServiceOptions_serialize(const google_protobuf_ServiceOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_ServiceOptions_has_deprecated(const google_protobuf_ServiceOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ServiceOptions_uninterpreted_option(const google_protobuf_ServiceOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } + +UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated(google_protobuf_ServiceOptions *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_mutable_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_resize_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOptions_add_uninterpreted_option(google_protobuf_ServiceOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.MethodOptions */ + +UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_new(upb_arena *arena) { + return (google_protobuf_MethodOptions *)upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); +} +UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_MethodOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_MethodOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_MethodOptions_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE google_protobuf_MethodOptions_IdempotencyLevel google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, UPB_SIZE(8, 8)); } +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); } + +UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, google_protobuf_MethodOptions_IdempotencyLevel value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t *len) { + return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len); +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_resize_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOptions_add_uninterpreted_option(google_protobuf_MethodOptions *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(20, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.UninterpretedOption */ + +UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_new(upb_arena *arena) { + return (google_protobuf_UninterpretedOption *)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena); +} +UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_UninterpretedOption_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_UninterpretedOption_serialize(const google_protobuf_UninterpretedOption *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_UninterpretedOption_NamePart* const* google_protobuf_UninterpretedOption_name(const google_protobuf_UninterpretedOption *msg, size_t *len) { return (const google_protobuf_UninterpretedOption_NamePart* const*)_upb_array_accessor(msg, UPB_SIZE(56, 80), len); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)); } + +UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_mutable_name(google_protobuf_UninterpretedOption *msg, size_t *len) { + return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 80), len); +} +UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_resize_name(google_protobuf_UninterpretedOption *msg, size_t len, upb_arena *arena) { + return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_add_name(google_protobuf_UninterpretedOption *msg, upb_arena *arena) { + struct google_protobuf_UninterpretedOption_NamePart* sub = (struct google_protobuf_UninterpretedOption_NamePart*)upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(56, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value(google_protobuf_UninterpretedOption *msg, int64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value(google_protobuf_UninterpretedOption *msg, double value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)) = value; +} + + +/* google.protobuf.UninterpretedOption.NamePart */ + +UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_new(upb_arena *arena) { + return (google_protobuf_UninterpretedOption_NamePart *)upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena); +} +UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_UninterpretedOption_NamePart_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_UninterpretedOption_NamePart_serialize(const google_protobuf_UninterpretedOption_NamePart *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } + +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart *msg, upb_strview value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} + + +/* google.protobuf.SourceCodeInfo */ + +UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_new(upb_arena *arena) { + return (google_protobuf_SourceCodeInfo *)upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_SourceCodeInfo_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_SourceCodeInfo_serialize(const google_protobuf_SourceCodeInfo *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_SourceCodeInfo_Location* const* google_protobuf_SourceCodeInfo_location(const google_protobuf_SourceCodeInfo *msg, size_t *len) { return (const google_protobuf_SourceCodeInfo_Location* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_mutable_location(google_protobuf_SourceCodeInfo *msg, size_t *len) { + return (google_protobuf_SourceCodeInfo_Location**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_resize_location(google_protobuf_SourceCodeInfo *msg, size_t len, upb_arena *arena) { + return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_add_location(google_protobuf_SourceCodeInfo *msg, upb_arena *arena) { + struct google_protobuf_SourceCodeInfo_Location* sub = (struct google_protobuf_SourceCodeInfo_Location*)upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.SourceCodeInfo.Location */ + +UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_new(upb_arena *arena) { + return (google_protobuf_SourceCodeInfo_Location *)upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_SourceCodeInfo_Location_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_SourceCodeInfo_Location_serialize(const google_protobuf_SourceCodeInfo_Location *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, arena, len); +} + +UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_path(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } +UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_span(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE upb_strview const* google_protobuf_SourceCodeInfo_Location_leading_detached_comments(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } + +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_path(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); +} +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_path(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 40), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_span(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_mutable_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_resize_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* google.protobuf.GeneratedCodeInfo */ + +UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_new(upb_arena *arena) { + return (google_protobuf_GeneratedCodeInfo *)upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_GeneratedCodeInfo_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_GeneratedCodeInfo_serialize(const google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_GeneratedCodeInfo_Annotation* const* google_protobuf_GeneratedCodeInfo_annotation(const google_protobuf_GeneratedCodeInfo *msg, size_t *len) { return (const google_protobuf_GeneratedCodeInfo_Annotation* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_mutable_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t *len) { + return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_resize_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t len, upb_arena *arena) { + return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_add_annotation(google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena) { + struct google_protobuf_GeneratedCodeInfo_Annotation* sub = (struct google_protobuf_GeneratedCodeInfo_Annotation*)upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.GeneratedCodeInfo.Annotation */ + +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_new(upb_arena *arena) { + return (google_protobuf_GeneratedCodeInfo_Annotation *)upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(const google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, len); +} + +UPB_INLINE int32_t const* google_protobuf_GeneratedCodeInfo_Annotation_path(const google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE upb_strview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } + +UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_mutable_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len); +} +UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_resize_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_strview value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/duration.upb.c b/src/core/ext/upb-generated/google/protobuf/duration.upb.c new file mode 100644 index 00000000000..7384c06cf27 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/duration.upb.c @@ -0,0 +1,27 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/duration.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/duration.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_Duration__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_Duration_msginit = { + NULL, + &google_protobuf_Duration__fields[0], + UPB_SIZE(16, 16), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/duration.upb.h b/src/core/ext/upb-generated/google/protobuf/duration.upb.h new file mode 100644 index 00000000000..871d67dcbb5 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/duration.upb.h @@ -0,0 +1,59 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/duration.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_Duration; +typedef struct google_protobuf_Duration google_protobuf_Duration; +extern const upb_msglayout google_protobuf_Duration_msginit; + +/* Enums */ + +/* google.protobuf.Duration */ + +UPB_INLINE google_protobuf_Duration *google_protobuf_Duration_new(upb_arena *arena) { + return (google_protobuf_Duration *)upb_msg_new(&google_protobuf_Duration_msginit, arena); +} +UPB_INLINE google_protobuf_Duration *google_protobuf_Duration_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Duration *ret = google_protobuf_Duration_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Duration_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Duration_serialize(const google_protobuf_Duration *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Duration_msginit, arena, len); +} + +UPB_INLINE int64_t google_protobuf_Duration_seconds(const google_protobuf_Duration *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } +UPB_INLINE int32_t google_protobuf_Duration_nanos(const google_protobuf_Duration *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } + +UPB_INLINE void google_protobuf_Duration_set_seconds(google_protobuf_Duration *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Duration_set_nanos(google_protobuf_Duration *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/struct.upb.c b/src/core/ext/upb-generated/google/protobuf/struct.upb.c new file mode 100644 index 00000000000..5c199fc5771 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/struct.upb.c @@ -0,0 +1,79 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/struct.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/struct.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const google_protobuf_Struct_submsgs[1] = { + &google_protobuf_Struct_FieldsEntry_msginit, +}; + +static const upb_msglayout_field google_protobuf_Struct__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_Struct_msginit = { + &google_protobuf_Struct_submsgs[0], + &google_protobuf_Struct__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const google_protobuf_Struct_FieldsEntry_submsgs[1] = { + &google_protobuf_Value_msginit, +}; + +static const upb_msglayout_field google_protobuf_Struct_FieldsEntry__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit = { + &google_protobuf_Struct_FieldsEntry_submsgs[0], + &google_protobuf_Struct_FieldsEntry__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const google_protobuf_Value_submsgs[2] = { + &google_protobuf_ListValue_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field google_protobuf_Value__fields[6] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 14, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 1, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {4, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 8, 1}, + {5, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 1, 11, 1}, + {6, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 11, 1}, +}; + +const upb_msglayout google_protobuf_Value_msginit = { + &google_protobuf_Value_submsgs[0], + &google_protobuf_Value__fields[0], + UPB_SIZE(16, 32), 6, false, +}; + +static const upb_msglayout *const google_protobuf_ListValue_submsgs[1] = { + &google_protobuf_Value_msginit, +}; + +static const upb_msglayout_field google_protobuf_ListValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_ListValue_msginit = { + &google_protobuf_ListValue_submsgs[0], + &google_protobuf_ListValue__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/struct.upb.h b/src/core/ext/upb-generated/google/protobuf/struct.upb.h new file mode 100644 index 00000000000..2e28858fc7b --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/struct.upb.h @@ -0,0 +1,216 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/struct.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_Struct; +struct google_protobuf_Struct_FieldsEntry; +struct google_protobuf_Value; +struct google_protobuf_ListValue; +typedef struct google_protobuf_Struct google_protobuf_Struct; +typedef struct google_protobuf_Struct_FieldsEntry google_protobuf_Struct_FieldsEntry; +typedef struct google_protobuf_Value google_protobuf_Value; +typedef struct google_protobuf_ListValue google_protobuf_ListValue; +extern const upb_msglayout google_protobuf_Struct_msginit; +extern const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit; +extern const upb_msglayout google_protobuf_Value_msginit; +extern const upb_msglayout google_protobuf_ListValue_msginit; + +/* Enums */ + +typedef enum { + google_protobuf_NULL_VALUE = 0 +} google_protobuf_NullValue; + +/* google.protobuf.Struct */ + +UPB_INLINE google_protobuf_Struct *google_protobuf_Struct_new(upb_arena *arena) { + return (google_protobuf_Struct *)upb_msg_new(&google_protobuf_Struct_msginit, arena); +} +UPB_INLINE google_protobuf_Struct *google_protobuf_Struct_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Struct *ret = google_protobuf_Struct_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Struct_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Struct_serialize(const google_protobuf_Struct *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Struct_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_Struct_FieldsEntry* const* google_protobuf_Struct_fields(const google_protobuf_Struct *msg, size_t *len) { return (const google_protobuf_Struct_FieldsEntry* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_Struct_FieldsEntry** google_protobuf_Struct_mutable_fields(google_protobuf_Struct *msg, size_t *len) { + return (google_protobuf_Struct_FieldsEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_Struct_FieldsEntry** google_protobuf_Struct_resize_fields(google_protobuf_Struct *msg, size_t len, upb_arena *arena) { + return (google_protobuf_Struct_FieldsEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Struct_FieldsEntry* google_protobuf_Struct_add_fields(google_protobuf_Struct *msg, upb_arena *arena) { + struct google_protobuf_Struct_FieldsEntry* sub = (struct google_protobuf_Struct_FieldsEntry*)upb_msg_new(&google_protobuf_Struct_FieldsEntry_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* google.protobuf.Struct.FieldsEntry */ + +UPB_INLINE google_protobuf_Struct_FieldsEntry *google_protobuf_Struct_FieldsEntry_new(upb_arena *arena) { + return (google_protobuf_Struct_FieldsEntry *)upb_msg_new(&google_protobuf_Struct_FieldsEntry_msginit, arena); +} +UPB_INLINE google_protobuf_Struct_FieldsEntry *google_protobuf_Struct_FieldsEntry_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Struct_FieldsEntry *ret = google_protobuf_Struct_FieldsEntry_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Struct_FieldsEntry_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Struct_FieldsEntry_serialize(const google_protobuf_Struct_FieldsEntry *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Struct_FieldsEntry_msginit, arena, len); +} + +UPB_INLINE upb_strview google_protobuf_Struct_FieldsEntry_key(const google_protobuf_Struct_FieldsEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const google_protobuf_Value* google_protobuf_Struct_FieldsEntry_value(const google_protobuf_Struct_FieldsEntry *msg) { return UPB_FIELD_AT(msg, const google_protobuf_Value*, UPB_SIZE(8, 16)); } + +UPB_INLINE void google_protobuf_Struct_FieldsEntry_set_key(google_protobuf_Struct_FieldsEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Struct_FieldsEntry_set_value(google_protobuf_Struct_FieldsEntry *msg, google_protobuf_Value* value) { + UPB_FIELD_AT(msg, google_protobuf_Value*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Value* google_protobuf_Struct_FieldsEntry_mutable_value(google_protobuf_Struct_FieldsEntry *msg, upb_arena *arena) { + struct google_protobuf_Value* sub = (struct google_protobuf_Value*)google_protobuf_Struct_FieldsEntry_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Value*)upb_msg_new(&google_protobuf_Value_msginit, arena); + if (!sub) return NULL; + google_protobuf_Struct_FieldsEntry_set_value(msg, sub); + } + return sub; +} + + +/* google.protobuf.Value */ + +UPB_INLINE google_protobuf_Value *google_protobuf_Value_new(upb_arena *arena) { + return (google_protobuf_Value *)upb_msg_new(&google_protobuf_Value_msginit, arena); +} +UPB_INLINE google_protobuf_Value *google_protobuf_Value_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Value *ret = google_protobuf_Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Value_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Value_serialize(const google_protobuf_Value *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Value_msginit, arena, len); +} + +typedef enum { + google_protobuf_Value_kind_null_value = 1, + google_protobuf_Value_kind_number_value = 2, + google_protobuf_Value_kind_string_value = 3, + google_protobuf_Value_kind_bool_value = 4, + google_protobuf_Value_kind_struct_value = 5, + google_protobuf_Value_kind_list_value = 6, + google_protobuf_Value_kind_NOT_SET = 0, +} google_protobuf_Value_kind_oneofcases; +UPB_INLINE google_protobuf_Value_kind_oneofcases google_protobuf_Value_kind_case(const google_protobuf_Value* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } + +UPB_INLINE bool google_protobuf_Value_has_null_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } +UPB_INLINE google_protobuf_NullValue google_protobuf_Value_null_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, google_protobuf_NullValue, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, google_protobuf_NULL_VALUE); } +UPB_INLINE bool google_protobuf_Value_has_number_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } +UPB_INLINE double google_protobuf_Value_number_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, double, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, 0); } +UPB_INLINE bool google_protobuf_Value_has_string_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 3); } +UPB_INLINE upb_strview google_protobuf_Value_string_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, upb_strview_make("", strlen(""))); } +UPB_INLINE bool google_protobuf_Value_has_bool_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 4); } +UPB_INLINE bool google_protobuf_Value_bool_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 4, false); } +UPB_INLINE bool google_protobuf_Value_has_struct_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 5); } +UPB_INLINE const google_protobuf_Struct* google_protobuf_Value_struct_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, const google_protobuf_Struct*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 5, NULL); } +UPB_INLINE bool google_protobuf_Value_has_list_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 6); } +UPB_INLINE const google_protobuf_ListValue* google_protobuf_Value_list_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, const google_protobuf_ListValue*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 6, NULL); } + +UPB_INLINE void google_protobuf_Value_set_null_value(google_protobuf_Value *msg, google_protobuf_NullValue value) { + UPB_WRITE_ONEOF(msg, google_protobuf_NullValue, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); +} +UPB_INLINE void google_protobuf_Value_set_number_value(google_protobuf_Value *msg, double value) { + UPB_WRITE_ONEOF(msg, double, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); +} +UPB_INLINE void google_protobuf_Value_set_string_value(google_protobuf_Value *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 3); +} +UPB_INLINE void google_protobuf_Value_set_bool_value(google_protobuf_Value *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 4); +} +UPB_INLINE void google_protobuf_Value_set_struct_value(google_protobuf_Value *msg, google_protobuf_Struct* value) { + UPB_WRITE_ONEOF(msg, google_protobuf_Struct*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 5); +} +UPB_INLINE struct google_protobuf_Struct* google_protobuf_Value_mutable_struct_value(google_protobuf_Value *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)google_protobuf_Value_struct_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + google_protobuf_Value_set_struct_value(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_Value_set_list_value(google_protobuf_Value *msg, google_protobuf_ListValue* value) { + UPB_WRITE_ONEOF(msg, google_protobuf_ListValue*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 6); +} +UPB_INLINE struct google_protobuf_ListValue* google_protobuf_Value_mutable_list_value(google_protobuf_Value *msg, upb_arena *arena) { + struct google_protobuf_ListValue* sub = (struct google_protobuf_ListValue*)google_protobuf_Value_list_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_ListValue*)upb_msg_new(&google_protobuf_ListValue_msginit, arena); + if (!sub) return NULL; + google_protobuf_Value_set_list_value(msg, sub); + } + return sub; +} + + +/* google.protobuf.ListValue */ + +UPB_INLINE google_protobuf_ListValue *google_protobuf_ListValue_new(upb_arena *arena) { + return (google_protobuf_ListValue *)upb_msg_new(&google_protobuf_ListValue_msginit, arena); +} +UPB_INLINE google_protobuf_ListValue *google_protobuf_ListValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_ListValue *ret = google_protobuf_ListValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_ListValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_ListValue_serialize(const google_protobuf_ListValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_ListValue_msginit, arena, len); +} + +UPB_INLINE const google_protobuf_Value* const* google_protobuf_ListValue_values(const google_protobuf_ListValue *msg, size_t *len) { return (const google_protobuf_Value* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE google_protobuf_Value** google_protobuf_ListValue_mutable_values(google_protobuf_ListValue *msg, size_t *len) { + return (google_protobuf_Value**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE google_protobuf_Value** google_protobuf_ListValue_resize_values(google_protobuf_ListValue *msg, size_t len, upb_arena *arena) { + return (google_protobuf_Value**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Value* google_protobuf_ListValue_add_values(google_protobuf_ListValue *msg, upb_arena *arena) { + struct google_protobuf_Value* sub = (struct google_protobuf_Value*)upb_msg_new(&google_protobuf_Value_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c new file mode 100644 index 00000000000..edc7af5f364 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.c @@ -0,0 +1,27 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/timestamp.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/timestamp.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_Timestamp__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_Timestamp_msginit = { + NULL, + &google_protobuf_Timestamp__fields[0], + UPB_SIZE(16, 16), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h new file mode 100644 index 00000000000..42413a43014 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h @@ -0,0 +1,59 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/timestamp.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_Timestamp; +typedef struct google_protobuf_Timestamp google_protobuf_Timestamp; +extern const upb_msglayout google_protobuf_Timestamp_msginit; + +/* Enums */ + +/* google.protobuf.Timestamp */ + +UPB_INLINE google_protobuf_Timestamp *google_protobuf_Timestamp_new(upb_arena *arena) { + return (google_protobuf_Timestamp *)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); +} +UPB_INLINE google_protobuf_Timestamp *google_protobuf_Timestamp_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Timestamp *ret = google_protobuf_Timestamp_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Timestamp_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Timestamp_serialize(const google_protobuf_Timestamp *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Timestamp_msginit, arena, len); +} + +UPB_INLINE int64_t google_protobuf_Timestamp_seconds(const google_protobuf_Timestamp *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } +UPB_INLINE int32_t google_protobuf_Timestamp_nanos(const google_protobuf_Timestamp *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } + +UPB_INLINE void google_protobuf_Timestamp_set_seconds(google_protobuf_Timestamp *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_protobuf_Timestamp_set_nanos(google_protobuf_Timestamp *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c new file mode 100644 index 00000000000..1b93ef437ac --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.c @@ -0,0 +1,106 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/wrappers.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/wrappers.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field google_protobuf_DoubleValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 1, 1}, +}; + +const upb_msglayout google_protobuf_DoubleValue_msginit = { + NULL, + &google_protobuf_DoubleValue__fields[0], + UPB_SIZE(8, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_FloatValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 2, 1}, +}; + +const upb_msglayout google_protobuf_FloatValue_msginit = { + NULL, + &google_protobuf_FloatValue__fields[0], + UPB_SIZE(4, 4), 1, false, +}; + +static const upb_msglayout_field google_protobuf_Int64Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, +}; + +const upb_msglayout google_protobuf_Int64Value_msginit = { + NULL, + &google_protobuf_Int64Value__fields[0], + UPB_SIZE(8, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_UInt64Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 4, 1}, +}; + +const upb_msglayout google_protobuf_UInt64Value_msginit = { + NULL, + &google_protobuf_UInt64Value__fields[0], + UPB_SIZE(8, 8), 1, false, +}; + +static const upb_msglayout_field google_protobuf_Int32Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 5, 1}, +}; + +const upb_msglayout google_protobuf_Int32Value_msginit = { + NULL, + &google_protobuf_Int32Value__fields[0], + UPB_SIZE(4, 4), 1, false, +}; + +static const upb_msglayout_field google_protobuf_UInt32Value__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 13, 1}, +}; + +const upb_msglayout google_protobuf_UInt32Value_msginit = { + NULL, + &google_protobuf_UInt32Value__fields[0], + UPB_SIZE(4, 4), 1, false, +}; + +static const upb_msglayout_field google_protobuf_BoolValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout google_protobuf_BoolValue_msginit = { + NULL, + &google_protobuf_BoolValue__fields[0], + UPB_SIZE(1, 1), 1, false, +}; + +static const upb_msglayout_field google_protobuf_StringValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout google_protobuf_StringValue_msginit = { + NULL, + &google_protobuf_StringValue__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +static const upb_msglayout_field google_protobuf_BytesValue__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 12, 1}, +}; + +const upb_msglayout google_protobuf_BytesValue_msginit = { + NULL, + &google_protobuf_BytesValue__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h new file mode 100644 index 00000000000..d08ee51780a --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h @@ -0,0 +1,239 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/wrappers.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_DoubleValue; +struct google_protobuf_FloatValue; +struct google_protobuf_Int64Value; +struct google_protobuf_UInt64Value; +struct google_protobuf_Int32Value; +struct google_protobuf_UInt32Value; +struct google_protobuf_BoolValue; +struct google_protobuf_StringValue; +struct google_protobuf_BytesValue; +typedef struct google_protobuf_DoubleValue google_protobuf_DoubleValue; +typedef struct google_protobuf_FloatValue google_protobuf_FloatValue; +typedef struct google_protobuf_Int64Value google_protobuf_Int64Value; +typedef struct google_protobuf_UInt64Value google_protobuf_UInt64Value; +typedef struct google_protobuf_Int32Value google_protobuf_Int32Value; +typedef struct google_protobuf_UInt32Value google_protobuf_UInt32Value; +typedef struct google_protobuf_BoolValue google_protobuf_BoolValue; +typedef struct google_protobuf_StringValue google_protobuf_StringValue; +typedef struct google_protobuf_BytesValue google_protobuf_BytesValue; +extern const upb_msglayout google_protobuf_DoubleValue_msginit; +extern const upb_msglayout google_protobuf_FloatValue_msginit; +extern const upb_msglayout google_protobuf_Int64Value_msginit; +extern const upb_msglayout google_protobuf_UInt64Value_msginit; +extern const upb_msglayout google_protobuf_Int32Value_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_StringValue_msginit; +extern const upb_msglayout google_protobuf_BytesValue_msginit; + +/* Enums */ + +/* google.protobuf.DoubleValue */ + +UPB_INLINE google_protobuf_DoubleValue *google_protobuf_DoubleValue_new(upb_arena *arena) { + return (google_protobuf_DoubleValue *)upb_msg_new(&google_protobuf_DoubleValue_msginit, arena); +} +UPB_INLINE google_protobuf_DoubleValue *google_protobuf_DoubleValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_DoubleValue *ret = google_protobuf_DoubleValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_DoubleValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_DoubleValue_serialize(const google_protobuf_DoubleValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_DoubleValue_msginit, arena, len); +} + +UPB_INLINE double google_protobuf_DoubleValue_value(const google_protobuf_DoubleValue *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_DoubleValue_set_value(google_protobuf_DoubleValue *msg, double value) { + UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.FloatValue */ + +UPB_INLINE google_protobuf_FloatValue *google_protobuf_FloatValue_new(upb_arena *arena) { + return (google_protobuf_FloatValue *)upb_msg_new(&google_protobuf_FloatValue_msginit, arena); +} +UPB_INLINE google_protobuf_FloatValue *google_protobuf_FloatValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_FloatValue *ret = google_protobuf_FloatValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_FloatValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_FloatValue_serialize(const google_protobuf_FloatValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_FloatValue_msginit, arena, len); +} + +UPB_INLINE float google_protobuf_FloatValue_value(const google_protobuf_FloatValue *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_FloatValue_set_value(google_protobuf_FloatValue *msg, float value) { + UPB_FIELD_AT(msg, float, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.Int64Value */ + +UPB_INLINE google_protobuf_Int64Value *google_protobuf_Int64Value_new(upb_arena *arena) { + return (google_protobuf_Int64Value *)upb_msg_new(&google_protobuf_Int64Value_msginit, arena); +} +UPB_INLINE google_protobuf_Int64Value *google_protobuf_Int64Value_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Int64Value *ret = google_protobuf_Int64Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Int64Value_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Int64Value_serialize(const google_protobuf_Int64Value *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Int64Value_msginit, arena, len); +} + +UPB_INLINE int64_t google_protobuf_Int64Value_value(const google_protobuf_Int64Value *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_Int64Value_set_value(google_protobuf_Int64Value *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.UInt64Value */ + +UPB_INLINE google_protobuf_UInt64Value *google_protobuf_UInt64Value_new(upb_arena *arena) { + return (google_protobuf_UInt64Value *)upb_msg_new(&google_protobuf_UInt64Value_msginit, arena); +} +UPB_INLINE google_protobuf_UInt64Value *google_protobuf_UInt64Value_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_UInt64Value *ret = google_protobuf_UInt64Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_UInt64Value_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_UInt64Value_serialize(const google_protobuf_UInt64Value *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_UInt64Value_msginit, arena, len); +} + +UPB_INLINE uint64_t google_protobuf_UInt64Value_value(const google_protobuf_UInt64Value *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_UInt64Value_set_value(google_protobuf_UInt64Value *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.Int32Value */ + +UPB_INLINE google_protobuf_Int32Value *google_protobuf_Int32Value_new(upb_arena *arena) { + return (google_protobuf_Int32Value *)upb_msg_new(&google_protobuf_Int32Value_msginit, arena); +} +UPB_INLINE google_protobuf_Int32Value *google_protobuf_Int32Value_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Int32Value *ret = google_protobuf_Int32Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Int32Value_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Int32Value_serialize(const google_protobuf_Int32Value *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Int32Value_msginit, arena, len); +} + +UPB_INLINE int32_t google_protobuf_Int32Value_value(const google_protobuf_Int32Value *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_Int32Value_set_value(google_protobuf_Int32Value *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.UInt32Value */ + +UPB_INLINE google_protobuf_UInt32Value *google_protobuf_UInt32Value_new(upb_arena *arena) { + return (google_protobuf_UInt32Value *)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); +} +UPB_INLINE google_protobuf_UInt32Value *google_protobuf_UInt32Value_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_UInt32Value *ret = google_protobuf_UInt32Value_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_UInt32Value_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_UInt32Value_serialize(const google_protobuf_UInt32Value *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_UInt32Value_msginit, arena, len); +} + +UPB_INLINE uint32_t google_protobuf_UInt32Value_value(const google_protobuf_UInt32Value *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_UInt32Value_set_value(google_protobuf_UInt32Value *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.BoolValue */ + +UPB_INLINE google_protobuf_BoolValue *google_protobuf_BoolValue_new(upb_arena *arena) { + return (google_protobuf_BoolValue *)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); +} +UPB_INLINE google_protobuf_BoolValue *google_protobuf_BoolValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_BoolValue *ret = google_protobuf_BoolValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_BoolValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_BoolValue_serialize(const google_protobuf_BoolValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_BoolValue_msginit, arena, len); +} + +UPB_INLINE bool google_protobuf_BoolValue_value(const google_protobuf_BoolValue *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_BoolValue_set_value(google_protobuf_BoolValue *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.StringValue */ + +UPB_INLINE google_protobuf_StringValue *google_protobuf_StringValue_new(upb_arena *arena) { + return (google_protobuf_StringValue *)upb_msg_new(&google_protobuf_StringValue_msginit, arena); +} +UPB_INLINE google_protobuf_StringValue *google_protobuf_StringValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_StringValue *ret = google_protobuf_StringValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_StringValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_StringValue_serialize(const google_protobuf_StringValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_StringValue_msginit, arena, len); +} + +UPB_INLINE upb_strview google_protobuf_StringValue_value(const google_protobuf_StringValue *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_StringValue_set_value(google_protobuf_StringValue *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* google.protobuf.BytesValue */ + +UPB_INLINE google_protobuf_BytesValue *google_protobuf_BytesValue_new(upb_arena *arena) { + return (google_protobuf_BytesValue *)upb_msg_new(&google_protobuf_BytesValue_msginit, arena); +} +UPB_INLINE google_protobuf_BytesValue *google_protobuf_BytesValue_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_BytesValue *ret = google_protobuf_BytesValue_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_BytesValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_BytesValue_serialize(const google_protobuf_BytesValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_BytesValue_msginit, arena, len); +} + +UPB_INLINE upb_strview google_protobuf_BytesValue_value(const google_protobuf_BytesValue *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void google_protobuf_BytesValue_set_value(google_protobuf_BytesValue *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ */ diff --git a/src/upb/gen_build_yaml.py b/src/upb/gen_build_yaml.py new file mode 100755 index 00000000000..8b726d374a3 --- /dev/null +++ b/src/upb/gen_build_yaml.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python2.7 + +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# TODO: This should ideally be in upb submodule to avoid hardcoding this here. + +import re +import os +import sys +import yaml + +srcs = [ + "third_party/upb/google/protobuf/descriptor.upb.c", + "third_party/upb/upb/decode.c", + "third_party/upb/upb/def.c", + "third_party/upb/upb/encode.c", + "third_party/upb/upb/handlers.c", + "third_party/upb/upb/msg.c", + "third_party/upb/upb/msgfactory.c", + "third_party/upb/upb/sink.c", + "third_party/upb/upb/table.c", + "third_party/upb/upb/upb.c", +] + +hdrs = [ + "third_party/upb/google/protobuf/descriptor.upb.h", + "third_party/upb/upb/decode.h", + "third_party/upb/upb/def.h", + "third_party/upb/upb/encode.h", + "third_party/upb/upb/handlers.h", + "third_party/upb/upb/msg.h", + "third_party/upb/upb/msgfactory.h", + "third_party/upb/upb/sink.h", + "third_party/upb/upb/upb.h", +] + +os.chdir(os.path.dirname(sys.argv[0])+'/../..') + +out = {} + +try: + out['libs'] = [{ + 'name': 'upb', + 'defaults': 'upb', + 'build': 'private', + 'language': 'c', + 'secure': 'no', + 'src': srcs, + 'headers': hdrs, + }] +except: + pass + +print yaml.dump(out) diff --git a/third_party/upb b/third_party/upb index 9ce4a77f61c..ed9faae0993 160000 --- a/third_party/upb +++ b/third_party/upb @@ -1 +1 @@ -Subproject commit 9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3 +Subproject commit ed9faae0993704b033c594b072d65e1bf19207fa diff --git a/tools/buildgen/generate_build_additions.sh b/tools/buildgen/generate_build_additions.sh index 5a1f4a598a7..c99ad6ee552 100755 --- a/tools/buildgen/generate_build_additions.sh +++ b/tools/buildgen/generate_build_additions.sh @@ -19,6 +19,7 @@ gen_build_yaml_dirs=" \ src/boringssl \ src/benchmark \ src/proto \ + src/upb \ src/zlib \ src/c-ares \ test/core/bad_client \ diff --git a/tools/codegen/core/gen_upb_api.sh b/tools/codegen/core/gen_upb_api.sh new file mode 100755 index 00000000000..9457e06f124 --- /dev/null +++ b/tools/codegen/core/gen_upb_api.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Copyright 2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# REQUIRES: Bazel +set -ex +rm -rf src/core/ext/upb-generated +mkdir src/core/ext/upb-generated +cd third_party +cd upb +bazel build :protoc-gen-upb + +cd ../.. + +proto_files=( \ + "google/protobuf/any.proto" \ + "google/protobuf/struct.proto" \ + "google/protobuf/wrappers.proto" \ + "google/protobuf/descriptor.proto" \ + "google/protobuf/duration.proto" \ + "google/protobuf/timestamp.proto" ) + +for i in "${proto_files[@]}" +do + protoc -I=$PWD/third_party/data-plane-api -I=$PWD/third_party/googleapis -I=$PWD/third_party/protobuf -I=$PWD/third_party/protoc-gen-validate $i --upb_out=./src/core/ext/upb-generated --plugin=protoc-gen-upb=third_party/upb/bazel-bin/protoc-gen-upb +done diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py index 787bef1778e..fd93cf31e05 100755 --- a/tools/distrib/check_copyright.py +++ b/tools/distrib/check_copyright.py @@ -104,6 +104,20 @@ _EXEMPT = frozenset(( # Designer-generated source 'examples/csharp/HelloworldXamarin/Droid/Resources/Resource.designer.cs', 'examples/csharp/HelloworldXamarin/iOS/ViewController.designer.cs', + + # Upb generated source + 'src/core/ext/upb-generated/google/protobuf/any.upb.h', + 'src/core/ext/upb-generated/google/protobuf/any.upb.c', + 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.h', + 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.c', + 'src/core/ext/upb-generated/google/protobuf/duration.upb.h', + 'src/core/ext/upb-generated/google/protobuf/duration.upb.c', + 'src/core/ext/upb-generated/google/protobuf/struct.upb.h', + 'src/core/ext/upb-generated/google/protobuf/struct.upb.c', + 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.h', + 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.c', + 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.h', + 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.c', )) RE_YEAR = r'Copyright (?P[0-9]+\-)?(?P[0-9]+) ([Tt]he )?gRPC [Aa]uthors(\.|)' diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py index b8d530cce06..ac166ef3844 100755 --- a/tools/distrib/check_include_guards.py +++ b/tools/distrib/check_include_guards.py @@ -165,6 +165,20 @@ KNOWN_BAD = set([ 'src/core/tsi/alts/handshaker/transport_security_common.pb.h', 'include/grpc++/ext/reflection.grpc.pb.h', 'include/grpc++/ext/reflection.pb.h', + + # Upb generated code. + 'src/core/ext/upb-generated/google/protobuf/any.upb.h', + 'src/core/ext/upb-generated/google/protobuf/any.upb.c', + 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.h', + 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.c', + 'src/core/ext/upb-generated/google/protobuf/duration.upb.h', + 'src/core/ext/upb-generated/google/protobuf/duration.upb.c', + 'src/core/ext/upb-generated/google/protobuf/struct.upb.h', + 'src/core/ext/upb-generated/google/protobuf/struct.upb.c', + 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.h', + 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.c', + 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.h', + 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.c', ]) grep_filter = r"grep -E '^(include|src/core)/.*\.h$'" diff --git a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh index 0c8ecc21a0c..ab37c0ae9bd 100755 --- a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh +++ b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh @@ -29,7 +29,7 @@ for dir in $DIRS do for glob in $GLOB do - files="$files `find ${CLANG_FORMAT_ROOT}/$dir -name $glob -and -not -name '*.generated.*' -and -not -name '*.pb.h' -and -not -name '*.pb.c' -and -not -name '*.pb.cc' -and -not -name '*.pbobjc.h' -and -not -name '*.pbobjc.m' -and -not -name '*.pbrpc.h' -and -not -name '*.pbrpc.m' -and -not -name end2end_tests.cc -and -not -name end2end_nosec_tests.cc -and -not -name public_headers_must_be_c89.c -and -not -name grpc_shadow_boringssl.h`" + files="$files `find ${CLANG_FORMAT_ROOT}/$dir -name $glob -and -not -name '*.generated.*' -and -not -name '*.upb.h' -and -not -name '*.upb.c' -and -not -name '*.pb.h' -and -not -name '*.pb.c' -and -not -name '*.pb.cc' -and -not -name '*.pbobjc.h' -and -not -name '*.pbobjc.m' -and -not -name '*.pbrpc.h' -and -not -name '*.pbrpc.m' -and -not -name end2end_tests.cc -and -not -name end2end_nosec_tests.cc -and -not -name public_headers_must_be_c89.c -and -not -name grpc_shadow_boringssl.h`" done done diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 7a72a885336..8adde9ec602 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8739,6 +8739,26 @@ "third_party": false, "type": "lib" }, + { + "deps": [], + "headers": [ + "third_party/upb/google/protobuf/descriptor.upb.h", + "third_party/upb/upb/decode.h", + "third_party/upb/upb/def.h", + "third_party/upb/upb/encode.h", + "third_party/upb/upb/handlers.h", + "third_party/upb/upb/msg.h", + "third_party/upb/upb/msgfactory.h", + "third_party/upb/upb/sink.h", + "third_party/upb/upb/upb.h" + ], + "is_filegroup": false, + "language": "c", + "name": "upb", + "src": [], + "third_party": false, + "type": "lib" + }, { "deps": [], "headers": [ diff --git a/tools/run_tests/sanity/check_port_platform.py b/tools/run_tests/sanity/check_port_platform.py index fff828eaee8..79e7f9c4033 100755 --- a/tools/run_tests/sanity/check_port_platform.py +++ b/tools/run_tests/sanity/check_port_platform.py @@ -35,6 +35,9 @@ def check_port_platform_inclusion(directory_root): continue if filename.endswith('.pb.h') or filename.endswith('.pb.c'): continue + # Skip check for upb generated code. + if filename.endswith('.upb.h') or filename.endswith('.upb.c'): + continue with open(path) as f: all_lines_in_file = f.readlines() for index, l in enumerate(all_lines_in_file): diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index 2c447f887ee..12e4c157193 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -40,7 +40,7 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules" 9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60) 582743bf40c5d3639a70f98f183914a2c0cd0680 third_party/protobuf (v3.7.0-rc.2-20-g582743bf) e143189bf6f37b3957fb31743df6a1bcf4a8c685 third_party/protoc-gen-validate (v0.0.10) - 9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3 third_party/upb (heads/upbc-cpp) + ed9faae0993704b033c594b072d65e1bf19207fa third_party/upb (heads/master) cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11) EOF From 3d287610296cacb34bb7c10881033aa05cb658d3 Mon Sep 17 00:00:00 2001 From: Norman Link Date: Fri, 18 Jan 2019 14:01:07 +0100 Subject: [PATCH 684/814] Fixing memory leak in interceptor by removing unsued send_status_ --- include/grpcpp/impl/codegen/interceptor_common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/interceptor_common.h b/include/grpcpp/impl/codegen/interceptor_common.h index 8ed84230911..e7290aca838 100644 --- a/include/grpcpp/impl/codegen/interceptor_common.h +++ b/include/grpcpp/impl/codegen/interceptor_common.h @@ -403,7 +403,6 @@ class InterceptorBatchMethodsImpl grpc_status_code* code_ = nullptr; grpc::string* error_details_ = nullptr; grpc::string* error_message_ = nullptr; - Status send_status_; std::multimap* send_trailing_metadata_ = nullptr; From 55897b9f69789420c581309bdea8fc6422d9ca67 Mon Sep 17 00:00:00 2001 From: John Luo Date: Wed, 13 Mar 2019 16:56:16 -0700 Subject: [PATCH 685/814] WIP Fix tests --- .../ProtoCompileCommandLineGeneratorTest.cs | 8 ++++---- src/csharp/Grpc.Tools/ProtoCompile.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs index cac71466345..1ed7ca67b42 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs @@ -49,7 +49,7 @@ namespace Grpc.Tools.Tests ExecuteExpectSuccess(); Assert.That(_task.LastPathToTool, Does.Match(@"protoc(.exe)?$")); Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { - "--csharp_out=outdir", "a.proto" })); + "--csharp_out=outdir", "--error_format=msvs", "a.proto" })); } [Test] @@ -58,7 +58,7 @@ namespace Grpc.Tools.Tests _task.ProtoBuf = Utils.MakeSimpleItems("a.proto", "foo/b.proto"); ExecuteExpectSuccess(); Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { - "--csharp_out=outdir", "a.proto", "foo/b.proto" })); + "--csharp_out=outdir", "--error_format=msvs", "a.proto", "foo/b.proto" })); } [Test] @@ -68,7 +68,7 @@ namespace Grpc.Tools.Tests ExecuteExpectSuccess(); Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { "--csharp_out=outdir", "--proto_path=/path1", - "--proto_path=/path2", "a.proto" })); + "--proto_path=/path2", "--error_format=msvs", "a.proto" })); } [TestCase("Cpp")] @@ -87,7 +87,7 @@ namespace Grpc.Tools.Tests ExecuteExpectSuccess(); gen = gen.ToLowerInvariant(); Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { - $"--{gen}_out=outdir", $"--{gen}_opt=foo,bar", "a.proto" })); + $"--{gen}_out=outdir", $"--{gen}_opt=foo,bar", "--error_format=msvs", "a.proto" })); } [Test] diff --git a/src/csharp/Grpc.Tools/ProtoCompile.cs b/src/csharp/Grpc.Tools/ProtoCompile.cs index f6964205d2b..abff1ea016a 100644 --- a/src/csharp/Grpc.Tools/ProtoCompile.cs +++ b/src/csharp/Grpc.Tools/ProtoCompile.cs @@ -318,11 +318,11 @@ namespace Grpc.Tools cmd.AddSwitchMaybe("proto_path", TrimEndSlash(path)); } cmd.AddSwitchMaybe("dependency_out", DependencyOut); + cmd.AddSwitchMaybe("error_format", "msvs"); foreach (var proto in ProtoBuf) { cmd.AddArg(proto.ItemSpec); } - cmd.AddSwitchMaybe("error_format", "msvs"); return cmd.ToString(); } From b089b21c6f62d9f324782a8903b757f699f5d10c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 14 Mar 2019 14:44:30 +0100 Subject: [PATCH 686/814] Fix source stepping by upgrading sourcelink --- src/csharp/Grpc.Core/SourceLink.csproj.include | 7 ++++++- src/csharp/build_packages_dotnetcli.bat | 14 +++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/csharp/Grpc.Core/SourceLink.csproj.include b/src/csharp/Grpc.Core/SourceLink.csproj.include index 526db954540..045dcb1a0d6 100755 --- a/src/csharp/Grpc.Core/SourceLink.csproj.include +++ b/src/csharp/Grpc.Core/SourceLink.csproj.include @@ -1,8 +1,13 @@ + + + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + + - + diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 58520f2f497..f500310865b 100755 --- a/src/csharp/build_packages_dotnetcli.bat +++ b/src/csharp/build_packages_dotnetcli.bat @@ -32,13 +32,13 @@ expand_dev_version.sh @rem To be able to build, we also need to put grpc_csharp_ext to its normal location xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\build\x64\Release\ -%DOTNET% pack --configuration Release Grpc.Core.Api /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.Core /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.Core.Testing /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.Auth /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.HealthCheck /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.Reflection /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error -%DOTNET% pack --configuration Release Grpc.Tools /p:SourceLinkCreate=true --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Core.Api --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Core --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Core.Testing --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Auth --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.HealthCheck --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Reflection --output ..\..\..\artifacts || goto :error +%DOTNET% pack --configuration Release Grpc.Tools --output ..\..\..\artifacts || goto :error @rem build auxiliary packages %DOTNET% pack --configuration Release Grpc --output ..\..\..\artifacts || goto :error %DOTNET% pack --configuration Release Grpc.Core.NativeDebug --output ..\..\..\artifacts || goto :error From b302f912cea43176170fc40a25be070e91b9dd59 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 14 Mar 2019 15:31:05 +0100 Subject: [PATCH 687/814] publish repository url --- src/csharp/Grpc.Core/SourceLink.csproj.include | 1 + 1 file changed, 1 insertion(+) diff --git a/src/csharp/Grpc.Core/SourceLink.csproj.include b/src/csharp/Grpc.Core/SourceLink.csproj.include index 045dcb1a0d6..9c027deaa3e 100755 --- a/src/csharp/Grpc.Core/SourceLink.csproj.include +++ b/src/csharp/Grpc.Core/SourceLink.csproj.include @@ -4,6 +4,7 @@ $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + true From e8c8ca6d708c8c61c6516ca15dc42ad1c05fcf56 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 14 Mar 2019 18:29:42 +0100 Subject: [PATCH 688/814] fix layout of Grpc.Tools package --- src/csharp/Grpc.Tools/Grpc.Tools.csproj | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index 89307bfdd65..e1e3633220e 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -70,20 +70,20 @@ Linux and MacOS. Managed runtime is supplied separately in the Grpc.Core package - <_Asset PackagePath="tools/windows_x86/protoc.exe" Include="$(Assets_ProtoCompiler)windows_x86/protoc.exe" /> - <_Asset PackagePath="tools/windows_x64/protoc.exe" Include="$(Assets_ProtoCompiler)windows_x64/protoc.exe" /> - <_Asset PackagePath="tools/linux_x86/protoc" Include="$(Assets_ProtoCompiler)linux_x86/protoc" /> - <_Asset PackagePath="tools/linux_x64/protoc" Include="$(Assets_ProtoCompiler)linux_x64/protoc" /> - <_Asset PackagePath="tools/macosx_x86/protoc" Include="$(Assets_ProtoCompiler)macos_x86/protoc" /> - <_Asset PackagePath="tools/macosx_x64/protoc" Include="$(Assets_ProtoCompiler)macos_x64/protoc" /> + <_Asset PackagePath="tools/windows_x86/" Include="$(Assets_ProtoCompiler)windows_x86/protoc.exe" /> + <_Asset PackagePath="tools/windows_x64/" Include="$(Assets_ProtoCompiler)windows_x64/protoc.exe" /> + <_Asset PackagePath="tools/linux_x86/" Include="$(Assets_ProtoCompiler)linux_x86/protoc" /> + <_Asset PackagePath="tools/linux_x64/" Include="$(Assets_ProtoCompiler)linux_x64/protoc" /> + <_Asset PackagePath="tools/macosx_x86/" Include="$(Assets_ProtoCompiler)macos_x86/protoc" /> + <_Asset PackagePath="tools/macosx_x64/" Include="$(Assets_ProtoCompiler)macos_x64/protoc" /> - <_Asset PackagePath="tools/windows_x86/grpc_csharp_plugin.exe" Include="$(Assets_GrpcPlugins)protoc_windows_x86/grpc_csharp_plugin.exe" /> - <_Asset PackagePath="tools/windows_x64/grpc_csharp_plugin.exe" Include="$(Assets_GrpcPlugins)protoc_windows_x64/grpc_csharp_plugin.exe" /> - <_Asset PackagePath="tools/linux_x86/grpc_csharp_plugin" Include="$(Assets_GrpcPlugins)protoc_linux_x86/grpc_csharp_plugin" /> - <_Asset PackagePath="tools/linux_x64/grpc_csharp_plugin" Include="$(Assets_GrpcPlugins)protoc_linux_x64/grpc_csharp_plugin" /> - <_Asset PackagePath="tools/macosx_x86/grpc_csharp_plugin" Include="$(Assets_GrpcPlugins)protoc_macos_x86/grpc_csharp_plugin" /> - <_Asset PackagePath="tools/macosx_x64/grpc_csharp_plugin" Include="$(Assets_GrpcPlugins)protoc_macos_x64/grpc_csharp_plugin" /> + <_Asset PackagePath="tools/windows_x86/" Include="$(Assets_GrpcPlugins)protoc_windows_x86/grpc_csharp_plugin.exe" /> + <_Asset PackagePath="tools/windows_x64/" Include="$(Assets_GrpcPlugins)protoc_windows_x64/grpc_csharp_plugin.exe" /> + <_Asset PackagePath="tools/linux_x86/" Include="$(Assets_GrpcPlugins)protoc_linux_x86/grpc_csharp_plugin" /> + <_Asset PackagePath="tools/linux_x64/" Include="$(Assets_GrpcPlugins)protoc_linux_x64/grpc_csharp_plugin" /> + <_Asset PackagePath="tools/macosx_x86/" Include="$(Assets_GrpcPlugins)protoc_macos_x86/grpc_csharp_plugin" /> + <_Asset PackagePath="tools/macosx_x64/" Include="$(Assets_GrpcPlugins)protoc_macos_x64/grpc_csharp_plugin" /> From ca90580d2be0b4516a2e542e9f88fa4438952369 Mon Sep 17 00:00:00 2001 From: John Luo Date: Wed, 13 Mar 2019 12:41:27 -0700 Subject: [PATCH 689/814] Enable design time builds by default - Design time build can be disable by setting DisasbleProtobufDesignTimeBuild to true --- .../build/_protobuf/Google.Protobuf.Tools.targets | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets index 26f9efb5a84..7896e62c75e 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -80,7 +80,7 @@ >$(Protobuf_PackagedToolsPath)/$(Protobuf_ToolsOs)_$(Protobuf_ToolsCpu)/protoc - @@ -93,7 +93,7 @@ - - @@ -246,7 +246,7 @@ @@ -289,7 +289,7 @@ compile though). You can empty this collection in your Before targets to do nothing. The target is not executed if the proto compiler is not executed. --> + Condition=" '$(DisableProtobufDesignTimeBuild)' != 'true' "> From 7dbe321d767f2a28991ed1c57650620d5b1b4afa Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Thu, 14 Mar 2019 10:54:02 -0700 Subject: [PATCH 690/814] Update pending_api_cleanups.md --- doc/core/pending_api_cleanups.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/core/pending_api_cleanups.md b/doc/core/pending_api_cleanups.md index 5a8270349a4..970bcd08300 100644 --- a/doc/core/pending_api_cleanups.md +++ b/doc/core/pending_api_cleanups.md @@ -15,4 +15,4 @@ number: `include/grpc/impl/codegen/grpc_types.h` (commit `af00d8b`) (cannot be done until after next grpc release, so that TensorFlow can use the same code both internally and externally) -- require a C++ runtime for all languages. +- require a C++ runtime for all languages wrapping core. From efe0b4b2ddf53bcee99a1645035300bdc800b02a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 14 Mar 2019 12:04:05 -0700 Subject: [PATCH 691/814] Use GRPC_LINUX_ERRQUEUE --- src/core/lib/iomgr/internal_errqueue.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/internal_errqueue.cc b/src/core/lib/iomgr/internal_errqueue.cc index 982d709f094..4e2bfe3ccd5 100644 --- a/src/core/lib/iomgr/internal_errqueue.cc +++ b/src/core/lib/iomgr/internal_errqueue.cc @@ -38,8 +38,7 @@ bool kernel_supports_errqueue() { return errqueue_supported; } void grpc_errqueue_init() { /* Both-compile time and run-time linux kernel versions should be atleast 4.0.0 */ -#ifdef LINUX_VERSION_CODE -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) +#ifdef GRPC_LINUX_ERRQUEUE struct utsname buffer; if (uname(&buffer) != 0) { gpr_log(GPR_ERROR, "uname: %s", strerror(errno)); @@ -55,8 +54,7 @@ void grpc_errqueue_init() { } else { gpr_log(GPR_DEBUG, "ERRQUEUE support not enabled"); } -#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */ -#endif /* LINUX_VERSION_CODE */ +#endif /* GRPC_LINUX_ERRQUEUE */ } } /* namespace grpc_core */ From d069bc772127f29c9e3535344e7fad949032427e Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Mar 2019 12:19:09 -0700 Subject: [PATCH 692/814] LB policy API cleanup --- .../filters/client_channel/client_channel.cc | 19 +- .../ext/filters/client_channel/lb_policy.cc | 60 +++++ .../ext/filters/client_channel/lb_policy.h | 246 +++++++++--------- .../client_channel/lb_policy/grpclb/grpclb.cc | 5 +- .../lb_policy/pick_first/pick_first.cc | 2 +- .../lb_policy/round_robin/round_robin.cc | 6 +- .../client_channel/lb_policy/xds/xds.cc | 5 +- test/core/util/test_lb_policies.cc | 4 +- 8 files changed, 207 insertions(+), 140 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index ad00855be71..891df3baf6b 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -94,7 +94,7 @@ grpc_core::TraceFlag grpc_client_channel_routing_trace( struct external_connectivity_watcher; struct QueuedPick { - LoadBalancingPolicy::PickState pick; + LoadBalancingPolicy::PickArgs pick; grpc_call_element* elem; QueuedPick* next = nullptr; }; @@ -298,7 +298,7 @@ static grpc_error* do_ping_locked(channel_data* chand, grpc_transport_op* op) { GRPC_ERROR_UNREF(error); return new_error; } - LoadBalancingPolicy::PickState pick; + LoadBalancingPolicy::PickArgs pick; chand->picker->Pick(&pick, &error); if (pick.connected_subchannel != nullptr) { pick.connected_subchannel->Ping(op->send_ping.on_initiate, @@ -931,7 +931,7 @@ static void free_cached_send_op_data_for_completed_batch( // void maybe_inject_recv_trailing_metadata_ready_for_lb( - const LoadBalancingPolicy::PickState& pick, + const LoadBalancingPolicy::PickArgs& pick, grpc_transport_stream_op_batch* batch) { if (pick.recv_trailing_metadata_ready != nullptr) { *pick.original_recv_trailing_metadata_ready = @@ -2635,14 +2635,13 @@ static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem) { } } -static const char* pick_result_name( - LoadBalancingPolicy::SubchannelPicker::PickResult result) { +static const char* pick_result_name(LoadBalancingPolicy::PickResult result) { switch (result) { - case LoadBalancingPolicy::SubchannelPicker::PICK_COMPLETE: + case LoadBalancingPolicy::PICK_COMPLETE: return "COMPLETE"; - case LoadBalancingPolicy::SubchannelPicker::PICK_QUEUE: + case LoadBalancingPolicy::PICK_QUEUE: return "QUEUE"; - case LoadBalancingPolicy::SubchannelPicker::PICK_TRANSIENT_FAILURE: + case LoadBalancingPolicy::PICK_TRANSIENT_FAILURE: return "TRANSIENT_FAILURE"; } GPR_UNREACHABLE_CODE(return "UNKNOWN"); @@ -2692,7 +2691,7 @@ static void start_pick_locked(void* arg, grpc_error* error) { grpc_error_string(error)); } switch (pick_result) { - case LoadBalancingPolicy::SubchannelPicker::PICK_TRANSIENT_FAILURE: + case LoadBalancingPolicy::PICK_TRANSIENT_FAILURE: // If we're shutting down, fail all RPCs. if (chand->disconnect_error != GRPC_ERROR_NONE) { GRPC_ERROR_UNREF(error); @@ -2724,7 +2723,7 @@ static void start_pick_locked(void* arg, grpc_error* error) { // picker. GRPC_ERROR_UNREF(error); // Fallthrough - case LoadBalancingPolicy::SubchannelPicker::PICK_QUEUE: + case LoadBalancingPolicy::PICK_QUEUE: if (!calld->pick_queued) add_call_to_queued_picks_locked(elem); break; default: // PICK_COMPLETE diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 527b241eb6b..f370d745bb1 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -28,6 +28,10 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount( namespace grpc_core { +// +// LoadBalancingPolicy +// + LoadBalancingPolicy::LoadBalancingPolicy(Args args, intptr_t initial_refcount) : InternallyRefCounted(&grpc_trace_lb_policy_refcount, initial_refcount), combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")), @@ -39,6 +43,26 @@ LoadBalancingPolicy::~LoadBalancingPolicy() { GRPC_COMBINER_UNREF(combiner_, "lb_policy"); } +void LoadBalancingPolicy::Orphan() { + // Invoke ShutdownAndUnrefLocked() inside of the combiner. + // TODO(roth): Is this actually needed? We should already be in the + // combiner here. Note that if we directly call ShutdownLocked(), + // then we can probably remove the hack whereby the helper is + // destroyed at shutdown instead of at destruction. + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(&LoadBalancingPolicy::ShutdownAndUnrefLocked, this, + grpc_combiner_scheduler(combiner_)), + GRPC_ERROR_NONE); +} + +void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, + grpc_error* ignored) { + LoadBalancingPolicy* policy = static_cast(arg); + policy->ShutdownLocked(); + policy->channel_control_helper_.reset(); + policy->Unref(); +} + grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( const grpc_json* lb_config_array) { if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { @@ -65,4 +89,40 @@ grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( return nullptr; } +// +// LoadBalancingPolicy::QueuePicker +// + +LoadBalancingPolicy::PickResult LoadBalancingPolicy::QueuePicker::Pick( + PickArgs* pick, grpc_error** error) { + // We invoke the parent's ExitIdleLocked() via a closure instead + // of doing it directly here, for two reasons: + // 1. ExitIdleLocked() may cause the policy's state to change and + // a new picker to be delivered to the channel. If that new + // picker is delivered before ExitIdleLocked() returns, then by + // the time this function returns, the pick will already have + // been processed, and we'll be trying to re-process the same + // pick again, leading to a crash. + // 2. In a subsequent PR, we will split the data plane and control + // plane synchronization into separate combiners, at which + // point this will need to hop from the data plane combiner into + // the control plane combiner. + if (!exit_idle_called_) { + exit_idle_called_ = true; + parent_->Ref().release(); // ref held by closure. + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(&CallExitIdle, parent_.get(), + grpc_combiner_scheduler(parent_->combiner())), + GRPC_ERROR_NONE); + } + return PICK_QUEUE; +} + +void LoadBalancingPolicy::QueuePicker::CallExitIdle(void* arg, + grpc_error* error) { + LoadBalancingPolicy* parent = static_cast(arg); + parent->ExitIdleLocked(); + parent->Unref(); +} + } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 785458cbe67..30ff9c3fc95 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -37,6 +37,36 @@ namespace grpc_core { /// Interface for load balancing policies. /// +/// The following concepts are used here: +/// +/// Channel: An abstraction that manages connections to backend servers +/// on behalf of a client application. The application creates a channel +/// for a given server name and then sends RPCs on it, and the channel +/// figures out which backend server to send each RPC to. A channel +/// contains a resolver, a load balancing policy (or a tree of LB policies), +/// and a set of one or more subchannels. +/// +/// Subchannel: A subchannel represents a connection to one backend server. +/// The LB policy decides which subchannels to create, manages the +/// connectivity state of those subchannels, and decides which subchannel +/// to send any given RPC to. +/// +/// Resolver: A plugin that takes a gRPC server URI and resolves it to a +/// list of one or more addresses and a service config, as described +/// in https://github.com/grpc/grpc/blob/master/doc/naming.md. See +/// resolver.h for the resolver API. +/// +/// Load Balancing (LB) Policy: A plugin that takes a list of addresses +/// from the resolver, maintains and manages a subchannel for each +/// backend address, and decides which subchannel to send each RPC on. +/// An LB policy has two parts: +/// - A LoadBalancingPolicy, which deals with the control plane work of +/// managing subchannels. +/// - A SubchannelPicker, which handles the data plane work of +/// determining which subchannel a given RPC should be sent on. + +/// LoadBalacingPolicy API. +/// /// Note: All methods with a "Locked" suffix must be called from the /// combiner passed to the constructor. /// @@ -46,36 +76,70 @@ namespace grpc_core { // interested_parties() hooks from the API. class LoadBalancingPolicy : public InternallyRefCounted { public: - /// State used for an LB pick. - struct PickState { + /// Arguments used when picking a subchannel for an RPC. + struct PickArgs { + /// + /// Input parameters. + /// /// Initial metadata associated with the picking call. - /// This is both an input and output parameter; the LB policy may - /// use metadata here to influence its routing decision, and it may - /// add new metadata here to be sent with the call to the chosen backend. + /// The LB policy may use the existing metadata to influence its routing + /// decision, and it may add new metadata elements to be sent with the + /// call to the chosen backend. + // TODO(roth): Provide a more generic metadata API here. grpc_metadata_batch* initial_metadata = nullptr; /// Storage for LB token in \a initial_metadata, or nullptr if not used. // TODO(roth): Remove this from the API. Maybe have the LB policy // allocate this on the arena instead? grpc_linked_mdelem lb_token_mdelem_storage; + /// + /// Output parameters. + /// + /// Will be set to the selected subchannel, or nullptr on failure or when + /// the LB policy decides to drop the call. + RefCountedPtr connected_subchannel; /// Callback set by lb policy to be notified of trailing metadata. /// The callback must be scheduled on grpc_schedule_on_exec_ctx. + // TODO(roth): Provide a cleaner callback API. grpc_closure* recv_trailing_metadata_ready = nullptr; /// The address that will be set to point to the original /// recv_trailing_metadata_ready callback, to be invoked by the LB /// policy's recv_trailing_metadata_ready callback when complete. /// Must be non-null if recv_trailing_metadata_ready is non-null. + // TODO(roth): Consider making the recv_trailing_metadata closure a + // synchronous callback, in which case it is not responsible for + // chaining to the next callback, so this can be removed from the API. grpc_closure** original_recv_trailing_metadata_ready = nullptr; /// If this is not nullptr, then the client channel will point it to the /// call's trailing metadata before invoking recv_trailing_metadata_ready. /// If this is nullptr, then the callback will still be called. /// The lb does not have ownership of the metadata. + // TODO(roth): If we make this a synchronous callback, then this can + // be passed to the callback as a parameter and can be removed from + // the API here. grpc_metadata_batch** recv_trailing_metadata = nullptr; - /// Will be set to the selected subchannel, or nullptr on failure or when - /// the LB policy decides to drop the call. - RefCountedPtr connected_subchannel; }; - /// A picker is the object used to actual perform picks. + /// The result of picking a subchannel for an RPC. + enum PickResult { + // Pick complete. If connected_subchannel is non-null, client channel + // can immediately proceed with the call on connected_subchannel; + // otherwise, call should be dropped. + PICK_COMPLETE, + // Pick cannot be completed until something changes on the control + // plane. Client channel will queue the pick and try again the + // next time the picker is updated. + PICK_QUEUE, + // LB policy is in transient failure. If the pick is wait_for_ready, + // client channel will wait for the next picker and try again; + // otherwise, the call will be failed immediately (although it may + // be retried if the client channel is configured to do so). + // The Pick() method will set its error parameter if this value is + // returned. + PICK_TRANSIENT_FAILURE, + }; + + /// A subchannel picker is the object used to pick the subchannel to + /// use for a given RPC. /// /// Pickers are intended to encapsulate all of the state and logic /// needed on the data plane (i.e., to actually process picks for @@ -92,90 +156,14 @@ class LoadBalancingPolicy : public InternallyRefCounted { // synchronization mechanisms, to avoid lock contention between the two. class SubchannelPicker { public: - enum PickResult { - // Pick complete. If connected_subchannel is non-null, client channel - // can immediately proceed with the call on connected_subchannel; - // otherwise, call should be dropped. - PICK_COMPLETE, - // Pick cannot be completed until something changes on the control - // plane. Client channel will queue the pick and try again the - // next time the picker is updated. - PICK_QUEUE, - // LB policy is in transient failure. If the pick is wait_for_ready, - // client channel will wait for the next picker and try again; - // otherwise, the call will be failed immediately (although it may - // be retried if the client channel is configured to do so). - // The Pick() method will set its error parameter if this value is - // returned. - PICK_TRANSIENT_FAILURE, - }; - SubchannelPicker() = default; virtual ~SubchannelPicker() = default; - virtual PickResult Pick(PickState* pick, grpc_error** error) GRPC_ABSTRACT; + virtual PickResult Pick(PickArgs* pick, grpc_error** error) GRPC_ABSTRACT; GRPC_ABSTRACT_BASE_CLASS }; - // A picker that returns PICK_QUEUE for all picks. - // Also calls the parent LB policy's ExitIdleLocked() method when the - // first pick is seen. - class QueuePicker : public SubchannelPicker { - public: - explicit QueuePicker(RefCountedPtr parent) - : parent_(std::move(parent)) {} - - PickResult Pick(PickState* pick, grpc_error** error) override { - // We invoke the parent's ExitIdleLocked() via a closure instead - // of doing it directly here, for two reasons: - // 1. ExitIdleLocked() may cause the policy's state to change and - // a new picker to be delivered to the channel. If that new - // picker is delivered before ExitIdleLocked() returns, then by - // the time this function returns, the pick will already have - // been processed, and we'll be trying to re-process the same - // pick again, leading to a crash. - // 2. In a subsequent PR, we will split the data plane and control - // plane synchronization into separate combiners, at which - // point this will need to hop from the data plane combiner into - // the control plane combiner. - if (!exit_idle_called_) { - exit_idle_called_ = true; - parent_->Ref().release(); // ref held by closure. - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(&CallExitIdle, parent_.get(), - grpc_combiner_scheduler(parent_->combiner())), - GRPC_ERROR_NONE); - } - return PICK_QUEUE; - } - - private: - static void CallExitIdle(void* arg, grpc_error* error) { - LoadBalancingPolicy* parent = static_cast(arg); - parent->ExitIdleLocked(); - parent->Unref(); - } - - RefCountedPtr parent_; - bool exit_idle_called_ = false; - }; - - // A picker that returns PICK_TRANSIENT_FAILURE for all picks. - class TransientFailurePicker : public SubchannelPicker { - public: - explicit TransientFailurePicker(grpc_error* error) : error_(error) {} - ~TransientFailurePicker() { GRPC_ERROR_UNREF(error_); } - - PickResult Pick(PickState* pick, grpc_error** error) override { - *error = GRPC_ERROR_REF(error_); - return PICK_TRANSIENT_FAILURE; - } - - private: - grpc_error* error_; - }; - /// A proxy object used by the LB policy to communicate with the client /// channel. class ChannelControlHelper { @@ -188,6 +176,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { GRPC_ABSTRACT; /// Creates a channel with the specified target and channel args. + /// This can be used in cases where the LB policy needs to create a + /// channel for its own use (e.g., to talk to an external load balancer). virtual grpc_channel* CreateChannel( const char* target, const grpc_channel_args& args) GRPC_ABSTRACT; @@ -203,7 +193,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { GRPC_ABSTRACT_BASE_CLASS }; - // Configuration for an LB policy instance. + /// Configuration for an LB policy instance. + // TODO(roth): Find a better JSON representation for this API. class Config : public RefCounted { public: Config(const grpc_json* lb_config, @@ -234,9 +225,13 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// their constructor. UniquePtr channel_control_helper; /// Channel args. + // TODO(roth): Find a better channel args representation for this API. const grpc_channel_args* args = nullptr; }; + explicit LoadBalancingPolicy(Args args, intptr_t initial_refcount = 1); + virtual ~LoadBalancingPolicy(); + // Not copyable nor movable. LoadBalancingPolicy(const LoadBalancingPolicy&) = delete; LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete; @@ -262,40 +257,62 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual void ResetBackoffLocked() GRPC_ABSTRACT; /// Populates child_subchannels and child_channels with the uuids of this - /// LB policy's referenced children. This is not invoked from the - /// client_channel's combiner. The implementation is responsible for - /// providing its own synchronization. + /// LB policy's referenced children. + /// + /// This is not invoked from the client_channel's combiner. The + /// implementation is responsible for providing its own synchronization. virtual void FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* child_channels) GRPC_ABSTRACT; - void Orphan() override { - // Invoke ShutdownAndUnrefLocked() inside of the combiner. - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(&LoadBalancingPolicy::ShutdownAndUnrefLocked, this, - grpc_combiner_scheduler(combiner_)), - GRPC_ERROR_NONE); - } - - /// Returns the JSON node of policy (with both policy name and config content) - /// given the JSON node of a LoadBalancingConfig array. - static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array); - - grpc_pollset_set* interested_parties() const { return interested_parties_; } - void set_channelz_node( RefCountedPtr channelz_node) { channelz_node_ = std::move(channelz_node); } + grpc_pollset_set* interested_parties() const { return interested_parties_; } + + void Orphan() override; + + /// Returns the JSON node of policy (with both policy name and config content) + /// given the JSON node of a LoadBalancingConfig array. + static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array); + + // A picker that returns PICK_QUEUE for all picks. + // Also calls the parent LB policy's ExitIdleLocked() method when the + // first pick is seen. + class QueuePicker : public SubchannelPicker { + public: + explicit QueuePicker(RefCountedPtr parent) + : parent_(std::move(parent)) {} + + PickResult Pick(PickArgs* pick, grpc_error** error) override; + + private: + static void CallExitIdle(void* arg, grpc_error* error); + + RefCountedPtr parent_; + bool exit_idle_called_ = false; + }; + + // A picker that returns PICK_TRANSIENT_FAILURE for all picks. + class TransientFailurePicker : public SubchannelPicker { + public: + explicit TransientFailurePicker(grpc_error* error) : error_(error) {} + ~TransientFailurePicker() override { GRPC_ERROR_UNREF(error_); } + + PickResult Pick(PickArgs* pick, grpc_error** error) override { + *error = GRPC_ERROR_REF(error_); + return PICK_TRANSIENT_FAILURE; + } + + private: + grpc_error* error_; + }; + GRPC_ABSTRACT_BASE_CLASS protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - - explicit LoadBalancingPolicy(Args args, intptr_t initial_refcount = 1); - virtual ~LoadBalancingPolicy(); - grpc_combiner* combiner() const { return combiner_; } // Note: LB policies MUST NOT call any method on the helper from their @@ -309,18 +326,11 @@ class LoadBalancingPolicy : public InternallyRefCounted { return channelz_node_.get(); } - /// Shuts down the policy. Any pending picks that have not been - /// handed off to a new policy via HandOffPendingPicksLocked() will be - /// failed. + /// Shuts down the policy. virtual void ShutdownLocked() GRPC_ABSTRACT; private: - static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) { - LoadBalancingPolicy* policy = static_cast(arg); - policy->ShutdownLocked(); - policy->channel_control_helper_.reset(); - policy->Unref(); - } + static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored); /// Combiner under which LB policy actions take place. grpc_combiner* combiner_; diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 34fe88215fe..269415af6cc 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -252,7 +252,7 @@ class GrpcLb : public LoadBalancingPolicy { child_picker_(std::move(child_picker)), client_stats_(std::move(client_stats)) {} - PickResult Pick(PickState* pick, grpc_error** error) override; + PickResult Pick(PickArgs* pick, grpc_error** error) override; private: // Storing the address for logging, but not holding a ref. @@ -531,8 +531,7 @@ const char* GrpcLb::Serverlist::ShouldDrop() { // GrpcLb::Picker // -GrpcLb::Picker::PickResult GrpcLb::Picker::Pick(PickState* pick, - grpc_error** error) { +GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs* pick, grpc_error** error) { // Check if we should drop the call. const char* drop_token = serverlist_->ShouldDrop(); if (drop_token != nullptr) { diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 0ac0f41d4ef..1eff26d57ae 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -109,7 +109,7 @@ class PickFirst : public LoadBalancingPolicy { explicit Picker(RefCountedPtr connected_subchannel) : connected_subchannel_(std::move(connected_subchannel)) {} - PickResult Pick(PickState* pick, grpc_error** error) override { + PickResult Pick(PickArgs* pick, grpc_error** error) override { pick->connected_subchannel = connected_subchannel_; return PICK_COMPLETE; } diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 704a5c28c9e..01068c6dc49 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -156,7 +156,7 @@ class RoundRobin : public LoadBalancingPolicy { public: Picker(RoundRobin* parent, RoundRobinSubchannelList* subchannel_list); - PickResult Pick(PickState* pick, grpc_error** error) override; + PickResult Pick(PickArgs* pick, grpc_error** error) override; private: // Using pointer value only, no ref held -- do not dereference! @@ -227,8 +227,8 @@ RoundRobin::Picker::Picker(RoundRobin* parent, } } -RoundRobin::Picker::PickResult RoundRobin::Picker::Pick(PickState* pick, - grpc_error** error) { +RoundRobin::PickResult RoundRobin::Picker::Pick(PickArgs* pick, + grpc_error** error) { last_picked_index_ = (last_picked_index_ + 1) % subchannels_.size(); if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index eca41bf3a2e..1711c1ab28d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -260,7 +260,7 @@ class XdsLb : public LoadBalancingPolicy { : child_picker_(std::move(child_picker)), client_stats_(std::move(client_stats)) {} - PickResult Pick(PickState* pick, grpc_error** error) override; + PickResult Pick(PickArgs* pick, grpc_error** error) override; private: UniquePtr child_picker_; @@ -366,8 +366,7 @@ class XdsLb : public LoadBalancingPolicy { // XdsLb::Picker // -XdsLb::Picker::PickResult XdsLb::Picker::Pick(PickState* pick, - grpc_error** error) { +XdsLb::PickResult XdsLb::Picker::Pick(PickArgs* pick, grpc_error** error) { // TODO(roth): Add support for drop handling. // Forward pick to child policy. PickResult result = child_picker_->Pick(pick, error); diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 745162f637f..a8657b02546 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -121,7 +121,7 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy cb_(cb), user_data_(user_data) {} - PickResult Pick(PickState* pick, grpc_error** error) override { + PickResult Pick(PickArgs* pick, grpc_error** error) override { PickResult result = delegate_picker_->Pick(pick, error); if (result == PICK_COMPLETE && pick->connected_subchannel != nullptr) { New(pick, cb_, user_data_); // deletes itself @@ -171,7 +171,7 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy class TrailingMetadataHandler { public: - TrailingMetadataHandler(PickState* pick, + TrailingMetadataHandler(PickArgs* pick, InterceptRecvTrailingMetadataCallback cb, void* user_data) : cb_(cb), user_data_(user_data) { From 7f6ed9267f5ff146ca2554afdcdebe9395e9e81b Mon Sep 17 00:00:00 2001 From: Michael Behr Date: Thu, 14 Mar 2019 15:27:15 -0400 Subject: [PATCH 693/814] Convert metadata flag keys to lowercase. --- test/cpp/interop/client.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index ad83a5c4249..ccfd2bb0c45 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -104,7 +104,8 @@ namespace { // Parse the contents of FLAGS_additional_metadata into a map. Allow // alphanumeric characters and dashes in keys, and any character but semicolons -// in values. On failure, log an error and return false. +// in values. Convert keys to lowercase. On failure, log an error and return +// false. bool ParseAdditionalMetadataFlag( const grpc::string& flag, std::multimap* additional_metadata) { @@ -134,6 +135,13 @@ bool ParseAdditionalMetadataFlag( return false; } + // Convert to lowercase. + for (char& c : key) { + if (c >= 'A' && c <= 'Z') { + c += ('a' - 'A'); + } + } + gpr_log(GPR_INFO, "Adding additional metadata with key %s and value %s", key.c_str(), value.c_str()); additional_metadata->insert({key, value}); From 2b03154cf4cb28cedafecd34726e73baf54f0beb Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 14 Mar 2019 12:28:29 -0700 Subject: [PATCH 694/814] Update naming doc. --- doc/naming.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/doc/naming.md b/doc/naming.md index f7cda581f25..42045fd8337 100644 --- a/doc/naming.md +++ b/doc/naming.md @@ -67,14 +67,10 @@ Resolvers should be able to contact the authority and get a resolution that they return back to the gRPC client library. The returned contents include: -- A list of resolved addresses, each of which has three attributes: - - The address itself, including both IP address and port. - - A boolean indicating whether the address is a backend address (i.e., - the address to use to contact the server directly) or a balancer - address (for cases where [external load balancing](load-balancing.md) - is in use). - - The name of the balancer, if the address is a balancer address. - This will be used to perform peer authorization. +- A list of resolved addresses (both IP address and port). Each address + may have a set of arbitrary attributes (key/value pairs) associated with + it, which can be used to communicate information from the resolver to the + [load balancing](load-balancing.md) policy. - A [service config](service_config.md). The plugin API allows the resolvers to continuously watch an endpoint From b017c801b683d47160bdb3f98c19124fcbd1fc0a Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 14 Mar 2019 15:24:48 -0700 Subject: [PATCH 695/814] Add SPIFFE security stack to gRPC core --- BUILD | 4 + CMakeLists.txt | 40 + Makefile | 40 + build.yaml | 4 + config.m4 | 3 + config.w32 | 3 + gRPC-C++.podspec | 2 + gRPC-Core.podspec | 6 + grpc.gemspec | 4 + grpc.gyp | 2 + include/grpc/grpc_security.h | 51 +- package.xml | 4 + .../tls/grpc_tls_credentials_options.h | 9 +- .../credentials/tls/spiffe_credentials.cc | 129 ++ .../credentials/tls/spiffe_credentials.h | 62 + .../ssl/ssl_security_connector.cc | 237 +-- .../security/security_connector/ssl_utils.cc | 134 ++ .../security/security_connector/ssl_utils.h | 32 + .../tls/spiffe_security_connector.cc | 426 ++++ .../tls/spiffe_security_connector.h | 122 ++ src/core/tsi/ssl_transport_security.cc | 22 +- src/python/grpcio/grpc_core_dependencies.py | 2 + test/core/end2end/fixtures/h2_spiffe.cc | 290 +++ test/core/end2end/gen_build_yaml.py | 1 + test/core/end2end/generate_tests.bzl | 1 + tools/doxygen/Doxyfile.core.internal | 4 + .../generated/sources_and_headers.json | 23 + tools/run_tests/generated/tests.json | 1775 +++++++++++++++++ 28 files changed, 3231 insertions(+), 201 deletions(-) create mode 100644 src/core/lib/security/credentials/tls/spiffe_credentials.cc create mode 100644 src/core/lib/security/credentials/tls/spiffe_credentials.h create mode 100644 src/core/lib/security/security_connector/tls/spiffe_security_connector.cc create mode 100644 src/core/lib/security/security_connector/tls/spiffe_security_connector.h create mode 100644 test/core/end2end/fixtures/h2_spiffe.cc diff --git a/BUILD b/BUILD index 0b6fff354f4..afeacf0239a 100644 --- a/BUILD +++ b/BUILD @@ -1618,6 +1618,7 @@ grpc_cc_library( "src/core/lib/security/credentials/plugin/plugin_credentials.cc", "src/core/lib/security/credentials/ssl/ssl_credentials.cc", "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc", + "src/core/lib/security/credentials/tls/spiffe_credentials.cc", "src/core/lib/security/security_connector/alts/alts_security_connector.cc", "src/core/lib/security/security_connector/fake/fake_security_connector.cc", "src/core/lib/security/security_connector/load_system_roots_fallback.cc", @@ -1626,6 +1627,7 @@ grpc_cc_library( "src/core/lib/security/security_connector/security_connector.cc", "src/core/lib/security/security_connector/ssl/ssl_security_connector.cc", "src/core/lib/security/security_connector/ssl_utils.cc", + "src/core/lib/security/security_connector/tls/spiffe_security_connector.cc", "src/core/lib/security/transport/client_auth_filter.cc", "src/core/lib/security/transport/secure_endpoint.cc", "src/core/lib/security/transport/security_handshaker.cc", @@ -1653,6 +1655,7 @@ grpc_cc_library( "src/core/lib/security/credentials/plugin/plugin_credentials.h", "src/core/lib/security/credentials/ssl/ssl_credentials.h", "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h", + "src/core/lib/security/credentials/tls/spiffe_credentials.h", "src/core/lib/security/security_connector/alts/alts_security_connector.h", "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", @@ -1661,6 +1664,7 @@ grpc_cc_library( "src/core/lib/security/security_connector/security_connector.h", "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", "src/core/lib/security/security_connector/ssl_utils.h", + "src/core/lib/security/security_connector/tls/spiffe_security_connector.h", "src/core/lib/security/transport/auth_filters.h", "src/core/lib/security/transport/secure_endpoint.h", "src/core/lib/security/transport/security_handshaker.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 0030c9eb9af..2308582c2f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -482,6 +482,7 @@ add_dependencies(buildtests_c h2_proxy_test) add_dependencies(buildtests_c h2_sockpair_test) add_dependencies(buildtests_c h2_sockpair+trace_test) add_dependencies(buildtests_c h2_sockpair_1byte_test) +add_dependencies(buildtests_c h2_spiffe_test) add_dependencies(buildtests_c h2_ssl_test) add_dependencies(buildtests_c h2_ssl_proxy_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -1164,6 +1165,7 @@ add_library(grpc src/core/lib/security/credentials/plugin/plugin_credentials.cc src/core/lib/security/credentials/ssl/ssl_credentials.cc src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc + src/core/lib/security/credentials/tls/spiffe_credentials.cc src/core/lib/security/security_connector/alts/alts_security_connector.cc src/core/lib/security/security_connector/fake/fake_security_connector.cc src/core/lib/security/security_connector/load_system_roots_fallback.cc @@ -1172,6 +1174,7 @@ add_library(grpc src/core/lib/security/security_connector/security_connector.cc src/core/lib/security/security_connector/ssl/ssl_security_connector.cc src/core/lib/security/security_connector/ssl_utils.cc + src/core/lib/security/security_connector/tls/spiffe_security_connector.cc src/core/lib/security/transport/client_auth_filter.cc src/core/lib/security/transport/secure_endpoint.cc src/core/lib/security/transport/security_handshaker.cc @@ -1621,6 +1624,7 @@ add_library(grpc_cronet src/core/lib/security/credentials/plugin/plugin_credentials.cc src/core/lib/security/credentials/ssl/ssl_credentials.cc src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc + src/core/lib/security/credentials/tls/spiffe_credentials.cc src/core/lib/security/security_connector/alts/alts_security_connector.cc src/core/lib/security/security_connector/fake/fake_security_connector.cc src/core/lib/security/security_connector/load_system_roots_fallback.cc @@ -1629,6 +1633,7 @@ add_library(grpc_cronet src/core/lib/security/security_connector/security_connector.cc src/core/lib/security/security_connector/ssl/ssl_security_connector.cc src/core/lib/security/security_connector/ssl_utils.cc + src/core/lib/security/security_connector/tls/spiffe_security_connector.cc src/core/lib/security/transport/client_auth_filter.cc src/core/lib/security/transport/secure_endpoint.cc src/core/lib/security/transport/security_handshaker.cc @@ -17469,6 +17474,41 @@ target_link_libraries(h2_sockpair_1byte_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(h2_spiffe_test + test/core/end2end/fixtures/h2_spiffe.cc +) + + +target_include_directories(h2_spiffe_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(h2_spiffe_test + ${_gRPC_ALLTARGETS_LIBRARIES} + end2end_tests + grpc_test_util + grpc + gpr +) + + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_spiffe_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_spiffe_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(h2_ssl_test test/core/end2end/fixtures/h2_ssl.cc ) diff --git a/Makefile b/Makefile index 5a31d648b32..69a2abbc8ca 100644 --- a/Makefile +++ b/Makefile @@ -1361,6 +1361,7 @@ h2_proxy_test: $(BINDIR)/$(CONFIG)/h2_proxy_test h2_sockpair_test: $(BINDIR)/$(CONFIG)/h2_sockpair_test h2_sockpair+trace_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test h2_sockpair_1byte_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test +h2_spiffe_test: $(BINDIR)/$(CONFIG)/h2_spiffe_test h2_ssl_test: $(BINDIR)/$(CONFIG)/h2_ssl_test h2_ssl_proxy_test: $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test h2_uds_test: $(BINDIR)/$(CONFIG)/h2_uds_test @@ -1623,6 +1624,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_sockpair_test \ $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test \ + $(BINDIR)/$(CONFIG)/h2_spiffe_test \ $(BINDIR)/$(CONFIG)/h2_ssl_test \ $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test \ $(BINDIR)/$(CONFIG)/h2_uds_test \ @@ -3708,6 +3710,7 @@ LIBGRPC_SRC = \ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \ + src/core/lib/security/credentials/tls/spiffe_credentials.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ @@ -3716,6 +3719,7 @@ LIBGRPC_SRC = \ src/core/lib/security/security_connector/security_connector.cc \ src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ src/core/lib/security/security_connector/ssl_utils.cc \ + src/core/lib/security/security_connector/tls/spiffe_security_connector.cc \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ src/core/lib/security/transport/security_handshaker.cc \ @@ -4159,6 +4163,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \ + src/core/lib/security/credentials/tls/spiffe_credentials.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ @@ -4167,6 +4172,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/security/security_connector/security_connector.cc \ src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ src/core/lib/security/security_connector/ssl_utils.cc \ + src/core/lib/security/security_connector/tls/spiffe_security_connector.cc \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ src/core/lib/security/transport/security_handshaker.cc \ @@ -24353,6 +24359,38 @@ endif endif +H2_SPIFFE_TEST_SRC = \ + test/core/end2end/fixtures/h2_spiffe.cc \ + +H2_SPIFFE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_SPIFFE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/h2_spiffe_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/h2_spiffe_test: $(H2_SPIFFE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(H2_SPIFFE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_spiffe_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_spiffe.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_h2_spiffe_test: $(H2_SPIFFE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(H2_SPIFFE_TEST_OBJS:.o=.dep) +endif +endif + + H2_SSL_TEST_SRC = \ test/core/end2end/fixtures/h2_ssl.cc \ @@ -25572,6 +25610,7 @@ src/core/lib/security/credentials/oauth2/oauth2_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/plugin/plugin_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/ssl/ssl_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc: $(OPENSSL_DEP) +src/core/lib/security/credentials/tls/spiffe_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/alts/alts_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/fake/fake_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/load_system_roots_fallback.cc: $(OPENSSL_DEP) @@ -25580,6 +25619,7 @@ src/core/lib/security/security_connector/local/local_security_connector.cc: $(OP src/core/lib/security/security_connector/security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/ssl/ssl_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/ssl_utils.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/tls/spiffe_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/transport/client_auth_filter.cc: $(OPENSSL_DEP) src/core/lib/security/transport/secure_endpoint.cc: $(OPENSSL_DEP) src/core/lib/security/transport/security_handshaker.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index d8322b176b7..34b271f58de 100644 --- a/build.yaml +++ b/build.yaml @@ -833,6 +833,7 @@ filegroups: - src/core/lib/security/credentials/plugin/plugin_credentials.h - src/core/lib/security/credentials/ssl/ssl_credentials.h - src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h + - src/core/lib/security/credentials/tls/spiffe_credentials.h - src/core/lib/security/security_connector/alts/alts_security_connector.h - src/core/lib/security/security_connector/fake/fake_security_connector.h - src/core/lib/security/security_connector/load_system_roots.h @@ -841,6 +842,7 @@ filegroups: - src/core/lib/security/security_connector/security_connector.h - src/core/lib/security/security_connector/ssl/ssl_security_connector.h - src/core/lib/security/security_connector/ssl_utils.h + - src/core/lib/security/security_connector/tls/spiffe_security_connector.h - src/core/lib/security/transport/auth_filters.h - src/core/lib/security/transport/secure_endpoint.h - src/core/lib/security/transport/security_handshaker.h @@ -866,6 +868,7 @@ filegroups: - src/core/lib/security/credentials/plugin/plugin_credentials.cc - src/core/lib/security/credentials/ssl/ssl_credentials.cc - src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc + - src/core/lib/security/credentials/tls/spiffe_credentials.cc - src/core/lib/security/security_connector/alts/alts_security_connector.cc - src/core/lib/security/security_connector/fake/fake_security_connector.cc - src/core/lib/security/security_connector/load_system_roots_fallback.cc @@ -874,6 +877,7 @@ filegroups: - src/core/lib/security/security_connector/security_connector.cc - src/core/lib/security/security_connector/ssl/ssl_security_connector.cc - src/core/lib/security/security_connector/ssl_utils.cc + - src/core/lib/security/security_connector/tls/spiffe_security_connector.cc - src/core/lib/security/transport/client_auth_filter.cc - src/core/lib/security/transport/secure_endpoint.cc - src/core/lib/security/transport/security_handshaker.cc diff --git a/config.m4 b/config.m4 index bb23c2ed956..b920799f49b 100644 --- a/config.m4 +++ b/config.m4 @@ -282,6 +282,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \ + src/core/lib/security/credentials/tls/spiffe_credentials.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ @@ -290,6 +291,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/security/security_connector/security_connector.cc \ src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ src/core/lib/security/security_connector/ssl_utils.cc \ + src/core/lib/security/security_connector/tls/spiffe_security_connector.cc \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ src/core/lib/security/transport/security_handshaker.cc \ @@ -733,6 +735,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/fake) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/local) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/ssl) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/tls) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/transport) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/util) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/slice) diff --git a/config.w32 b/config.w32 index 35e52e15bd0..49eab2dc109 100644 --- a/config.w32 +++ b/config.w32 @@ -257,6 +257,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\security\\credentials\\plugin\\plugin_credentials.cc " + "src\\core\\lib\\security\\credentials\\ssl\\ssl_credentials.cc " + "src\\core\\lib\\security\\credentials\\tls\\grpc_tls_credentials_options.cc " + + "src\\core\\lib\\security\\credentials\\tls\\spiffe_credentials.cc " + "src\\core\\lib\\security\\security_connector\\alts\\alts_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\fake\\fake_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\load_system_roots_fallback.cc " + @@ -265,6 +266,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\security\\security_connector\\security_connector.cc " + "src\\core\\lib\\security\\security_connector\\ssl\\ssl_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\ssl_utils.cc " + + "src\\core\\lib\\security\\security_connector\\tls\\spiffe_security_connector.cc " + "src\\core\\lib\\security\\transport\\client_auth_filter.cc " + "src\\core\\lib\\security\\transport\\secure_endpoint.cc " + "src\\core\\lib\\security\\transport\\security_handshaker.cc " + @@ -748,6 +750,7 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\fake"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\local"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\ssl"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\tls"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\transport"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\util"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\slice"); diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index e755b7aa602..5a850bc8438 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -299,6 +299,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/plugin/plugin_credentials.h', 'src/core/lib/security/credentials/ssl/ssl_credentials.h', 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h', + 'src/core/lib/security/credentials/tls/spiffe_credentials.h', 'src/core/lib/security/security_connector/alts/alts_security_connector.h', 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', @@ -307,6 +308,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/security_connector/security_connector.h', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', 'src/core/lib/security/security_connector/ssl_utils.h', + 'src/core/lib/security/security_connector/tls/spiffe_security_connector.h', 'src/core/lib/security/transport/auth_filters.h', 'src/core/lib/security/transport/secure_endpoint.h', 'src/core/lib/security/transport/security_handshaker.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 7068f039870..42633186ac3 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -293,6 +293,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/plugin/plugin_credentials.h', 'src/core/lib/security/credentials/ssl/ssl_credentials.h', 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h', + 'src/core/lib/security/credentials/tls/spiffe_credentials.h', 'src/core/lib/security/security_connector/alts/alts_security_connector.h', 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', @@ -301,6 +302,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/security_connector/security_connector.h', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', 'src/core/lib/security/security_connector/ssl_utils.h', + 'src/core/lib/security/security_connector/tls/spiffe_security_connector.h', 'src/core/lib/security/transport/auth_filters.h', 'src/core/lib/security/transport/secure_endpoint.h', 'src/core/lib/security/transport/security_handshaker.h', @@ -728,6 +730,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc', + 'src/core/lib/security/credentials/tls/spiffe_credentials.cc', 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', @@ -736,6 +739,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/security_connector/security_connector.cc', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', 'src/core/lib/security/security_connector/ssl_utils.cc', + 'src/core/lib/security/security_connector/tls/spiffe_security_connector.cc', 'src/core/lib/security/transport/client_auth_filter.cc', 'src/core/lib/security/transport/secure_endpoint.cc', 'src/core/lib/security/transport/security_handshaker.cc', @@ -919,6 +923,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/plugin/plugin_credentials.h', 'src/core/lib/security/credentials/ssl/ssl_credentials.h', 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h', + 'src/core/lib/security/credentials/tls/spiffe_credentials.h', 'src/core/lib/security/security_connector/alts/alts_security_connector.h', 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', @@ -927,6 +932,7 @@ Pod::Spec.new do |s| 'src/core/lib/security/security_connector/security_connector.h', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', 'src/core/lib/security/security_connector/ssl_utils.h', + 'src/core/lib/security/security_connector/tls/spiffe_security_connector.h', 'src/core/lib/security/transport/auth_filters.h', 'src/core/lib/security/transport/secure_endpoint.h', 'src/core/lib/security/transport/security_handshaker.h', diff --git a/grpc.gemspec b/grpc.gemspec index 5c749dd285d..d9fc6ef0ebc 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -223,6 +223,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h ) s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h ) s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h ) + s.files += %w( src/core/lib/security/credentials/tls/spiffe_credentials.h ) s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/fake/fake_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/load_system_roots.h ) @@ -231,6 +232,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/security_connector/security_connector.h ) s.files += %w( src/core/lib/security/security_connector/ssl/ssl_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/ssl_utils.h ) + s.files += %w( src/core/lib/security/security_connector/tls/spiffe_security_connector.h ) s.files += %w( src/core/lib/security/transport/auth_filters.h ) s.files += %w( src/core/lib/security/transport/secure_endpoint.h ) s.files += %w( src/core/lib/security/transport/security_handshaker.h ) @@ -662,6 +664,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.cc ) s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.cc ) s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc ) + s.files += %w( src/core/lib/security/credentials/tls/spiffe_credentials.cc ) s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/fake/fake_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/load_system_roots_fallback.cc ) @@ -670,6 +673,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/security_connector/security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/ssl/ssl_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/ssl_utils.cc ) + s.files += %w( src/core/lib/security/security_connector/tls/spiffe_security_connector.cc ) s.files += %w( src/core/lib/security/transport/client_auth_filter.cc ) s.files += %w( src/core/lib/security/transport/secure_endpoint.cc ) s.files += %w( src/core/lib/security/transport/security_handshaker.cc ) diff --git a/grpc.gyp b/grpc.gyp index cce9f738fbd..b3795cbfd06 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -464,6 +464,7 @@ 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc', + 'src/core/lib/security/credentials/tls/spiffe_credentials.cc', 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', @@ -472,6 +473,7 @@ 'src/core/lib/security/security_connector/security_connector.cc', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', 'src/core/lib/security/security_connector/ssl_utils.cc', + 'src/core/lib/security/security_connector/tls/spiffe_security_connector.cc', 'src/core/lib/security/transport/client_auth_filter.cc', 'src/core/lib/security/transport/secure_endpoint.cc', 'src/core/lib/security/transport/security_handshaker.cc', diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 9b7822627e0..f1185d2b2a6 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -720,7 +720,7 @@ struct grpc_tls_credential_reload_arg { grpc_tls_on_credential_reload_done_cb cb; void* cb_user_data; grpc_tls_key_materials_config* key_materials_config; - grpc_status_code status; + grpc_ssl_certificate_config_reload_status status; const char* error_details; }; @@ -767,17 +767,19 @@ typedef void (*grpc_tls_on_server_authorization_check_done_cb)( /** A struct containing all information necessary to schedule/cancel a server authorization check request. cb and cb_user_data represent a gRPC-provided - callback and an argument passed to it. result will store the result of - server authorization check. target_name is the name of an endpoint the - channel is connecting to and certificate represents a complete certificate - chain including both signing and leaf certificates. status and error_details - contain information about errors occurred when a server authorization check - request is scheduled/cancelled. It is used for experimental purpose for now - and subject to change.*/ + callback and an argument passed to it. success will store the result of + server authorization check. That is, if success returns a non-zero value, it + means the authorization check passes and if returning zero, it means the + check fails. target_name is the name of an endpoint the channel is connecting + to and certificate represents a complete certificate chain including both + signing and leaf certificates. status and error_details contain information + about errors occurred when a server authorization check request is + scheduled/cancelled. It is used for experimental purpose for now and subject + to change.*/ struct grpc_tls_server_authorization_check_arg { grpc_tls_on_server_authorization_check_done_cb cb; void* cb_user_data; - int result; + int success; const char* target_name; const char* peer_cert; grpc_status_code status; @@ -813,6 +815,37 @@ grpc_tls_server_authorization_check_config_create( grpc_tls_server_authorization_check_arg* arg), void (*destruct)(void* config_user_data)); +/** --- SPIFFE channel/server credentials --- **/ + +/** + * This method creates a TLS SPIFFE channel credential object. + * It takes ownership of the options parameter. + * + * - options: grpc TLS credentials options instance. + * + * It returns the created credential object. + * + * It is used for experimental purpose for now and subject + * to change. + */ + +grpc_channel_credentials* grpc_tls_spiffe_credentials_create( + grpc_tls_credentials_options* options); + +/** + * This method creates a TLS server credential object. + * It takes ownership of the options parameter. + * + * - options: grpc TLS credentials options instance. + * + * It returns the created credential object. + * + * It is used for experimental purpose for now and subject + * to change. + */ +grpc_server_credentials* grpc_tls_spiffe_server_credentials_create( + grpc_tls_credentials_options* options); + #ifdef __cplusplus } #endif diff --git a/package.xml b/package.xml index be7e258b98a..48ccdeff73b 100644 --- a/package.xml +++ b/package.xml @@ -228,6 +228,7 @@ + @@ -236,6 +237,7 @@ + @@ -667,6 +669,7 @@ + @@ -675,6 +678,7 @@ + diff --git a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h index 71410d20a8f..aee9292acb8 100644 --- a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +++ b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h @@ -167,19 +167,16 @@ struct grpc_tls_credentials_options grpc_ssl_client_certificate_request_type cert_request_type() const { return cert_request_type_; } - const grpc_tls_key_materials_config* key_materials_config() const { + grpc_tls_key_materials_config* key_materials_config() const { return key_materials_config_.get(); } - const grpc_tls_credential_reload_config* credential_reload_config() const { + grpc_tls_credential_reload_config* credential_reload_config() const { return credential_reload_config_.get(); } - const grpc_tls_server_authorization_check_config* + grpc_tls_server_authorization_check_config* server_authorization_check_config() const { return server_authorization_check_config_.get(); } - grpc_tls_key_materials_config* mutable_key_materials_config() { - return key_materials_config_.get(); - } /* Setters for member fields. */ void set_cert_request_type( diff --git a/src/core/lib/security/credentials/tls/spiffe_credentials.cc b/src/core/lib/security/credentials/tls/spiffe_credentials.cc new file mode 100644 index 00000000000..da764936c76 --- /dev/null +++ b/src/core/lib/security/credentials/tls/spiffe_credentials.cc @@ -0,0 +1,129 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/security/credentials/tls/spiffe_credentials.h" + +#include + +#include +#include +#include +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/security/security_connector/tls/spiffe_security_connector.h" + +#define GRPC_CREDENTIALS_TYPE_SPIFFE "Spiffe" + +namespace { + +bool CredentialOptionSanityCheck(const grpc_tls_credentials_options* options, + bool is_client) { + if (options == nullptr) { + gpr_log(GPR_ERROR, "SPIFFE TLS credentials options is nullptr."); + return false; + } + if (options->key_materials_config() == nullptr && + options->credential_reload_config() == nullptr) { + gpr_log( + GPR_ERROR, + "SPIFFE TLS credentials options must specify either key materials or " + "credential reload config."); + return false; + } + if (!is_client && options->server_authorization_check_config() != nullptr) { + gpr_log(GPR_INFO, + "Server's credentials options should not contain server " + "authorization check config."); + } + return true; +} + +} // namespace + +SpiffeCredentials::SpiffeCredentials( + grpc_core::RefCountedPtr options) + : grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_SPIFFE), + options_(std::move(options)) {} + +SpiffeCredentials::~SpiffeCredentials() {} + +grpc_core::RefCountedPtr +SpiffeCredentials::create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target_name, const grpc_channel_args* args, + grpc_channel_args** new_args) { + const char* overridden_target_name = nullptr; + tsi_ssl_session_cache* ssl_session_cache = nullptr; + for (size_t i = 0; args != nullptr && i < args->num_args; i++) { + grpc_arg* arg = &args->args[i]; + if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 && + arg->type == GRPC_ARG_STRING) { + overridden_target_name = arg->value.string; + } + if (strcmp(arg->key, GRPC_SSL_SESSION_CACHE_ARG) == 0 && + arg->type == GRPC_ARG_POINTER) { + ssl_session_cache = + static_cast(arg->value.pointer.p); + } + } + grpc_core::RefCountedPtr sc = + SpiffeChannelSecurityConnector::CreateSpiffeChannelSecurityConnector( + this->Ref(), std::move(call_creds), target_name, + overridden_target_name, ssl_session_cache); + if (sc == nullptr) { + return nullptr; + } + grpc_arg new_arg = grpc_channel_arg_string_create( + (char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https"); + *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1); + return sc; +} + +SpiffeServerCredentials::SpiffeServerCredentials( + grpc_core::RefCountedPtr options) + : grpc_server_credentials(GRPC_CREDENTIALS_TYPE_SPIFFE), + options_(std::move(options)) {} + +SpiffeServerCredentials::~SpiffeServerCredentials() {} + +grpc_core::RefCountedPtr +SpiffeServerCredentials::create_security_connector() { + return SpiffeServerSecurityConnector::CreateSpiffeServerSecurityConnector( + this->Ref()); +} + +grpc_channel_credentials* grpc_tls_spiffe_credentials_create( + grpc_tls_credentials_options* options) { + if (!CredentialOptionSanityCheck(options, true /* is_client */)) { + return nullptr; + } + return grpc_core::New( + grpc_core::RefCountedPtr(options)); +} + +grpc_server_credentials* grpc_tls_spiffe_server_credentials_create( + grpc_tls_credentials_options* options) { + if (!CredentialOptionSanityCheck(options, false /* is_client */)) { + return nullptr; + } + return grpc_core::New( + grpc_core::RefCountedPtr(options)); +} diff --git a/src/core/lib/security/credentials/tls/spiffe_credentials.h b/src/core/lib/security/credentials/tls/spiffe_credentials.h new file mode 100644 index 00000000000..4985fda4a7e --- /dev/null +++ b/src/core/lib/security/credentials/tls/spiffe_credentials.h @@ -0,0 +1,62 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_SPIFFE_CREDENTIALS_H +#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_SPIFFE_CREDENTIALS_H + +#include + +#include + +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" + +class SpiffeCredentials final : public grpc_channel_credentials { + public: + explicit SpiffeCredentials( + grpc_core::RefCountedPtr options); + ~SpiffeCredentials() override; + + grpc_core::RefCountedPtr + create_security_connector( + grpc_core::RefCountedPtr call_creds, + const char* target_name, const grpc_channel_args* args, + grpc_channel_args** new_args) override; + + const grpc_tls_credentials_options& options() const { return *options_; } + + private: + grpc_core::RefCountedPtr options_; +}; + +class SpiffeServerCredentials final : public grpc_server_credentials { + public: + explicit SpiffeServerCredentials( + grpc_core::RefCountedPtr options); + ~SpiffeServerCredentials() override; + + grpc_core::RefCountedPtr + create_security_connector() override; + + const grpc_tls_credentials_options& options() const { return *options_; } + + private: + grpc_core::RefCountedPtr options_; +}; + +#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_SPIFFE_CREDENTIALS_H */ diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index 8a00bbb82ed..39c5434208b 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -41,33 +41,6 @@ #include "src/core/tsi/transport_security.h" namespace { -grpc_error* ssl_check_peer( - const char* peer_name, const tsi_peer* peer, - grpc_core::RefCountedPtr* auth_context) { -#if TSI_OPENSSL_ALPN_SUPPORT - /* Check the ALPN if ALPN is supported. */ - const tsi_peer_property* p = - tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); - if (p == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: missing selected ALPN property."); - } - if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: invalid ALPN value."); - } -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ - /* Check the peer name if specified. */ - if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { - char* msg; - gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name); - grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); - return error; - } - *auth_context = grpc_ssl_peer_to_auth_context(peer); - return GRPC_ERROR_NONE; -} class grpc_ssl_channel_security_connector final : public grpc_channel_security_connector { @@ -96,34 +69,10 @@ class grpc_ssl_channel_security_connector final } grpc_security_status InitializeHandshakerFactory( - const grpc_ssl_config* config, const char* pem_root_certs, - const tsi_ssl_root_certs_store* root_store, - tsi_ssl_session_cache* ssl_session_cache) { - bool has_key_cert_pair = - config->pem_key_cert_pair != nullptr && - config->pem_key_cert_pair->private_key != nullptr && - config->pem_key_cert_pair->cert_chain != nullptr; - tsi_ssl_client_handshaker_options options; - GPR_DEBUG_ASSERT(pem_root_certs != nullptr); - options.pem_root_certs = pem_root_certs; - options.root_store = root_store; - options.alpn_protocols = - grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); - if (has_key_cert_pair) { - options.pem_key_cert_pair = config->pem_key_cert_pair; - } - options.cipher_suites = grpc_get_ssl_cipher_suites(); - options.session_cache = ssl_session_cache; - const tsi_result result = - tsi_create_ssl_client_handshaker_factory_with_options( - &options, &client_handshaker_factory_); - gpr_free((void*)options.alpn_protocols); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - return GRPC_SECURITY_ERROR; - } - return GRPC_SECURITY_OK; + const grpc_ssl_config* config, tsi_ssl_session_cache* ssl_session_cache) { + return grpc_ssl_tsi_client_handshaker_factory_init( + config->pem_key_cert_pair, config->pem_root_certs, ssl_session_cache, + &client_handshaker_factory_); } void add_handshakers(grpc_pollset_set* interested_parties, @@ -150,29 +99,35 @@ class grpc_ssl_channel_security_connector final const char* target_name = overridden_target_name_ != nullptr ? overridden_target_name_ : target_name_; - grpc_error* error = ssl_check_peer(target_name, &peer, auth_context); - if (error == GRPC_ERROR_NONE && - verify_options_->verify_peer_callback != nullptr) { - const tsi_peer_property* p = - tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); - if (p == nullptr) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: missing pem cert property."); - } else { - char* peer_pem = static_cast(gpr_malloc(p->value.length + 1)); - memcpy(peer_pem, p->value.data, p->value.length); - peer_pem[p->value.length] = '\0'; - int callback_status = verify_options_->verify_peer_callback( - target_name, peer_pem, - verify_options_->verify_peer_callback_userdata); - gpr_free(peer_pem); - if (callback_status) { - char* msg; - gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", - callback_status); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); + grpc_error* error = grpc_ssl_check_alpn(&peer); + if (error == GRPC_ERROR_NONE) { + error = grpc_ssl_check_peer_name(target_name, &peer); + if (error == GRPC_ERROR_NONE) { + if (verify_options_->verify_peer_callback != nullptr) { + const tsi_peer_property* p = + tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); + if (p == nullptr) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing pem cert property."); + } else { + char* peer_pem = + static_cast(gpr_malloc(p->value.length + 1)); + memcpy(peer_pem, p->value.data, p->value.length); + peer_pem[p->value.length] = '\0'; + int callback_status = verify_options_->verify_peer_callback( + target_name, peer_pem, + verify_options_->verify_peer_callback_userdata); + gpr_free(peer_pem); + if (callback_status) { + char* msg; + gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", + callback_status); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + } + } } + *auth_context = grpc_ssl_peer_to_auth_context(&peer); } } GRPC_CLOSURE_SCHED(on_peer_checked, error); @@ -184,34 +139,16 @@ class grpc_ssl_channel_security_connector final reinterpret_cast(other_sc); int c = channel_security_connector_cmp(other); if (c != 0) return c; - c = strcmp(target_name_, other->target_name_); - if (c != 0) return c; - return (overridden_target_name_ == nullptr || - other->overridden_target_name_ == nullptr) - ? GPR_ICMP(overridden_target_name_, - other->overridden_target_name_) - : strcmp(overridden_target_name_, - other->overridden_target_name_); + return grpc_ssl_cmp_target_name(target_name_, other->target_name_, + overridden_target_name_, + other->overridden_target_name_); } bool check_call_host(const char* host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { - grpc_security_status status = GRPC_SECURITY_ERROR; - tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); - if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; - /* If the target name was overridden, then the original target_name was - 'checked' transitively during the previous peer check at the end of the - handshake. */ - if (overridden_target_name_ != nullptr && strcmp(host, target_name_) == 0) { - status = GRPC_SECURITY_OK; - } - if (status != GRPC_SECURITY_OK) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "call host does not match SSL server name"); - } - grpc_shallow_peer_destruct(&peer); - return true; + return grpc_ssl_check_call_host(host, target_name_, overridden_target_name_, + auth_context, on_call_host_checked, error); } void cancel_check_call_host(grpc_closure* on_call_host_checked, @@ -248,43 +185,25 @@ class grpc_ssl_server_security_connector } grpc_security_status InitializeHandshakerFactory() { + grpc_security_status retval = GRPC_SECURITY_OK; if (has_cert_config_fetcher()) { // Load initial credentials from certificate_config_fetcher: if (!try_fetch_ssl_server_credentials()) { gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher."); - return GRPC_SECURITY_ERROR; + retval = GRPC_SECURITY_ERROR; } } else { auto* server_credentials = static_cast(server_creds()); - size_t num_alpn_protocols = 0; - const char** alpn_protocol_strings = - grpc_fill_alpn_protocol_strings(&num_alpn_protocols); - tsi_ssl_server_handshaker_options options; - options.pem_key_cert_pairs = - server_credentials->config().pem_key_cert_pairs; - options.num_key_cert_pairs = - server_credentials->config().num_key_cert_pairs; - options.pem_client_root_certs = - server_credentials->config().pem_root_certs; - options.client_certificate_request = - grpc_get_tsi_client_certificate_request_type( - server_credentials->config().client_certificate_request); - options.cipher_suites = grpc_get_ssl_cipher_suites(); - options.alpn_protocols = alpn_protocol_strings; - options.num_alpn_protocols = static_cast(num_alpn_protocols); - const tsi_result result = - tsi_create_ssl_server_handshaker_factory_with_options( - &options, &server_handshaker_factory_); - gpr_free((void*)alpn_protocol_strings); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - return GRPC_SECURITY_ERROR; - } + retval = grpc_ssl_tsi_server_handshaker_factory_init( + server_credentials->config().pem_key_cert_pairs, + server_credentials->config().num_key_cert_pairs, + server_credentials->config().pem_root_certs, + server_credentials->config().client_certificate_request, + &server_handshaker_factory_); } - return GRPC_SECURITY_OK; + return retval; } void add_handshakers(grpc_pollset_set* interested_parties, @@ -306,7 +225,8 @@ class grpc_ssl_server_security_connector void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { - grpc_error* error = ssl_check_peer(nullptr, &peer, auth_context); + grpc_error* error = grpc_ssl_check_alpn(&peer); + *auth_context = grpc_ssl_peer_to_auth_context(&peer); tsi_peer_destruct(&peer); GRPC_CLOSURE_SCHED(on_peer_checked, error); } @@ -323,9 +243,7 @@ class grpc_ssl_server_security_connector bool try_fetch_ssl_server_credentials() { grpc_ssl_server_certificate_config* certificate_config = nullptr; bool status; - if (!has_cert_config_fetcher()) return false; - grpc_ssl_server_credentials* server_creds = static_cast(this->mutable_server_creds()); grpc_ssl_certificate_config_reload_status cb_result = @@ -342,7 +260,6 @@ class grpc_ssl_server_security_connector "use previously-loaded credentials."); status = false; } - if (certificate_config != nullptr) { grpc_ssl_server_certificate_config_destroy(certificate_config); } @@ -361,34 +278,18 @@ class grpc_ssl_server_security_connector "config."); return false; } - gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config); - - size_t num_alpn_protocols = 0; - const char** alpn_protocol_strings = - grpc_fill_alpn_protocol_strings(&num_alpn_protocols); - tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; - const grpc_ssl_server_credentials* server_creds = + tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = + grpc_convert_grpc_to_tsi_cert_pairs(config->pem_key_cert_pairs, + config->num_key_cert_pairs); + const grpc_ssl_server_credentials* server_credentials = static_cast(this->server_creds()); - GPR_DEBUG_ASSERT(config->pem_root_certs != nullptr); - tsi_ssl_server_handshaker_options options; - options.pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( - config->pem_key_cert_pairs, config->num_key_cert_pairs); - options.num_key_cert_pairs = config->num_key_cert_pairs; - options.pem_client_root_certs = config->pem_root_certs; - options.client_certificate_request = - grpc_get_tsi_client_certificate_request_type( - server_creds->config().client_certificate_request); - options.cipher_suites = grpc_get_ssl_cipher_suites(); - options.alpn_protocols = alpn_protocol_strings; - options.num_alpn_protocols = static_cast(num_alpn_protocols); - tsi_result result = tsi_create_ssl_server_handshaker_factory_with_options( - &options, &new_handshaker_factory); - gpr_free((void*)options.pem_key_cert_pairs); - gpr_free((void*)alpn_protocol_strings); - - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); + tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; + grpc_security_status retval = grpc_ssl_tsi_server_handshaker_factory_init( + pem_key_cert_pairs, config->num_key_cert_pairs, config->pem_root_certs, + server_credentials->config().client_certificate_request, + &new_handshaker_factory); + gpr_free(pem_key_cert_pairs); + if (retval != GRPC_SECURITY_OK) { return false; } set_server_handshaker_factory(new_handshaker_factory); @@ -418,28 +319,12 @@ grpc_ssl_channel_security_connector_create( gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); return nullptr; } - - const char* pem_root_certs; - const tsi_ssl_root_certs_store* root_store; - if (config->pem_root_certs == nullptr) { - // Use default root certificates. - pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); - if (pem_root_certs == nullptr) { - gpr_log(GPR_ERROR, "Could not get default pem root certs."); - return nullptr; - } - root_store = grpc_core::DefaultSslRootStore::GetRootStore(); - } else { - pem_root_certs = config->pem_root_certs; - root_store = nullptr; - } - grpc_core::RefCountedPtr c = grpc_core::MakeRefCounted( std::move(channel_creds), std::move(request_metadata_creds), config, target_name, overridden_target_name); - const grpc_security_status result = c->InitializeHandshakerFactory( - config, pem_root_certs, root_store, ssl_session_cache); + const grpc_security_status result = + c->InitializeHandshakerFactory(config, ssl_session_cache); if (result != GRPC_SECURITY_OK) { return nullptr; } diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index 29030f07ad6..c9af5ca6ad0 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -112,6 +112,55 @@ grpc_get_tsi_client_certificate_request_type( } } +grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer) { +#if TSI_OPENSSL_ALPN_SUPPORT + /* Check the ALPN if ALPN is supported. */ + const tsi_peer_property* p = + tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); + if (p == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing selected ALPN property."); + } + if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: invalid ALPN value."); + } +#endif /* TSI_OPENSSL_ALPN_SUPPORT */ + return GRPC_ERROR_NONE; +} + +grpc_error* grpc_ssl_check_peer_name(const char* peer_name, + const tsi_peer* peer) { + /* Check the peer name if specified. */ + if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { + char* msg; + gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name); + grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + return error; + } + return GRPC_ERROR_NONE; +} + +bool grpc_ssl_check_call_host(const char* host, const char* target_name, + const char* overridden_target_name, + grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) { + grpc_security_status status = GRPC_SECURITY_ERROR; + tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); + if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; + if (overridden_target_name != nullptr && strcmp(host, target_name) == 0) { + status = GRPC_SECURITY_OK; + } + if (status != GRPC_SECURITY_OK) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "call host does not match SSL server name"); + } + grpc_shallow_peer_destruct(&peer); + return true; +} + const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols) { GPR_ASSERT(num_alpn_protocols != nullptr); *num_alpn_protocols = grpc_chttp2_num_alpn_versions(); @@ -142,6 +191,18 @@ int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) { return r; } +bool grpc_ssl_cmp_target_name(const char* target_name, + const char* other_target_name, + const char* overridden_target_name, + const char* other_overridden_target_name) { + int c = strcmp(target_name, other_target_name); + if (c != 0) return c; + return (overridden_target_name == nullptr || + other_overridden_target_name == nullptr) + ? GPR_ICMP(overridden_target_name, other_overridden_target_name) + : strcmp(overridden_target_name, other_overridden_target_name); +} + grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( const tsi_peer* peer) { size_t i; @@ -230,6 +291,79 @@ void grpc_shallow_peer_destruct(tsi_peer* peer) { if (peer->properties != nullptr) gpr_free(peer->properties); } +grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init( + tsi_ssl_pem_key_cert_pair* pem_key_cert_pair, const char* pem_root_certs, + tsi_ssl_session_cache* ssl_session_cache, + tsi_ssl_client_handshaker_factory** handshaker_factory) { + const char* root_certs; + const tsi_ssl_root_certs_store* root_store; + if (pem_root_certs == nullptr) { + // Use default root certificates. + root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); + if (root_certs == nullptr) { + gpr_log(GPR_ERROR, "Could not get default pem root certs."); + return GRPC_SECURITY_ERROR; + } + root_store = grpc_core::DefaultSslRootStore::GetRootStore(); + } else { + root_certs = pem_root_certs; + root_store = nullptr; + } + bool has_key_cert_pair = pem_key_cert_pair != nullptr && + pem_key_cert_pair->private_key != nullptr && + pem_key_cert_pair->cert_chain != nullptr; + tsi_ssl_client_handshaker_options options; + GPR_DEBUG_ASSERT(root_certs != nullptr); + options.pem_root_certs = root_certs; + options.root_store = root_store; + options.alpn_protocols = + grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); + if (has_key_cert_pair) { + options.pem_key_cert_pair = pem_key_cert_pair; + } + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.session_cache = ssl_session_cache; + const tsi_result result = + tsi_create_ssl_client_handshaker_factory_with_options(&options, + handshaker_factory); + gpr_free((void*)options.alpn_protocols); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return GRPC_SECURITY_ERROR; + } + return GRPC_SECURITY_OK; +} + +grpc_security_status grpc_ssl_tsi_server_handshaker_factory_init( + tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs, + const char* pem_root_certs, + grpc_ssl_client_certificate_request_type client_certificate_request, + tsi_ssl_server_handshaker_factory** handshaker_factory) { + size_t num_alpn_protocols = 0; + const char** alpn_protocol_strings = + grpc_fill_alpn_protocol_strings(&num_alpn_protocols); + tsi_ssl_server_handshaker_options options; + options.pem_key_cert_pairs = pem_key_cert_pairs; + options.num_key_cert_pairs = num_key_cert_pairs; + options.pem_client_root_certs = pem_root_certs; + options.client_certificate_request = + grpc_get_tsi_client_certificate_request_type(client_certificate_request); + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.alpn_protocols = alpn_protocol_strings; + options.num_alpn_protocols = static_cast(num_alpn_protocols); + const tsi_result result = + tsi_create_ssl_server_handshaker_factory_with_options(&options, + handshaker_factory); + gpr_free((void*)alpn_protocol_strings); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return GRPC_SECURITY_ERROR; + } + return GRPC_SECURITY_OK; +} + /* --- Ssl cache implementation. --- */ grpc_ssl_session_cache* grpc_ssl_session_cache_create_lru(size_t capacity) { diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h index 972ca439dea..080e277f944 100644 --- a/src/core/lib/security/security_connector/ssl_utils.h +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -27,7 +27,10 @@ #include #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/tsi/ssl_transport_security.h" +#include "src/core/tsi/transport_security.h" #include "src/core/tsi/transport_security_interface.h" /* --- Util. --- */ @@ -35,6 +38,23 @@ /* --- URL schemes. --- */ #define GRPC_SSL_URL_SCHEME "https" +/* Check ALPN information returned from SSL handshakes. */ +grpc_error* grpc_ssl_check_alpn(const tsi_peer* peer); + +/* Check peer name information returned from SSL handshakes. */ +grpc_error* grpc_ssl_check_peer_name(const char* peer_name, + const tsi_peer* peer); +/* Compare targer_name information extracted from SSL security connectors. */ +bool grpc_ssl_cmp_target_name(const char* target_name, + const char* other_target_name, + const char* overridden_target_name, + const char* other_overridden_target_name); +/* Check the host that will be set for a call is acceptable.*/ +bool grpc_ssl_check_call_host(const char* host, const char* target_name, + const char* overridden_target_name, + grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error); /* Return HTTP2-compliant cipher suites that gRPC accepts by default. */ const char* grpc_get_ssl_cipher_suites(void); @@ -47,6 +67,18 @@ grpc_get_tsi_client_certificate_request_type( /* Return an array of strings containing alpn protocols. */ const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols); +/* Initialize TSI SSL server/client handshaker factory. */ +grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init( + tsi_ssl_pem_key_cert_pair* key_cert_pair, const char* pem_root_certs, + tsi_ssl_session_cache* ssl_session_cache, + tsi_ssl_client_handshaker_factory** handshaker_factory); + +grpc_security_status grpc_ssl_tsi_server_handshaker_factory_init( + tsi_ssl_pem_key_cert_pair* key_cert_pairs, size_t num_key_cert_pairs, + const char* pem_root_certs, + grpc_ssl_client_certificate_request_type client_certificate_request, + tsi_ssl_server_handshaker_factory** handshaker_factory); + /* Exposed for testing only. */ grpc_core::RefCountedPtr grpc_ssl_peer_to_auth_context( const tsi_peer* peer); diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc new file mode 100644 index 00000000000..075b1c9d53c --- /dev/null +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc @@ -0,0 +1,426 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/security/security_connector/tls/spiffe_security_connector.h" + +#include +#include + +#include +#include +#include +#include + +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/security/credentials/ssl/ssl_credentials.h" +#include "src/core/lib/security/credentials/tls/spiffe_credentials.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" +#include "src/core/lib/security/transport/security_handshaker.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/transport/transport.h" +#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/tsi/transport_security.h" + +namespace { + +tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair( + const grpc_tls_key_materials_config::PemKeyCertPairList& cert_pair_list) { + tsi_ssl_pem_key_cert_pair* tsi_pairs = nullptr; + size_t num_key_cert_pairs = cert_pair_list.size(); + if (num_key_cert_pairs > 0) { + GPR_ASSERT(cert_pair_list.data() != nullptr); + tsi_pairs = static_cast( + gpr_zalloc(num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair))); + } + for (size_t i = 0; i < num_key_cert_pairs; i++) { + GPR_ASSERT(cert_pair_list[i].private_key() != nullptr); + GPR_ASSERT(cert_pair_list[i].cert_chain() != nullptr); + tsi_pairs[i].cert_chain = gpr_strdup(cert_pair_list[i].cert_chain()); + tsi_pairs[i].private_key = gpr_strdup(cert_pair_list[i].private_key()); + } + return tsi_pairs; +} + +/** -- Util function to populate SPIFFE server/channel credentials. -- */ +grpc_core::RefCountedPtr +PopulateSpiffeCredentials(const grpc_tls_credentials_options& options) { + GPR_ASSERT(options.credential_reload_config() != nullptr || + options.key_materials_config() != nullptr); + grpc_core::RefCountedPtr key_materials_config; + /* Use credential reload config to fetch credentials. */ + if (options.credential_reload_config() != nullptr) { + grpc_tls_credential_reload_arg* arg = + grpc_core::New(); + key_materials_config = grpc_tls_key_materials_config_create()->Ref(); + arg->key_materials_config = key_materials_config.get(); + int result = options.credential_reload_config()->Schedule(arg); + if (result) { + /* Do not support async credential reload. */ + gpr_log(GPR_ERROR, "Async credential reload is unsupported now."); + } else { + grpc_ssl_certificate_config_reload_status status = arg->status; + if (status == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { + gpr_log(GPR_DEBUG, "Credential does not change after reload."); + } else if (status == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL) { + gpr_log(GPR_ERROR, "Credential reload failed with an error: %s", + arg->error_details); + } + } + gpr_free((void*)arg->error_details); + grpc_core::Delete(arg); + /* Use existing key materials config. */ + } else { + key_materials_config = options.key_materials_config()->Ref(); + } + return key_materials_config; +} + +} // namespace + +SpiffeChannelSecurityConnector::SpiffeChannelSecurityConnector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name) + : grpc_channel_security_connector(GRPC_SSL_URL_SCHEME, + std::move(channel_creds), + std::move(request_metadata_creds)), + overridden_target_name_(overridden_target_name == nullptr + ? nullptr + : gpr_strdup(overridden_target_name)) { + check_arg_ = ServerAuthorizationCheckArgCreate(this); + char* port; + gpr_split_host_port(target_name, &target_name_, &port); + gpr_free(port); +} + +SpiffeChannelSecurityConnector::~SpiffeChannelSecurityConnector() { + if (target_name_ != nullptr) { + gpr_free(target_name_); + } + if (overridden_target_name_ != nullptr) { + gpr_free(overridden_target_name_); + } + if (client_handshaker_factory_ != nullptr) { + tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); + } + ServerAuthorizationCheckArgDestroy(check_arg_); +} + +void SpiffeChannelSecurityConnector::add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) { + // Instantiate TSI handshaker. + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( + client_handshaker_factory_, + overridden_target_name_ != nullptr ? overridden_target_name_ + : target_name_, + &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this)); +} + +void SpiffeChannelSecurityConnector::check_peer( + tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + const char* target_name = overridden_target_name_ != nullptr + ? overridden_target_name_ + : target_name_; + grpc_error* error = grpc_ssl_check_alpn(&peer); + if (error != GRPC_ERROR_NONE) { + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); + return; + } + *auth_context = grpc_ssl_peer_to_auth_context(&peer); + const SpiffeCredentials* creds = + static_cast(channel_creds()); + const grpc_tls_server_authorization_check_config* config = + creds->options().server_authorization_check_config(); + /* If server authorization config is not null, use it to perform + * server authorizaiton check. */ + if (config != nullptr) { + const tsi_peer_property* p = + tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); + if (p == nullptr) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing pem cert property."); + } else { + char* peer_pem = static_cast(gpr_malloc(p->value.length + 1)); + memcpy(peer_pem, p->value.data, p->value.length); + peer_pem[p->value.length] = '\0'; + GPR_ASSERT(check_arg_ != nullptr); + check_arg_->peer_cert = check_arg_->peer_cert == nullptr + ? gpr_strdup(peer_pem) + : check_arg_->peer_cert; + check_arg_->target_name = check_arg_->target_name == nullptr + ? gpr_strdup(target_name) + : check_arg_->target_name; + on_peer_checked_ = on_peer_checked; + gpr_free(peer_pem); + int callback_status = config->Schedule(check_arg_); + /* Server authorization check is handled asynchronously. */ + if (callback_status) { + tsi_peer_destruct(&peer); + return; + } + /* Server authorization check is handled synchronously. */ + error = ProcessServerAuthorizationCheckResult(check_arg_); + } + } + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); +} + +int SpiffeChannelSecurityConnector::cmp( + const grpc_security_connector* other_sc) const { + auto* other = + reinterpret_cast(other_sc); + int c = channel_security_connector_cmp(other); + if (c != 0) { + return c; + } + return grpc_ssl_cmp_target_name(target_name_, other->target_name_, + overridden_target_name_, + other->overridden_target_name_); +} + +bool SpiffeChannelSecurityConnector::check_call_host( + const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, grpc_error** error) { + return grpc_ssl_check_call_host(host, target_name_, overridden_target_name_, + auth_context, on_call_host_checked, error); +} + +void SpiffeChannelSecurityConnector::cancel_check_call_host( + grpc_closure* on_call_host_checked, grpc_error* error) { + GRPC_ERROR_UNREF(error); +} + +grpc_core::RefCountedPtr +SpiffeChannelSecurityConnector::CreateSpiffeChannelSecurityConnector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache) { + if (channel_creds == nullptr) { + gpr_log(GPR_ERROR, + "channel_creds is nullptr in " + "SpiffeChannelSecurityConnectorCreate()"); + return nullptr; + } + if (target_name == nullptr) { + gpr_log(GPR_ERROR, + "target_name is nullptr in " + "SpiffeChannelSecurityConnectorCreate()"); + return nullptr; + } + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + std::move(channel_creds), std::move(request_metadata_creds), + target_name, overridden_target_name); + if (c->InitializeHandshakerFactory(ssl_session_cache) != GRPC_SECURITY_OK) { + return nullptr; + } + return c; +} + +grpc_security_status +SpiffeChannelSecurityConnector::InitializeHandshakerFactory( + tsi_ssl_session_cache* ssl_session_cache) { + const SpiffeCredentials* creds = + static_cast(channel_creds()); + auto key_materials_config = PopulateSpiffeCredentials(creds->options()); + if (!key_materials_config.get()->pem_key_cert_pair_list().size()) { + key_materials_config.get()->Unref(); + return GRPC_SECURITY_ERROR; + } + tsi_ssl_pem_key_cert_pair* pem_key_cert_pair = ConvertToTsiPemKeyCertPair( + key_materials_config.get()->pem_key_cert_pair_list()); + grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init( + pem_key_cert_pair, key_materials_config.get()->pem_root_certs(), + ssl_session_cache, &client_handshaker_factory_); + // Free memory. + key_materials_config.get()->Unref(); + grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1); + return status; +} + +void SpiffeChannelSecurityConnector::ServerAuthorizationCheckDone( + grpc_tls_server_authorization_check_arg* arg) { + GPR_ASSERT(arg != nullptr); + grpc_core::ExecCtx exec_ctx; + grpc_error* error = ProcessServerAuthorizationCheckResult(arg); + SpiffeChannelSecurityConnector* connector = + static_cast(arg->cb_user_data); + GRPC_CLOSURE_SCHED(connector->on_peer_checked_, error); +} + +grpc_error* +SpiffeChannelSecurityConnector::ProcessServerAuthorizationCheckResult( + grpc_tls_server_authorization_check_arg* arg) { + grpc_error* error = GRPC_ERROR_NONE; + char* msg = nullptr; + /* Server authorization check is cancelled by caller. */ + if (arg->status == GRPC_STATUS_CANCELLED) { + gpr_asprintf(&msg, + "Server authorization check is cancelled by the caller with " + "error: %s", + arg->error_details); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + } else if (arg->status == GRPC_STATUS_OK) { + /* Server authorization check completed successfully but returned check + * failure. */ + if (!arg->success) { + gpr_asprintf(&msg, "Server authorization check failed with error: %s", + arg->error_details); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + } + /* Server authorization check did not complete correctly. */ + } else { + gpr_asprintf( + &msg, + "Server authorization check did not finish correctly with error: %s", + arg->error_details); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + } + gpr_free(msg); + return error; +} + +grpc_tls_server_authorization_check_arg* +SpiffeChannelSecurityConnector::ServerAuthorizationCheckArgCreate( + void* user_data) { + grpc_tls_server_authorization_check_arg* arg = + grpc_core::New(); + arg->cb = ServerAuthorizationCheckDone; + arg->cb_user_data = user_data; + arg->status = GRPC_STATUS_OK; + return arg; +} + +void SpiffeChannelSecurityConnector::ServerAuthorizationCheckArgDestroy( + grpc_tls_server_authorization_check_arg* arg) { + if (arg == nullptr) { + return; + } + gpr_free((void*)arg->target_name); + gpr_free((void*)arg->peer_cert); + gpr_free((void*)arg->error_details); + grpc_core::Delete(arg); +} + +SpiffeServerSecurityConnector::SpiffeServerSecurityConnector( + grpc_core::RefCountedPtr server_creds) + : grpc_server_security_connector(GRPC_SSL_URL_SCHEME, + std::move(server_creds)) {} + +SpiffeServerSecurityConnector::~SpiffeServerSecurityConnector() { + if (server_handshaker_factory_ != nullptr) { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } +} + +void SpiffeServerSecurityConnector::add_handshakers( + grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) { + /* Create a TLS SPIFFE TSI handshaker for server. */ + RefreshServerHandshakerFactory(); + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( + server_handshaker_factory_, &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this)); +} + +void SpiffeServerSecurityConnector::check_peer( + tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) { + grpc_error* error = grpc_ssl_check_alpn(&peer); + *auth_context = grpc_ssl_peer_to_auth_context(&peer); + tsi_peer_destruct(&peer); + GRPC_CLOSURE_SCHED(on_peer_checked, error); +} + +int SpiffeServerSecurityConnector::cmp( + const grpc_security_connector* other) const { + return server_security_connector_cmp( + static_cast(other)); +} + +grpc_core::RefCountedPtr +SpiffeServerSecurityConnector::CreateSpiffeServerSecurityConnector( + grpc_core::RefCountedPtr server_creds) { + if (server_creds == nullptr) { + gpr_log(GPR_ERROR, + "server_creds is nullptr in " + "SpiffeServerSecurityConnectorCreate()"); + return nullptr; + } + grpc_core::RefCountedPtr c = + grpc_core::MakeRefCounted( + std::move(server_creds)); + if (c->RefreshServerHandshakerFactory() != GRPC_SECURITY_OK) { + return nullptr; + } + return c; +} + +grpc_security_status +SpiffeServerSecurityConnector::RefreshServerHandshakerFactory() { + const SpiffeServerCredentials* creds = + static_cast(server_creds()); + auto key_materials_config = PopulateSpiffeCredentials(creds->options()); + /* Credential reload does NOT take effect and we need to keep using + * the existing handshaker factory. */ + if (key_materials_config.get()->pem_key_cert_pair_list().empty()) { + key_materials_config.get()->Unref(); + return GRPC_SECURITY_ERROR; + } + /* Credential reload takes effect and we need to free the existing + * handshaker library. */ + if (server_handshaker_factory_) { + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + } + tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = ConvertToTsiPemKeyCertPair( + key_materials_config.get()->pem_key_cert_pair_list()); + size_t num_key_cert_pairs = + key_materials_config.get()->pem_key_cert_pair_list().size(); + grpc_security_status status = grpc_ssl_tsi_server_handshaker_factory_init( + pem_key_cert_pairs, num_key_cert_pairs, + key_materials_config.get()->pem_root_certs(), + creds->options().cert_request_type(), &server_handshaker_factory_); + // Free memory. + key_materials_config.get()->Unref(); + grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pairs, + num_key_cert_pairs); + return status; +} diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.h b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h new file mode 100644 index 00000000000..56972153e07 --- /dev/null +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.h @@ -0,0 +1,122 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_SPIFFE_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_SPIFFE_SECURITY_CONNECTOR_H + +#include + +#include "src/core/lib/security/context/security_context.h" +#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" + +#define GRPC_TLS_SPIFFE_TRANSPORT_SECURITY_TYPE "spiffe" + +// Spiffe channel security connector. +class SpiffeChannelSecurityConnector final + : public grpc_channel_security_connector { + public: + // static factory method to create a SPIFFE channel security connector. + static grpc_core::RefCountedPtr + CreateSpiffeChannelSecurityConnector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache); + + SpiffeChannelSecurityConnector( + grpc_core::RefCountedPtr channel_creds, + grpc_core::RefCountedPtr request_metadata_creds, + const char* target_name, const char* overridden_target_name); + ~SpiffeChannelSecurityConnector() override; + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) override; + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override; + + int cmp(const grpc_security_connector* other_sc) const override; + + bool check_call_host(const char* host, grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) override; + + void cancel_check_call_host(grpc_closure* on_call_host_checked, + grpc_error* error) override; + + private: + // Initialize SSL TSI client handshaker factory. + grpc_security_status InitializeHandshakerFactory( + tsi_ssl_session_cache* ssl_session_cache); + + // gRPC-provided callback executed by application, which servers to bring the + // control back to gRPC core. + static void ServerAuthorizationCheckDone( + grpc_tls_server_authorization_check_arg* arg); + + // A util function to process server authorization check result. + static grpc_error* ProcessServerAuthorizationCheckResult( + grpc_tls_server_authorization_check_arg* arg); + + // A util function to create a server authorization check arg instance. + static grpc_tls_server_authorization_check_arg* + ServerAuthorizationCheckArgCreate(void* user_data); + + // A util function to destroy a server authorization check arg instance. + static void ServerAuthorizationCheckArgDestroy( + grpc_tls_server_authorization_check_arg* arg); + + grpc_closure* on_peer_checked_; + char* target_name_; + char* overridden_target_name_; + tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr; + grpc_tls_server_authorization_check_arg* check_arg_; +}; + +// Spiffe server security connector. +class SpiffeServerSecurityConnector final + : public grpc_server_security_connector { + public: + // static factory method to create a SPIFFE server security connector. + static grpc_core::RefCountedPtr + CreateSpiffeServerSecurityConnector( + grpc_core::RefCountedPtr server_creds); + + explicit SpiffeServerSecurityConnector( + grpc_core::RefCountedPtr server_creds); + ~SpiffeServerSecurityConnector() override; + + void add_handshakers(grpc_pollset_set* interested_parties, + grpc_core::HandshakeManager* handshake_mgr) override; + + void check_peer(tsi_peer peer, grpc_endpoint* ep, + grpc_core::RefCountedPtr* auth_context, + grpc_closure* on_peer_checked) override; + + int cmp(const grpc_security_connector* other) const override; + + private: + // A util function to refresh SSL TSI server handshaker factory with a valid + // credential. + grpc_security_status RefreshServerHandshakerFactory(); + tsi_ssl_server_handshaker_factory* server_handshaker_factory_ = nullptr; +}; + +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_SPIFFE_SECURITY_CONNECTOR_H \ + */ diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 2107bcaa748..9ab76d99c02 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -344,18 +344,24 @@ static tsi_result add_subject_alt_names_properties_to_peer( size_t subject_alt_name_count) { size_t i; tsi_result result = TSI_OK; - /* Reset for DNS entries filtering. */ peer->property_count -= subject_alt_name_count; - for (i = 0; i < subject_alt_name_count; i++) { GENERAL_NAME* subject_alt_name = sk_GENERAL_NAME_value(subject_alt_names, TSI_SIZE_AS_SIZE(i)); - /* Filter out the non-dns entries names. */ - if (subject_alt_name->type == GEN_DNS) { + if (subject_alt_name->type == GEN_DNS || + subject_alt_name->type == GEN_EMAIL || + subject_alt_name->type == GEN_URI) { unsigned char* name = nullptr; int name_size; - name_size = ASN1_STRING_to_UTF8(&name, subject_alt_name->d.dNSName); + if (subject_alt_name->type == GEN_DNS) { + name_size = ASN1_STRING_to_UTF8(&name, subject_alt_name->d.dNSName); + } else if (subject_alt_name->type == GEN_EMAIL) { + name_size = ASN1_STRING_to_UTF8(&name, subject_alt_name->d.rfc822Name); + } else { + name_size = ASN1_STRING_to_UTF8( + &name, subject_alt_name->d.uniformResourceIdentifier); + } if (name_size < 0) { gpr_log(GPR_ERROR, "Could not get utf8 from asn1 string."); result = TSI_INTERNAL_ERROR; @@ -369,7 +375,6 @@ static tsi_result add_subject_alt_names_properties_to_peer( } else if (subject_alt_name->type == GEN_IPADD) { char ntop_buf[INET6_ADDRSTRLEN]; int af; - if (subject_alt_name->d.iPAddress->length == 4) { af = AF_INET; } else if (subject_alt_name->d.iPAddress->length == 16) { @@ -386,7 +391,6 @@ static tsi_result add_subject_alt_names_properties_to_peer( result = TSI_INTERNAL_ERROR; break; } - result = tsi_construct_string_peer_property_from_cstring( TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, name, &peer->properties[peer->property_count++]); @@ -1017,7 +1021,6 @@ static void tsi_ssl_handshaker_factory_init( } /* --- tsi_handshaker_result methods implementation. ---*/ - static tsi_result ssl_handshaker_result_extract_peer( const tsi_handshaker_result* self, tsi_peer* peer) { tsi_result result = TSI_OK; @@ -1025,6 +1028,7 @@ static tsi_result ssl_handshaker_result_extract_peer( unsigned int alpn_selected_len; const tsi_ssl_handshaker_result* impl = reinterpret_cast(self); + // TODO(yihuazhang): Return a full certificate chain as a peer property. X509* peer_cert = SSL_get_peer_certificate(impl->ssl); if (peer_cert != nullptr) { result = peer_from_x509(peer_cert, 1, peer); @@ -1066,7 +1070,6 @@ static tsi_result ssl_handshaker_result_extract_peer( &peer->properties[peer->property_count]); if (result != TSI_OK) return result; peer->property_count++; - return result; } @@ -1400,7 +1403,6 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client, static_cast(gpr_zalloc(impl->outgoing_bytes_buffer_size)); impl->base.vtable = &handshaker_vtable; impl->factory_ref = tsi_ssl_handshaker_factory_ref(factory); - *handshaker = &impl->base; return TSI_OK; } diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 8f7da3a5b04..814f920eaf7 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -256,6 +256,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', 'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc', + 'src/core/lib/security/credentials/tls/spiffe_credentials.cc', 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', @@ -264,6 +265,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/security/security_connector/security_connector.cc', 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', 'src/core/lib/security/security_connector/ssl_utils.cc', + 'src/core/lib/security/security_connector/tls/spiffe_security_connector.cc', 'src/core/lib/security/transport/client_auth_filter.cc', 'src/core/lib/security/transport/secure_endpoint.cc', 'src/core/lib/security/transport/security_handshaker.cc', diff --git a/test/core/end2end/fixtures/h2_spiffe.cc b/test/core/end2end/fixtures/h2_spiffe.cc new file mode 100644 index 00000000000..3cd7c362212 --- /dev/null +++ b/test/core/end2end/fixtures/h2_spiffe.cc @@ -0,0 +1,290 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include +#include + +#include +#include +#include + +#include +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/inlined_vector.h" +#include "src/core/lib/gprpp/thd.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" +#include "test/core/end2end/data/ssl_test_data.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +typedef grpc_core::InlinedVector ThreadList; + +typedef struct fullstack_secure_fixture_data { + char* localaddr; + ThreadList thd_list; +} fullstack_secure_fixture_data; + +static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + int port = grpc_pick_unused_port_or_die(); + fullstack_secure_fixture_data* ffd = + grpc_core::New(); + memset(&f, 0, sizeof(f)); + gpr_join_host_port(&ffd->localaddr, "localhost", port); + f.fixture_data = ffd; + f.cq = grpc_completion_queue_create_for_next(nullptr); + f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); + return f; +} + +static void process_auth_failure(void* state, grpc_auth_context* ctx, + const grpc_metadata* md, size_t md_count, + grpc_process_auth_metadata_done_cb cb, + void* user_data) { + GPR_ASSERT(state == nullptr); + cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr); +} + +static void chttp2_init_client_secure_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* client_args, + grpc_channel_credentials* creds) { + fullstack_secure_fixture_data* ffd = + static_cast(f->fixture_data); + f->client = + grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr); + GPR_ASSERT(f->client != nullptr); + grpc_channel_credentials_release(creds); +} + +static void chttp2_init_server_secure_fullstack( + grpc_end2end_test_fixture* f, grpc_channel_args* server_args, + grpc_server_credentials* server_creds) { + fullstack_secure_fixture_data* ffd = + static_cast(f->fixture_data); + if (f->server) { + grpc_server_destroy(f->server); + } + f->server = grpc_server_create(server_args, nullptr); + grpc_server_register_completion_queue(f->server, f->cq, nullptr); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + server_creds)); + grpc_server_credentials_release(server_creds); + grpc_server_start(f->server); +} + +void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture* f) { + fullstack_secure_fixture_data* ffd = + static_cast(f->fixture_data); + for (size_t ind = 0; ind < ffd->thd_list.size(); ind++) { + ffd->thd_list[ind].Join(); + } + gpr_free(ffd->localaddr); + grpc_core::Delete(ffd); +} + +// Application-provided callback for server authorization check. +static void server_authz_check_cb(void* user_data) { + grpc_tls_server_authorization_check_arg* check_arg = + static_cast(user_data); + GPR_ASSERT(check_arg != nullptr); + // result = 1 indicates the server authorization check passes. + // Normally, the applicaiton code should resort to mapping information + // between server identity and target name to derive the result. + // For this test, we directly return 1 for simplicity. + check_arg->success = 1; + check_arg->status = GRPC_STATUS_OK; + check_arg->cb(check_arg); +} + +// Asynchronous implementation of schedule field in +// grpc_server_authorization_check_config. +static int server_authz_check_async( + void* config_user_data, grpc_tls_server_authorization_check_arg* arg) { + fullstack_secure_fixture_data* ffd = + static_cast(config_user_data); + ffd->thd_list.push_back( + grpc_core::Thread("h2_spiffe_test", &server_authz_check_cb, arg)); + ffd->thd_list[ffd->thd_list.size() - 1].Start(); + return 1; +} + +// Synchronous implementation of schedule field in +// grpc_tls_credential_reload_config instance that is a part of client-side +// grpc_tls_credentials_options instance. +static int client_cred_reload_sync(void* config_user_data, + grpc_tls_credential_reload_arg* arg) { + grpc_ssl_pem_key_cert_pair** key_cert_pair = + static_cast( + gpr_zalloc(sizeof(grpc_ssl_pem_key_cert_pair*))); + key_cert_pair[0] = static_cast( + gpr_zalloc(sizeof(grpc_ssl_pem_key_cert_pair))); + key_cert_pair[0]->private_key = gpr_strdup(test_server1_key); + key_cert_pair[0]->cert_chain = gpr_strdup(test_server1_cert); + if (!arg->key_materials_config->pem_key_cert_pair_list().size()) { + grpc_tls_key_materials_config_set_key_materials( + arg->key_materials_config, gpr_strdup(test_root_cert), + (const grpc_ssl_pem_key_cert_pair**)key_cert_pair, 1); + } + // new credential has been reloaded. + arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW; + return 0; +} + +// Synchronous implementation of schedule field in +// grpc_tls_credential_reload_config instance that is a part of server-side +// grpc_tls_credentials_options instance. +static int server_cred_reload_sync(void* config_user_data, + grpc_tls_credential_reload_arg* arg) { + grpc_ssl_pem_key_cert_pair** key_cert_pair = + static_cast( + gpr_zalloc(sizeof(grpc_ssl_pem_key_cert_pair*))); + key_cert_pair[0] = static_cast( + gpr_zalloc(sizeof(grpc_ssl_pem_key_cert_pair))); + key_cert_pair[0]->private_key = gpr_strdup(test_server1_key); + key_cert_pair[0]->cert_chain = gpr_strdup(test_server1_cert); + GPR_ASSERT(arg != nullptr); + GPR_ASSERT(arg->key_materials_config != nullptr); + GPR_ASSERT(arg->key_materials_config->pem_key_cert_pair_list().data() != + nullptr); + if (!arg->key_materials_config->pem_key_cert_pair_list().size()) { + grpc_tls_key_materials_config_set_key_materials( + arg->key_materials_config, gpr_strdup(test_root_cert), + (const grpc_ssl_pem_key_cert_pair**)key_cert_pair, 1); + } + // new credential has been reloaded. + arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW; + return 0; +} + +// Create a SPIFFE channel credential. +static grpc_channel_credentials* create_spiffe_channel_credentials( + fullstack_secure_fixture_data* ffd) { + grpc_tls_credentials_options* options = grpc_tls_credentials_options_create(); + /* Set credential reload config. */ + grpc_tls_credential_reload_config* reload_config = + grpc_tls_credential_reload_config_create(nullptr, client_cred_reload_sync, + nullptr, nullptr); + grpc_tls_credentials_options_set_credential_reload_config(options, + reload_config); + /* Set server authorization check config. */ + grpc_tls_server_authorization_check_config* check_config = + grpc_tls_server_authorization_check_config_create( + ffd, server_authz_check_async, nullptr, nullptr); + grpc_tls_credentials_options_set_server_authorization_check_config( + options, check_config); + /* Create SPIFFE channel credentials. */ + grpc_channel_credentials* creds = grpc_tls_spiffe_credentials_create(options); + return creds; +} + +// Create a SPIFFE server credential. +static grpc_server_credentials* create_spiffe_server_credentials() { + grpc_tls_credentials_options* options = grpc_tls_credentials_options_create(); + /* Set credential reload config. */ + grpc_tls_credential_reload_config* reload_config = + grpc_tls_credential_reload_config_create(nullptr, server_cred_reload_sync, + nullptr, nullptr); + grpc_tls_credentials_options_set_credential_reload_config(options, + reload_config); + /* Set client certificate request type. */ + grpc_tls_credentials_options_set_cert_request_type( + options, GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY); + grpc_server_credentials* creds = + grpc_tls_spiffe_server_credentials_create(options); + return creds; +} + +static void chttp2_init_client(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + grpc_channel_credentials* ssl_creds = create_spiffe_channel_credentials( + static_cast(f->fixture_data)); + grpc_arg ssl_name_override = { + GRPC_ARG_STRING, + const_cast(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), + {const_cast("foo.test.google.fr")}}; + grpc_channel_args* new_client_args = + grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1); + chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds); + grpc_channel_args_destroy(new_client_args); +} + +static int fail_server_auth_check(grpc_channel_args* server_args) { + size_t i; + if (server_args == nullptr) return 0; + for (i = 0; i < server_args->num_args; i++) { + if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) == + 0) { + return 1; + } + } + return 0; +} + +static void chttp2_init_server(grpc_end2end_test_fixture* f, + grpc_channel_args* server_args) { + grpc_server_credentials* ssl_creds = create_spiffe_server_credentials(); + if (fail_server_auth_check(server_args)) { + grpc_auth_metadata_processor processor = {process_auth_failure, nullptr, + nullptr}; + grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor); + } + chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); +} + +static grpc_end2end_test_config configs[] = { + /* client sync reload async authz + server sync reload. */ + {"chttp2/simple_ssl_fullstack", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS | + FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | + FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, + "foo.test.google.fr", chttp2_create_fixture_secure_fullstack, + chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack}, +}; + +int main(int argc, char** argv) { + FILE* roots_file; + size_t roots_size = strlen(test_root_cert); + char* roots_filename; + grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); + /* Set the SSL roots env var. */ + roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); + GPR_ASSERT(roots_filename != nullptr); + GPR_ASSERT(roots_file != nullptr); + GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); + fclose(roots_file); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + grpc_init(); + for (size_t ind = 0; ind < sizeof(configs) / sizeof(*configs); ind++) { + grpc_end2end_tests(argc, argv, configs[ind]); + } + grpc_shutdown(); + /* Cleanup. */ + remove(roots_filename); + gpr_free(roots_filename); + return 0; +} diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index f8ac7036530..231d2262a9d 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -74,6 +74,7 @@ END2END_FIXTURES = { 'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace( ci_mac=False, tracing=True, large_writes=False, exclude_iomgrs=['uv']), 'h2_ssl': default_secure_fixture_options, + 'h2_spiffe': default_secure_fixture_options, 'h2_local_uds': local_fixture_options, 'h2_local_ipv4': local_fixture_options, 'h2_local_ipv6': local_fixture_options, diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index a5fe091c2fc..d1ce92ebfba 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -87,6 +87,7 @@ END2END_FIXTURES = { client_channel = False, ), "h2_ssl": _fixture_options(secure = True), + "h2_spiffe": _fixture_options(secure = True), "h2_local_uds": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), "h2_local_ipv4": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), "h2_local_ipv6": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 6e4a57ba00f..5ce5d5d3ce3 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1381,6 +1381,8 @@ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.h \ src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \ src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h \ +src/core/lib/security/credentials/tls/spiffe_credentials.cc \ +src/core/lib/security/credentials/tls/spiffe_credentials.h \ src/core/lib/security/security_connector/alts/alts_security_connector.cc \ src/core/lib/security/security_connector/alts/alts_security_connector.h \ src/core/lib/security/security_connector/fake/fake_security_connector.cc \ @@ -1397,6 +1399,8 @@ src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ src/core/lib/security/security_connector/ssl/ssl_security_connector.h \ src/core/lib/security/security_connector/ssl_utils.cc \ src/core/lib/security/security_connector/ssl_utils.h \ +src/core/lib/security/security_connector/tls/spiffe_security_connector.cc \ +src/core/lib/security/security_connector/tls/spiffe_security_connector.h \ src/core/lib/security/transport/auth_filters.h \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8adde9ec602..2d427804d07 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -6285,6 +6285,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "end2end_tests", + "gpr", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "h2_spiffe_test", + "src": [ + "test/core/end2end/fixtures/h2_spiffe.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "end2end_tests", @@ -10458,6 +10475,7 @@ "src/core/lib/security/credentials/plugin/plugin_credentials.h", "src/core/lib/security/credentials/ssl/ssl_credentials.h", "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h", + "src/core/lib/security/credentials/tls/spiffe_credentials.h", "src/core/lib/security/security_connector/alts/alts_security_connector.h", "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", @@ -10466,6 +10484,7 @@ "src/core/lib/security/security_connector/security_connector.h", "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", "src/core/lib/security/security_connector/ssl_utils.h", + "src/core/lib/security/security_connector/tls/spiffe_security_connector.h", "src/core/lib/security/transport/auth_filters.h", "src/core/lib/security/transport/secure_endpoint.h", "src/core/lib/security/transport/security_handshaker.h", @@ -10513,6 +10532,8 @@ "src/core/lib/security/credentials/ssl/ssl_credentials.h", "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc", "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h", + "src/core/lib/security/credentials/tls/spiffe_credentials.cc", + "src/core/lib/security/credentials/tls/spiffe_credentials.h", "src/core/lib/security/security_connector/alts/alts_security_connector.cc", "src/core/lib/security/security_connector/alts/alts_security_connector.h", "src/core/lib/security/security_connector/fake/fake_security_connector.cc", @@ -10529,6 +10550,8 @@ "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", "src/core/lib/security/security_connector/ssl_utils.cc", "src/core/lib/security/security_connector/ssl_utils.h", + "src/core/lib/security/security_connector/tls/spiffe_security_connector.cc", + "src/core/lib/security/security_connector/tls/spiffe_security_connector.h", "src/core/lib/security/transport/auth_filters.h", "src/core/lib/security/transport/client_auth_filter.cc", "src/core/lib/security/transport/secure_endpoint.cc", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 7c9fb8d6804..cffc8b98764 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -34543,6 +34543,1781 @@ "posix" ] }, + { + "args": [ + "authority_not_supported" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_hostname" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "bad_ping" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "binary_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "call_creds" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "call_host_override" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_accept" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_client_done" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_invoke" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_after_round_trip" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_before_invoke" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_in_a_vacuum" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "cancel_with_status" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "channelz" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "compressed_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "connectivity" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "default_host" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "disappearing_server" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": true, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "empty_batch" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_call_init_fails" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_context" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_latency" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "filter_status_code" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "graceful_server_shutdown" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "high_initial_seqno" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "hpack_size" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "idempotent_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "invoke_large_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "keepalive_timeout" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "large_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_concurrent_streams" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_age" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_connection_idle" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "max_message_length" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "negative_deadline" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_error_on_hotpath" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_logging" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "no_op" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "ping_pong_streaming" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "registered_call" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_flags" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "request_with_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "resource_quota_server" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_cancellation" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_disabled" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_initial_batch" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_exceeds_buffer_size_in_subsequent_batch" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_non_retriable_status" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_non_retriable_status_before_recv_trailing_metadata_started" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_initial_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_recv_message" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_delay" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_server_pushback_disabled" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_after_commit" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_streaming_succeeds_before_replay_finished" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_throttled" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "retry_too_many_attempts" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "server_finishes_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_calls" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "shutdown_finishes_tags" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_cacheable_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_delayed_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "simple_request" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_compressed_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_payload" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "stream_compression_ping_pong_streaming" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "streaming_error_response" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "trailing_metadata" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "workaround_cronet_compression" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, + { + "args": [ + "write_buffering_at_end" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 0.1, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "language": "c", + "name": "h2_spiffe_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "authority_not_supported" From 32b9e5245353eef7cf2f71ff115f82a9d3652a39 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 15 Mar 2019 00:47:15 +0100 Subject: [PATCH 696/814] Fix a memset on a non-trivial object. --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 829bee6bedd..49ec869d707 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -2476,7 +2476,6 @@ static grpc_error* try_http_parsing(grpc_chttp2_transport* t) { size_t i = 0; grpc_error* error = GRPC_ERROR_NONE; grpc_http_response response; - memset(&response, 0, sizeof(response)); grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response); From 8479bed4b5a240001a9a4f2813e7af8090cf9c57 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 15 Mar 2019 01:01:29 +0100 Subject: [PATCH 697/814] Removing superfluous const in a static_cast. This seems to be producing a warning on some compilers, and it's unnecessary anyway. --- src/core/ext/transport/chttp2/transport/flow_control.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/flow_control.cc b/src/core/ext/transport/chttp2/transport/flow_control.cc index ee2bb930802..d53475a1b61 100644 --- a/src/core/ext/transport/chttp2/transport/flow_control.cc +++ b/src/core/ext/transport/chttp2/transport/flow_control.cc @@ -190,7 +190,7 @@ TransportFlowControl::TransportFlowControl(const grpc_chttp2_transport* t, uint32_t TransportFlowControl::MaybeSendUpdate(bool writing_anyway) { FlowControlTrace trace("t updt sent", this, nullptr); const uint32_t target_announced_window = - static_cast(target_window()); + static_cast(target_window()); if ((writing_anyway || announced_window_ <= target_announced_window / 2) && announced_window_ != target_announced_window) { const uint32_t announce = static_cast GPR_CLAMP( From ec78d0f56913fde14995b21515a525882e175602 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Thu, 14 Mar 2019 19:51:09 -0700 Subject: [PATCH 698/814] Use correct C integer types in Cython --- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 759479089d4..88a6c0039c6 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -13,15 +13,7 @@ # limitations under the License. cimport libc.time -from libc.stdint cimport intptr_t - - -# Typedef types with approximately the same semantics to provide their names to -# Cython -ctypedef unsigned char uint8_t -ctypedef int int32_t -ctypedef unsigned uint32_t -ctypedef long int64_t +from libc.stdint cimport intptr_t, uint8_t, int32_t, uint32_t, int64_t cdef extern from "grpc/support/alloc.h": From cf6a31176137984d3335ad72273333491dc25153 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 15 Mar 2019 17:15:20 +0100 Subject: [PATCH 699/814] Revert "Windows builds for gRPC C++ tests" --- bazel/grpc_build_system.bzl | 16 +++------------- bazel/grpc_deps.bzl | 9 +++++---- test/core/bad_connection/BUILD | 1 - test/core/client_channel/BUILD | 1 - test/core/end2end/generate_tests.bzl | 15 ++++----------- test/core/iomgr/BUILD | 10 ---------- test/cpp/common/BUILD | 1 - test/cpp/end2end/BUILD | 2 -- test/cpp/interop/BUILD | 1 - test/cpp/microbenchmarks/BUILD | 18 ------------------ .../generate_resolver_component_tests.bzl | 5 +---- test/cpp/performance/BUILD | 1 - test/cpp/qps/qps_benchmark_script.bzl | 1 - test/cpp/server/BUILD | 3 --- test/cpp/server/load_reporter/BUILD | 1 - third_party/BUILD | 1 + third_party/benchmark.BUILD | 15 +++++++++++++++ tools/remote_build/README.md | 6 ------ tools/remote_build/windows.bazelrc | 3 --- 19 files changed, 29 insertions(+), 81 deletions(-) create mode 100644 third_party/benchmark.BUILD delete mode 100644 tools/remote_build/windows.bazelrc diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 59e9c46e0a3..2a09022c64c 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -28,12 +28,6 @@ load("//bazel:cc_grpc_library.bzl", "cc_grpc_library") # The set of pollers to test against if a test exercises polling POLLERS = ["epollex", "epoll1", "poll"] -def is_msvc(): - return select({ - "//:windows_msvc": True, - "//conditions:default": False, - }) - def if_not_windows(a): return select({ "//:windows": [], @@ -86,8 +80,7 @@ def grpc_cc_library( visibility = None, alwayslink = 0, data = [], - use_cfstream = False, - tags = []): + use_cfstream = False): copts = [] if use_cfstream: copts = if_mac(["-DGRPC_CFSTREAM"]) @@ -124,7 +117,6 @@ def grpc_cc_library( ], alwayslink = alwayslink, data = data, - tags = tags, ) def grpc_proto_plugin(name, srcs = [], deps = []): @@ -167,9 +159,8 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data "size": size, "timeout": timeout, "exec_compatible_with": exec_compatible_with, - "tags": tags, } - if uses_polling and not is_msvc(): + if uses_polling: native.cc_test(testonly = True, tags = ["manual"], **args) for poller in POLLERS: native.sh_test( @@ -190,7 +181,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data else: native.cc_test(**args) -def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = [], tags = []): +def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = []): copts = [] if language.upper() == "C": copts = ["-std=c99"] @@ -204,7 +195,6 @@ def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], da deps = deps + _get_external_deps(external_deps), copts = copts, linkopts = if_not_windows(["-pthread"]) + linkopts, - tags = tags, ) def grpc_generate_one_off_targets(): diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 9b6aaacbd58..6b04c0b2c48 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -147,15 +147,16 @@ def grpc_deps(): if "com_github_gflags_gflags" not in native.existing_rules(): http_archive( name = "com_github_gflags_gflags", - strip_prefix = "gflags-28f50e0fed19872e0fd50dd23ce2ee8cd759338e", - url = "https://github.com/gflags/gflags/archive/28f50e0fed19872e0fd50dd23ce2ee8cd759338e.tar.gz", + strip_prefix = "gflags-30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e", + url = "https://github.com/gflags/gflags/archive/30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e.tar.gz", ) if "com_github_google_benchmark" not in native.existing_rules(): http_archive( name = "com_github_google_benchmark", - strip_prefix = "benchmark-e776aa0275e293707b6a0901e0e8d8a8a3679508", - url = "https://github.com/google/benchmark/archive/e776aa0275e293707b6a0901e0e8d8a8a3679508.tar.gz", + build_file = "@com_github_grpc_grpc//third_party:benchmark.BUILD", + strip_prefix = "benchmark-9913418d323e64a0111ca0da81388260c2bbe1e9", + url = "https://github.com/google/benchmark/archive/9913418d323e64a0111ca0da81388260c2bbe1e9.tar.gz", ) if "com_github_cares_cares" not in native.existing_rules(): diff --git a/test/core/bad_connection/BUILD b/test/core/bad_connection/BUILD index 82b38ccc469..8ada933e796 100644 --- a/test/core/bad_connection/BUILD +++ b/test/core/bad_connection/BUILD @@ -29,5 +29,4 @@ grpc_cc_binary( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD index 68a71632daf..57e5191af4c 100644 --- a/test/core/client_channel/BUILD +++ b/test/core/client_channel/BUILD @@ -52,7 +52,6 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) grpc_cc_test( diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index a5fe091c2fc..7bb246b6067 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -15,7 +15,7 @@ """Generates the appropriate build.json data for all the end2end tests.""" -load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library", "is_msvc") +load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library") POLLERS = ["epollex", "epoll1", "poll"] @@ -31,8 +31,7 @@ def _fixture_options( is_http2 = True, supports_proxy_auth = False, supports_write_buffering = True, - client_channel = True, - supports_msvc = True,): + client_channel = True): return struct( fullstack = fullstack, includes_proxy = includes_proxy, @@ -45,7 +44,6 @@ def _fixture_options( supports_proxy_auth = supports_proxy_auth, supports_write_buffering = supports_write_buffering, client_channel = client_channel, - supports_msvc = supports_msvc, #_platforms=_platforms, ) @@ -121,11 +119,10 @@ END2END_NOSEC_FIXTURES = { client_channel = False, secure = False, _platforms = ["linux", "mac", "posix"], - supports_msvc = False, ), "h2_full": _fixture_options(secure = False), - "h2_full+pipe": _fixture_options(secure = False, _platforms = ["linux"], supports_msvc = False), - "h2_full+trace": _fixture_options(secure = False, tracing = True, supports_msvc = False), + "h2_full+pipe": _fixture_options(secure = False, _platforms = ["linux"]), + "h2_full+trace": _fixture_options(secure = False, tracing = True), "h2_full+workarounds": _fixture_options(secure = False), "h2_http_proxy": _fixture_options(secure = False, supports_proxy_auth = True), "h2_proxy": _fixture_options(secure = False, includes_proxy = True), @@ -154,7 +151,6 @@ END2END_NOSEC_FIXTURES = { dns_resolver = False, _platforms = ["linux", "mac", "posix"], secure = False, - supports_msvc = False, ), } @@ -333,9 +329,6 @@ END2END_TESTS = { } def _compatible(fopt, topt): - if is_msvc: - if not fopt.supports_msvc: - return False if topt.needs_fullstack: if not fopt.fullstack: return False diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 1aefa0ab224..5e4338aee37 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -81,7 +81,6 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -93,7 +92,6 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -105,7 +103,6 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -142,7 +139,6 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -157,7 +153,6 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -219,7 +214,6 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -231,7 +225,6 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -244,7 +237,6 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -267,7 +259,6 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -312,5 +303,4 @@ grpc_cc_test( "//:grpc", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD index b67c1995ff7..01699b26add 100644 --- a/test/cpp/common/BUILD +++ b/test/cpp/common/BUILD @@ -28,7 +28,6 @@ grpc_cc_test( "//:grpc++_unsecure", "//test/core/util:grpc_test_util_unsecure", ], - tags = ["no_windows"], ) grpc_cc_test( diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 68e0ec3cef1..de7725d163d 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -99,7 +99,6 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -631,7 +630,6 @@ grpc_cc_test( "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", ], - tags = ["no_windows"], ) grpc_cc_test( diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index 6cf4719c17b..f36494d98db 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -161,5 +161,4 @@ grpc_cc_test( "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], - tags = ["no_windows"], ) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 6e844a6dc62..70b4000780c 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -45,7 +45,6 @@ grpc_cc_library( "//test/core/util:grpc_test_util_unsecure", "//test/cpp/util:test_config", ], - tags = ["no_windows"], ) grpc_cc_binary( @@ -53,7 +52,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_closure.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -61,7 +59,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_alarm.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -69,7 +66,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_arena.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -77,7 +73,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_byte_buffer.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -85,7 +80,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_channel.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -93,7 +87,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_call_create.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -101,7 +94,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_cq.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -109,7 +101,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_cq_multiple_threads.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -117,7 +108,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_error.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_library( @@ -127,7 +117,6 @@ grpc_cc_library( "fullstack_streaming_ping_pong.h", ], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -137,7 +126,6 @@ grpc_cc_binary( "bm_fullstack_streaming_ping_pong.cc", ], deps = [":fullstack_streaming_ping_pong_h"], - tags = ["no_windows"], ) grpc_cc_library( @@ -156,7 +144,6 @@ grpc_cc_binary( "bm_fullstack_streaming_pump.cc", ], deps = [":fullstack_streaming_pump_h"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -164,7 +151,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_fullstack_trickle.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_library( @@ -183,7 +169,6 @@ grpc_cc_binary( "bm_fullstack_unary_ping_pong.cc", ], deps = [":fullstack_unary_ping_pong_h"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -191,7 +176,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_metadata.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -199,7 +183,6 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_chttp2_hpack.cc"], deps = [":helpers"], - tags = ["no_windows"], ) grpc_cc_binary( @@ -219,5 +202,4 @@ grpc_cc_binary( testonly = 1, srcs = ["bm_timer.cc"], deps = [":helpers"], - tags = ["no_windows"], ) diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl index 589176762e6..f36021560c1 100755 --- a/test/cpp/naming/generate_resolver_component_tests.bzl +++ b/test/cpp/naming/generate_resolver_component_tests.bzl @@ -33,7 +33,6 @@ def generate_resolver_component_tests(): "//:gpr", "//test/cpp/util:test_config", ], - tags = ["no_windows"], ) # meant to be invoked only through the top-level shell script driver grpc_cc_binary( @@ -53,7 +52,6 @@ def generate_resolver_component_tests(): "//:gpr", "//test/cpp/util:test_config", ], - tags = ["no_windows"], ) grpc_cc_test( name = "resolver_component_tests_runner_invoker%s" % unsecure_build_config_suffix, @@ -79,6 +77,5 @@ def generate_resolver_component_tests(): args = [ "--test_bin_name=resolver_component_test%s" % unsecure_build_config_suffix, "--running_under_bazel=true", - ], - tags = ["no_windows"], + ] ) diff --git a/test/cpp/performance/BUILD b/test/cpp/performance/BUILD index 6068c33f95f..4fe95d5905e 100644 --- a/test/cpp/performance/BUILD +++ b/test/cpp/performance/BUILD @@ -31,5 +31,4 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_base", ], - tags = ["no_windows"], ) diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl index b4767ec8e09..855caa0d37c 100644 --- a/test/cpp/qps/qps_benchmark_script.bzl +++ b/test/cpp/qps/qps_benchmark_script.bzl @@ -75,6 +75,5 @@ def json_run_localhost_batch(): ], tags = [ "json_run_localhost", - "no_windows", ], ) diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD index a4811031691..050b83f5c4f 100644 --- a/test/cpp/server/BUILD +++ b/test/cpp/server/BUILD @@ -29,7 +29,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -43,7 +42,6 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - tags = ["no_windows"], ) grpc_cc_test( @@ -57,5 +55,4 @@ grpc_cc_test( "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", ], - tags = ["no_windows"], ) diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD index db5c93263ad..8d876c56d29 100644 --- a/test/cpp/server/load_reporter/BUILD +++ b/test/cpp/server/load_reporter/BUILD @@ -45,7 +45,6 @@ grpc_cc_test( "//:lb_server_load_reporting_filter", "//test/core/util:grpc_test_util", ], - tags = ["no_windows"], ) grpc_cc_test( diff --git a/third_party/BUILD b/third_party/BUILD index 8b43d6b8300..5ec919dc48d 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -1,4 +1,5 @@ exports_files([ + "benchmark.BUILD", "gtest.BUILD", "objective_c/Cronet/bidirectional_stream_c.h", "zlib.BUILD", diff --git a/third_party/benchmark.BUILD b/third_party/benchmark.BUILD new file mode 100644 index 00000000000..4c622f32a84 --- /dev/null +++ b/third_party/benchmark.BUILD @@ -0,0 +1,15 @@ +cc_library( + name = "benchmark", + srcs = glob(["src/*.cc"]), + hdrs = glob(["include/**/*.h", "src/*.h"]), + includes = [ + "include", "." + ], + copts = [ + "-DHAVE_POSIX_REGEX" + ], + linkstatic = 1, + visibility = [ + "//visibility:public", + ], +) diff --git a/tools/remote_build/README.md b/tools/remote_build/README.md index 8a236973946..19739e9ee12 100644 --- a/tools/remote_build/README.md +++ b/tools/remote_build/README.md @@ -29,11 +29,5 @@ Sanitizer runs (asan, msan, tsan, ubsan): bazel --bazelrc=tools/remote_build/manual.bazelrc test --config=asan //test/... ``` -Run on Windows MSVC: -``` -# local manual run only for C++ targets (RBE to be supported) -bazel --bazelrc=tools/remote_build/windows.bazelrc test //test/cpp/... -``` - Available command line options can be found in [Bazel command line reference](https://docs.bazel.build/versions/master/command-line-reference.html) diff --git a/tools/remote_build/windows.bazelrc b/tools/remote_build/windows.bazelrc deleted file mode 100644 index 70575372d02..00000000000 --- a/tools/remote_build/windows.bazelrc +++ /dev/null @@ -1,3 +0,0 @@ -# TODO(yfen): Merge with rbe_common.bazelrc and enable Windows RBE -build --test_tag_filters=-no_windows -build --build_tag_filters=-no_windows From a5e0fe95e89061dcb23edd6d9d83941e7c74ed97 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 15 Mar 2019 17:31:17 +0100 Subject: [PATCH 700/814] Removing a few more non-trivial struct memsets. This structure (tsi_ssl_client_handshaker_options) has an explicit constructor that sets everything to zeroes. --- src/core/tsi/ssl_transport_security.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 2107bcaa748..2953fb53a57 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -1634,7 +1634,6 @@ tsi_result tsi_create_ssl_client_handshaker_factory( const char** alpn_protocols, uint16_t num_alpn_protocols, tsi_ssl_client_handshaker_factory** factory) { tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); options.pem_key_cert_pair = pem_key_cert_pair; options.pem_root_certs = pem_root_certs; options.cipher_suites = cipher_suites; @@ -1764,7 +1763,6 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex( const char* cipher_suites, const char** alpn_protocols, uint16_t num_alpn_protocols, tsi_ssl_server_handshaker_factory** factory) { tsi_ssl_server_handshaker_options options; - memset(&options, 0, sizeof(options)); options.pem_key_cert_pairs = pem_key_cert_pairs; options.num_key_cert_pairs = num_key_cert_pairs; options.pem_client_root_certs = pem_client_root_certs; From 2bf934f97d33a076f87f52ed846bb8620f0dbae9 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 10:20:06 -0700 Subject: [PATCH 701/814] Revert "Fold opencensus into grpc_impl namespace" --- BUILD | 1 - include/grpcpp/opencensus.h | 26 +++++++- include/grpcpp/opencensus_impl.h | 51 --------------- src/cpp/ext/filters/census/grpc_plugin.cc | 65 +++++++++---------- src/cpp/ext/filters/census/grpc_plugin.h | 6 +- src/cpp/ext/filters/census/views.cc | 32 +++++---- .../census/stats_plugin_end2end_test.cc | 2 +- .../microbenchmarks/bm_opencensus_plugin.cc | 6 +- 8 files changed, 75 insertions(+), 114 deletions(-) delete mode 100644 include/grpcpp/opencensus_impl.h diff --git a/BUILD b/BUILD index 0b6fff354f4..e158059b30f 100644 --- a/BUILD +++ b/BUILD @@ -2279,7 +2279,6 @@ grpc_cc_library( ], hdrs = [ "include/grpcpp/opencensus.h", - "include/grpcpp/opencensus_impl.h", "src/cpp/ext/filters/census/channel_filter.h", "src/cpp/ext/filters/census/client_filter.h", "src/cpp/ext/filters/census/context.h", diff --git a/include/grpcpp/opencensus.h b/include/grpcpp/opencensus.h index 3b170336834..29b221f7674 100644 --- a/include/grpcpp/opencensus.h +++ b/include/grpcpp/opencensus.h @@ -19,6 +19,30 @@ #ifndef GRPCPP_OPENCENSUS_H #define GRPCPP_OPENCENSUS_H -#include "grpcpp/opencensus_impl.h" +#include "opencensus/trace/span.h" + +namespace grpc { +// These symbols in this file will not be included in the binary unless +// grpc_opencensus_plugin build target was added as a dependency. At the moment +// it is only setup to be built with Bazel. + +// Registers the OpenCensus plugin with gRPC, so that it will be used for future +// RPCs. This must be called before any views are created. +void RegisterOpenCensusPlugin(); + +// RPC stats definitions, defined by +// https://github.com/census-instrumentation/opencensus-specs/blob/master/stats/gRPC.md + +// Registers the cumulative gRPC views so that they will be exported by any +// registered stats exporter. For on-task stats, construct a View using the +// ViewDescriptors below. +void RegisterOpenCensusViewsForExport(); + +class ServerContext; + +// Returns the tracing Span for the current RPC. +::opencensus::trace::Span GetSpanFromServerContext(ServerContext* context); + +} // namespace grpc #endif // GRPCPP_OPENCENSUS_H diff --git a/include/grpcpp/opencensus_impl.h b/include/grpcpp/opencensus_impl.h deleted file mode 100644 index 631d2b861fd..00000000000 --- a/include/grpcpp/opencensus_impl.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPCPP_OPENCENSUS_IMPL_H -#define GRPCPP_OPENCENSUS_IMPL_H - -#include "opencensus/trace/span.h" - -namespace grpc { - -class ServerContext; -} -namespace grpc_impl { -// These symbols in this file will not be included in the binary unless -// grpc_opencensus_plugin build target was added as a dependency. At the moment -// it is only setup to be built with Bazel. - -// Registers the OpenCensus plugin with gRPC, so that it will be used for future -// RPCs. This must be called before any views are created. -void RegisterOpenCensusPlugin(); - -// RPC stats definitions, defined by -// https://github.com/census-instrumentation/opencensus-specs/blob/master/stats/gRPC.md - -// Registers the cumulative gRPC views so that they will be exported by any -// registered stats exporter. For on-task stats, construct a View using the -// ViewDescriptors below. -void RegisterOpenCensusViewsForExport(); - -// Returns the tracing Span for the current RPC. -::opencensus::trace::Span GetSpanFromServerContext( - grpc::ServerContext* context); - -} // namespace grpc_impl - -#endif // GRPCPP_OPENCENSUS_IMPL_H diff --git a/src/cpp/ext/filters/census/grpc_plugin.cc b/src/cpp/ext/filters/census/grpc_plugin.cc index c5018f0673a..f978ed3bf51 100644 --- a/src/cpp/ext/filters/census/grpc_plugin.cc +++ b/src/cpp/ext/filters/census/grpc_plugin.cc @@ -30,6 +30,35 @@ namespace grpc { +void RegisterOpenCensusPlugin() { + RegisterChannelFilter( + "opencensus_client", GRPC_CLIENT_CHANNEL, INT_MAX /* priority */, + nullptr /* condition function */); + RegisterChannelFilter( + "opencensus_server", GRPC_SERVER_CHANNEL, INT_MAX /* priority */, + nullptr /* condition function */); + + // Access measures to ensure they are initialized. Otherwise, creating a view + // before the first RPC would cause an error. + RpcClientSentBytesPerRpc(); + RpcClientReceivedBytesPerRpc(); + RpcClientRoundtripLatency(); + RpcClientServerLatency(); + RpcClientSentMessagesPerRpc(); + RpcClientReceivedMessagesPerRpc(); + + RpcServerSentBytesPerRpc(); + RpcServerReceivedBytesPerRpc(); + RpcServerServerLatency(); + RpcServerSentMessagesPerRpc(); + RpcServerReceivedMessagesPerRpc(); +} + +::opencensus::trace::Span GetSpanFromServerContext(ServerContext* context) { + return reinterpret_cast(context->census_context()) + ->Span(); +} + // These measure definitions should be kept in sync across opencensus // implementations--see // https://github.com/census-instrumentation/opencensus-java/blob/master/contrib/grpc_metrics/src/main/java/io/opencensus/contrib/grpc/metrics/RpcMeasureConstants.java. @@ -97,39 +126,5 @@ ABSL_CONST_INIT const absl::string_view ABSL_CONST_INIT const absl::string_view kRpcServerServerLatencyMeasureName = "grpc.io/server/server_latency"; + } // namespace grpc -namespace grpc_impl { - -void RegisterOpenCensusPlugin() { - grpc::RegisterChannelFilter( - "opencensus_client", GRPC_CLIENT_CHANNEL, INT_MAX /* priority */, - nullptr /* condition function */); - grpc::RegisterChannelFilter( - "opencensus_server", GRPC_SERVER_CHANNEL, INT_MAX /* priority */, - nullptr /* condition function */); - - // Access measures to ensure they are initialized. Otherwise, creating a view - // before the first RPC would cause an error. - grpc::RpcClientSentBytesPerRpc(); - grpc::RpcClientReceivedBytesPerRpc(); - grpc::RpcClientRoundtripLatency(); - grpc::RpcClientServerLatency(); - grpc::RpcClientSentMessagesPerRpc(); - grpc::RpcClientReceivedMessagesPerRpc(); - - grpc::RpcServerSentBytesPerRpc(); - grpc::RpcServerReceivedBytesPerRpc(); - grpc::RpcServerServerLatency(); - grpc::RpcServerSentMessagesPerRpc(); - grpc::RpcServerReceivedMessagesPerRpc(); -} - -::opencensus::trace::Span GetSpanFromServerContext( - grpc::ServerContext* context) { - return reinterpret_cast(context->census_context()) - ->Span(); -} - -} // namespace grpc_impl diff --git a/src/cpp/ext/filters/census/grpc_plugin.h b/src/cpp/ext/filters/census/grpc_plugin.h index 209fad139ce..9e319cb994e 100644 --- a/src/cpp/ext/filters/census/grpc_plugin.h +++ b/src/cpp/ext/filters/census/grpc_plugin.h @@ -22,14 +22,12 @@ #include #include "absl/strings/string_view.h" -#include "include/grpcpp/opencensus_impl.h" +#include "include/grpcpp/opencensus.h" #include "opencensus/stats/stats.h" -namespace grpc_impl { +namespace grpc { class ServerContext; -} -namespace grpc { // The tag keys set when recording RPC stats. ::opencensus::stats::TagKey ClientMethodTagKey(); diff --git a/src/cpp/ext/filters/census/views.cc b/src/cpp/ext/filters/census/views.cc index d7e3c81a955..2c0c5f72950 100644 --- a/src/cpp/ext/filters/census/views.cc +++ b/src/cpp/ext/filters/census/views.cc @@ -25,23 +25,6 @@ #include "opencensus/stats/internal/set_aggregation_window.h" #include "opencensus/stats/stats.h" -namespace grpc_impl { - -void RegisterOpenCensusViewsForExport() { - grpc::ClientSentMessagesPerRpcCumulative().RegisterForExport(); - grpc::ClientSentBytesPerRpcCumulative().RegisterForExport(); - grpc::ClientReceivedMessagesPerRpcCumulative().RegisterForExport(); - grpc::ClientReceivedBytesPerRpcCumulative().RegisterForExport(); - grpc::ClientRoundtripLatencyCumulative().RegisterForExport(); - grpc::ClientServerLatencyCumulative().RegisterForExport(); - - grpc::ServerSentMessagesPerRpcCumulative().RegisterForExport(); - grpc::ServerSentBytesPerRpcCumulative().RegisterForExport(); - grpc::ServerReceivedMessagesPerRpcCumulative().RegisterForExport(); - grpc::ServerReceivedBytesPerRpcCumulative().RegisterForExport(); - grpc::ServerServerLatencyCumulative().RegisterForExport(); -} -} // namespace grpc_impl namespace grpc { using ::opencensus::stats::Aggregation; @@ -88,6 +71,21 @@ ViewDescriptor HourDescriptor() { } // namespace +void RegisterOpenCensusViewsForExport() { + ClientSentMessagesPerRpcCumulative().RegisterForExport(); + ClientSentBytesPerRpcCumulative().RegisterForExport(); + ClientReceivedMessagesPerRpcCumulative().RegisterForExport(); + ClientReceivedBytesPerRpcCumulative().RegisterForExport(); + ClientRoundtripLatencyCumulative().RegisterForExport(); + ClientServerLatencyCumulative().RegisterForExport(); + + ServerSentMessagesPerRpcCumulative().RegisterForExport(); + ServerSentBytesPerRpcCumulative().RegisterForExport(); + ServerReceivedMessagesPerRpcCumulative().RegisterForExport(); + ServerReceivedBytesPerRpcCumulative().RegisterForExport(); + ServerServerLatencyCumulative().RegisterForExport(); +} + // client cumulative const ViewDescriptor& ClientSentBytesPerRpcCumulative() { const static ViewDescriptor descriptor = diff --git a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc index ad788a2dd68..73394028309 100644 --- a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc +++ b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc @@ -58,7 +58,7 @@ class EchoServer final : public EchoTestService::Service { class StatsPluginEnd2EndTest : public ::testing::Test { protected: - static void SetUpTestCase() { grpc_impl::RegisterOpenCensusPlugin(); } + static void SetUpTestCase() { RegisterOpenCensusPlugin(); } void SetUp() { // Set up a synchronous server on a different thread to avoid the asynch diff --git a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc index d23c4f0573f..9d42eb891df 100644 --- a/test/cpp/microbenchmarks/bm_opencensus_plugin.cc +++ b/test/cpp/microbenchmarks/bm_opencensus_plugin.cc @@ -29,9 +29,7 @@ #include "test/cpp/microbenchmarks/helpers.h" absl::once_flag once; -void RegisterOnce() { - absl::call_once(once, grpc_impl::RegisterOpenCensusPlugin); -} +void RegisterOnce() { absl::call_once(once, grpc::RegisterOpenCensusPlugin); } class EchoServer final : public grpc::testing::EchoTestService::Service { grpc::Status Echo(grpc::ServerContext* context, @@ -101,7 +99,7 @@ static void BM_E2eLatencyCensusEnabled(benchmark::State& state) { RegisterOnce(); // This we can safely repeat, and doing so clears accumulated data to avoid // initialization costs varying between runs. - grpc_impl::RegisterOpenCensusViewsForExport(); + grpc::RegisterOpenCensusViewsForExport(); EchoServerThread server; std::unique_ptr stub = From e9ad9e90b35138259d2749a58c89f169380a5146 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 15 Mar 2019 11:41:57 -0700 Subject: [PATCH 702/814] reinstated version bump of google benchmark --- bazel/grpc_deps.bzl | 9 ++++----- third_party/BUILD | 1 - third_party/benchmark.BUILD | 15 --------------- 3 files changed, 4 insertions(+), 21 deletions(-) delete mode 100644 third_party/benchmark.BUILD diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 6b04c0b2c48..9b6aaacbd58 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -147,16 +147,15 @@ def grpc_deps(): if "com_github_gflags_gflags" not in native.existing_rules(): http_archive( name = "com_github_gflags_gflags", - strip_prefix = "gflags-30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e", - url = "https://github.com/gflags/gflags/archive/30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e.tar.gz", + strip_prefix = "gflags-28f50e0fed19872e0fd50dd23ce2ee8cd759338e", + url = "https://github.com/gflags/gflags/archive/28f50e0fed19872e0fd50dd23ce2ee8cd759338e.tar.gz", ) if "com_github_google_benchmark" not in native.existing_rules(): http_archive( name = "com_github_google_benchmark", - build_file = "@com_github_grpc_grpc//third_party:benchmark.BUILD", - strip_prefix = "benchmark-9913418d323e64a0111ca0da81388260c2bbe1e9", - url = "https://github.com/google/benchmark/archive/9913418d323e64a0111ca0da81388260c2bbe1e9.tar.gz", + strip_prefix = "benchmark-e776aa0275e293707b6a0901e0e8d8a8a3679508", + url = "https://github.com/google/benchmark/archive/e776aa0275e293707b6a0901e0e8d8a8a3679508.tar.gz", ) if "com_github_cares_cares" not in native.existing_rules(): diff --git a/third_party/BUILD b/third_party/BUILD index 5ec919dc48d..8b43d6b8300 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -1,5 +1,4 @@ exports_files([ - "benchmark.BUILD", "gtest.BUILD", "objective_c/Cronet/bidirectional_stream_c.h", "zlib.BUILD", diff --git a/third_party/benchmark.BUILD b/third_party/benchmark.BUILD deleted file mode 100644 index 4c622f32a84..00000000000 --- a/third_party/benchmark.BUILD +++ /dev/null @@ -1,15 +0,0 @@ -cc_library( - name = "benchmark", - srcs = glob(["src/*.cc"]), - hdrs = glob(["include/**/*.h", "src/*.h"]), - includes = [ - "include", "." - ], - copts = [ - "-DHAVE_POSIX_REGEX" - ], - linkstatic = 1, - visibility = [ - "//visibility:public", - ], -) From c3ecc618672631c36db5a204b94fc6b259bda191 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 15 Mar 2019 11:48:10 -0700 Subject: [PATCH 703/814] Use C-Core API to perform time conversion --- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi | 6 ++++++ src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi | 2 +- src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi | 13 ++++++------- .../tests/unit/_cython/_channel_test.py | 6 ++++++ 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 88a6c0039c6..7e20f7a4e2d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -53,6 +53,10 @@ cdef extern from "grpc/grpc.h": void *grpc_slice_start_ptr "GRPC_SLICE_START_PTR" (grpc_slice s) nogil size_t grpc_slice_length "GRPC_SLICE_LENGTH" (grpc_slice s) nogil + const int GPR_MS_PER_SEC + const int GPR_US_PER_SEC + const int GPR_NS_PER_SEC + ctypedef enum gpr_clock_type: GPR_CLOCK_MONOTONIC GPR_CLOCK_REALTIME @@ -74,6 +78,8 @@ cdef extern from "grpc/grpc.h": gpr_clock_type target_clock) nogil gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type type) nogil + gpr_timespec gpr_time_from_nanos(int64_t ns, gpr_clock_type type) nogil + double gpr_timespec_to_micros(gpr_timespec t) nogil gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) nogil diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi index 1319ac0481d..c46e8a98b04 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi @@ -13,7 +13,7 @@ # limitations under the License. -cdef gpr_timespec _timespec_from_time(object time) +cdef gpr_timespec _timespec_from_time(object time) except * cdef double _time_from_timespec(gpr_timespec timespec) except * diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi index c452dd54f82..6d181bb1d60 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi @@ -13,18 +13,17 @@ # limitations under the License. -cdef gpr_timespec _timespec_from_time(object time): - cdef gpr_timespec timespec +cdef gpr_timespec _timespec_from_time(object time) except *: if time is None: return gpr_inf_future(GPR_CLOCK_REALTIME) else: - timespec.seconds = time - timespec.nanoseconds = (time - float(timespec.seconds)) * 1e9 - timespec.clock_type = GPR_CLOCK_REALTIME - return timespec + return gpr_time_from_nanos( + (time * GPR_NS_PER_SEC), + GPR_CLOCK_REALTIME, + ) cdef double _time_from_timespec(gpr_timespec timespec) except *: cdef gpr_timespec real_timespec = gpr_convert_clock_type( timespec, GPR_CLOCK_REALTIME) - return real_timespec.seconds + real_timespec.nanoseconds / 1e9 + return gpr_timespec_to_micros(real_timespec) / GPR_US_PER_SEC diff --git a/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py b/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py index d95286071d5..9fd9ede144d 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py @@ -57,6 +57,12 @@ class ChannelTest(unittest.TestCase): def test_multiple_channels_lonely_connectivity(self): _in_parallel(_create_loop_destroy, ()) + def test_negative_deadline_connectivity(self): + channel = _channel() + connectivity = channel.check_connectivity_state(True) + channel.watch_connectivity_state(connectivity, -3.14) + channel.close(cygrpc.StatusCode.ok, 'Channel close!') + if __name__ == '__main__': unittest.main(verbosity=2) From 64caf4d3dfa1aea9e299d5715b7907a7157690ac Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Fri, 15 Mar 2019 12:57:25 -0700 Subject: [PATCH 704/814] fix clang-tidy errors --- .../tls/spiffe_security_connector.cc | 24 +++++++++---------- test/core/end2end/fixtures/h2_spiffe.cc | 6 ++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc index 075b1c9d53c..ebf9c905079 100644 --- a/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +++ b/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc @@ -161,7 +161,7 @@ void SpiffeChannelSecurityConnector::check_peer( const grpc_tls_server_authorization_check_config* config = creds->options().server_authorization_check_config(); /* If server authorization config is not null, use it to perform - * server authorizaiton check. */ + * server authorization check. */ if (config != nullptr) { const tsi_peer_property* p = tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); @@ -254,17 +254,17 @@ SpiffeChannelSecurityConnector::InitializeHandshakerFactory( const SpiffeCredentials* creds = static_cast(channel_creds()); auto key_materials_config = PopulateSpiffeCredentials(creds->options()); - if (!key_materials_config.get()->pem_key_cert_pair_list().size()) { - key_materials_config.get()->Unref(); + if (key_materials_config->pem_key_cert_pair_list().empty()) { + key_materials_config->Unref(); return GRPC_SECURITY_ERROR; } tsi_ssl_pem_key_cert_pair* pem_key_cert_pair = ConvertToTsiPemKeyCertPair( - key_materials_config.get()->pem_key_cert_pair_list()); + key_materials_config->pem_key_cert_pair_list()); grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init( - pem_key_cert_pair, key_materials_config.get()->pem_root_certs(), + pem_key_cert_pair, key_materials_config->pem_root_certs(), ssl_session_cache, &client_handshaker_factory_); // Free memory. - key_materials_config.get()->Unref(); + key_materials_config->Unref(); grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1); return status; } @@ -401,8 +401,8 @@ SpiffeServerSecurityConnector::RefreshServerHandshakerFactory() { auto key_materials_config = PopulateSpiffeCredentials(creds->options()); /* Credential reload does NOT take effect and we need to keep using * the existing handshaker factory. */ - if (key_materials_config.get()->pem_key_cert_pair_list().empty()) { - key_materials_config.get()->Unref(); + if (key_materials_config->pem_key_cert_pair_list().empty()) { + key_materials_config->Unref(); return GRPC_SECURITY_ERROR; } /* Credential reload takes effect and we need to free the existing @@ -411,15 +411,15 @@ SpiffeServerSecurityConnector::RefreshServerHandshakerFactory() { tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); } tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = ConvertToTsiPemKeyCertPair( - key_materials_config.get()->pem_key_cert_pair_list()); + key_materials_config->pem_key_cert_pair_list()); size_t num_key_cert_pairs = - key_materials_config.get()->pem_key_cert_pair_list().size(); + key_materials_config->pem_key_cert_pair_list().size(); grpc_security_status status = grpc_ssl_tsi_server_handshaker_factory_init( pem_key_cert_pairs, num_key_cert_pairs, - key_materials_config.get()->pem_root_certs(), + key_materials_config->pem_root_certs(), creds->options().cert_request_type(), &server_handshaker_factory_); // Free memory. - key_materials_config.get()->Unref(); + key_materials_config->Unref(); grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pairs, num_key_cert_pairs); return status; diff --git a/test/core/end2end/fixtures/h2_spiffe.cc b/test/core/end2end/fixtures/h2_spiffe.cc index 3cd7c362212..9ab796ea429 100644 --- a/test/core/end2end/fixtures/h2_spiffe.cc +++ b/test/core/end2end/fixtures/h2_spiffe.cc @@ -111,7 +111,7 @@ static void server_authz_check_cb(void* user_data) { static_cast(user_data); GPR_ASSERT(check_arg != nullptr); // result = 1 indicates the server authorization check passes. - // Normally, the applicaiton code should resort to mapping information + // Normally, the application code should resort to mapping information // between server identity and target name to derive the result. // For this test, we directly return 1 for simplicity. check_arg->success = 1; @@ -143,7 +143,7 @@ static int client_cred_reload_sync(void* config_user_data, gpr_zalloc(sizeof(grpc_ssl_pem_key_cert_pair))); key_cert_pair[0]->private_key = gpr_strdup(test_server1_key); key_cert_pair[0]->cert_chain = gpr_strdup(test_server1_cert); - if (!arg->key_materials_config->pem_key_cert_pair_list().size()) { + if (arg->key_materials_config->pem_key_cert_pair_list().empty()) { grpc_tls_key_materials_config_set_key_materials( arg->key_materials_config, gpr_strdup(test_root_cert), (const grpc_ssl_pem_key_cert_pair**)key_cert_pair, 1); @@ -169,7 +169,7 @@ static int server_cred_reload_sync(void* config_user_data, GPR_ASSERT(arg->key_materials_config != nullptr); GPR_ASSERT(arg->key_materials_config->pem_key_cert_pair_list().data() != nullptr); - if (!arg->key_materials_config->pem_key_cert_pair_list().size()) { + if (arg->key_materials_config->pem_key_cert_pair_list().empty()) { grpc_tls_key_materials_config_set_key_materials( arg->key_materials_config, gpr_strdup(test_root_cert), (const grpc_ssl_pem_key_cert_pair**)key_cert_pair, 1); From dfb5a2dbc67d7968c3c9218d003c9a3d97e452a5 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 15 Mar 2019 13:01:28 -0700 Subject: [PATCH 705/814] Disable negative deadline test in gevent --- src/python/grpcio_tests/commands.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 866fb6de1f7..e6e5e3d4e93 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -147,7 +147,9 @@ class TestGevent(setuptools.Command): # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels', 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels_and_sockets', - 'channelz._channelz_servicer_test.ChannelzServicerTest.test_streaming_rpc' + 'channelz._channelz_servicer_test.ChannelzServicerTest.test_streaming_rpc', + # TODO(https://github.com/grpc/grpc/issues/15411) enable this test + 'unit._cython._channel_test.ChannelTest.test_negative_deadline_connectivity' ) description = 'run tests with gevent. Assumes grpc/gevent are installed' user_options = [] From 78fc00f0ce9ac0228861ea8dcb344ce80d21fe92 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 15 Mar 2019 13:16:18 -0700 Subject: [PATCH 706/814] Fix reresolution condition in grpclb --- .../filters/client_channel/lb_policy/grpclb/grpclb.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 184215a3da9..18d25aa8842 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -684,11 +684,11 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, void GrpcLb::Helper::RequestReresolution() { if (parent_->shutting_down_) return; - // If there is a pending child policy, ignore re-resolution requests - // from the current child policy (or any outdated child). - if (parent_->pending_child_policy_ != nullptr && !CalledByPendingChild()) { - return; - } + const LoadBalancingPolicy* latest_child_policy = + parent_->pending_child_policy_ != nullptr + ? parent_->pending_child_policy_.get() + : parent_->child_policy_.get(); + if (child_ != latest_child_policy) return; if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, "[grpclb %p] Re-resolution requested from child policy (%p).", From c02034eb96c29e27dccda249a6cc180e8f48668c Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 14 Mar 2019 19:17:14 -0700 Subject: [PATCH 707/814] Add more tracing around the status of each c-ares query; refactor error handling --- .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 47 ++++++++----------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 986af89454f..37b0b365eed 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -67,9 +67,7 @@ struct grpc_ares_request { /** number of ongoing queries */ size_t pending_queries; - /** is there at least one successful query, set in on_done_cb */ - bool success; - /** the errors explaining the request failure, set in on_done_cb */ + /** the errors explaining query failures, appended to in query callbacks */ grpc_error* error; }; @@ -145,6 +143,10 @@ void grpc_ares_complete_request_locked(grpc_ares_request* r) { ServerAddressList* addresses = r->addresses_out->get(); if (addresses != nullptr) { grpc_cares_wrapper_address_sorting_sort(addresses); + GRPC_ERROR_UNREF(r->error); + r->error = GRPC_ERROR_NONE; + // TODO(apolcyn): allow c-ares to return a service config + // with no addresses along side it } GRPC_CLOSURE_SCHED(r->on_done, r->error); } @@ -175,9 +177,9 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, static_cast(arg); grpc_ares_request* r = hr->parent_request; if (status == ARES_SUCCESS) { - GRPC_ERROR_UNREF(r->error); - r->error = GRPC_ERROR_NONE; - r->success = true; + GRPC_CARES_TRACE_LOG( + "request:%p on_hostbyname_done_locked host=%s ARES_SUCCESS", r, + hr->host); if (*r->addresses_out == nullptr) { *r->addresses_out = grpc_core::MakeUnique(); } @@ -229,17 +231,15 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, } } } - } else if (!r->success) { + } else { char* error_msg; gpr_asprintf(&error_msg, "C-ares status is not ARES_SUCCESS: %s", ares_strerror(status)); + GRPC_CARES_TRACE_LOG("request:%p on_hostbyname_done_locked host=%s %s", r, + hr->host, error_msg); grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); gpr_free(error_msg); - if (r->error == GRPC_ERROR_NONE) { - r->error = error; - } else { - r->error = grpc_error_add_child(error, r->error); - } + r->error = grpc_error_add_child(error, r->error); } destroy_hostbyname_request_locked(hr); } @@ -247,9 +247,8 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts, static void on_srv_query_done_locked(void* arg, int status, int timeouts, unsigned char* abuf, int alen) { grpc_ares_request* r = static_cast(arg); - GRPC_CARES_TRACE_LOG("request:%p on_query_srv_done_locked", r); if (status == ARES_SUCCESS) { - GRPC_CARES_TRACE_LOG("request:%p on_query_srv_done_locked ARES_SUCCESS", r); + GRPC_CARES_TRACE_LOG("request:%p on_srv_query_done_locked ARES_SUCCESS", r); struct ares_srv_reply* reply; const int parse_status = ares_parse_srv_reply(abuf, alen, &reply); if (parse_status == ARES_SUCCESS) { @@ -273,17 +272,15 @@ static void on_srv_query_done_locked(void* arg, int status, int timeouts, if (reply != nullptr) { ares_free_data(reply); } - } else if (!r->success) { + } else { char* error_msg; gpr_asprintf(&error_msg, "C-ares status is not ARES_SUCCESS: %s", ares_strerror(status)); + GRPC_CARES_TRACE_LOG("request:%p on_srv_query_done_locked %s", r, + error_msg); grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); gpr_free(error_msg); - if (r->error == GRPC_ERROR_NONE) { - r->error = error; - } else { - r->error = grpc_error_add_child(error, r->error); - } + r->error = grpc_error_add_child(error, r->error); } grpc_ares_request_unref_locked(r); } @@ -294,12 +291,12 @@ static void on_txt_done_locked(void* arg, int status, int timeouts, unsigned char* buf, int len) { char* error_msg; grpc_ares_request* r = static_cast(arg); - GRPC_CARES_TRACE_LOG("request:%p on_txt_done_locked", r); const size_t prefix_len = sizeof(g_service_config_attribute_prefix) - 1; struct ares_txt_ext* result = nullptr; struct ares_txt_ext* reply = nullptr; grpc_error* error = GRPC_ERROR_NONE; if (status != ARES_SUCCESS) goto fail; + GRPC_CARES_TRACE_LOG("request:%p on_txt_done_locked ARES_SUCCESS", r); status = ares_parse_txt_reply_ext(buf, len, &reply); if (status != ARES_SUCCESS) goto fail; // Find service config in TXT record. @@ -337,12 +334,9 @@ fail: gpr_asprintf(&error_msg, "C-ares TXT lookup status is not ARES_SUCCESS: %s", ares_strerror(status)); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + GRPC_CARES_TRACE_LOG("request:%p on_txt_done_locked %s", r, error_msg); gpr_free(error_msg); - if (r->error == GRPC_ERROR_NONE) { - r->error = error; - } else { - r->error = grpc_error_add_child(error, r->error); - } + r->error = grpc_error_add_child(error, r->error); done: grpc_ares_request_unref_locked(r); } @@ -534,7 +528,6 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( r->on_done = on_done; r->addresses_out = addrs; r->service_config_json_out = service_config_json; - r->success = false; r->error = GRPC_ERROR_NONE; r->pending_queries = 0; GRPC_CARES_TRACE_LOG( From 335ced6b79bf61819f2aa5efd89c83a4d87f1a37 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 15 Mar 2019 13:30:31 -0700 Subject: [PATCH 708/814] Improve logging --- .../ext/filters/client_channel/lb_policy/grpclb/grpclb.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 18d25aa8842..734342a1e77 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -691,8 +691,8 @@ void GrpcLb::Helper::RequestReresolution() { if (child_ != latest_child_policy) return; if (grpc_lb_glb_trace.enabled()) { gpr_log(GPR_INFO, - "[grpclb %p] Re-resolution requested from child policy (%p).", - parent_.get(), child_); + "[grpclb %p] Re-resolution requested from %schild policy (%p).", + parent_.get(), CalledByPendingChild() ? "pending " : "", child_); } // If we are talking to a balancer, we expect to get updated addresses // from the balancer, so we can ignore the re-resolution request from From b0ad6ac3ae04de924fd7c1331b413f7b230772d9 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 15 Mar 2019 13:54:28 -0700 Subject: [PATCH 709/814] Clean up grpclb and xds end2end tests. --- test/cpp/end2end/grpclb_end2end_test.cc | 629 +++++++++++++----------- test/cpp/end2end/xds_end2end_test.cc | 392 +++++++-------- 2 files changed, 530 insertions(+), 491 deletions(-) diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index abce031c539..761b6ec39d3 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -56,13 +56,8 @@ // TODO(dgq): Other scenarios in need of testing: // - Send a serverlist with faulty ip:port addresses (port > 2^16, etc). // - Test reception of invalid serverlist -// - Test pinging // - Test against a non-LB server. // - Random LB server closing the stream unexpectedly. -// - Test using DNS-resolvable names (localhost?) -// - Test handling of creation of faulty RR instance by having the LB return a -// serverlist with non-existent backends after having initially returned a -// valid one. // // Findings from end to end testing to be covered here: // - Handling of LB servers restart, including reconnection after backing-off @@ -74,8 +69,6 @@ // part of the grpclb shutdown process. // 2) the retry timer is active. Again, the weak reference it holds should // prevent a premature call to \a glb_destroy. -// - Restart of backend servers with no changes to serverlist. This exercises -// the RR handover mechanism. using std::chrono::system_clock; @@ -149,14 +142,7 @@ class BackendServiceImpl : public BackendService { return status; } - // Returns true on its first invocation, false otherwise. - bool Shutdown() { - std::unique_lock lock(mu_); - const bool prev = !shutdown_; - shutdown_ = true; - gpr_log(GPR_INFO, "Backend: shut down"); - return prev; - } + void Shutdown() {} std::set clients() { std::unique_lock lock(clients_mu_); @@ -170,7 +156,6 @@ class BackendServiceImpl : public BackendService { } std::mutex mu_; - bool shutdown_ = false; std::mutex clients_mu_; std::set clients_; }; @@ -200,6 +185,14 @@ struct ClientStats { } return *this; } + + void Reset() { + num_calls_started = 0; + num_calls_finished = 0; + num_calls_finished_with_client_failed_to_send = 0; + num_calls_finished_known_received = 0; + drop_token_counts.clear(); + } }; class BalancerServiceImpl : public BalancerService { @@ -209,8 +202,7 @@ class BalancerServiceImpl : public BalancerService { explicit BalancerServiceImpl(int client_load_reporting_interval_seconds) : client_load_reporting_interval_seconds_( - client_load_reporting_interval_seconds), - shutdown_(false) {} + client_load_reporting_interval_seconds) {} Status BalanceLoad(ServerContext* context, Stream* stream) override { // Balancer shouldn't receive the call credentials metadata. @@ -241,16 +233,11 @@ class BalancerServiceImpl : public BalancerService { responses_and_delays = responses_and_delays_; } for (const auto& response_and_delay : responses_and_delays) { - { - std::unique_lock lock(mu_); - if (shutdown_) goto done; - } SendResponse(stream, response_and_delay.first, response_and_delay.second); } { std::unique_lock lock(mu_); - if (shutdown_) goto done; - serverlist_cond_.wait(lock, [this] { return serverlist_ready_; }); + serverlist_cond_.wait(lock, [this] { return serverlist_done_; }); } if (client_load_reporting_interval_seconds_ > 0) { @@ -291,14 +278,12 @@ class BalancerServiceImpl : public BalancerService { responses_and_delays_.push_back(std::make_pair(response, send_after_ms)); } - // Returns true on its first invocation, false otherwise. - bool Shutdown() { - NotifyDoneWithServerlists(); + void Shutdown() { std::unique_lock lock(mu_); - const bool prev = !shutdown_; - shutdown_ = true; + NotifyDoneWithServerlistsLocked(); + responses_and_delays_.clear(); + client_stats_.Reset(); gpr_log(GPR_INFO, "LB[%p]: shut down", this); - return prev; } static LoadBalanceResponse BuildResponseForBackends( @@ -334,8 +319,14 @@ class BalancerServiceImpl : public BalancerService { void NotifyDoneWithServerlists() { std::lock_guard lock(mu_); - serverlist_ready_ = true; - serverlist_cond_.notify_all(); + NotifyDoneWithServerlistsLocked(); + } + + void NotifyDoneWithServerlistsLocked() { + if (!serverlist_done_) { + serverlist_done_ = true; + serverlist_cond_.notify_all(); + } } private: @@ -357,14 +348,13 @@ class BalancerServiceImpl : public BalancerService { std::condition_variable load_report_cond_; bool load_report_ready_ = false; std::condition_variable serverlist_cond_; - bool serverlist_ready_ = false; + bool serverlist_done_ = false; ClientStats client_stats_; - bool shutdown_; }; class GrpclbEnd2endTest : public ::testing::Test { protected: - GrpclbEnd2endTest(int num_backends, int num_balancers, + GrpclbEnd2endTest(size_t num_backends, size_t num_balancers, int client_load_reporting_interval_seconds) : server_host_("localhost"), num_backends_(num_backends), @@ -381,29 +371,35 @@ class GrpclbEnd2endTest : public ::testing::Test { grpc_core::MakeRefCounted(); // Start the backends. for (size_t i = 0; i < num_backends_; ++i) { - backends_.emplace_back(new BackendServiceImpl()); - backend_servers_.emplace_back(ServerThread( - "backend", server_host_, backends_.back().get())); + backends_.emplace_back(new ServerThread("backend")); + backends_.back()->Start(server_host_); } // Start the load balancers. for (size_t i = 0; i < num_balancers_; ++i) { - balancers_.emplace_back( - new BalancerServiceImpl(client_load_reporting_interval_seconds_)); - balancer_servers_.emplace_back(ServerThread( - "balancer", server_host_, balancers_.back().get())); + balancers_.emplace_back(new ServerThread( + "balancer", client_load_reporting_interval_seconds_)); + balancers_.back()->Start(server_host_); } ResetStub(); } void TearDown() override { - for (size_t i = 0; i < backends_.size(); ++i) { - if (backends_[i]->Shutdown()) backend_servers_[i].Shutdown(); - } - for (size_t i = 0; i < balancers_.size(); ++i) { - if (balancers_[i]->Shutdown()) balancer_servers_[i].Shutdown(); - } + ShutdownAllBackends(); + for (auto& balancer : balancers_) balancer->Shutdown(); } + void StartAllBackends() { + for (auto& backend : backends_) backend->Start(server_host_); + } + + void StartBackend(size_t index) { backends_[index]->Start(server_host_); } + + void ShutdownAllBackends() { + for (auto& backend : backends_) backend->Shutdown(); + } + + void ShutdownBackend(size_t index) { backends_[index]->Shutdown(); } + void ResetStub(int fallback_timeout = 0, const grpc::string& expected_targets = "") { ChannelArguments args; @@ -431,20 +427,21 @@ class GrpclbEnd2endTest : public ::testing::Test { } void ResetBackendCounters() { - for (const auto& backend : backends_) backend->ResetCounters(); + for (auto& backend : backends_) backend->service_.ResetCounters(); } ClientStats WaitForLoadReports() { ClientStats client_stats; - for (const auto& balancer : balancers_) { - client_stats += balancer->WaitForLoadReport(); + for (auto& balancer : balancers_) { + client_stats += balancer->service_.WaitForLoadReport(); } return client_stats; } - bool SeenAllBackends() { - for (const auto& backend : backends_) { - if (backend->request_count() == 0) return false; + bool SeenAllBackends(size_t start_index = 0, size_t stop_index = 0) { + if (stop_index == 0) stop_index = backends_.size(); + for (size_t i = start_index; i < stop_index; ++i) { + if (backends_[i]->service_.request_count() == 0) return false; } return true; } @@ -464,13 +461,14 @@ class GrpclbEnd2endTest : public ::testing::Test { ++*num_total; } - std::tuple WaitForAllBackends( - int num_requests_multiple_of = 1) { + std::tuple WaitForAllBackends(int num_requests_multiple_of = 1, + size_t start_index = 0, + size_t stop_index = 0) { int num_ok = 0; int num_failure = 0; int num_drops = 0; int num_total = 0; - while (!SeenAllBackends()) { + while (!SeenAllBackends(start_index, stop_index)) { SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops); } while (num_total % num_requests_multiple_of != 0) { @@ -488,7 +486,7 @@ class GrpclbEnd2endTest : public ::testing::Test { void WaitForBackend(size_t backend_idx) { do { (void)SendRpc(); - } while (backends_[backend_idx]->request_count() == 0); + } while (backends_[backend_idx]->service_.request_count() == 0); ResetBackendCounters(); } @@ -528,8 +526,8 @@ class GrpclbEnd2endTest : public ::testing::Test { void SetNextResolutionAllBalancers( const char* service_config_json = nullptr) { std::vector addresses; - for (size_t i = 0; i < balancer_servers_.size(); ++i) { - addresses.emplace_back(AddressData{balancer_servers_[i].port_, true, ""}); + for (size_t i = 0; i < balancers_.size(); ++i) { + addresses.emplace_back(AddressData{balancers_[i]->port_, true, ""}); } SetNextResolution(addresses, service_config_json); } @@ -561,10 +559,12 @@ class GrpclbEnd2endTest : public ::testing::Test { response_generator_->SetReresolutionResponse(&fake_result); } - const std::vector GetBackendPorts(const size_t start_index = 0) const { + const std::vector GetBackendPorts(size_t start_index = 0, + size_t stop_index = 0) const { + if (stop_index == 0) stop_index = backends_.size(); std::vector backend_ports; - for (size_t i = start_index; i < backend_servers_.size(); ++i) { - backend_ports.push_back(backend_servers_[i].port_); + for (size_t i = start_index; i < stop_index; ++i) { + backend_ports.push_back(backends_[i]->port_); } return backend_ports; } @@ -572,7 +572,7 @@ class GrpclbEnd2endTest : public ::testing::Test { void ScheduleResponseForBalancer(size_t i, const LoadBalanceResponse& response, int delay_ms) { - balancers_.at(i)->add_response(response, delay_ms); + balancers_[i]->service_.add_response(response, delay_ms); } Status SendRpc(EchoResponse* response = nullptr, int timeout_ms = 1000, @@ -607,23 +607,28 @@ class GrpclbEnd2endTest : public ::testing::Test { template struct ServerThread { - explicit ServerThread(const grpc::string& type, - const grpc::string& server_host, T* service) - : type_(type), service_(service) { + template + explicit ServerThread(const grpc::string& type, Args&&... args) + : port_(grpc_pick_unused_port_or_die()), + type_(type), + service_(std::forward(args)...) {} + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); + GPR_ASSERT(!running_); + running_ = true; std::mutex mu; // We need to acquire the lock here in order to prevent the notify_one - // by ServerThread::Start from firing before the wait below is hit. + // by ServerThread::Serve from firing before the wait below is hit. std::unique_lock lock(mu); - port_ = grpc_pick_unused_port_or_die(); - gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); std::condition_variable cond; thread_.reset(new std::thread( - std::bind(&ServerThread::Start, this, server_host, &mu, &cond))); + std::bind(&ServerThread::Serve, this, server_host, &mu, &cond))); cond.wait(lock); gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); } - void Start(const grpc::string& server_host, std::mutex* mu, + void Serve(const grpc::string& server_host, std::mutex* mu, std::condition_variable* cond) { // We need to acquire the lock here in order to prevent the notify_one // below from firing before its corresponding wait is executed. @@ -634,23 +639,27 @@ class GrpclbEnd2endTest : public ::testing::Test { std::shared_ptr creds(new SecureServerCredentials( grpc_fake_transport_security_server_credentials_create())); builder.AddListeningPort(server_address.str(), creds); - builder.RegisterService(service_); + builder.RegisterService(&service_); server_ = builder.BuildAndStart(); cond->notify_one(); } void Shutdown() { + if (!running_) return; gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str()); + service_.Shutdown(); server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); thread_->join(); gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str()); + running_ = false; } - int port_; + const int port_; grpc::string type_; + T service_; std::unique_ptr server_; - T* service_; std::unique_ptr thread_; + bool running_ = false; }; const grpc::string server_host_; @@ -659,10 +668,8 @@ class GrpclbEnd2endTest : public ::testing::Test { const int client_load_reporting_interval_seconds_; std::shared_ptr channel_; std::unique_ptr stub_; - std::vector> backends_; - std::vector> balancers_; - std::vector> backend_servers_; - std::vector> balancer_servers_; + std::vector>> backends_; + std::vector>> balancers_; grpc_core::RefCountedPtr response_generator_; const grpc::string kRequestMessage_ = "Live long and prosper."; @@ -689,14 +696,13 @@ TEST_F(SingleBalancerTest, Vanilla) { // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // Check LB policy name for the channel. EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); @@ -714,11 +720,11 @@ TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfig) { 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), 0); CheckRpcSendOk(1, 1000 /* timeout_ms */, true /* wait_for_ready */); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // Check LB policy name for the channel. EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } @@ -752,7 +758,7 @@ TEST_F(SingleBalancerTest, const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); ResetStub(kFallbackTimeoutMs); // Resolution includes fallback address but no balancers. - SetNextResolution({AddressData{backend_servers_[0].port_, false, ""}}, + SetNextResolution({AddressData{backends_[0]->port_, false, ""}}, "{\n" " \"loadBalancingConfig\":[\n" " { \"does_not_exist\":{} },\n" @@ -780,17 +786,17 @@ TEST_F(SingleBalancerTest, UsePickFirstChildPolicy) { 0); const size_t kNumRpcs = num_backends_ * 2; CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // Check that all requests went to the first backend. This verifies // that we used pick_first instead of round_robin as the child policy. - EXPECT_EQ(backend_servers_[0].service_->request_count(), kNumRpcs); + EXPECT_EQ(backends_[0]->service_.request_count(), kNumRpcs); for (size_t i = 1; i < backends_.size(); ++i) { - EXPECT_EQ(backend_servers_[i].service_->request_count(), 0UL); + EXPECT_EQ(backends_[i]->service_.request_count(), 0UL); } // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // Check LB policy name for the channel. EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } @@ -813,9 +819,9 @@ TEST_F(SingleBalancerTest, SwapChildPolicy) { CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); // Check that all requests went to the first backend. This verifies // that we used pick_first instead of round_robin as the child policy. - EXPECT_EQ(backend_servers_[0].service_->request_count(), kNumRpcs); + EXPECT_EQ(backends_[0]->service_.request_count(), kNumRpcs); for (size_t i = 1; i < backends_.size(); ++i) { - EXPECT_EQ(backend_servers_[i].service_->request_count(), 0UL); + EXPECT_EQ(backends_[i]->service_.request_count(), 0UL); } // Send new resolution that removes child policy from service config. SetNextResolutionAllBalancers("{}"); @@ -824,14 +830,14 @@ TEST_F(SingleBalancerTest, SwapChildPolicy) { // Check that every backend saw the same number of requests. This verifies // that we used round_robin. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(backend_servers_[i].service_->request_count(), 2UL); + EXPECT_EQ(backends_[i]->service_.request_count(), 2UL); } // Done. - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // Check LB policy name for the channel. EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } @@ -848,7 +854,7 @@ TEST_F(SingleBalancerTest, UpdatesGoToMostRecentChildPolicy) { // Unreachable balancer. {unreachable_balancer_port, true, ""}, // Fallback address: first backend. - {backend_servers_[0].port_, false, ""}, + {backends_[0]->port_, false, ""}, }, "{\n" " \"loadBalancingConfig\":[\n" @@ -891,8 +897,8 @@ TEST_F(SingleBalancerTest, UpdatesGoToMostRecentChildPolicy) { // Unreachable balancer. {unreachable_balancer_port, true, ""}, // Fallback address: second and third backends. - {backend_servers_[1].port_, false, ""}, - {backend_servers_[2].port_, false, ""}, + {backends_[1]->port_, false, ""}, + {backends_[2]->port_, false, ""}, }, "{\n" " \"loadBalancingConfig\":[\n" @@ -912,8 +918,8 @@ TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { SetNextResolutionAllBalancers(); // Same backend listed twice. std::vector ports; - ports.push_back(backend_servers_[0].port_); - ports.push_back(backend_servers_[0].port_); + ports.push_back(backends_[0]->port_); + ports.push_back(backends_[0]->port_); const size_t kNumRpcsPerAddress = 10; ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends(ports, {}), 0); @@ -922,17 +928,16 @@ TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { // Send kNumRpcsPerAddress RPCs per server. CheckRpcSendOk(kNumRpcsPerAddress * ports.size()); // Backend should have gotten 20 requests. - EXPECT_EQ(kNumRpcsPerAddress * 2, - backend_servers_[0].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress * 2, backends_[0]->service_.request_count()); // And they should have come from a single client port, because of // subchannel sharing. - EXPECT_EQ(1UL, backends_[0]->clients().size()); - balancers_[0]->NotifyDoneWithServerlists(); + EXPECT_EQ(1UL, backends_[0]->service_.clients().size()); + balancers_[0]->service_.NotifyDoneWithServerlists(); } TEST_F(SingleBalancerTest, SecureNaming) { ResetStub(0, kApplicationTargetName_ + ";lb"); - SetNextResolution({AddressData{balancer_servers_[0].port_, true, "lb"}}); + SetNextResolution({AddressData{balancers_[0]->port_, true, "lb"}}); const size_t kNumRpcsPerAddress = 100; ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), @@ -946,14 +951,13 @@ TEST_F(SingleBalancerTest, SecureNaming) { // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // Check LB policy name for the channel. EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } @@ -965,8 +969,7 @@ TEST_F(SingleBalancerTest, SecureNamingDeathTest) { ASSERT_DEATH( { ResetStub(0, kApplicationTargetName_ + ";lb"); - SetNextResolution( - {AddressData{balancer_servers_[0].port_, true, "woops"}}); + SetNextResolution({AddressData{balancers_[0]->port_, true, "woops"}}); channel_->WaitForConnected(grpc_timeout_seconds_to_deadline(1)); }, ""); @@ -993,11 +996,11 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) { // populated serverlist but under the call's deadline (which is enforced by // the call's deadline). EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent two responses. - EXPECT_EQ(2U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(2U, balancers_[0]->service_.response_count()); } TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { @@ -1012,11 +1015,11 @@ TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { const Status status = SendRpc(); // The error shouldn't be DEADLINE_EXCEEDED. EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code()); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } TEST_F(SingleBalancerTest, Fallback) { @@ -1027,9 +1030,9 @@ TEST_F(SingleBalancerTest, Fallback) { ResetStub(kFallbackTimeoutMs); std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); for (size_t i = 0; i < kNumBackendInResolution; ++i) { - addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""}); + addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); } SetNextResolution(addresses); @@ -1053,10 +1056,10 @@ TEST_F(SingleBalancerTest, Fallback) { // Fallback is used: each backend returned by the resolver should have // gotten one request. for (size_t i = 0; i < kNumBackendInResolution; ++i) { - EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(1U, backends_[i]->service_.request_count()); } for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } // Wait until the serverlist reception has been processed and all backends @@ -1073,17 +1076,17 @@ TEST_F(SingleBalancerTest, Fallback) { // Serverlist is used: each backend returned by the balancer should // have gotten one request. for (size_t i = 0; i < kNumBackendInResolution; ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { - EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(1U, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } TEST_F(SingleBalancerTest, FallbackUpdate) { @@ -1095,9 +1098,9 @@ TEST_F(SingleBalancerTest, FallbackUpdate) { ResetStub(kFallbackTimeoutMs); std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); for (size_t i = 0; i < kNumBackendInResolution; ++i) { - addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""}); + addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); } SetNextResolution(addresses); @@ -1123,17 +1126,17 @@ TEST_F(SingleBalancerTest, FallbackUpdate) { // Fallback is used: each backend returned by the resolver should have // gotten one request. for (size_t i = 0; i < kNumBackendInResolution; ++i) { - EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(1U, backends_[i]->service_.request_count()); } for (size_t i = kNumBackendInResolution; i < backends_.size(); ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } addresses.clear(); - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); for (size_t i = kNumBackendInResolution; i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { - addresses.emplace_back(AddressData{backend_servers_[i].port_, false, ""}); + addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); } SetNextResolution(addresses); @@ -1152,15 +1155,15 @@ TEST_F(SingleBalancerTest, FallbackUpdate) { // The resolution update is used: each backend in the resolution update should // have gotten one request. for (size_t i = 0; i < kNumBackendInResolution; ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } for (size_t i = kNumBackendInResolution; i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { - EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(1U, backends_[i]->service_.request_count()); } for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate; i < backends_.size(); ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } // Wait until the serverlist reception has been processed and all backends @@ -1180,18 +1183,18 @@ TEST_F(SingleBalancerTest, FallbackUpdate) { // have gotten one request. for (size_t i = 0; i < kNumBackendInResolution + kNumBackendInResolutionUpdate; ++i) { - EXPECT_EQ(0U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(0U, backends_[i]->service_.request_count()); } for (size_t i = kNumBackendInResolution + kNumBackendInResolutionUpdate; i < backends_.size(); ++i) { - EXPECT_EQ(1U, backend_servers_[i].service_->request_count()); + EXPECT_EQ(1U, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerChannelFails) { @@ -1200,7 +1203,7 @@ TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerChannelFails) { // Return an unreachable balancer and one fallback backend. std::vector addresses; addresses.emplace_back(AddressData{grpc_pick_unused_port_or_die(), true, ""}); - addresses.emplace_back(AddressData{backend_servers_[0].port_, false, ""}); + addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); SetNextResolution(addresses); // Send RPC with deadline less than the fallback timeout and make sure it // succeeds. @@ -1218,27 +1221,18 @@ TEST_F(SingleBalancerTest, BackendsRestart) { channel_->GetState(true /* try_to_connect */); // Send kNumRpcsPerAddress RPCs per server. CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - for (size_t i = 0; i < backends_.size(); ++i) { - if (backends_[i]->Shutdown()) backend_servers_[i].Shutdown(); - } - CheckRpcSendFailure(); - for (size_t i = 0; i < num_backends_; ++i) { - backends_.emplace_back(new BackendServiceImpl()); - backend_servers_.emplace_back(ServerThread( - "backend", server_host_, backends_.back().get())); - } - // The following RPC will fail due to the backend ports having changed. It - // will nonetheless exercise the grpclb-roundrobin handling of the RR policy - // having gone into shutdown. - // TODO(dgq): implement the "backend restart" component as well. We need extra - // machinery to either update the LB responses "on the fly" or instruct - // backends which ports to restart on. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + // Stop backends. RPCs should fail. + ShutdownAllBackends(); CheckRpcSendFailure(); + // Restart backends. RPCs should start succeeding again. + StartAllBackends(); + CheckRpcSendOk(1 /* times */, 1000 /* timeout_ms */, + true /* wait_for_ready */); } class UpdatesTest : public GrpclbEnd2endTest { @@ -1264,47 +1258,47 @@ TEST_F(UpdatesTest, UpdateBalancers) { gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); - balancers_[0]->NotifyDoneWithServerlists(); - balancers_[1]->NotifyDoneWithServerlists(); - balancers_[2]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); + balancers_[1]->service_.NotifyDoneWithServerlists(); + balancers_[2]->service_.NotifyDoneWithServerlists(); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); // Wait until update has been processed, as signaled by the second backend // receiving a request. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); WaitForBackend(1); - backend_servers_[1].service_->ResetCounters(); + backends_[1]->service_.ResetCounters(); gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(10U, backends_[1]->service_.request_count()); - balancers_[0]->NotifyDoneWithServerlists(); - balancers_[1]->NotifyDoneWithServerlists(); - balancers_[2]->NotifyDoneWithServerlists(); - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(1U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + balancers_[0]->service_.NotifyDoneWithServerlists(); + balancers_[1]->service_.NotifyDoneWithServerlists(); + balancers_[2]->service_.NotifyDoneWithServerlists(); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(1U, balancers_[1]->service_.request_count()); + EXPECT_EQ(1U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); } // Send an update with the same set of LBs as the one in SetUp() in order to @@ -1329,27 +1323,27 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); - addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""}); - addresses.emplace_back(AddressData{balancer_servers_[2].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[2]->port_, true, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); gpr_timespec deadline = gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); // Send 10 seconds worth of RPCs @@ -1358,17 +1352,17 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); // grpclb continued using the original LB call to the first balancer, which // doesn't assign the second backend. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); - balancers_[0]->NotifyDoneWithServerlists(); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + balancers_[0]->service_.NotifyDoneWithServerlists(); addresses.clear(); - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); - addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 2 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 2 DONE =========="); - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); // Send 10 seconds worth of RPCs @@ -1377,13 +1371,13 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); // grpclb continued using the original LB call to the first balancer, which // doesn't assign the second backend. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); - balancers_[0]->NotifyDoneWithServerlists(); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); + balancers_[0]->service_.NotifyDoneWithServerlists(); } TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); SetNextResolution(addresses); const std::vector first_backend{GetBackendPorts()[0]}; const std::vector second_backend{GetBackendPorts()[1]}; @@ -1398,12 +1392,11 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); // Kill balancer 0 gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); - balancers_[0]->NotifyDoneWithServerlists(); - if (balancers_[0]->Shutdown()) balancer_servers_[0].Shutdown(); + balancers_[0]->Shutdown(); gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); // This is serviced by the existing RR policy @@ -1411,23 +1404,23 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // All 10 requests should again have gone to the first backend. - EXPECT_EQ(20U, backend_servers_[0].service_->request_count()); - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(20U, backends_[0]->service_.request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); - balancers_[0]->NotifyDoneWithServerlists(); - balancers_[1]->NotifyDoneWithServerlists(); - balancers_[2]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); + balancers_[1]->service_.NotifyDoneWithServerlists(); + balancers_[2]->service_.NotifyDoneWithServerlists(); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); addresses.clear(); - addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); @@ -1435,32 +1428,32 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { // Wait until update has been processed, as signaled by the second backend // receiving a request. In the meantime, the client continues to be serviced // (by the first backend) without interruption. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); WaitForBackend(1); // This is serviced by the updated RR policy - backend_servers_[1].service_->ResetCounters(); + backends_[1]->service_.ResetCounters(); gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(10U, backends_[1]->service_.request_count()); - balancers_[0]->NotifyDoneWithServerlists(); - balancers_[1]->NotifyDoneWithServerlists(); - balancers_[2]->NotifyDoneWithServerlists(); - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + balancers_[0]->service_.NotifyDoneWithServerlists(); + balancers_[1]->service_.NotifyDoneWithServerlists(); + balancers_[2]->service_.NotifyDoneWithServerlists(); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // The second balancer, published as part of the first update, may end up // getting two requests (that is, 1 <= #req <= 2) if the LB call retry timer // firing races with the arrival of the update containing the second // balancer. - EXPECT_GE(balancer_servers_[1].service_->request_count(), 1U); - EXPECT_GE(balancer_servers_[1].service_->response_count(), 1U); - EXPECT_LE(balancer_servers_[1].service_->request_count(), 2U); - EXPECT_LE(balancer_servers_[1].service_->response_count(), 2U); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_GE(balancers_[1]->service_.request_count(), 1U); + EXPECT_GE(balancers_[1]->service_.response_count(), 1U); + EXPECT_LE(balancers_[1]->service_.request_count(), 2U); + EXPECT_LE(balancers_[1]->service_.response_count(), 2U); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); } TEST_F(UpdatesTest, ReresolveDeadBackend) { @@ -1468,14 +1461,14 @@ TEST_F(UpdatesTest, ReresolveDeadBackend) { // The first resolution contains the addresses of a balancer that never // responds, and a fallback backend. std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); - addresses.emplace_back(AddressData{backend_servers_[0].port_, false, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); SetNextResolution(addresses); // The re-resolution result will contain the addresses of the same balancer // and a new fallback backend. addresses.clear(); - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); - addresses.emplace_back(AddressData{backend_servers_[1].port_, false, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{backends_[1]->port_, false, ""}); SetNextReresolutionResponse(addresses); // Start servers and send 10 RPCs per server. @@ -1483,11 +1476,11 @@ TEST_F(UpdatesTest, ReresolveDeadBackend) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the fallback backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); // Kill backend 0. gpr_log(GPR_INFO, "********** ABOUT TO KILL BACKEND 0 *************"); - if (backends_[0]->Shutdown()) backend_servers_[0].Shutdown(); + backends_[0]->Shutdown(); gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************"); // Wait until re-resolution has finished, as signaled by the second backend @@ -1498,17 +1491,17 @@ TEST_F(UpdatesTest, ReresolveDeadBackend) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(10U, backends_[1]->service_.request_count()); - balancers_[0]->NotifyDoneWithServerlists(); - balancers_[1]->NotifyDoneWithServerlists(); - balancers_[2]->NotifyDoneWithServerlists(); - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + balancers_[0]->service_.NotifyDoneWithServerlists(); + balancers_[1]->service_.NotifyDoneWithServerlists(); + balancers_[2]->service_.NotifyDoneWithServerlists(); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(0U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); } // TODO(juanlishen): Should be removed when the first response is always the @@ -1523,10 +1516,10 @@ class UpdatesWithClientLoadReportingTest : public GrpclbEnd2endTest { TEST_F(UpdatesWithClientLoadReportingTest, ReresolveDeadBalancer) { std::vector addresses; - addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); SetNextResolution(addresses); addresses.clear(); - addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); SetNextReresolutionResponse(addresses); const std::vector first_backend{GetBackendPorts()[0]}; const std::vector second_backend{GetBackendPorts()[1]}; @@ -1541,27 +1534,27 @@ TEST_F(UpdatesWithClientLoadReportingTest, ReresolveDeadBalancer) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); // Kill backend 0. gpr_log(GPR_INFO, "********** ABOUT TO KILL BACKEND 0 *************"); - if (backends_[0]->Shutdown()) backend_servers_[0].Shutdown(); + backends_[0]->Shutdown(); gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************"); CheckRpcSendFailure(); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); // Kill balancer 0. gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); - if (balancers_[0]->Shutdown()) balancer_servers_[0].Shutdown(); + balancers_[0]->Shutdown(); gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); // Wait until re-resolution has finished, as signaled by the second backend @@ -1573,22 +1566,22 @@ TEST_F(UpdatesWithClientLoadReportingTest, ReresolveDeadBalancer) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(10U, backends_[1]->service_.request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // After balancer 0 is killed, we restart an LB call immediately (because we // disconnect to a previously connected balancer). Although we will cancel // this call when the re-resolution update is done and another LB call restart // is needed, this old call may still succeed reaching the LB server if // re-resolution is slow. So balancer 1 may have received 2 requests and sent // 2 responses. - EXPECT_GE(balancer_servers_[1].service_->request_count(), 1U); - EXPECT_GE(balancer_servers_[1].service_->response_count(), 1U); - EXPECT_LE(balancer_servers_[1].service_->request_count(), 2U); - EXPECT_LE(balancer_servers_[1].service_->response_count(), 2U); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_GE(balancers_[1]->service_.request_count(), 1U); + EXPECT_GE(balancers_[1]->service_.response_count(), 1U); + EXPECT_LE(balancers_[1]->service_.request_count(), 2U); + EXPECT_LE(balancers_[1]->service_.response_count(), 2U); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); } TEST_F(SingleBalancerTest, Drop) { @@ -1623,16 +1616,14 @@ TEST_F(SingleBalancerTest, Drop) { } } EXPECT_EQ(kNumRpcsPerAddress * num_of_drop_addresses, num_drops); - // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } TEST_F(SingleBalancerTest, DropAllFirst) { @@ -1682,9 +1673,6 @@ class SingleBalancerWithClientLoadReportingTest : public GrpclbEnd2endTest { SingleBalancerWithClientLoadReportingTest() : GrpclbEnd2endTest(4, 1, 3) {} }; -// TODO(roth): Add test that when switching balancers, we don't include -// any calls that were sent prior to connecting to the new balancer. - TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) { SetNextResolutionAllBalancers(); const size_t kNumRpcsPerAddress = 100; @@ -1700,14 +1688,13 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) { CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); const ClientStats client_stats = WaitForLoadReports(); EXPECT_EQ(kNumRpcsPerAddress * num_backends_ + num_ok, @@ -1720,6 +1707,69 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) { EXPECT_THAT(client_stats.drop_token_counts, ::testing::ElementsAre()); } +TEST_F(SingleBalancerWithClientLoadReportingTest, BalancerRestart) { + SetNextResolutionAllBalancers(); + const size_t kNumBackendsFirstPass = 2; + const size_t kNumBackendsSecondPass = + backends_.size() - kNumBackendsFirstPass; + // Balancer returns backends starting at index 1. + ScheduleResponseForBalancer( + 0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(0, kNumBackendsFirstPass), {}), + 0); + // Wait until all backends returned by the balancer are ready. + int num_ok = 0; + int num_failure = 0; + int num_drops = 0; + std::tie(num_ok, num_failure, num_drops) = + WaitForAllBackends(/* num_requests_multiple_of */ 1, /* start_index */ 0, + /* stop_index */ kNumBackendsFirstPass); + balancers_[0]->service_.NotifyDoneWithServerlists(); + ClientStats client_stats = WaitForLoadReports(); + EXPECT_EQ(static_cast(num_ok), client_stats.num_calls_started); + EXPECT_EQ(static_cast(num_ok), client_stats.num_calls_finished); + EXPECT_EQ(0U, client_stats.num_calls_finished_with_client_failed_to_send); + EXPECT_EQ(static_cast(num_ok), + client_stats.num_calls_finished_known_received); + EXPECT_THAT(client_stats.drop_token_counts, ::testing::ElementsAre()); + // Shut down the balancer. + balancers_[0]->Shutdown(); + // Send 10 more requests per backend. This will continue using the + // last serverlist we received from the balancer before it was shut down. + ResetBackendCounters(); + CheckRpcSendOk(kNumBackendsFirstPass); + // Each backend should have gotten 1 request. + for (size_t i = 0; i < kNumBackendsFirstPass; ++i) { + EXPECT_EQ(1UL, backends_[i]->service_.request_count()); + } + // Now restart the balancer, this time pointing to all backends. + balancers_[0]->Start(server_host_); + ScheduleResponseForBalancer(0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumBackendsFirstPass), {}), + 0); + // Wait for queries to start going to one of the new backends. + // This tells us that we're now using the new serverlist. + do { + CheckRpcSendOk(); + } while (backends_[2]->service_.request_count() == 0 && + backends_[3]->service_.request_count() == 0); + // Send one RPC per backend. + CheckRpcSendOk(kNumBackendsSecondPass); + balancers_[0]->service_.NotifyDoneWithServerlists(); + EXPECT_EQ(2U, balancers_[0]->service_.request_count()); + EXPECT_EQ(2U, balancers_[0]->service_.response_count()); + // Check client stats. + client_stats = WaitForLoadReports(); + EXPECT_EQ(kNumBackendsSecondPass + 1, client_stats.num_calls_started); + EXPECT_EQ(kNumBackendsSecondPass + 1, client_stats.num_calls_finished); + EXPECT_EQ(0U, client_stats.num_calls_finished_with_client_failed_to_send); + EXPECT_EQ(kNumBackendsSecondPass + 1, + client_stats.num_calls_finished_known_received); + EXPECT_THAT(client_stats.drop_token_counts, ::testing::ElementsAre()); +} + TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) { SetNextResolutionAllBalancers(); const size_t kNumRpcsPerAddress = 3; @@ -1759,14 +1809,13 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) { EXPECT_EQ(kNumRpcsPerAddress * num_of_drop_addresses, num_drops); // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); const ClientStats client_stats = WaitForLoadReports(); EXPECT_EQ( diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 667481bafd2..8657ba78d90 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -56,13 +56,8 @@ // TODO(dgq): Other scenarios in need of testing: // - Send a serverlist with faulty ip:port addresses (port > 2^16, etc). // - Test reception of invalid serverlist -// - Test pinging // - Test against a non-LB server. // - Random LB server closing the stream unexpectedly. -// - Test using DNS-resolvable names (localhost?) -// - Test handling of creation of faulty RR instance by having the LB return a -// serverlist with non-existent backends after having initially returned a -// valid one. // // Findings from end to end testing to be covered here: // - Handling of LB servers restart, including reconnection after backing-off @@ -74,8 +69,6 @@ // part of the xds shutdown process. // 2) the retry timer is active. Again, the weak reference it holds should // prevent a premature call to \a glb_destroy. -// - Restart of backend servers with no changes to serverlist. This exercises -// the RR handover mechanism. using std::chrono::system_clock; @@ -149,14 +142,7 @@ class BackendServiceImpl : public BackendService { return status; } - // Returns true on its first invocation, false otherwise. - bool Shutdown() { - std::unique_lock lock(mu_); - const bool prev = !shutdown_; - shutdown_ = true; - gpr_log(GPR_INFO, "Backend: shut down"); - return prev; - } + void Shutdown() {} std::set clients() { std::unique_lock lock(clients_mu_); @@ -170,7 +156,6 @@ class BackendServiceImpl : public BackendService { } std::mutex mu_; - bool shutdown_ = false; std::mutex clients_mu_; std::set clients_; }; @@ -200,6 +185,14 @@ struct ClientStats { } return *this; } + + void Reset() { + num_calls_started = 0; + num_calls_finished = 0; + num_calls_finished_with_client_failed_to_send = 0; + num_calls_finished_known_received = 0; + drop_token_counts.clear(); + } }; class BalancerServiceImpl : public BalancerService { @@ -209,17 +202,11 @@ class BalancerServiceImpl : public BalancerService { explicit BalancerServiceImpl(int client_load_reporting_interval_seconds) : client_load_reporting_interval_seconds_( - client_load_reporting_interval_seconds), - shutdown_(false) {} + client_load_reporting_interval_seconds) {} Status BalanceLoad(ServerContext* context, Stream* stream) override { // TODO(juanlishen): Clean up the scoping. gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this); - { - std::unique_lock lock(mu_); - if (shutdown_) goto done; - } - { // Balancer shouldn't receive the call credentials metadata. EXPECT_EQ(context->client_metadata().find(g_kCallCredsMdKey), @@ -247,17 +234,12 @@ class BalancerServiceImpl : public BalancerService { responses_and_delays = responses_and_delays_; } for (const auto& response_and_delay : responses_and_delays) { - { - std::unique_lock lock(mu_); - if (shutdown_) goto done; - } SendResponse(stream, response_and_delay.first, response_and_delay.second); } { std::unique_lock lock(mu_); - if (shutdown_) goto done; - serverlist_cond_.wait(lock, [this] { return serverlist_ready_; }); + serverlist_cond_.wait(lock, [this] { return serverlist_done_; }); } if (client_load_reporting_interval_seconds_ > 0) { @@ -299,17 +281,12 @@ class BalancerServiceImpl : public BalancerService { responses_and_delays_.push_back(std::make_pair(response, send_after_ms)); } - // Returns true on its first invocation, false otherwise. - bool Shutdown() { - bool prev; - { - std::unique_lock lock(mu_); - prev = !shutdown_; - shutdown_ = true; - } - NotifyDoneWithServerlists(); + void Shutdown() { + std::unique_lock lock(mu_); + NotifyDoneWithServerlistsLocked(); + responses_and_delays_.clear(); + client_stats_.Reset(); gpr_log(GPR_INFO, "LB[%p]: shut down", this); - return prev; } static LoadBalanceResponse BuildResponseForBackends( @@ -345,8 +322,14 @@ class BalancerServiceImpl : public BalancerService { void NotifyDoneWithServerlists() { std::lock_guard lock(mu_); - serverlist_ready_ = true; - serverlist_cond_.notify_all(); + NotifyDoneWithServerlistsLocked(); + } + + void NotifyDoneWithServerlistsLocked() { + if (!serverlist_done_) { + serverlist_done_ = true; + serverlist_cond_.notify_all(); + } } private: @@ -368,14 +351,13 @@ class BalancerServiceImpl : public BalancerService { std::condition_variable load_report_cond_; bool load_report_ready_ = false; std::condition_variable serverlist_cond_; - bool serverlist_ready_ = false; + bool serverlist_done_ = false; ClientStats client_stats_; - bool shutdown_; }; class XdsEnd2endTest : public ::testing::Test { protected: - XdsEnd2endTest(int num_backends, int num_balancers, + XdsEnd2endTest(size_t num_backends, size_t num_balancers, int client_load_reporting_interval_seconds) : server_host_("localhost"), num_backends_(num_backends), @@ -394,29 +376,35 @@ class XdsEnd2endTest : public ::testing::Test { grpc_core::MakeRefCounted(); // Start the backends. for (size_t i = 0; i < num_backends_; ++i) { - backends_.emplace_back(new BackendServiceImpl()); - backend_servers_.emplace_back(ServerThread( - "backend", server_host_, backends_.back().get())); + backends_.emplace_back(new ServerThread("backend")); + backends_.back()->Start(server_host_); } // Start the load balancers. for (size_t i = 0; i < num_balancers_; ++i) { - balancers_.emplace_back( - new BalancerServiceImpl(client_load_reporting_interval_seconds_)); - balancer_servers_.emplace_back(ServerThread( - "balancer", server_host_, balancers_.back().get())); + balancers_.emplace_back(new ServerThread( + "balancer", client_load_reporting_interval_seconds_)); + balancers_.back()->Start(server_host_); } ResetStub(); } void TearDown() override { - for (size_t i = 0; i < backends_.size(); ++i) { - if (backends_[i]->Shutdown()) backend_servers_[i].Shutdown(); - } - for (size_t i = 0; i < balancers_.size(); ++i) { - if (balancers_[i]->Shutdown()) balancer_servers_[i].Shutdown(); - } + ShutdownAllBackends(); + for (auto& balancer : balancers_) balancer->Shutdown(); } + void StartAllBackends() { + for (auto& backend : backends_) backend->Start(server_host_); + } + + void StartBackend(size_t index) { backends_[index]->Start(server_host_); } + + void ShutdownAllBackends() { + for (auto& backend : backends_) backend->Shutdown(); + } + + void ShutdownBackend(size_t index) { backends_[index]->Shutdown(); } + void ResetStub(int fallback_timeout = 0, const grpc::string& expected_targets = "") { ChannelArguments args; @@ -445,20 +433,21 @@ class XdsEnd2endTest : public ::testing::Test { } void ResetBackendCounters() { - for (const auto& backend : backends_) backend->ResetCounters(); + for (auto& backend : backends_) backend->service_.ResetCounters(); } ClientStats WaitForLoadReports() { ClientStats client_stats; - for (const auto& balancer : balancers_) { - client_stats += balancer->WaitForLoadReport(); + for (auto& balancer : balancers_) { + client_stats += balancer->service_.WaitForLoadReport(); } return client_stats; } - bool SeenAllBackends() { - for (const auto& backend : backends_) { - if (backend->request_count() == 0) return false; + bool SeenAllBackends(size_t start_index = 0, size_t stop_index = 0) { + if (stop_index == 0) stop_index = backends_.size(); + for (size_t i = start_index; i < stop_index; ++i) { + if (backends_[i]->service_.request_count() == 0) return false; } return true; } @@ -478,13 +467,14 @@ class XdsEnd2endTest : public ::testing::Test { ++*num_total; } - std::tuple WaitForAllBackends( - int num_requests_multiple_of = 1) { + std::tuple WaitForAllBackends(int num_requests_multiple_of = 1, + size_t start_index = 0, + size_t stop_index = 0) { int num_ok = 0; int num_failure = 0; int num_drops = 0; int num_total = 0; - while (!SeenAllBackends()) { + while (!SeenAllBackends(start_index, stop_index)) { SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops); } while (num_total % num_requests_multiple_of != 0) { @@ -502,7 +492,7 @@ class XdsEnd2endTest : public ::testing::Test { void WaitForBackend(size_t backend_idx) { do { (void)SendRpc(); - } while (backends_[backend_idx]->request_count() == 0); + } while (backends_[backend_idx]->service_.request_count() == 0); ResetBackendCounters(); } @@ -553,8 +543,8 @@ class XdsEnd2endTest : public ::testing::Test { grpc_core::FakeResolverResponseGenerator* lb_channel_response_generator = nullptr) { std::vector ports; - for (size_t i = 0; i < balancer_servers_.size(); ++i) { - ports.emplace_back(balancer_servers_[i].port_); + for (size_t i = 0; i < balancers_.size(); ++i) { + ports.emplace_back(balancers_[i]->port_); } SetNextResolutionForLbChannel(ports, service_config_json, lb_channel_response_generator); @@ -591,10 +581,12 @@ class XdsEnd2endTest : public ::testing::Test { response_generator_->SetReresolutionResponse(&fake_result); } - const std::vector GetBackendPorts(const size_t start_index = 0) const { + const std::vector GetBackendPorts(size_t start_index = 0, + size_t stop_index = 0) const { + if (stop_index == 0) stop_index = backends_.size(); std::vector backend_ports; - for (size_t i = start_index; i < backend_servers_.size(); ++i) { - backend_ports.push_back(backend_servers_[i].port_); + for (size_t i = start_index; i < stop_index; ++i) { + backend_ports.push_back(backends_[i]->port_); } return backend_ports; } @@ -602,7 +594,7 @@ class XdsEnd2endTest : public ::testing::Test { void ScheduleResponseForBalancer(size_t i, const LoadBalanceResponse& response, int delay_ms) { - balancers_.at(i)->add_response(response, delay_ms); + balancers_[i]->service_.add_response(response, delay_ms); } Status SendRpc(EchoResponse* response = nullptr, int timeout_ms = 1000, @@ -637,23 +629,28 @@ class XdsEnd2endTest : public ::testing::Test { template struct ServerThread { - explicit ServerThread(const grpc::string& type, - const grpc::string& server_host, T* service) - : type_(type), service_(service) { + template + explicit ServerThread(const grpc::string& type, Args&&... args) + : port_(grpc_pick_unused_port_or_die()), + type_(type), + service_(std::forward(args)...) {} + + void Start(const grpc::string& server_host) { + gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); + GPR_ASSERT(!running_); + running_ = true; std::mutex mu; // We need to acquire the lock here in order to prevent the notify_one - // by ServerThread::Start from firing before the wait below is hit. + // by ServerThread::Serve from firing before the wait below is hit. std::unique_lock lock(mu); - port_ = grpc_pick_unused_port_or_die(); - gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); std::condition_variable cond; thread_.reset(new std::thread( - std::bind(&ServerThread::Start, this, server_host, &mu, &cond))); + std::bind(&ServerThread::Serve, this, server_host, &mu, &cond))); cond.wait(lock); gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); } - void Start(const grpc::string& server_host, std::mutex* mu, + void Serve(const grpc::string& server_host, std::mutex* mu, std::condition_variable* cond) { // We need to acquire the lock here in order to prevent the notify_one // below from firing before its corresponding wait is executed. @@ -664,23 +661,27 @@ class XdsEnd2endTest : public ::testing::Test { std::shared_ptr creds(new SecureServerCredentials( grpc_fake_transport_security_server_credentials_create())); builder.AddListeningPort(server_address.str(), creds); - builder.RegisterService(service_); + builder.RegisterService(&service_); server_ = builder.BuildAndStart(); cond->notify_one(); } void Shutdown() { + if (!running_) return; gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str()); + service_.Shutdown(); server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); thread_->join(); gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str()); + running_ = false; } - int port_; + const int port_; grpc::string type_; + T service_; std::unique_ptr server_; - T* service_; std::unique_ptr thread_; + bool running_ = false; }; const grpc::string server_host_; @@ -689,10 +690,8 @@ class XdsEnd2endTest : public ::testing::Test { const int client_load_reporting_interval_seconds_; std::shared_ptr channel_; std::unique_ptr stub_; - std::vector> backends_; - std::vector> balancers_; - std::vector> backend_servers_; - std::vector> balancer_servers_; + std::vector>> backends_; + std::vector>> balancers_; grpc_core::RefCountedPtr response_generator_; grpc_core::RefCountedPtr @@ -728,14 +727,13 @@ TEST_F(SingleBalancerTest, Vanilla) { CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // Check LB policy name for the channel. EXPECT_EQ("xds_experimental", channel_->GetLoadBalancingPolicyName()); @@ -746,8 +744,8 @@ TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { SetNextResolutionForLbChannelAllBalancers(); // Same backend listed twice. std::vector ports; - ports.push_back(backend_servers_[0].port_); - ports.push_back(backend_servers_[0].port_); + ports.push_back(backends_[0]->port_); + ports.push_back(backends_[0]->port_); const size_t kNumRpcsPerAddress = 10; ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends(ports, {}), 0); @@ -756,19 +754,18 @@ TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { // Send kNumRpcsPerAddress RPCs per server. CheckRpcSendOk(kNumRpcsPerAddress * ports.size()); // Backend should have gotten 20 requests. - EXPECT_EQ(kNumRpcsPerAddress * 2, - backend_servers_[0].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress * 2, backends_[0]->service_.request_count()); // And they should have come from a single client port, because of // subchannel sharing. - EXPECT_EQ(1UL, backends_[0]->clients().size()); - balancers_[0]->NotifyDoneWithServerlists(); + EXPECT_EQ(1UL, backends_[0]->service_.clients().size()); + balancers_[0]->service_.NotifyDoneWithServerlists(); } TEST_F(SingleBalancerTest, SecureNaming) { // TODO(juanlishen): Use separate fake creds for the balancer channel. ResetStub(0, kApplicationTargetName_ + ";lb"); SetNextResolution({}, kDefaultServiceConfig_.c_str()); - SetNextResolutionForLbChannel({balancer_servers_[0].port_}); + SetNextResolutionForLbChannel({balancers_[0]->port_}); const size_t kNumRpcsPerAddress = 100; ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), @@ -782,13 +779,12 @@ TEST_F(SingleBalancerTest, SecureNaming) { // Each backend should have gotten 100 requests. for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backend_servers_[i].service_->request_count()); + EXPECT_EQ(kNumRpcsPerAddress, backends_[i]->service_.request_count()); } // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } TEST_F(SingleBalancerTest, SecureNamingDeathTest) { @@ -806,7 +802,7 @@ TEST_F(SingleBalancerTest, SecureNamingDeathTest) { "\"fake:///wrong_lb\" } }\n" " ]\n" "}"); - SetNextResolutionForLbChannel({balancer_servers_[0].port_}); + SetNextResolutionForLbChannel({balancers_[0]->port_}); channel_->WaitForConnected(grpc_timeout_seconds_to_deadline(1)); }, ""); @@ -834,11 +830,11 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) { // populated serverlist but under the call's deadline (which is enforced by // the call's deadline). EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent two responses. - EXPECT_EQ(2U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(2U, balancers_[0]->service_.response_count()); } TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { @@ -854,11 +850,11 @@ TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { const Status status = SendRpc(); // The error shouldn't be DEADLINE_EXCEEDED. EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code()); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } // The fallback tests are deferred because the fallback mode hasn't been @@ -882,27 +878,18 @@ TEST_F(SingleBalancerTest, BackendsRestart) { channel_->GetState(true /* try_to_connect */); // Send kNumRpcsPerAddress RPCs per server. CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); - balancers_[0]->NotifyDoneWithServerlists(); + balancers_[0]->service_.NotifyDoneWithServerlists(); // The balancer got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - for (size_t i = 0; i < backends_.size(); ++i) { - if (backends_[i]->Shutdown()) backend_servers_[i].Shutdown(); - } - CheckRpcSendFailure(); - for (size_t i = 0; i < num_backends_; ++i) { - backends_.emplace_back(new BackendServiceImpl()); - backend_servers_.emplace_back(ServerThread( - "backend", server_host_, backends_.back().get())); - } - // The following RPC will fail due to the backend ports having changed. It - // will nonetheless exercise the xds-roundrobin handling of the RR policy - // having gone into shutdown. - // TODO(dgq): implement the "backend restart" component as well. We need extra - // machinery to either update the LB responses "on the fly" or instruct - // backends which ports to restart on. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + // Stop backends. RPCs should fail. + ShutdownAllBackends(); CheckRpcSendFailure(); + // Restart all backends. RPCs should start succeeding again. + StartAllBackends(); + CheckRpcSendOk(1 /* times */, 1000 /* timeout_ms */, + true /* wait_for_ready */); } class UpdatesTest : public XdsEnd2endTest { @@ -929,22 +916,22 @@ TEST_F(UpdatesTest, UpdateBalancersButKeepUsingOriginalBalancer) { gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); - SetNextResolutionForLbChannel({balancer_servers_[1].port_}); + SetNextResolutionForLbChannel({balancers_[1]->port_}); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); gpr_timespec deadline = gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); // Send 10 seconds worth of RPCs @@ -953,14 +940,14 @@ TEST_F(UpdatesTest, UpdateBalancersButKeepUsingOriginalBalancer) { } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); // The current LB call is still working, so xds continued using it to the // first balancer, which doesn't assign the second backend. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); } TEST_F(UpdatesTest, UpdateBalancerName) { @@ -982,19 +969,19 @@ TEST_F(UpdatesTest, UpdateBalancerName) { gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); std::vector ports; - ports.emplace_back(balancer_servers_[1].port_); + ports.emplace_back(balancers_[1]->port_); auto new_lb_channel_response_generator = grpc_core::MakeRefCounted(); SetNextResolutionForLbChannel(ports, nullptr, @@ -1013,22 +1000,22 @@ TEST_F(UpdatesTest, UpdateBalancerName) { // Wait until update has been processed, as signaled by the second backend // receiving a request. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); WaitForBackend(1); - backend_servers_[1].service_->ResetCounters(); + backends_[1]->service_.ResetCounters(); gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(10U, backends_[1]->service_.request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(1U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(1U, balancers_[1]->service_.request_count()); + EXPECT_EQ(1U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); } // Send an update with the same set of LBs as the one in SetUp() in order to @@ -1054,26 +1041,26 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); std::vector ports; - ports.emplace_back(balancer_servers_[0].port_); - ports.emplace_back(balancer_servers_[1].port_); - ports.emplace_back(balancer_servers_[2].port_); + ports.emplace_back(balancers_[0]->port_); + ports.emplace_back(balancers_[1]->port_); + ports.emplace_back(balancers_[2]->port_); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); SetNextResolutionForLbChannel(ports); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); gpr_timespec deadline = gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); // Send 10 seconds worth of RPCs @@ -1082,16 +1069,16 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); // xds continued using the original LB call to the first balancer, which // doesn't assign the second backend. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); ports.clear(); - ports.emplace_back(balancer_servers_[0].port_); - ports.emplace_back(balancer_servers_[1].port_); + ports.emplace_back(balancers_[0]->port_); + ports.emplace_back(balancers_[1]->port_); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 2 =========="); SetNextResolutionForLbChannel(ports); gpr_log(GPR_INFO, "========= UPDATE 2 DONE =========="); - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); // Send 10 seconds worth of RPCs @@ -1100,12 +1087,12 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); // xds continued using the original LB call to the first balancer, which // doesn't assign the second backend. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); } TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { SetNextResolution({}, kDefaultServiceConfig_.c_str()); - SetNextResolutionForLbChannel({balancer_servers_[0].port_}); + SetNextResolutionForLbChannel({balancers_[0]->port_}); const std::vector first_backend{GetBackendPorts()[0]}; const std::vector second_backend{GetBackendPorts()[1]}; @@ -1119,11 +1106,11 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backend_servers_[0].service_->request_count()); + EXPECT_EQ(10U, backends_[0]->service_.request_count()); // Kill balancer 0 gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); - if (balancers_[0]->Shutdown()) balancer_servers_[0].Shutdown(); + balancers_[0]->Shutdown(); gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); // This is serviced by the existing child policy. @@ -1131,48 +1118,48 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // All 10 requests should again have gone to the first backend. - EXPECT_EQ(20U, backend_servers_[0].service_->request_count()); - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(20U, backends_[0]->service_.request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); // Balancer 0 got a single request. - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); // and sent a single response. - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[1].service_->response_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); + EXPECT_EQ(0U, balancers_[1]->service_.request_count()); + EXPECT_EQ(0U, balancers_[1]->service_.response_count()); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); - SetNextResolutionForLbChannel({balancer_servers_[1].port_}); + SetNextResolutionForLbChannel({balancers_[1]->port_}); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); // Wait until update has been processed, as signaled by the second backend // receiving a request. In the meantime, the client continues to be serviced // (by the first backend) without interruption. - EXPECT_EQ(0U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(0U, backends_[1]->service_.request_count()); WaitForBackend(1); // This is serviced by the updated RR policy - backend_servers_[1].service_->ResetCounters(); + backends_[1]->service_.ResetCounters(); gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); CheckRpcSendOk(10); gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backend_servers_[1].service_->request_count()); + EXPECT_EQ(10U, backends_[1]->service_.request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->request_count()); - EXPECT_EQ(1U, balancer_servers_[0].service_->response_count()); + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // The second balancer, published as part of the first update, may end up // getting two requests (that is, 1 <= #req <= 2) if the LB call retry timer // firing races with the arrival of the update containing the second // balancer. - EXPECT_GE(balancer_servers_[1].service_->request_count(), 1U); - EXPECT_GE(balancer_servers_[1].service_->response_count(), 1U); - EXPECT_LE(balancer_servers_[1].service_->request_count(), 2U); - EXPECT_LE(balancer_servers_[1].service_->response_count(), 2U); - EXPECT_EQ(0U, balancer_servers_[2].service_->request_count()); - EXPECT_EQ(0U, balancer_servers_[2].service_->response_count()); + EXPECT_GE(balancers_[1]->service_.request_count(), 1U); + EXPECT_GE(balancers_[1]->service_.response_count(), 1U); + EXPECT_LE(balancers_[1]->service_.request_count(), 2U); + EXPECT_LE(balancers_[1]->service_.response_count(), 2U); + EXPECT_EQ(0U, balancers_[2]->service_.request_count()); + EXPECT_EQ(0U, balancers_[2]->service_.response_count()); } // The re-resolution tests are deferred because they rely on the fallback mode, @@ -1201,6 +1188,9 @@ class SingleBalancerWithClientLoadReportingTest : public XdsEnd2endTest { // TODO(vpowar): Add TEST_F(SingleBalancerWithClientLoadReportingTest, Vanilla) +// TODO(roth): Add TEST_F(SingleBalancerWithClientLoadReportingTest, +// BalancerRestart) + // TODO(roth): Add TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) } // namespace From f569cc1b36940a94c7f21cd547f2af4e880ee62c Mon Sep 17 00:00:00 2001 From: Vishal Powar Date: Fri, 15 Mar 2019 10:14:14 -0700 Subject: [PATCH 710/814] Add BUILD rul and generated upb code for protos required to do DiscoveryRequest to xDS server Also, - cleanup check scripts to look for file extension to exempt upb generated code. --- BUILD | 72 +- .../envoy/api/v2/core/address.upb.c | 110 + .../envoy/api/v2/core/address.upb.h | 325 +++ .../envoy/api/v2/core/base.upb.c | 179 ++ .../envoy/api/v2/core/base.upb.h | 507 ++++ .../envoy/api/v2/core/health_check.upb.c | 144 ++ .../envoy/api/v2/core/health_check.upb.h | 559 +++++ .../envoy/api/v2/discovery.upb.c | 123 + .../envoy/api/v2/discovery.upb.h | 359 +++ .../upb-generated/envoy/type/percent.upb.c | 39 + .../upb-generated/envoy/type/percent.upb.h | 88 + .../ext/upb-generated/envoy/type/range.upb.c | 39 + .../ext/upb-generated/envoy/type/range.upb.h | 86 + .../ext/upb-generated/gogoproto/gogo.upb.c | 17 + .../ext/upb-generated/gogoproto/gogo.upb.h | 32 + .../google/api/annotations.upb.c | 18 + .../google/api/annotations.upb.h | 32 + .../ext/upb-generated/google/api/http.upb.c | 66 + .../ext/upb-generated/google/api/http.upb.h | 191 ++ .../ext/upb-generated/google/rpc/status.upb.c | 33 + .../ext/upb-generated/google/rpc/status.upb.h | 75 + .../ext/upb-generated/validate/validate.upb.c | 443 ++++ .../ext/upb-generated/validate/validate.upb.h | 2038 +++++++++++++++++ tools/codegen/core/gen_upb_api.sh | 15 +- tools/distrib/check_copyright.py | 17 +- tools/distrib/check_include_guards.py | 17 +- 26 files changed, 5594 insertions(+), 30 deletions(-) create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h create mode 100644 src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h create mode 100644 src/core/ext/upb-generated/envoy/type/percent.upb.c create mode 100644 src/core/ext/upb-generated/envoy/type/percent.upb.h create mode 100644 src/core/ext/upb-generated/envoy/type/range.upb.c create mode 100644 src/core/ext/upb-generated/envoy/type/range.upb.h create mode 100644 src/core/ext/upb-generated/gogoproto/gogo.upb.c create mode 100644 src/core/ext/upb-generated/gogoproto/gogo.upb.h create mode 100644 src/core/ext/upb-generated/google/api/annotations.upb.c create mode 100644 src/core/ext/upb-generated/google/api/annotations.upb.h create mode 100644 src/core/ext/upb-generated/google/api/http.upb.c create mode 100644 src/core/ext/upb-generated/google/api/http.upb.h create mode 100644 src/core/ext/upb-generated/google/rpc/status.upb.c create mode 100644 src/core/ext/upb-generated/google/rpc/status.upb.h create mode 100644 src/core/ext/upb-generated/validate/validate.upb.c create mode 100644 src/core/ext/upb-generated/validate/validate.upb.h diff --git a/BUILD b/BUILD index 835edbfb48f..9e052dcf0c2 100644 --- a/BUILD +++ b/BUILD @@ -2313,22 +2313,92 @@ grpc_cc_library( #TODO: Get this into build.yaml once we start using it. grpc_cc_library( - name = "google_protobuf_upb", + name = "envoy_ads_upb", srcs = [ + "src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h", + ], + language = "c++", + external_deps = [ + "upb_lib", + ], + deps = [ + ":google_api_upb", + ":proto_gen_validate_upb", + ":envoy_type_upb", + ] +) + +grpc_cc_library( + name = "envoy_type_upb", + srcs = [ + "src/core/ext/upb-generated/envoy/type/percent.upb.c", + "src/core/ext/upb-generated/envoy/type/range.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/envoy/type/percent.upb.h", + "src/core/ext/upb-generated/envoy/type/range.upb.h", + ], + language = "c++", + external_deps = [ + "upb_lib", + ], + deps = [ + ":google_api_upb", + ":proto_gen_validate_upb" + ] +) + +grpc_cc_library( + name = "proto_gen_validate_upb", + srcs = [ + "src/core/ext/upb-generated/gogoproto/gogo.upb.c", + "src/core/ext/upb-generated/validate/validate.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/gogoproto/gogo.upb.h", + "src/core/ext/upb-generated/validate/validate.upb.h", + ], + language = "c++", + external_deps = [ + "upb_lib", + ], + deps = [ + ":google_api_upb", + ] +) + +grpc_cc_library( + name = "google_api_upb", + srcs = [ + "src/core/ext/upb-generated/google/api/annotations.upb.c", + "src/core/ext/upb-generated/google/api/http.upb.c", "src/core/ext/upb-generated/google/protobuf/any.upb.c", "src/core/ext/upb-generated/google/protobuf/descriptor.upb.c", "src/core/ext/upb-generated/google/protobuf/duration.upb.c", "src/core/ext/upb-generated/google/protobuf/struct.upb.c", "src/core/ext/upb-generated/google/protobuf/timestamp.upb.c", "src/core/ext/upb-generated/google/protobuf/wrappers.upb.c", + "src/core/ext/upb-generated/google/rpc/status.upb.c", ], hdrs = [ + "src/core/ext/upb-generated/google/api/annotations.upb.h", + "src/core/ext/upb-generated/google/api/http.upb.h", "src/core/ext/upb-generated/google/protobuf/any.upb.h", "src/core/ext/upb-generated/google/protobuf/descriptor.upb.h", "src/core/ext/upb-generated/google/protobuf/duration.upb.h", "src/core/ext/upb-generated/google/protobuf/struct.upb.h", "src/core/ext/upb-generated/google/protobuf/timestamp.upb.h", "src/core/ext/upb-generated/google/protobuf/wrappers.upb.h", + "src/core/ext/upb-generated/google/rpc/status.upb.h", ], language = "c++", external_deps = [ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c new file mode 100644 index 00000000000..5a37e5785c3 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c @@ -0,0 +1,110 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/address.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/address.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field envoy_api_v2_core_Pipe__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Pipe_msginit = { + NULL, + &envoy_api_v2_core_Pipe__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_SocketAddress__fields[6] = { + {1, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {2, UPB_SIZE(12, 16), 0, 0, 9, 1}, + {3, UPB_SIZE(28, 48), UPB_SIZE(-37, -65), 0, 13, 1}, + {4, UPB_SIZE(28, 48), UPB_SIZE(-37, -65), 0, 9, 1}, + {5, UPB_SIZE(20, 32), 0, 0, 9, 1}, + {6, UPB_SIZE(8, 8), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_core_SocketAddress_msginit = { + NULL, + &envoy_api_v2_core_SocketAddress__fields[0], + UPB_SIZE(40, 80), 6, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_TcpKeepalive_submsgs[3] = { + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_TcpKeepalive__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_TcpKeepalive_msginit = { + &envoy_api_v2_core_TcpKeepalive_submsgs[0], + &envoy_api_v2_core_TcpKeepalive__fields[0], + UPB_SIZE(12, 24), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_BindConfig_submsgs[3] = { + &envoy_api_v2_core_SocketAddress_msginit, + &envoy_api_v2_core_SocketOption_msginit, + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_BindConfig__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 2, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 1, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_core_BindConfig_msginit = { + &envoy_api_v2_core_BindConfig_submsgs[0], + &envoy_api_v2_core_BindConfig__fields[0], + UPB_SIZE(12, 24), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Address_submsgs[2] = { + &envoy_api_v2_core_Pipe_msginit, + &envoy_api_v2_core_SocketAddress_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Address__fields[2] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 1, 11, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Address_msginit = { + &envoy_api_v2_core_Address_submsgs[0], + &envoy_api_v2_core_Address__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_CidrRange_submsgs[1] = { + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_CidrRange__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_CidrRange_msginit = { + &envoy_api_v2_core_CidrRange_submsgs[0], + &envoy_api_v2_core_CidrRange__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h new file mode 100644 index 00000000000..be9e8312b70 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h @@ -0,0 +1,325 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/address.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_ADDRESS_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_ADDRESS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_Pipe; +struct envoy_api_v2_core_SocketAddress; +struct envoy_api_v2_core_TcpKeepalive; +struct envoy_api_v2_core_BindConfig; +struct envoy_api_v2_core_Address; +struct envoy_api_v2_core_CidrRange; +typedef struct envoy_api_v2_core_Pipe envoy_api_v2_core_Pipe; +typedef struct envoy_api_v2_core_SocketAddress envoy_api_v2_core_SocketAddress; +typedef struct envoy_api_v2_core_TcpKeepalive envoy_api_v2_core_TcpKeepalive; +typedef struct envoy_api_v2_core_BindConfig envoy_api_v2_core_BindConfig; +typedef struct envoy_api_v2_core_Address envoy_api_v2_core_Address; +typedef struct envoy_api_v2_core_CidrRange envoy_api_v2_core_CidrRange; +extern const upb_msglayout envoy_api_v2_core_Pipe_msginit; +extern const upb_msglayout envoy_api_v2_core_SocketAddress_msginit; +extern const upb_msglayout envoy_api_v2_core_TcpKeepalive_msginit; +extern const upb_msglayout envoy_api_v2_core_BindConfig_msginit; +extern const upb_msglayout envoy_api_v2_core_Address_msginit; +extern const upb_msglayout envoy_api_v2_core_CidrRange_msginit; +struct google_protobuf_UInt32Value; +struct google_protobuf_BoolValue; +struct envoy_api_v2_core_SocketOption; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout envoy_api_v2_core_SocketOption_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_core_SocketAddress_TCP = 0, + envoy_api_v2_core_SocketAddress_UDP = 1 +} envoy_api_v2_core_SocketAddress_Protocol; + +/* envoy.api.v2.core.Pipe */ + +UPB_INLINE envoy_api_v2_core_Pipe *envoy_api_v2_core_Pipe_new(upb_arena *arena) { + return (envoy_api_v2_core_Pipe *)upb_msg_new(&envoy_api_v2_core_Pipe_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Pipe *envoy_api_v2_core_Pipe_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Pipe *ret = envoy_api_v2_core_Pipe_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Pipe_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Pipe_serialize(const envoy_api_v2_core_Pipe *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Pipe_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_Pipe_path(const envoy_api_v2_core_Pipe *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_Pipe_set_path(envoy_api_v2_core_Pipe *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.SocketAddress */ + +UPB_INLINE envoy_api_v2_core_SocketAddress *envoy_api_v2_core_SocketAddress_new(upb_arena *arena) { + return (envoy_api_v2_core_SocketAddress *)upb_msg_new(&envoy_api_v2_core_SocketAddress_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_SocketAddress *envoy_api_v2_core_SocketAddress_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_SocketAddress *ret = envoy_api_v2_core_SocketAddress_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_SocketAddress_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_SocketAddress_serialize(const envoy_api_v2_core_SocketAddress *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_SocketAddress_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_SocketAddress_port_specifier_port_value = 3, + envoy_api_v2_core_SocketAddress_port_specifier_named_port = 4, + envoy_api_v2_core_SocketAddress_port_specifier_NOT_SET = 0, +} envoy_api_v2_core_SocketAddress_port_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_SocketAddress_port_specifier_oneofcases envoy_api_v2_core_SocketAddress_port_specifier_case(const envoy_api_v2_core_SocketAddress* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(36, 64)); } + +UPB_INLINE envoy_api_v2_core_SocketAddress_Protocol envoy_api_v2_core_SocketAddress_protocol(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, envoy_api_v2_core_SocketAddress_Protocol, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_SocketAddress_address(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)); } +UPB_INLINE bool envoy_api_v2_core_SocketAddress_has_port_value(const envoy_api_v2_core_SocketAddress *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 64), 3); } +UPB_INLINE uint32_t envoy_api_v2_core_SocketAddress_port_value(const envoy_api_v2_core_SocketAddress *msg) { return UPB_READ_ONEOF(msg, uint32_t, UPB_SIZE(28, 48), UPB_SIZE(36, 64), 3, 0); } +UPB_INLINE bool envoy_api_v2_core_SocketAddress_has_named_port(const envoy_api_v2_core_SocketAddress *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 64), 4); } +UPB_INLINE upb_strview envoy_api_v2_core_SocketAddress_named_port(const envoy_api_v2_core_SocketAddress *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 48), UPB_SIZE(36, 64), 4, upb_strview_make("", strlen(""))); } +UPB_INLINE upb_strview envoy_api_v2_core_SocketAddress_resolver_name(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 32)); } +UPB_INLINE bool envoy_api_v2_core_SocketAddress_ipv4_compat(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)); } + +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_protocol(envoy_api_v2_core_SocketAddress *msg, envoy_api_v2_core_SocketAddress_Protocol value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_SocketAddress_Protocol, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_address(envoy_api_v2_core_SocketAddress *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_port_value(envoy_api_v2_core_SocketAddress *msg, uint32_t value) { + UPB_WRITE_ONEOF(msg, uint32_t, UPB_SIZE(28, 48), value, UPB_SIZE(36, 64), 3); +} +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_named_port(envoy_api_v2_core_SocketAddress *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 48), value, UPB_SIZE(36, 64), 4); +} +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_resolver_name(envoy_api_v2_core_SocketAddress *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 32)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_ipv4_compat(envoy_api_v2_core_SocketAddress *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)) = value; +} + + +/* envoy.api.v2.core.TcpKeepalive */ + +UPB_INLINE envoy_api_v2_core_TcpKeepalive *envoy_api_v2_core_TcpKeepalive_new(upb_arena *arena) { + return (envoy_api_v2_core_TcpKeepalive *)upb_msg_new(&envoy_api_v2_core_TcpKeepalive_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_TcpKeepalive *envoy_api_v2_core_TcpKeepalive_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_TcpKeepalive *ret = envoy_api_v2_core_TcpKeepalive_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_TcpKeepalive_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_TcpKeepalive_serialize(const envoy_api_v2_core_TcpKeepalive *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_TcpKeepalive_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_keepalive_probes(const envoy_api_v2_core_TcpKeepalive *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_keepalive_time(const envoy_api_v2_core_TcpKeepalive *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_keepalive_interval(const envoy_api_v2_core_TcpKeepalive *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_TcpKeepalive_set_keepalive_probes(envoy_api_v2_core_TcpKeepalive *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_mutable_keepalive_probes(envoy_api_v2_core_TcpKeepalive *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_TcpKeepalive_keepalive_probes(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_TcpKeepalive_set_keepalive_probes(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_TcpKeepalive_set_keepalive_time(envoy_api_v2_core_TcpKeepalive *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_mutable_keepalive_time(envoy_api_v2_core_TcpKeepalive *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_TcpKeepalive_keepalive_time(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_TcpKeepalive_set_keepalive_time(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_TcpKeepalive_set_keepalive_interval(envoy_api_v2_core_TcpKeepalive *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_TcpKeepalive_mutable_keepalive_interval(envoy_api_v2_core_TcpKeepalive *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_TcpKeepalive_keepalive_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_TcpKeepalive_set_keepalive_interval(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.BindConfig */ + +UPB_INLINE envoy_api_v2_core_BindConfig *envoy_api_v2_core_BindConfig_new(upb_arena *arena) { + return (envoy_api_v2_core_BindConfig *)upb_msg_new(&envoy_api_v2_core_BindConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_BindConfig *envoy_api_v2_core_BindConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_BindConfig *ret = envoy_api_v2_core_BindConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_BindConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_BindConfig_serialize(const envoy_api_v2_core_BindConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_BindConfig_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_core_SocketAddress* envoy_api_v2_core_BindConfig_source_address(const envoy_api_v2_core_BindConfig *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_SocketAddress*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_core_BindConfig_freebind(const envoy_api_v2_core_BindConfig *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct envoy_api_v2_core_SocketOption* const* envoy_api_v2_core_BindConfig_socket_options(const envoy_api_v2_core_BindConfig *msg, size_t *len) { return (const struct envoy_api_v2_core_SocketOption* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); } + +UPB_INLINE void envoy_api_v2_core_BindConfig_set_source_address(envoy_api_v2_core_BindConfig *msg, envoy_api_v2_core_SocketAddress* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_SocketAddress*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_SocketAddress* envoy_api_v2_core_BindConfig_mutable_source_address(envoy_api_v2_core_BindConfig *msg, upb_arena *arena) { + struct envoy_api_v2_core_SocketAddress* sub = (struct envoy_api_v2_core_SocketAddress*)envoy_api_v2_core_BindConfig_source_address(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_SocketAddress*)upb_msg_new(&envoy_api_v2_core_SocketAddress_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_BindConfig_set_source_address(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_BindConfig_set_freebind(envoy_api_v2_core_BindConfig *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_core_BindConfig_mutable_freebind(envoy_api_v2_core_BindConfig *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_core_BindConfig_freebind(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_BindConfig_set_freebind(msg, sub); + } + return sub; +} +UPB_INLINE struct envoy_api_v2_core_SocketOption** envoy_api_v2_core_BindConfig_mutable_socket_options(envoy_api_v2_core_BindConfig *msg, size_t *len) { + return (struct envoy_api_v2_core_SocketOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len); +} +UPB_INLINE struct envoy_api_v2_core_SocketOption** envoy_api_v2_core_BindConfig_resize_socket_options(envoy_api_v2_core_BindConfig *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_SocketOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_SocketOption* envoy_api_v2_core_BindConfig_add_socket_options(envoy_api_v2_core_BindConfig *msg, upb_arena *arena) { + struct envoy_api_v2_core_SocketOption* sub = (struct envoy_api_v2_core_SocketOption*)upb_msg_new(&envoy_api_v2_core_SocketOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(8, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.core.Address */ + +UPB_INLINE envoy_api_v2_core_Address *envoy_api_v2_core_Address_new(upb_arena *arena) { + return (envoy_api_v2_core_Address *)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Address *envoy_api_v2_core_Address_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Address *ret = envoy_api_v2_core_Address_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Address_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Address_serialize(const envoy_api_v2_core_Address *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Address_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_Address_address_socket_address = 1, + envoy_api_v2_core_Address_address_pipe = 2, + envoy_api_v2_core_Address_address_NOT_SET = 0, +} envoy_api_v2_core_Address_address_oneofcases; +UPB_INLINE envoy_api_v2_core_Address_address_oneofcases envoy_api_v2_core_Address_address_case(const envoy_api_v2_core_Address* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(4, 8)); } + +UPB_INLINE bool envoy_api_v2_core_Address_has_socket_address(const envoy_api_v2_core_Address *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 1); } +UPB_INLINE const envoy_api_v2_core_SocketAddress* envoy_api_v2_core_Address_socket_address(const envoy_api_v2_core_Address *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_SocketAddress*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 1, NULL); } +UPB_INLINE bool envoy_api_v2_core_Address_has_pipe(const envoy_api_v2_core_Address *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 2); } +UPB_INLINE const envoy_api_v2_core_Pipe* envoy_api_v2_core_Address_pipe(const envoy_api_v2_core_Address *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_Pipe*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 2, NULL); } + +UPB_INLINE void envoy_api_v2_core_Address_set_socket_address(envoy_api_v2_core_Address *msg, envoy_api_v2_core_SocketAddress* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_SocketAddress*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 1); +} +UPB_INLINE struct envoy_api_v2_core_SocketAddress* envoy_api_v2_core_Address_mutable_socket_address(envoy_api_v2_core_Address *msg, upb_arena *arena) { + struct envoy_api_v2_core_SocketAddress* sub = (struct envoy_api_v2_core_SocketAddress*)envoy_api_v2_core_Address_socket_address(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_SocketAddress*)upb_msg_new(&envoy_api_v2_core_SocketAddress_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Address_set_socket_address(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Address_set_pipe(envoy_api_v2_core_Address *msg, envoy_api_v2_core_Pipe* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_Pipe*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 2); +} +UPB_INLINE struct envoy_api_v2_core_Pipe* envoy_api_v2_core_Address_mutable_pipe(envoy_api_v2_core_Address *msg, upb_arena *arena) { + struct envoy_api_v2_core_Pipe* sub = (struct envoy_api_v2_core_Pipe*)envoy_api_v2_core_Address_pipe(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Pipe*)upb_msg_new(&envoy_api_v2_core_Pipe_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Address_set_pipe(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.CidrRange */ + +UPB_INLINE envoy_api_v2_core_CidrRange *envoy_api_v2_core_CidrRange_new(upb_arena *arena) { + return (envoy_api_v2_core_CidrRange *)upb_msg_new(&envoy_api_v2_core_CidrRange_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_CidrRange *envoy_api_v2_core_CidrRange_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_CidrRange *ret = envoy_api_v2_core_CidrRange_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_CidrRange_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_CidrRange_serialize(const envoy_api_v2_core_CidrRange *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_CidrRange_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_CidrRange_address_prefix(const envoy_api_v2_core_CidrRange *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_CidrRange_prefix_len(const envoy_api_v2_core_CidrRange *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_CidrRange_set_address_prefix(envoy_api_v2_core_CidrRange *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_CidrRange_set_prefix_len(envoy_api_v2_core_CidrRange *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_CidrRange_mutable_prefix_len(envoy_api_v2_core_CidrRange *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_CidrRange_prefix_len(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_CidrRange_set_prefix_len(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_ADDRESS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c new file mode 100644 index 00000000000..1e5c9190381 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c @@ -0,0 +1,179 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/base.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/any.upb.h" +#include "google/protobuf/struct.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" +#include "envoy/type/percent.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field envoy_api_v2_core_Locality__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {3, UPB_SIZE(16, 32), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Locality_msginit = { + NULL, + &envoy_api_v2_core_Locality__fields[0], + UPB_SIZE(24, 48), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Node_submsgs[2] = { + &envoy_api_v2_core_Locality_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Node__fields[5] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {3, UPB_SIZE(24, 48), 0, 1, 11, 1}, + {4, UPB_SIZE(28, 56), 0, 0, 11, 1}, + {5, UPB_SIZE(16, 32), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Node_msginit = { + &envoy_api_v2_core_Node_submsgs[0], + &envoy_api_v2_core_Node__fields[0], + UPB_SIZE(32, 64), 5, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Metadata_submsgs[1] = { + &envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Metadata__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_core_Metadata_msginit = { + &envoy_api_v2_core_Metadata_submsgs[0], + &envoy_api_v2_core_Metadata__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Metadata_FilterMetadataEntry_submsgs[1] = { + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Metadata_FilterMetadataEntry__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit = { + &envoy_api_v2_core_Metadata_FilterMetadataEntry_submsgs[0], + &envoy_api_v2_core_Metadata_FilterMetadataEntry__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_RuntimeUInt32__fields[2] = { + {2, UPB_SIZE(0, 0), 0, 0, 13, 1}, + {3, UPB_SIZE(4, 8), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_RuntimeUInt32_msginit = { + NULL, + &envoy_api_v2_core_RuntimeUInt32__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_HeaderValue__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HeaderValue_msginit = { + NULL, + &envoy_api_v2_core_HeaderValue__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_HeaderValueOption_submsgs[2] = { + &envoy_api_v2_core_HeaderValue_msginit, + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HeaderValueOption__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HeaderValueOption_msginit = { + &envoy_api_v2_core_HeaderValueOption_submsgs[0], + &envoy_api_v2_core_HeaderValueOption__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_DataSource__fields[3] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 12, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_DataSource_msginit = { + NULL, + &envoy_api_v2_core_DataSource__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_TransportSocket_submsgs[2] = { + &google_protobuf_Any_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_TransportSocket__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_TransportSocket_msginit = { + &envoy_api_v2_core_TransportSocket_submsgs[0], + &envoy_api_v2_core_TransportSocket__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_SocketOption__fields[6] = { + {1, UPB_SIZE(24, 24), 0, 0, 9, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 3, 1}, + {3, UPB_SIZE(8, 8), 0, 0, 3, 1}, + {4, UPB_SIZE(32, 40), UPB_SIZE(-41, -57), 0, 3, 1}, + {5, UPB_SIZE(32, 40), UPB_SIZE(-41, -57), 0, 12, 1}, + {6, UPB_SIZE(16, 16), 0, 0, 14, 1}, +}; + +const upb_msglayout envoy_api_v2_core_SocketOption_msginit = { + NULL, + &envoy_api_v2_core_SocketOption__fields[0], + UPB_SIZE(48, 64), 6, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_RuntimeFractionalPercent_submsgs[1] = { + &envoy_type_FractionalPercent_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_RuntimeFractionalPercent__fields[2] = { + {1, UPB_SIZE(8, 16), 0, 0, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_RuntimeFractionalPercent_msginit = { + &envoy_api_v2_core_RuntimeFractionalPercent_submsgs[0], + &envoy_api_v2_core_RuntimeFractionalPercent__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h new file mode 100644 index 00000000000..e630d1d53ca --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h @@ -0,0 +1,507 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/base.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_BASE_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_BASE_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_Locality; +struct envoy_api_v2_core_Node; +struct envoy_api_v2_core_Metadata; +struct envoy_api_v2_core_Metadata_FilterMetadataEntry; +struct envoy_api_v2_core_RuntimeUInt32; +struct envoy_api_v2_core_HeaderValue; +struct envoy_api_v2_core_HeaderValueOption; +struct envoy_api_v2_core_DataSource; +struct envoy_api_v2_core_TransportSocket; +struct envoy_api_v2_core_SocketOption; +struct envoy_api_v2_core_RuntimeFractionalPercent; +typedef struct envoy_api_v2_core_Locality envoy_api_v2_core_Locality; +typedef struct envoy_api_v2_core_Node envoy_api_v2_core_Node; +typedef struct envoy_api_v2_core_Metadata envoy_api_v2_core_Metadata; +typedef struct envoy_api_v2_core_Metadata_FilterMetadataEntry envoy_api_v2_core_Metadata_FilterMetadataEntry; +typedef struct envoy_api_v2_core_RuntimeUInt32 envoy_api_v2_core_RuntimeUInt32; +typedef struct envoy_api_v2_core_HeaderValue envoy_api_v2_core_HeaderValue; +typedef struct envoy_api_v2_core_HeaderValueOption envoy_api_v2_core_HeaderValueOption; +typedef struct envoy_api_v2_core_DataSource envoy_api_v2_core_DataSource; +typedef struct envoy_api_v2_core_TransportSocket envoy_api_v2_core_TransportSocket; +typedef struct envoy_api_v2_core_SocketOption envoy_api_v2_core_SocketOption; +typedef struct envoy_api_v2_core_RuntimeFractionalPercent envoy_api_v2_core_RuntimeFractionalPercent; +extern const upb_msglayout envoy_api_v2_core_Locality_msginit; +extern const upb_msglayout envoy_api_v2_core_Node_msginit; +extern const upb_msglayout envoy_api_v2_core_Metadata_msginit; +extern const upb_msglayout envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit; +extern const upb_msglayout envoy_api_v2_core_RuntimeUInt32_msginit; +extern const upb_msglayout envoy_api_v2_core_HeaderValue_msginit; +extern const upb_msglayout envoy_api_v2_core_HeaderValueOption_msginit; +extern const upb_msglayout envoy_api_v2_core_DataSource_msginit; +extern const upb_msglayout envoy_api_v2_core_TransportSocket_msginit; +extern const upb_msglayout envoy_api_v2_core_SocketOption_msginit; +extern const upb_msglayout envoy_api_v2_core_RuntimeFractionalPercent_msginit; +struct google_protobuf_Any; +struct google_protobuf_Struct; +struct google_protobuf_BoolValue; +struct envoy_type_FractionalPercent; +extern const upb_msglayout google_protobuf_Any_msginit; +extern const upb_msglayout google_protobuf_Struct_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout envoy_type_FractionalPercent_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_core_METHOD_UNSPECIFIED = 0, + envoy_api_v2_core_GET = 1, + envoy_api_v2_core_HEAD = 2, + envoy_api_v2_core_POST = 3, + envoy_api_v2_core_PUT = 4, + envoy_api_v2_core_DELETE = 5, + envoy_api_v2_core_CONNECT = 6, + envoy_api_v2_core_OPTIONS = 7, + envoy_api_v2_core_TRACE = 8 +} envoy_api_v2_core_RequestMethod; + +typedef enum { + envoy_api_v2_core_DEFAULT = 0, + envoy_api_v2_core_HIGH = 1 +} envoy_api_v2_core_RoutingPriority; + +typedef enum { + envoy_api_v2_core_SocketOption_STATE_PREBIND = 0, + envoy_api_v2_core_SocketOption_STATE_BOUND = 1, + envoy_api_v2_core_SocketOption_STATE_LISTENING = 2 +} envoy_api_v2_core_SocketOption_SocketState; + +/* envoy.api.v2.core.Locality */ + +UPB_INLINE envoy_api_v2_core_Locality *envoy_api_v2_core_Locality_new(upb_arena *arena) { + return (envoy_api_v2_core_Locality *)upb_msg_new(&envoy_api_v2_core_Locality_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Locality *envoy_api_v2_core_Locality_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Locality *ret = envoy_api_v2_core_Locality_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Locality_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Locality_serialize(const envoy_api_v2_core_Locality *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Locality_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_Locality_region(const envoy_api_v2_core_Locality *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_Locality_zone(const envoy_api_v2_core_Locality *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview envoy_api_v2_core_Locality_sub_zone(const envoy_api_v2_core_Locality *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)); } + +UPB_INLINE void envoy_api_v2_core_Locality_set_region(envoy_api_v2_core_Locality *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_Locality_set_zone(envoy_api_v2_core_Locality *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void envoy_api_v2_core_Locality_set_sub_zone(envoy_api_v2_core_Locality *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)) = value; +} + + +/* envoy.api.v2.core.Node */ + +UPB_INLINE envoy_api_v2_core_Node *envoy_api_v2_core_Node_new(upb_arena *arena) { + return (envoy_api_v2_core_Node *)upb_msg_new(&envoy_api_v2_core_Node_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Node *envoy_api_v2_core_Node_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Node *ret = envoy_api_v2_core_Node_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Node_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Node_serialize(const envoy_api_v2_core_Node *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Node_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_Node_id(const envoy_api_v2_core_Node *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_Node_cluster(const envoy_api_v2_core_Node *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_Node_metadata(const envoy_api_v2_core_Node *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Struct*, UPB_SIZE(24, 48)); } +UPB_INLINE const envoy_api_v2_core_Locality* envoy_api_v2_core_Node_locality(const envoy_api_v2_core_Node *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_Locality*, UPB_SIZE(28, 56)); } +UPB_INLINE upb_strview envoy_api_v2_core_Node_build_version(const envoy_api_v2_core_Node *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)); } + +UPB_INLINE void envoy_api_v2_core_Node_set_id(envoy_api_v2_core_Node *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_Node_set_cluster(envoy_api_v2_core_Node *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void envoy_api_v2_core_Node_set_metadata(envoy_api_v2_core_Node *msg, struct google_protobuf_Struct* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Struct*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_Node_mutable_metadata(envoy_api_v2_core_Node *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_Node_metadata(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Node_set_metadata(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Node_set_locality(envoy_api_v2_core_Node *msg, envoy_api_v2_core_Locality* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_Locality*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Locality* envoy_api_v2_core_Node_mutable_locality(envoy_api_v2_core_Node *msg, upb_arena *arena) { + struct envoy_api_v2_core_Locality* sub = (struct envoy_api_v2_core_Locality*)envoy_api_v2_core_Node_locality(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Locality*)upb_msg_new(&envoy_api_v2_core_Locality_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Node_set_locality(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Node_set_build_version(envoy_api_v2_core_Node *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)) = value; +} + + +/* envoy.api.v2.core.Metadata */ + +UPB_INLINE envoy_api_v2_core_Metadata *envoy_api_v2_core_Metadata_new(upb_arena *arena) { + return (envoy_api_v2_core_Metadata *)upb_msg_new(&envoy_api_v2_core_Metadata_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Metadata *envoy_api_v2_core_Metadata_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Metadata *ret = envoy_api_v2_core_Metadata_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Metadata_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Metadata_serialize(const envoy_api_v2_core_Metadata *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Metadata_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_core_Metadata_FilterMetadataEntry* const* envoy_api_v2_core_Metadata_filter_metadata(const envoy_api_v2_core_Metadata *msg, size_t *len) { return (const envoy_api_v2_core_Metadata_FilterMetadataEntry* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE envoy_api_v2_core_Metadata_FilterMetadataEntry** envoy_api_v2_core_Metadata_mutable_filter_metadata(envoy_api_v2_core_Metadata *msg, size_t *len) { + return (envoy_api_v2_core_Metadata_FilterMetadataEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE envoy_api_v2_core_Metadata_FilterMetadataEntry** envoy_api_v2_core_Metadata_resize_filter_metadata(envoy_api_v2_core_Metadata *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_core_Metadata_FilterMetadataEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_Metadata_FilterMetadataEntry* envoy_api_v2_core_Metadata_add_filter_metadata(envoy_api_v2_core_Metadata *msg, upb_arena *arena) { + struct envoy_api_v2_core_Metadata_FilterMetadataEntry* sub = (struct envoy_api_v2_core_Metadata_FilterMetadataEntry*)upb_msg_new(&envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.core.Metadata.FilterMetadataEntry */ + +UPB_INLINE envoy_api_v2_core_Metadata_FilterMetadataEntry *envoy_api_v2_core_Metadata_FilterMetadataEntry_new(upb_arena *arena) { + return (envoy_api_v2_core_Metadata_FilterMetadataEntry *)upb_msg_new(&envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Metadata_FilterMetadataEntry *envoy_api_v2_core_Metadata_FilterMetadataEntry_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Metadata_FilterMetadataEntry *ret = envoy_api_v2_core_Metadata_FilterMetadataEntry_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Metadata_FilterMetadataEntry_serialize(const envoy_api_v2_core_Metadata_FilterMetadataEntry *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Metadata_FilterMetadataEntry_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_Metadata_FilterMetadataEntry_key(const envoy_api_v2_core_Metadata_FilterMetadataEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_Metadata_FilterMetadataEntry_value(const envoy_api_v2_core_Metadata_FilterMetadataEntry *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Struct*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_Metadata_FilterMetadataEntry_set_key(envoy_api_v2_core_Metadata_FilterMetadataEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_Metadata_FilterMetadataEntry_set_value(envoy_api_v2_core_Metadata_FilterMetadataEntry *msg, struct google_protobuf_Struct* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Struct*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_Metadata_FilterMetadataEntry_mutable_value(envoy_api_v2_core_Metadata_FilterMetadataEntry *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_Metadata_FilterMetadataEntry_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Metadata_FilterMetadataEntry_set_value(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.RuntimeUInt32 */ + +UPB_INLINE envoy_api_v2_core_RuntimeUInt32 *envoy_api_v2_core_RuntimeUInt32_new(upb_arena *arena) { + return (envoy_api_v2_core_RuntimeUInt32 *)upb_msg_new(&envoy_api_v2_core_RuntimeUInt32_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_RuntimeUInt32 *envoy_api_v2_core_RuntimeUInt32_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_RuntimeUInt32 *ret = envoy_api_v2_core_RuntimeUInt32_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_RuntimeUInt32_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_RuntimeUInt32_serialize(const envoy_api_v2_core_RuntimeUInt32 *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_RuntimeUInt32_msginit, arena, len); +} + +UPB_INLINE uint32_t envoy_api_v2_core_RuntimeUInt32_default_value(const envoy_api_v2_core_RuntimeUInt32 *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_RuntimeUInt32_runtime_key(const envoy_api_v2_core_RuntimeUInt32 *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_core_RuntimeUInt32_set_default_value(envoy_api_v2_core_RuntimeUInt32 *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_RuntimeUInt32_set_runtime_key(envoy_api_v2_core_RuntimeUInt32 *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} + + +/* envoy.api.v2.core.HeaderValue */ + +UPB_INLINE envoy_api_v2_core_HeaderValue *envoy_api_v2_core_HeaderValue_new(upb_arena *arena) { + return (envoy_api_v2_core_HeaderValue *)upb_msg_new(&envoy_api_v2_core_HeaderValue_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HeaderValue *envoy_api_v2_core_HeaderValue_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HeaderValue *ret = envoy_api_v2_core_HeaderValue_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HeaderValue_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HeaderValue_serialize(const envoy_api_v2_core_HeaderValue *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HeaderValue_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_HeaderValue_key(const envoy_api_v2_core_HeaderValue *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_HeaderValue_value(const envoy_api_v2_core_HeaderValue *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_HeaderValue_set_key(envoy_api_v2_core_HeaderValue *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_HeaderValue_set_value(envoy_api_v2_core_HeaderValue *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} + + +/* envoy.api.v2.core.HeaderValueOption */ + +UPB_INLINE envoy_api_v2_core_HeaderValueOption *envoy_api_v2_core_HeaderValueOption_new(upb_arena *arena) { + return (envoy_api_v2_core_HeaderValueOption *)upb_msg_new(&envoy_api_v2_core_HeaderValueOption_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HeaderValueOption *envoy_api_v2_core_HeaderValueOption_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HeaderValueOption *ret = envoy_api_v2_core_HeaderValueOption_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HeaderValueOption_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HeaderValueOption_serialize(const envoy_api_v2_core_HeaderValueOption *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HeaderValueOption_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_core_HeaderValue* envoy_api_v2_core_HeaderValueOption_header(const envoy_api_v2_core_HeaderValueOption *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_HeaderValue*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_core_HeaderValueOption_append(const envoy_api_v2_core_HeaderValueOption *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_core_HeaderValueOption_set_header(envoy_api_v2_core_HeaderValueOption *msg, envoy_api_v2_core_HeaderValue* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_HeaderValue*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HeaderValue* envoy_api_v2_core_HeaderValueOption_mutable_header(envoy_api_v2_core_HeaderValueOption *msg, upb_arena *arena) { + struct envoy_api_v2_core_HeaderValue* sub = (struct envoy_api_v2_core_HeaderValue*)envoy_api_v2_core_HeaderValueOption_header(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HeaderValue*)upb_msg_new(&envoy_api_v2_core_HeaderValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HeaderValueOption_set_header(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HeaderValueOption_set_append(envoy_api_v2_core_HeaderValueOption *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_core_HeaderValueOption_mutable_append(envoy_api_v2_core_HeaderValueOption *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_core_HeaderValueOption_append(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HeaderValueOption_set_append(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.DataSource */ + +UPB_INLINE envoy_api_v2_core_DataSource *envoy_api_v2_core_DataSource_new(upb_arena *arena) { + return (envoy_api_v2_core_DataSource *)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_DataSource *envoy_api_v2_core_DataSource_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_DataSource *ret = envoy_api_v2_core_DataSource_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_DataSource_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_DataSource_serialize(const envoy_api_v2_core_DataSource *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_DataSource_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_DataSource_specifier_filename = 1, + envoy_api_v2_core_DataSource_specifier_inline_bytes = 2, + envoy_api_v2_core_DataSource_specifier_inline_string = 3, + envoy_api_v2_core_DataSource_specifier_NOT_SET = 0, +} envoy_api_v2_core_DataSource_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_DataSource_specifier_oneofcases envoy_api_v2_core_DataSource_specifier_case(const envoy_api_v2_core_DataSource* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } + +UPB_INLINE bool envoy_api_v2_core_DataSource_has_filename(const envoy_api_v2_core_DataSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } +UPB_INLINE upb_strview envoy_api_v2_core_DataSource_filename(const envoy_api_v2_core_DataSource *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_DataSource_has_inline_bytes(const envoy_api_v2_core_DataSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } +UPB_INLINE upb_strview envoy_api_v2_core_DataSource_inline_bytes(const envoy_api_v2_core_DataSource *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_DataSource_has_inline_string(const envoy_api_v2_core_DataSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 3); } +UPB_INLINE upb_strview envoy_api_v2_core_DataSource_inline_string(const envoy_api_v2_core_DataSource *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, upb_strview_make("", strlen(""))); } + +UPB_INLINE void envoy_api_v2_core_DataSource_set_filename(envoy_api_v2_core_DataSource *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); +} +UPB_INLINE void envoy_api_v2_core_DataSource_set_inline_bytes(envoy_api_v2_core_DataSource *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); +} +UPB_INLINE void envoy_api_v2_core_DataSource_set_inline_string(envoy_api_v2_core_DataSource *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 3); +} + + +/* envoy.api.v2.core.TransportSocket */ + +UPB_INLINE envoy_api_v2_core_TransportSocket *envoy_api_v2_core_TransportSocket_new(upb_arena *arena) { + return (envoy_api_v2_core_TransportSocket *)upb_msg_new(&envoy_api_v2_core_TransportSocket_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_TransportSocket *envoy_api_v2_core_TransportSocket_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_TransportSocket *ret = envoy_api_v2_core_TransportSocket_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_TransportSocket_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_TransportSocket_serialize(const envoy_api_v2_core_TransportSocket *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_TransportSocket_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_TransportSocket_config_type_config = 2, + envoy_api_v2_core_TransportSocket_config_type_typed_config = 3, + envoy_api_v2_core_TransportSocket_config_type_NOT_SET = 0, +} envoy_api_v2_core_TransportSocket_config_type_oneofcases; +UPB_INLINE envoy_api_v2_core_TransportSocket_config_type_oneofcases envoy_api_v2_core_TransportSocket_config_type_case(const envoy_api_v2_core_TransportSocket* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE upb_strview envoy_api_v2_core_TransportSocket_name(const envoy_api_v2_core_TransportSocket *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE bool envoy_api_v2_core_TransportSocket_has_config(const envoy_api_v2_core_TransportSocket *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_TransportSocket_config(const envoy_api_v2_core_TransportSocket *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Struct*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_TransportSocket_has_typed_config(const envoy_api_v2_core_TransportSocket *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 3); } +UPB_INLINE const struct google_protobuf_Any* envoy_api_v2_core_TransportSocket_typed_config(const envoy_api_v2_core_TransportSocket *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Any*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 3, NULL); } + +UPB_INLINE void envoy_api_v2_core_TransportSocket_set_name(envoy_api_v2_core_TransportSocket *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_TransportSocket_set_config(envoy_api_v2_core_TransportSocket *msg, struct google_protobuf_Struct* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Struct*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_TransportSocket_mutable_config(envoy_api_v2_core_TransportSocket *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_TransportSocket_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_TransportSocket_set_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_TransportSocket_set_typed_config(envoy_api_v2_core_TransportSocket *msg, struct google_protobuf_Any* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Any*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 3); +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_core_TransportSocket_mutable_typed_config(envoy_api_v2_core_TransportSocket *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_api_v2_core_TransportSocket_typed_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_TransportSocket_set_typed_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.SocketOption */ + +UPB_INLINE envoy_api_v2_core_SocketOption *envoy_api_v2_core_SocketOption_new(upb_arena *arena) { + return (envoy_api_v2_core_SocketOption *)upb_msg_new(&envoy_api_v2_core_SocketOption_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_SocketOption *envoy_api_v2_core_SocketOption_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_SocketOption *ret = envoy_api_v2_core_SocketOption_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_SocketOption_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_SocketOption_serialize(const envoy_api_v2_core_SocketOption *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_SocketOption_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_SocketOption_value_int_value = 4, + envoy_api_v2_core_SocketOption_value_buf_value = 5, + envoy_api_v2_core_SocketOption_value_NOT_SET = 0, +} envoy_api_v2_core_SocketOption_value_oneofcases; +UPB_INLINE envoy_api_v2_core_SocketOption_value_oneofcases envoy_api_v2_core_SocketOption_value_case(const envoy_api_v2_core_SocketOption* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(40, 56)); } + +UPB_INLINE upb_strview envoy_api_v2_core_SocketOption_description(const envoy_api_v2_core_SocketOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(24, 24)); } +UPB_INLINE int64_t envoy_api_v2_core_SocketOption_level(const envoy_api_v2_core_SocketOption *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } +UPB_INLINE int64_t envoy_api_v2_core_SocketOption_name(const envoy_api_v2_core_SocketOption *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool envoy_api_v2_core_SocketOption_has_int_value(const envoy_api_v2_core_SocketOption *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(40, 56), 4); } +UPB_INLINE int64_t envoy_api_v2_core_SocketOption_int_value(const envoy_api_v2_core_SocketOption *msg) { return UPB_READ_ONEOF(msg, int64_t, UPB_SIZE(32, 40), UPB_SIZE(40, 56), 4, 0); } +UPB_INLINE bool envoy_api_v2_core_SocketOption_has_buf_value(const envoy_api_v2_core_SocketOption *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(40, 56), 5); } +UPB_INLINE upb_strview envoy_api_v2_core_SocketOption_buf_value(const envoy_api_v2_core_SocketOption *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(32, 40), UPB_SIZE(40, 56), 5, upb_strview_make("", strlen(""))); } +UPB_INLINE envoy_api_v2_core_SocketOption_SocketState envoy_api_v2_core_SocketOption_state(const envoy_api_v2_core_SocketOption *msg) { return UPB_FIELD_AT(msg, envoy_api_v2_core_SocketOption_SocketState, UPB_SIZE(16, 16)); } + +UPB_INLINE void envoy_api_v2_core_SocketOption_set_description(envoy_api_v2_core_SocketOption *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketOption_set_level(envoy_api_v2_core_SocketOption *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketOption_set_name(envoy_api_v2_core_SocketOption *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void envoy_api_v2_core_SocketOption_set_int_value(envoy_api_v2_core_SocketOption *msg, int64_t value) { + UPB_WRITE_ONEOF(msg, int64_t, UPB_SIZE(32, 40), value, UPB_SIZE(40, 56), 4); +} +UPB_INLINE void envoy_api_v2_core_SocketOption_set_buf_value(envoy_api_v2_core_SocketOption *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(32, 40), value, UPB_SIZE(40, 56), 5); +} +UPB_INLINE void envoy_api_v2_core_SocketOption_set_state(envoy_api_v2_core_SocketOption *msg, envoy_api_v2_core_SocketOption_SocketState value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_SocketOption_SocketState, UPB_SIZE(16, 16)) = value; +} + + +/* envoy.api.v2.core.RuntimeFractionalPercent */ + +UPB_INLINE envoy_api_v2_core_RuntimeFractionalPercent *envoy_api_v2_core_RuntimeFractionalPercent_new(upb_arena *arena) { + return (envoy_api_v2_core_RuntimeFractionalPercent *)upb_msg_new(&envoy_api_v2_core_RuntimeFractionalPercent_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_RuntimeFractionalPercent *envoy_api_v2_core_RuntimeFractionalPercent_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_RuntimeFractionalPercent *ret = envoy_api_v2_core_RuntimeFractionalPercent_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_RuntimeFractionalPercent_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_RuntimeFractionalPercent_serialize(const envoy_api_v2_core_RuntimeFractionalPercent *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_RuntimeFractionalPercent_msginit, arena, len); +} + +UPB_INLINE const struct envoy_type_FractionalPercent* envoy_api_v2_core_RuntimeFractionalPercent_default_value(const envoy_api_v2_core_RuntimeFractionalPercent *msg) { return UPB_FIELD_AT(msg, const struct envoy_type_FractionalPercent*, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview envoy_api_v2_core_RuntimeFractionalPercent_runtime_key(const envoy_api_v2_core_RuntimeFractionalPercent *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_RuntimeFractionalPercent_set_default_value(envoy_api_v2_core_RuntimeFractionalPercent *msg, struct envoy_type_FractionalPercent* value) { + UPB_FIELD_AT(msg, struct envoy_type_FractionalPercent*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_type_FractionalPercent* envoy_api_v2_core_RuntimeFractionalPercent_mutable_default_value(envoy_api_v2_core_RuntimeFractionalPercent *msg, upb_arena *arena) { + struct envoy_type_FractionalPercent* sub = (struct envoy_type_FractionalPercent*)envoy_api_v2_core_RuntimeFractionalPercent_default_value(msg); + if (sub == NULL) { + sub = (struct envoy_type_FractionalPercent*)upb_msg_new(&envoy_type_FractionalPercent_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_RuntimeFractionalPercent_set_default_value(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_RuntimeFractionalPercent_set_runtime_key(envoy_api_v2_core_RuntimeFractionalPercent *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_BASE_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c new file mode 100644 index 00000000000..a6dcd52d45b --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c @@ -0,0 +1,144 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/health_check.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/health_check.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/any.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/struct.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_core_HealthCheck_submsgs[15] = { + &envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit, + &envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit, + &envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit, + &envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit, + &google_protobuf_BoolValue_msginit, + &google_protobuf_Duration_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck__fields[17] = { + {1, UPB_SIZE(12, 24), 0, 5, 11, 1}, + {2, UPB_SIZE(16, 32), 0, 5, 11, 1}, + {3, UPB_SIZE(20, 40), 0, 5, 11, 1}, + {4, UPB_SIZE(24, 48), 0, 6, 11, 1}, + {5, UPB_SIZE(28, 56), 0, 6, 11, 1}, + {6, UPB_SIZE(32, 64), 0, 6, 11, 1}, + {7, UPB_SIZE(36, 72), 0, 4, 11, 1}, + {8, UPB_SIZE(56, 112), UPB_SIZE(-61, -121), 2, 11, 1}, + {9, UPB_SIZE(56, 112), UPB_SIZE(-61, -121), 3, 11, 1}, + {11, UPB_SIZE(56, 112), UPB_SIZE(-61, -121), 1, 11, 1}, + {12, UPB_SIZE(40, 80), 0, 5, 11, 1}, + {13, UPB_SIZE(56, 112), UPB_SIZE(-61, -121), 0, 11, 1}, + {14, UPB_SIZE(44, 88), 0, 5, 11, 1}, + {15, UPB_SIZE(48, 96), 0, 5, 11, 1}, + {16, UPB_SIZE(52, 104), 0, 5, 11, 1}, + {17, UPB_SIZE(4, 8), 0, 0, 9, 1}, + {18, UPB_SIZE(0, 0), 0, 0, 13, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_msginit = { + &envoy_api_v2_core_HealthCheck_submsgs[0], + &envoy_api_v2_core_HealthCheck__fields[0], + UPB_SIZE(64, 128), 17, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_Payload__fields[2] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 12, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_Payload_msginit = { + NULL, + &envoy_api_v2_core_HealthCheck_Payload__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_HealthCheck_HttpHealthCheck_submsgs[3] = { + &envoy_api_v2_core_HeaderValueOption_msginit, + &envoy_api_v2_core_HealthCheck_Payload_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_HttpHealthCheck__fields[8] = { + {1, UPB_SIZE(4, 8), 0, 0, 9, 1}, + {2, UPB_SIZE(12, 24), 0, 0, 9, 1}, + {3, UPB_SIZE(28, 56), 0, 1, 11, 1}, + {4, UPB_SIZE(32, 64), 0, 1, 11, 1}, + {5, UPB_SIZE(20, 40), 0, 0, 9, 1}, + {6, UPB_SIZE(36, 72), 0, 0, 11, 3}, + {7, UPB_SIZE(0, 0), 0, 0, 8, 1}, + {8, UPB_SIZE(40, 80), 0, 0, 9, 3}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit = { + &envoy_api_v2_core_HealthCheck_HttpHealthCheck_submsgs[0], + &envoy_api_v2_core_HealthCheck_HttpHealthCheck__fields[0], + UPB_SIZE(48, 96), 8, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_HealthCheck_TcpHealthCheck_submsgs[2] = { + &envoy_api_v2_core_HealthCheck_Payload_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_TcpHealthCheck__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit = { + &envoy_api_v2_core_HealthCheck_TcpHealthCheck_submsgs[0], + &envoy_api_v2_core_HealthCheck_TcpHealthCheck__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_RedisHealthCheck__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_RedisHealthCheck_msginit = { + NULL, + &envoy_api_v2_core_HealthCheck_RedisHealthCheck__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_GrpcHealthCheck__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit = { + NULL, + &envoy_api_v2_core_HealthCheck_GrpcHealthCheck__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_HealthCheck_CustomHealthCheck_submsgs[2] = { + &google_protobuf_Any_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HealthCheck_CustomHealthCheck__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit = { + &envoy_api_v2_core_HealthCheck_CustomHealthCheck_submsgs[0], + &envoy_api_v2_core_HealthCheck_CustomHealthCheck__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h new file mode 100644 index 00000000000..d788fea61c6 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h @@ -0,0 +1,559 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/health_check.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_HEALTH_CHECK_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_HEALTH_CHECK_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_HealthCheck; +struct envoy_api_v2_core_HealthCheck_Payload; +struct envoy_api_v2_core_HealthCheck_HttpHealthCheck; +struct envoy_api_v2_core_HealthCheck_TcpHealthCheck; +struct envoy_api_v2_core_HealthCheck_RedisHealthCheck; +struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck; +struct envoy_api_v2_core_HealthCheck_CustomHealthCheck; +typedef struct envoy_api_v2_core_HealthCheck envoy_api_v2_core_HealthCheck; +typedef struct envoy_api_v2_core_HealthCheck_Payload envoy_api_v2_core_HealthCheck_Payload; +typedef struct envoy_api_v2_core_HealthCheck_HttpHealthCheck envoy_api_v2_core_HealthCheck_HttpHealthCheck; +typedef struct envoy_api_v2_core_HealthCheck_TcpHealthCheck envoy_api_v2_core_HealthCheck_TcpHealthCheck; +typedef struct envoy_api_v2_core_HealthCheck_RedisHealthCheck envoy_api_v2_core_HealthCheck_RedisHealthCheck; +typedef struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck envoy_api_v2_core_HealthCheck_GrpcHealthCheck; +typedef struct envoy_api_v2_core_HealthCheck_CustomHealthCheck envoy_api_v2_core_HealthCheck_CustomHealthCheck; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_Payload_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_RedisHealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit; +struct google_protobuf_Any; +struct google_protobuf_Struct; +struct google_protobuf_UInt32Value; +struct google_protobuf_BoolValue; +struct google_protobuf_Duration; +struct envoy_api_v2_core_HeaderValueOption; +extern const upb_msglayout google_protobuf_Any_msginit; +extern const upb_msglayout google_protobuf_Struct_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout envoy_api_v2_core_HeaderValueOption_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_core_UNKNOWN = 0, + envoy_api_v2_core_HEALTHY = 1, + envoy_api_v2_core_UNHEALTHY = 2, + envoy_api_v2_core_DRAINING = 3, + envoy_api_v2_core_TIMEOUT = 4 +} envoy_api_v2_core_HealthStatus; + +/* envoy.api.v2.core.HealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck *envoy_api_v2_core_HealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck *envoy_api_v2_core_HealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck *ret = envoy_api_v2_core_HealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_serialize(const envoy_api_v2_core_HealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_HealthCheck_health_checker_http_health_check = 8, + envoy_api_v2_core_HealthCheck_health_checker_tcp_health_check = 9, + envoy_api_v2_core_HealthCheck_health_checker_grpc_health_check = 11, + envoy_api_v2_core_HealthCheck_health_checker_custom_health_check = 13, + envoy_api_v2_core_HealthCheck_health_checker_NOT_SET = 0, +} envoy_api_v2_core_HealthCheck_health_checker_oneofcases; +UPB_INLINE envoy_api_v2_core_HealthCheck_health_checker_oneofcases envoy_api_v2_core_HealthCheck_health_checker_case(const envoy_api_v2_core_HealthCheck* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(60, 120)); } + +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_timeout(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(12, 24)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_interval(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(16, 32)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_interval_jitter(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(20, 40)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_unhealthy_threshold(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(24, 48)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_healthy_threshold(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(28, 56)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_alt_port(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(32, 64)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_core_HealthCheck_reuse_connection(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(36, 72)); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_has_http_health_check(const envoy_api_v2_core_HealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(60, 120), 8); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_HttpHealthCheck* envoy_api_v2_core_HealthCheck_http_health_check(const envoy_api_v2_core_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_HealthCheck_HttpHealthCheck*, UPB_SIZE(56, 112), UPB_SIZE(60, 120), 8, NULL); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_has_tcp_health_check(const envoy_api_v2_core_HealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(60, 120), 9); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_TcpHealthCheck* envoy_api_v2_core_HealthCheck_tcp_health_check(const envoy_api_v2_core_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_HealthCheck_TcpHealthCheck*, UPB_SIZE(56, 112), UPB_SIZE(60, 120), 9, NULL); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_has_grpc_health_check(const envoy_api_v2_core_HealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(60, 120), 11); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_GrpcHealthCheck* envoy_api_v2_core_HealthCheck_grpc_health_check(const envoy_api_v2_core_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_HealthCheck_GrpcHealthCheck*, UPB_SIZE(56, 112), UPB_SIZE(60, 120), 11, NULL); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_no_traffic_interval(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(40, 80)); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_has_custom_health_check(const envoy_api_v2_core_HealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(60, 120), 13); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_CustomHealthCheck* envoy_api_v2_core_HealthCheck_custom_health_check(const envoy_api_v2_core_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_HealthCheck_CustomHealthCheck*, UPB_SIZE(56, 112), UPB_SIZE(60, 120), 13, NULL); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_unhealthy_interval(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(44, 88)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_unhealthy_edge_interval(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(48, 96)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_healthy_edge_interval(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(52, 104)); } +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_event_log_path(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE uint32_t envoy_api_v2_core_HealthCheck_interval_jitter_percent(const envoy_api_v2_core_HealthCheck *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_timeout(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_timeout(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_timeout(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_timeout(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_interval(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_interval(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_interval_jitter(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_interval_jitter(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_interval_jitter(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_interval_jitter(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_unhealthy_threshold(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_mutable_unhealthy_threshold(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_HealthCheck_unhealthy_threshold(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_unhealthy_threshold(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_healthy_threshold(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_mutable_healthy_threshold(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_HealthCheck_healthy_threshold(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_healthy_threshold(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_alt_port(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_HealthCheck_mutable_alt_port(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_HealthCheck_alt_port(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_alt_port(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_reuse_connection(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(36, 72)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_core_HealthCheck_mutable_reuse_connection(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_core_HealthCheck_reuse_connection(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_reuse_connection(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_http_health_check(envoy_api_v2_core_HealthCheck *msg, envoy_api_v2_core_HealthCheck_HttpHealthCheck* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_HealthCheck_HttpHealthCheck*, UPB_SIZE(56, 112), value, UPB_SIZE(60, 120), 8); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_HttpHealthCheck* envoy_api_v2_core_HealthCheck_mutable_http_health_check(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_HttpHealthCheck* sub = (struct envoy_api_v2_core_HealthCheck_HttpHealthCheck*)envoy_api_v2_core_HealthCheck_http_health_check(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_HttpHealthCheck*)upb_msg_new(&envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_http_health_check(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_tcp_health_check(envoy_api_v2_core_HealthCheck *msg, envoy_api_v2_core_HealthCheck_TcpHealthCheck* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_HealthCheck_TcpHealthCheck*, UPB_SIZE(56, 112), value, UPB_SIZE(60, 120), 9); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_TcpHealthCheck* envoy_api_v2_core_HealthCheck_mutable_tcp_health_check(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_TcpHealthCheck* sub = (struct envoy_api_v2_core_HealthCheck_TcpHealthCheck*)envoy_api_v2_core_HealthCheck_tcp_health_check(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_TcpHealthCheck*)upb_msg_new(&envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_tcp_health_check(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_grpc_health_check(envoy_api_v2_core_HealthCheck *msg, envoy_api_v2_core_HealthCheck_GrpcHealthCheck* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_HealthCheck_GrpcHealthCheck*, UPB_SIZE(56, 112), value, UPB_SIZE(60, 120), 11); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck* envoy_api_v2_core_HealthCheck_mutable_grpc_health_check(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck* sub = (struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck*)envoy_api_v2_core_HealthCheck_grpc_health_check(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_GrpcHealthCheck*)upb_msg_new(&envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_grpc_health_check(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_no_traffic_interval(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(40, 80)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_no_traffic_interval(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_no_traffic_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_no_traffic_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_custom_health_check(envoy_api_v2_core_HealthCheck *msg, envoy_api_v2_core_HealthCheck_CustomHealthCheck* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_HealthCheck_CustomHealthCheck*, UPB_SIZE(56, 112), value, UPB_SIZE(60, 120), 13); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_CustomHealthCheck* envoy_api_v2_core_HealthCheck_mutable_custom_health_check(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_CustomHealthCheck* sub = (struct envoy_api_v2_core_HealthCheck_CustomHealthCheck*)envoy_api_v2_core_HealthCheck_custom_health_check(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_CustomHealthCheck*)upb_msg_new(&envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_custom_health_check(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_unhealthy_interval(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(44, 88)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_unhealthy_interval(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_unhealthy_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_unhealthy_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_unhealthy_edge_interval(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(48, 96)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_unhealthy_edge_interval(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_unhealthy_edge_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_unhealthy_edge_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_healthy_edge_interval(envoy_api_v2_core_HealthCheck *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(52, 104)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HealthCheck_mutable_healthy_edge_interval(envoy_api_v2_core_HealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HealthCheck_healthy_edge_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_set_healthy_edge_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_event_log_path(envoy_api_v2_core_HealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_set_interval_jitter_percent(envoy_api_v2_core_HealthCheck *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.HealthCheck.Payload */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_Payload *envoy_api_v2_core_HealthCheck_Payload_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_Payload *)upb_msg_new(&envoy_api_v2_core_HealthCheck_Payload_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_Payload *envoy_api_v2_core_HealthCheck_Payload_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_Payload *ret = envoy_api_v2_core_HealthCheck_Payload_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_Payload_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_Payload_serialize(const envoy_api_v2_core_HealthCheck_Payload *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_Payload_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_HealthCheck_Payload_payload_text = 1, + envoy_api_v2_core_HealthCheck_Payload_payload_binary = 2, + envoy_api_v2_core_HealthCheck_Payload_payload_NOT_SET = 0, +} envoy_api_v2_core_HealthCheck_Payload_payload_oneofcases; +UPB_INLINE envoy_api_v2_core_HealthCheck_Payload_payload_oneofcases envoy_api_v2_core_HealthCheck_Payload_payload_case(const envoy_api_v2_core_HealthCheck_Payload* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } + +UPB_INLINE bool envoy_api_v2_core_HealthCheck_Payload_has_text(const envoy_api_v2_core_HealthCheck_Payload *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_Payload_text(const envoy_api_v2_core_HealthCheck_Payload *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_Payload_has_binary(const envoy_api_v2_core_HealthCheck_Payload *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_Payload_binary(const envoy_api_v2_core_HealthCheck_Payload *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, upb_strview_make("", strlen(""))); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_Payload_set_text(envoy_api_v2_core_HealthCheck_Payload *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_Payload_set_binary(envoy_api_v2_core_HealthCheck_Payload *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); +} + + +/* envoy.api.v2.core.HealthCheck.HttpHealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_HttpHealthCheck *envoy_api_v2_core_HealthCheck_HttpHealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_HttpHealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_HttpHealthCheck *envoy_api_v2_core_HealthCheck_HttpHealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_HttpHealthCheck *ret = envoy_api_v2_core_HealthCheck_HttpHealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_HttpHealthCheck_serialize(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_HttpHealthCheck_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_HttpHealthCheck_host(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_HttpHealthCheck_path(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_HttpHealthCheck_send(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(28, 56)); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_HttpHealthCheck_receive(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(32, 64)); } +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_HttpHealthCheck_service_name(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); } +UPB_INLINE const struct envoy_api_v2_core_HeaderValueOption* const* envoy_api_v2_core_HealthCheck_HttpHealthCheck_request_headers_to_add(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t *len) { return (const struct envoy_api_v2_core_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_HttpHealthCheck_use_http2(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview const* envoy_api_v2_core_HealthCheck_HttpHealthCheck_request_headers_to_remove(const envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_host(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_path(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_send(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, envoy_api_v2_core_HealthCheck_Payload* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_HttpHealthCheck_mutable_send(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_Payload* sub = (struct envoy_api_v2_core_HealthCheck_Payload*)envoy_api_v2_core_HealthCheck_HttpHealthCheck_send(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_Payload*)upb_msg_new(&envoy_api_v2_core_HealthCheck_Payload_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_send(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_receive(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, envoy_api_v2_core_HealthCheck_Payload* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_HttpHealthCheck_mutable_receive(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_Payload* sub = (struct envoy_api_v2_core_HealthCheck_Payload*)envoy_api_v2_core_HealthCheck_HttpHealthCheck_receive(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_Payload*)upb_msg_new(&envoy_api_v2_core_HealthCheck_Payload_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_receive(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_service_name(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HeaderValueOption** envoy_api_v2_core_HealthCheck_HttpHealthCheck_mutable_request_headers_to_add(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t *len) { + return (struct envoy_api_v2_core_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len); +} +UPB_INLINE struct envoy_api_v2_core_HeaderValueOption** envoy_api_v2_core_HealthCheck_HttpHealthCheck_resize_request_headers_to_add(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_HeaderValueOption* envoy_api_v2_core_HealthCheck_HttpHealthCheck_add_request_headers_to_add(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HeaderValueOption* sub = (struct envoy_api_v2_core_HeaderValueOption*)upb_msg_new(&envoy_api_v2_core_HeaderValueOption_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_HttpHealthCheck_set_use_http2(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE upb_strview* envoy_api_v2_core_HealthCheck_HttpHealthCheck_mutable_request_headers_to_remove(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len); +} +UPB_INLINE upb_strview* envoy_api_v2_core_HealthCheck_HttpHealthCheck_resize_request_headers_to_remove(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_core_HealthCheck_HttpHealthCheck_add_request_headers_to_remove(envoy_api_v2_core_HealthCheck_HttpHealthCheck *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(40, 80), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* envoy.api.v2.core.HealthCheck.TcpHealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_TcpHealthCheck *envoy_api_v2_core_HealthCheck_TcpHealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_TcpHealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_TcpHealthCheck *envoy_api_v2_core_HealthCheck_TcpHealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_TcpHealthCheck *ret = envoy_api_v2_core_HealthCheck_TcpHealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_TcpHealthCheck_serialize(const envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_TcpHealthCheck_send(const envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_core_HealthCheck_Payload* const* envoy_api_v2_core_HealthCheck_TcpHealthCheck_receive(const envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, size_t *len) { return (const envoy_api_v2_core_HealthCheck_Payload* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_TcpHealthCheck_set_send(envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, envoy_api_v2_core_HealthCheck_Payload* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_HealthCheck_Payload*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_TcpHealthCheck_mutable_send(envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_Payload* sub = (struct envoy_api_v2_core_HealthCheck_Payload*)envoy_api_v2_core_HealthCheck_TcpHealthCheck_send(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HealthCheck_Payload*)upb_msg_new(&envoy_api_v2_core_HealthCheck_Payload_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_TcpHealthCheck_set_send(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_core_HealthCheck_Payload** envoy_api_v2_core_HealthCheck_TcpHealthCheck_mutable_receive(envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, size_t *len) { + return (envoy_api_v2_core_HealthCheck_Payload**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_Payload** envoy_api_v2_core_HealthCheck_TcpHealthCheck_resize_receive(envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_Payload**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck_Payload* envoy_api_v2_core_HealthCheck_TcpHealthCheck_add_receive(envoy_api_v2_core_HealthCheck_TcpHealthCheck *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck_Payload* sub = (struct envoy_api_v2_core_HealthCheck_Payload*)upb_msg_new(&envoy_api_v2_core_HealthCheck_Payload_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.core.HealthCheck.RedisHealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_RedisHealthCheck *envoy_api_v2_core_HealthCheck_RedisHealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_RedisHealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_RedisHealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_RedisHealthCheck *envoy_api_v2_core_HealthCheck_RedisHealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_RedisHealthCheck *ret = envoy_api_v2_core_HealthCheck_RedisHealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_RedisHealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_RedisHealthCheck_serialize(const envoy_api_v2_core_HealthCheck_RedisHealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_RedisHealthCheck_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_RedisHealthCheck_key(const envoy_api_v2_core_HealthCheck_RedisHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_RedisHealthCheck_set_key(envoy_api_v2_core_HealthCheck_RedisHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.HealthCheck.GrpcHealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_GrpcHealthCheck *envoy_api_v2_core_HealthCheck_GrpcHealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_GrpcHealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_GrpcHealthCheck *envoy_api_v2_core_HealthCheck_GrpcHealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_GrpcHealthCheck *ret = envoy_api_v2_core_HealthCheck_GrpcHealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_GrpcHealthCheck_serialize(const envoy_api_v2_core_HealthCheck_GrpcHealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_GrpcHealthCheck_service_name(const envoy_api_v2_core_HealthCheck_GrpcHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_GrpcHealthCheck_set_service_name(envoy_api_v2_core_HealthCheck_GrpcHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.HealthCheck.CustomHealthCheck */ + +UPB_INLINE envoy_api_v2_core_HealthCheck_CustomHealthCheck *envoy_api_v2_core_HealthCheck_CustomHealthCheck_new(upb_arena *arena) { + return (envoy_api_v2_core_HealthCheck_CustomHealthCheck *)upb_msg_new(&envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HealthCheck_CustomHealthCheck *envoy_api_v2_core_HealthCheck_CustomHealthCheck_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HealthCheck_CustomHealthCheck *ret = envoy_api_v2_core_HealthCheck_CustomHealthCheck_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HealthCheck_CustomHealthCheck_serialize(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_config = 2, + envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_typed_config = 3, + envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_NOT_SET = 0, +} envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_oneofcases; +UPB_INLINE envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_oneofcases envoy_api_v2_core_HealthCheck_CustomHealthCheck_config_type_case(const envoy_api_v2_core_HealthCheck_CustomHealthCheck* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE upb_strview envoy_api_v2_core_HealthCheck_CustomHealthCheck_name(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_CustomHealthCheck_has_config(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_HealthCheck_CustomHealthCheck_config(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Struct*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_HealthCheck_CustomHealthCheck_has_typed_config(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 3); } +UPB_INLINE const struct google_protobuf_Any* envoy_api_v2_core_HealthCheck_CustomHealthCheck_typed_config(const envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Any*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 3, NULL); } + +UPB_INLINE void envoy_api_v2_core_HealthCheck_CustomHealthCheck_set_name(envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_CustomHealthCheck_set_config(envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, struct google_protobuf_Struct* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Struct*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_HealthCheck_CustomHealthCheck_mutable_config(envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_HealthCheck_CustomHealthCheck_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_CustomHealthCheck_set_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_HealthCheck_CustomHealthCheck_set_typed_config(envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, struct google_protobuf_Any* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Any*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 3); +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_core_HealthCheck_CustomHealthCheck_mutable_typed_config(envoy_api_v2_core_HealthCheck_CustomHealthCheck *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_api_v2_core_HealthCheck_CustomHealthCheck_typed_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HealthCheck_CustomHealthCheck_set_typed_config(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_HEALTH_CHECK_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c b/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c new file mode 100644 index 00000000000..2f67f55a8a3 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c @@ -0,0 +1,123 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/discovery.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/discovery.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/any.upb.h" +#include "google/rpc/status.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_DiscoveryRequest_submsgs[2] = { + &envoy_api_v2_core_Node_msginit, + &google_rpc_Status_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_DiscoveryRequest__fields[6] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(24, 48), 0, 0, 11, 1}, + {3, UPB_SIZE(32, 64), 0, 0, 9, 3}, + {4, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {5, UPB_SIZE(16, 32), 0, 0, 9, 1}, + {6, UPB_SIZE(28, 56), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_DiscoveryRequest_msginit = { + &envoy_api_v2_DiscoveryRequest_submsgs[0], + &envoy_api_v2_DiscoveryRequest__fields[0], + UPB_SIZE(40, 80), 6, false, +}; + +static const upb_msglayout *const envoy_api_v2_DiscoveryResponse_submsgs[1] = { + &google_protobuf_Any_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_DiscoveryResponse__fields[5] = { + {1, UPB_SIZE(4, 8), 0, 0, 9, 1}, + {2, UPB_SIZE(28, 56), 0, 0, 11, 3}, + {3, UPB_SIZE(0, 0), 0, 0, 8, 1}, + {4, UPB_SIZE(12, 24), 0, 0, 9, 1}, + {5, UPB_SIZE(20, 40), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_DiscoveryResponse_msginit = { + &envoy_api_v2_DiscoveryResponse_submsgs[0], + &envoy_api_v2_DiscoveryResponse__fields[0], + UPB_SIZE(32, 64), 5, false, +}; + +static const upb_msglayout *const envoy_api_v2_IncrementalDiscoveryRequest_submsgs[3] = { + &envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit, + &envoy_api_v2_core_Node_msginit, + &google_rpc_Status_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_IncrementalDiscoveryRequest__fields[7] = { + {1, UPB_SIZE(16, 32), 0, 1, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {3, UPB_SIZE(24, 48), 0, 0, 9, 3}, + {4, UPB_SIZE(28, 56), 0, 0, 9, 3}, + {5, UPB_SIZE(32, 64), 0, 0, 11, 3}, + {6, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {7, UPB_SIZE(20, 40), 0, 2, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_IncrementalDiscoveryRequest_msginit = { + &envoy_api_v2_IncrementalDiscoveryRequest_submsgs[0], + &envoy_api_v2_IncrementalDiscoveryRequest__fields[0], + UPB_SIZE(40, 80), 7, false, +}; + +static const upb_msglayout_field envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit = { + NULL, + &envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_IncrementalDiscoveryResponse_submsgs[1] = { + &envoy_api_v2_Resource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_IncrementalDiscoveryResponse__fields[4] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(16, 32), 0, 0, 11, 3}, + {5, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {6, UPB_SIZE(20, 40), 0, 0, 9, 3}, +}; + +const upb_msglayout envoy_api_v2_IncrementalDiscoveryResponse_msginit = { + &envoy_api_v2_IncrementalDiscoveryResponse_submsgs[0], + &envoy_api_v2_IncrementalDiscoveryResponse__fields[0], + UPB_SIZE(24, 48), 4, false, +}; + +static const upb_msglayout *const envoy_api_v2_Resource_submsgs[1] = { + &google_protobuf_Any_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Resource__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Resource_msginit = { + &envoy_api_v2_Resource_submsgs[0], + &envoy_api_v2_Resource__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h b/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h new file mode 100644 index 00000000000..a437ebaad5c --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h @@ -0,0 +1,359 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/discovery.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_DISCOVERY_PROTO_UPB_H_ +#define ENVOY_API_V2_DISCOVERY_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_DiscoveryRequest; +struct envoy_api_v2_DiscoveryResponse; +struct envoy_api_v2_IncrementalDiscoveryRequest; +struct envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry; +struct envoy_api_v2_IncrementalDiscoveryResponse; +struct envoy_api_v2_Resource; +typedef struct envoy_api_v2_DiscoveryRequest envoy_api_v2_DiscoveryRequest; +typedef struct envoy_api_v2_DiscoveryResponse envoy_api_v2_DiscoveryResponse; +typedef struct envoy_api_v2_IncrementalDiscoveryRequest envoy_api_v2_IncrementalDiscoveryRequest; +typedef struct envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry; +typedef struct envoy_api_v2_IncrementalDiscoveryResponse envoy_api_v2_IncrementalDiscoveryResponse; +typedef struct envoy_api_v2_Resource envoy_api_v2_Resource; +extern const upb_msglayout envoy_api_v2_DiscoveryRequest_msginit; +extern const upb_msglayout envoy_api_v2_DiscoveryResponse_msginit; +extern const upb_msglayout envoy_api_v2_IncrementalDiscoveryRequest_msginit; +extern const upb_msglayout envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit; +extern const upb_msglayout envoy_api_v2_IncrementalDiscoveryResponse_msginit; +extern const upb_msglayout envoy_api_v2_Resource_msginit; +struct google_protobuf_Any; +struct envoy_api_v2_core_Node; +struct google_rpc_Status; +extern const upb_msglayout google_protobuf_Any_msginit; +extern const upb_msglayout envoy_api_v2_core_Node_msginit; +extern const upb_msglayout google_rpc_Status_msginit; + +/* Enums */ + +/* envoy.api.v2.DiscoveryRequest */ + +UPB_INLINE envoy_api_v2_DiscoveryRequest *envoy_api_v2_DiscoveryRequest_new(upb_arena *arena) { + return (envoy_api_v2_DiscoveryRequest *)upb_msg_new(&envoy_api_v2_DiscoveryRequest_msginit, arena); +} +UPB_INLINE envoy_api_v2_DiscoveryRequest *envoy_api_v2_DiscoveryRequest_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_DiscoveryRequest *ret = envoy_api_v2_DiscoveryRequest_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_DiscoveryRequest_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_DiscoveryRequest_serialize(const envoy_api_v2_DiscoveryRequest *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_DiscoveryRequest_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_DiscoveryRequest_version_info(const envoy_api_v2_DiscoveryRequest *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_Node* envoy_api_v2_DiscoveryRequest_node(const envoy_api_v2_DiscoveryRequest *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Node*, UPB_SIZE(24, 48)); } +UPB_INLINE upb_strview const* envoy_api_v2_DiscoveryRequest_resource_names(const envoy_api_v2_DiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); } +UPB_INLINE upb_strview envoy_api_v2_DiscoveryRequest_type_url(const envoy_api_v2_DiscoveryRequest *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview envoy_api_v2_DiscoveryRequest_response_nonce(const envoy_api_v2_DiscoveryRequest *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)); } +UPB_INLINE const struct google_rpc_Status* envoy_api_v2_DiscoveryRequest_error_detail(const envoy_api_v2_DiscoveryRequest *msg) { return UPB_FIELD_AT(msg, const struct google_rpc_Status*, UPB_SIZE(28, 56)); } + +UPB_INLINE void envoy_api_v2_DiscoveryRequest_set_version_info(envoy_api_v2_DiscoveryRequest *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_DiscoveryRequest_set_node(envoy_api_v2_DiscoveryRequest *msg, struct envoy_api_v2_core_Node* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Node*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Node* envoy_api_v2_DiscoveryRequest_mutable_node(envoy_api_v2_DiscoveryRequest *msg, upb_arena *arena) { + struct envoy_api_v2_core_Node* sub = (struct envoy_api_v2_core_Node*)envoy_api_v2_DiscoveryRequest_node(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Node*)upb_msg_new(&envoy_api_v2_core_Node_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_DiscoveryRequest_set_node(msg, sub); + } + return sub; +} +UPB_INLINE upb_strview* envoy_api_v2_DiscoveryRequest_mutable_resource_names(envoy_api_v2_DiscoveryRequest *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len); +} +UPB_INLINE upb_strview* envoy_api_v2_DiscoveryRequest_resize_resource_names(envoy_api_v2_DiscoveryRequest *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_DiscoveryRequest_add_resource_names(envoy_api_v2_DiscoveryRequest *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(32, 64), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE void envoy_api_v2_DiscoveryRequest_set_type_url(envoy_api_v2_DiscoveryRequest *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void envoy_api_v2_DiscoveryRequest_set_response_nonce(envoy_api_v2_DiscoveryRequest *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void envoy_api_v2_DiscoveryRequest_set_error_detail(envoy_api_v2_DiscoveryRequest *msg, struct google_rpc_Status* value) { + UPB_FIELD_AT(msg, struct google_rpc_Status*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_rpc_Status* envoy_api_v2_DiscoveryRequest_mutable_error_detail(envoy_api_v2_DiscoveryRequest *msg, upb_arena *arena) { + struct google_rpc_Status* sub = (struct google_rpc_Status*)envoy_api_v2_DiscoveryRequest_error_detail(msg); + if (sub == NULL) { + sub = (struct google_rpc_Status*)upb_msg_new(&google_rpc_Status_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_DiscoveryRequest_set_error_detail(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.DiscoveryResponse */ + +UPB_INLINE envoy_api_v2_DiscoveryResponse *envoy_api_v2_DiscoveryResponse_new(upb_arena *arena) { + return (envoy_api_v2_DiscoveryResponse *)upb_msg_new(&envoy_api_v2_DiscoveryResponse_msginit, arena); +} +UPB_INLINE envoy_api_v2_DiscoveryResponse *envoy_api_v2_DiscoveryResponse_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_DiscoveryResponse *ret = envoy_api_v2_DiscoveryResponse_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_DiscoveryResponse_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_DiscoveryResponse_serialize(const envoy_api_v2_DiscoveryResponse *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_DiscoveryResponse_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_DiscoveryResponse_version_info(const envoy_api_v2_DiscoveryResponse *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_Any* const* envoy_api_v2_DiscoveryResponse_resources(const envoy_api_v2_DiscoveryResponse *msg, size_t *len) { return (const struct google_protobuf_Any* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } +UPB_INLINE bool envoy_api_v2_DiscoveryResponse_canary(const envoy_api_v2_DiscoveryResponse *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_DiscoveryResponse_type_url(const envoy_api_v2_DiscoveryResponse *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); } +UPB_INLINE upb_strview envoy_api_v2_DiscoveryResponse_nonce(const envoy_api_v2_DiscoveryResponse *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); } + +UPB_INLINE void envoy_api_v2_DiscoveryResponse_set_version_info(envoy_api_v2_DiscoveryResponse *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_Any** envoy_api_v2_DiscoveryResponse_mutable_resources(envoy_api_v2_DiscoveryResponse *msg, size_t *len) { + return (struct google_protobuf_Any**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE struct google_protobuf_Any** envoy_api_v2_DiscoveryResponse_resize_resources(envoy_api_v2_DiscoveryResponse *msg, size_t len, upb_arena *arena) { + return (struct google_protobuf_Any**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_DiscoveryResponse_add_resources(envoy_api_v2_DiscoveryResponse *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_DiscoveryResponse_set_canary(envoy_api_v2_DiscoveryResponse *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_DiscoveryResponse_set_type_url(envoy_api_v2_DiscoveryResponse *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE void envoy_api_v2_DiscoveryResponse_set_nonce(envoy_api_v2_DiscoveryResponse *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value; +} + + +/* envoy.api.v2.IncrementalDiscoveryRequest */ + +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest *envoy_api_v2_IncrementalDiscoveryRequest_new(upb_arena *arena) { + return (envoy_api_v2_IncrementalDiscoveryRequest *)upb_msg_new(&envoy_api_v2_IncrementalDiscoveryRequest_msginit, arena); +} +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest *envoy_api_v2_IncrementalDiscoveryRequest_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_IncrementalDiscoveryRequest *ret = envoy_api_v2_IncrementalDiscoveryRequest_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_IncrementalDiscoveryRequest_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_IncrementalDiscoveryRequest_serialize(const envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_IncrementalDiscoveryRequest_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_Node* envoy_api_v2_IncrementalDiscoveryRequest_node(const envoy_api_v2_IncrementalDiscoveryRequest *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Node*, UPB_SIZE(16, 32)); } +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryRequest_type_url(const envoy_api_v2_IncrementalDiscoveryRequest *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview const* envoy_api_v2_IncrementalDiscoveryRequest_resource_names_subscribe(const envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE upb_strview const* envoy_api_v2_IncrementalDiscoveryRequest_resource_names_unsubscribe(const envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } +UPB_INLINE const envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry* const* envoy_api_v2_IncrementalDiscoveryRequest_initial_resource_versions(const envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { return (const envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); } +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryRequest_response_nonce(const envoy_api_v2_IncrementalDiscoveryRequest *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE const struct google_rpc_Status* envoy_api_v2_IncrementalDiscoveryRequest_error_detail(const envoy_api_v2_IncrementalDiscoveryRequest *msg) { return UPB_FIELD_AT(msg, const struct google_rpc_Status*, UPB_SIZE(20, 40)); } + +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_set_node(envoy_api_v2_IncrementalDiscoveryRequest *msg, struct envoy_api_v2_core_Node* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Node*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Node* envoy_api_v2_IncrementalDiscoveryRequest_mutable_node(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_arena *arena) { + struct envoy_api_v2_core_Node* sub = (struct envoy_api_v2_core_Node*)envoy_api_v2_IncrementalDiscoveryRequest_node(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Node*)upb_msg_new(&envoy_api_v2_core_Node_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_IncrementalDiscoveryRequest_set_node(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_set_type_url(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryRequest_mutable_resource_names_subscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryRequest_resize_resource_names_subscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_IncrementalDiscoveryRequest_add_resource_names_subscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryRequest_mutable_resource_names_unsubscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryRequest_resize_resource_names_unsubscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_IncrementalDiscoveryRequest_add_resource_names_unsubscribe(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry** envoy_api_v2_IncrementalDiscoveryRequest_mutable_initial_resource_versions(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t *len) { + return (envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len); +} +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry** envoy_api_v2_IncrementalDiscoveryRequest_resize_initial_resource_versions(envoy_api_v2_IncrementalDiscoveryRequest *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry* envoy_api_v2_IncrementalDiscoveryRequest_add_initial_resource_versions(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_arena *arena) { + struct envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry* sub = (struct envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry*)upb_msg_new(&envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_set_response_nonce(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_set_error_detail(envoy_api_v2_IncrementalDiscoveryRequest *msg, struct google_rpc_Status* value) { + UPB_FIELD_AT(msg, struct google_rpc_Status*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE struct google_rpc_Status* envoy_api_v2_IncrementalDiscoveryRequest_mutable_error_detail(envoy_api_v2_IncrementalDiscoveryRequest *msg, upb_arena *arena) { + struct google_rpc_Status* sub = (struct google_rpc_Status*)envoy_api_v2_IncrementalDiscoveryRequest_error_detail(msg); + if (sub == NULL) { + sub = (struct google_rpc_Status*)upb_msg_new(&google_rpc_Status_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_IncrementalDiscoveryRequest_set_error_detail(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.IncrementalDiscoveryRequest.InitialResourceVersionsEntry */ + +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_new(upb_arena *arena) { + return (envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *)upb_msg_new(&envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit, arena); +} +UPB_INLINE envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *ret = envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_serialize(const envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_key(const envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_value(const envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_set_key(envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_set_value(envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} + + +/* envoy.api.v2.IncrementalDiscoveryResponse */ + +UPB_INLINE envoy_api_v2_IncrementalDiscoveryResponse *envoy_api_v2_IncrementalDiscoveryResponse_new(upb_arena *arena) { + return (envoy_api_v2_IncrementalDiscoveryResponse *)upb_msg_new(&envoy_api_v2_IncrementalDiscoveryResponse_msginit, arena); +} +UPB_INLINE envoy_api_v2_IncrementalDiscoveryResponse *envoy_api_v2_IncrementalDiscoveryResponse_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_IncrementalDiscoveryResponse *ret = envoy_api_v2_IncrementalDiscoveryResponse_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_IncrementalDiscoveryResponse_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_IncrementalDiscoveryResponse_serialize(const envoy_api_v2_IncrementalDiscoveryResponse *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_IncrementalDiscoveryResponse_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryResponse_system_version_info(const envoy_api_v2_IncrementalDiscoveryResponse *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_Resource* const* envoy_api_v2_IncrementalDiscoveryResponse_resources(const envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t *len) { return (const envoy_api_v2_Resource* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } +UPB_INLINE upb_strview envoy_api_v2_IncrementalDiscoveryResponse_nonce(const envoy_api_v2_IncrementalDiscoveryResponse *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview const* envoy_api_v2_IncrementalDiscoveryResponse_removed_resources(const envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } + +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryResponse_set_system_version_info(envoy_api_v2_IncrementalDiscoveryResponse *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE envoy_api_v2_Resource** envoy_api_v2_IncrementalDiscoveryResponse_mutable_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t *len) { + return (envoy_api_v2_Resource**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); +} +UPB_INLINE envoy_api_v2_Resource** envoy_api_v2_IncrementalDiscoveryResponse_resize_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_Resource**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_Resource* envoy_api_v2_IncrementalDiscoveryResponse_add_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, upb_arena *arena) { + struct envoy_api_v2_Resource* sub = (struct envoy_api_v2_Resource*)upb_msg_new(&envoy_api_v2_Resource_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_IncrementalDiscoveryResponse_set_nonce(envoy_api_v2_IncrementalDiscoveryResponse *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryResponse_mutable_removed_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); +} +UPB_INLINE upb_strview* envoy_api_v2_IncrementalDiscoveryResponse_resize_removed_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_IncrementalDiscoveryResponse_add_removed_resources(envoy_api_v2_IncrementalDiscoveryResponse *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 40), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* envoy.api.v2.Resource */ + +UPB_INLINE envoy_api_v2_Resource *envoy_api_v2_Resource_new(upb_arena *arena) { + return (envoy_api_v2_Resource *)upb_msg_new(&envoy_api_v2_Resource_msginit, arena); +} +UPB_INLINE envoy_api_v2_Resource *envoy_api_v2_Resource_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Resource *ret = envoy_api_v2_Resource_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Resource_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Resource_serialize(const envoy_api_v2_Resource *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Resource_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_Resource_version(const envoy_api_v2_Resource *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Any* envoy_api_v2_Resource_resource(const envoy_api_v2_Resource *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Any*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_Resource_set_version(envoy_api_v2_Resource *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_Resource_set_resource(envoy_api_v2_Resource *msg, struct google_protobuf_Any* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Any*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_Resource_mutable_resource(envoy_api_v2_Resource *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_api_v2_Resource_resource(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Resource_set_resource(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_DISCOVERY_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/type/percent.upb.c b/src/core/ext/upb-generated/envoy/type/percent.upb.c new file mode 100644 index 00000000000..0ef0ae176e2 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/type/percent.upb.c @@ -0,0 +1,39 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/type/percent.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/type/percent.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field envoy_type_Percent__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 1, 1}, +}; + +const upb_msglayout envoy_type_Percent_msginit = { + NULL, + &envoy_type_Percent__fields[0], + UPB_SIZE(8, 8), 1, false, +}; + +static const upb_msglayout_field envoy_type_FractionalPercent__fields[2] = { + {1, UPB_SIZE(8, 8), 0, 0, 13, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 14, 1}, +}; + +const upb_msglayout envoy_type_FractionalPercent_msginit = { + NULL, + &envoy_type_FractionalPercent__fields[0], + UPB_SIZE(16, 16), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/type/percent.upb.h b/src/core/ext/upb-generated/envoy/type/percent.upb.h new file mode 100644 index 00000000000..6fa665a2de9 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/type/percent.upb.h @@ -0,0 +1,88 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/type/percent.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_TYPE_PERCENT_PROTO_UPB_H_ +#define ENVOY_TYPE_PERCENT_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_type_Percent; +struct envoy_type_FractionalPercent; +typedef struct envoy_type_Percent envoy_type_Percent; +typedef struct envoy_type_FractionalPercent envoy_type_FractionalPercent; +extern const upb_msglayout envoy_type_Percent_msginit; +extern const upb_msglayout envoy_type_FractionalPercent_msginit; + +/* Enums */ + +typedef enum { + envoy_type_FractionalPercent_HUNDRED = 0, + envoy_type_FractionalPercent_TEN_THOUSAND = 1, + envoy_type_FractionalPercent_MILLION = 2 +} envoy_type_FractionalPercent_DenominatorType; + +/* envoy.type.Percent */ + +UPB_INLINE envoy_type_Percent *envoy_type_Percent_new(upb_arena *arena) { + return (envoy_type_Percent *)upb_msg_new(&envoy_type_Percent_msginit, arena); +} +UPB_INLINE envoy_type_Percent *envoy_type_Percent_parsenew(upb_strview buf, upb_arena *arena) { + envoy_type_Percent *ret = envoy_type_Percent_new(arena); + return (ret && upb_decode(buf, ret, &envoy_type_Percent_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_type_Percent_serialize(const envoy_type_Percent *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_type_Percent_msginit, arena, len); +} + +UPB_INLINE double envoy_type_Percent_value(const envoy_type_Percent *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_type_Percent_set_value(envoy_type_Percent *msg, double value) { + UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.type.FractionalPercent */ + +UPB_INLINE envoy_type_FractionalPercent *envoy_type_FractionalPercent_new(upb_arena *arena) { + return (envoy_type_FractionalPercent *)upb_msg_new(&envoy_type_FractionalPercent_msginit, arena); +} +UPB_INLINE envoy_type_FractionalPercent *envoy_type_FractionalPercent_parsenew(upb_strview buf, upb_arena *arena) { + envoy_type_FractionalPercent *ret = envoy_type_FractionalPercent_new(arena); + return (ret && upb_decode(buf, ret, &envoy_type_FractionalPercent_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_type_FractionalPercent_serialize(const envoy_type_FractionalPercent *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_type_FractionalPercent_msginit, arena, len); +} + +UPB_INLINE uint32_t envoy_type_FractionalPercent_numerator(const envoy_type_FractionalPercent *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)); } +UPB_INLINE envoy_type_FractionalPercent_DenominatorType envoy_type_FractionalPercent_denominator(const envoy_type_FractionalPercent *msg) { return UPB_FIELD_AT(msg, envoy_type_FractionalPercent_DenominatorType, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_type_FractionalPercent_set_numerator(envoy_type_FractionalPercent *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void envoy_type_FractionalPercent_set_denominator(envoy_type_FractionalPercent *msg, envoy_type_FractionalPercent_DenominatorType value) { + UPB_FIELD_AT(msg, envoy_type_FractionalPercent_DenominatorType, UPB_SIZE(0, 0)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_TYPE_PERCENT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/type/range.upb.c b/src/core/ext/upb-generated/envoy/type/range.upb.c new file mode 100644 index 00000000000..2e71b82611e --- /dev/null +++ b/src/core/ext/upb-generated/envoy/type/range.upb.c @@ -0,0 +1,39 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/type/range.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/type/range.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field envoy_type_Int64Range__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 3, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 3, 1}, +}; + +const upb_msglayout envoy_type_Int64Range_msginit = { + NULL, + &envoy_type_Int64Range__fields[0], + UPB_SIZE(16, 16), 2, false, +}; + +static const upb_msglayout_field envoy_type_DoubleRange__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 1, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 1, 1}, +}; + +const upb_msglayout envoy_type_DoubleRange_msginit = { + NULL, + &envoy_type_DoubleRange__fields[0], + UPB_SIZE(16, 16), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/type/range.upb.h b/src/core/ext/upb-generated/envoy/type/range.upb.h new file mode 100644 index 00000000000..c036ee66a95 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/type/range.upb.h @@ -0,0 +1,86 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/type/range.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_TYPE_RANGE_PROTO_UPB_H_ +#define ENVOY_TYPE_RANGE_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_type_Int64Range; +struct envoy_type_DoubleRange; +typedef struct envoy_type_Int64Range envoy_type_Int64Range; +typedef struct envoy_type_DoubleRange envoy_type_DoubleRange; +extern const upb_msglayout envoy_type_Int64Range_msginit; +extern const upb_msglayout envoy_type_DoubleRange_msginit; + +/* Enums */ + +/* envoy.type.Int64Range */ + +UPB_INLINE envoy_type_Int64Range *envoy_type_Int64Range_new(upb_arena *arena) { + return (envoy_type_Int64Range *)upb_msg_new(&envoy_type_Int64Range_msginit, arena); +} +UPB_INLINE envoy_type_Int64Range *envoy_type_Int64Range_parsenew(upb_strview buf, upb_arena *arena) { + envoy_type_Int64Range *ret = envoy_type_Int64Range_new(arena); + return (ret && upb_decode(buf, ret, &envoy_type_Int64Range_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_type_Int64Range_serialize(const envoy_type_Int64Range *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_type_Int64Range_msginit, arena, len); +} + +UPB_INLINE int64_t envoy_type_Int64Range_start(const envoy_type_Int64Range *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } +UPB_INLINE int64_t envoy_type_Int64Range_end(const envoy_type_Int64Range *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)); } + +UPB_INLINE void envoy_type_Int64Range_set_start(envoy_type_Int64Range *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_type_Int64Range_set_end(envoy_type_Int64Range *msg, int64_t value) { + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)) = value; +} + + +/* envoy.type.DoubleRange */ + +UPB_INLINE envoy_type_DoubleRange *envoy_type_DoubleRange_new(upb_arena *arena) { + return (envoy_type_DoubleRange *)upb_msg_new(&envoy_type_DoubleRange_msginit, arena); +} +UPB_INLINE envoy_type_DoubleRange *envoy_type_DoubleRange_parsenew(upb_strview buf, upb_arena *arena) { + envoy_type_DoubleRange *ret = envoy_type_DoubleRange_new(arena); + return (ret && upb_decode(buf, ret, &envoy_type_DoubleRange_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_type_DoubleRange_serialize(const envoy_type_DoubleRange *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_type_DoubleRange_msginit, arena, len); +} + +UPB_INLINE double envoy_type_DoubleRange_start(const envoy_type_DoubleRange *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)); } +UPB_INLINE double envoy_type_DoubleRange_end(const envoy_type_DoubleRange *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)); } + +UPB_INLINE void envoy_type_DoubleRange_set_start(envoy_type_DoubleRange *msg, double value) { + UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_type_DoubleRange_set_end(envoy_type_DoubleRange *msg, double value) { + UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_TYPE_RANGE_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/gogoproto/gogo.upb.c b/src/core/ext/upb-generated/gogoproto/gogo.upb.c new file mode 100644 index 00000000000..7517fdcbbe8 --- /dev/null +++ b/src/core/ext/upb-generated/gogoproto/gogo.upb.c @@ -0,0 +1,17 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * gogoproto/gogo.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "gogoproto/gogo.upb.h" +#include "google/protobuf/descriptor.upb.h" + +#include "upb/port_def.inc" + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/gogoproto/gogo.upb.h b/src/core/ext/upb-generated/gogoproto/gogo.upb.h new file mode 100644 index 00000000000..313d6fa644e --- /dev/null +++ b/src/core/ext/upb-generated/gogoproto/gogo.upb.h @@ -0,0 +1,32 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * gogoproto/gogo.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOGOPROTO_GOGO_PROTO_UPB_H_ +#define GOGOPROTO_GOGO_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + + +/* Enums */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOGOPROTO_GOGO_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/api/annotations.upb.c b/src/core/ext/upb-generated/google/api/annotations.upb.c new file mode 100644 index 00000000000..a1385cc3e70 --- /dev/null +++ b/src/core/ext/upb-generated/google/api/annotations.upb.c @@ -0,0 +1,18 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/api/annotations.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/api/annotations.upb.h" +#include "google/api/http.upb.h" +#include "google/protobuf/descriptor.upb.h" + +#include "upb/port_def.inc" + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/api/annotations.upb.h b/src/core/ext/upb-generated/google/api/annotations.upb.h new file mode 100644 index 00000000000..93d7868ff34 --- /dev/null +++ b/src/core/ext/upb-generated/google/api/annotations.upb.h @@ -0,0 +1,32 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/api/annotations.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_API_ANNOTATIONS_PROTO_UPB_H_ +#define GOOGLE_API_ANNOTATIONS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + + +/* Enums */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_API_ANNOTATIONS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/api/http.upb.c b/src/core/ext/upb-generated/google/api/http.upb.c new file mode 100644 index 00000000000..8ad07dcd9fd --- /dev/null +++ b/src/core/ext/upb-generated/google/api/http.upb.c @@ -0,0 +1,66 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/api/http.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/api/http.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const google_api_Http_submsgs[1] = { + &google_api_HttpRule_msginit, +}; + +static const upb_msglayout_field google_api_Http__fields[2] = { + {1, UPB_SIZE(4, 8), 0, 0, 11, 3}, + {2, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout google_api_Http_msginit = { + &google_api_Http_submsgs[0], + &google_api_Http__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const google_api_HttpRule_submsgs[2] = { + &google_api_CustomHttpPattern_msginit, + &google_api_HttpRule_msginit, +}; + +static const upb_msglayout_field google_api_HttpRule__fields[10] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1}, + {3, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1}, + {4, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1}, + {5, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1}, + {6, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1}, + {7, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {8, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 11, 1}, + {11, UPB_SIZE(24, 48), 0, 1, 11, 3}, + {12, UPB_SIZE(16, 32), 0, 0, 9, 1}, +}; + +const upb_msglayout google_api_HttpRule_msginit = { + &google_api_HttpRule_submsgs[0], + &google_api_HttpRule__fields[0], + UPB_SIZE(40, 80), 10, false, +}; + +static const upb_msglayout_field google_api_CustomHttpPattern__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, +}; + +const upb_msglayout google_api_CustomHttpPattern_msginit = { + NULL, + &google_api_CustomHttpPattern__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/api/http.upb.h b/src/core/ext/upb-generated/google/api/http.upb.h new file mode 100644 index 00000000000..6fec36802d3 --- /dev/null +++ b/src/core/ext/upb-generated/google/api/http.upb.h @@ -0,0 +1,191 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/api/http.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_API_HTTP_PROTO_UPB_H_ +#define GOOGLE_API_HTTP_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_api_Http; +struct google_api_HttpRule; +struct google_api_CustomHttpPattern; +typedef struct google_api_Http google_api_Http; +typedef struct google_api_HttpRule google_api_HttpRule; +typedef struct google_api_CustomHttpPattern google_api_CustomHttpPattern; +extern const upb_msglayout google_api_Http_msginit; +extern const upb_msglayout google_api_HttpRule_msginit; +extern const upb_msglayout google_api_CustomHttpPattern_msginit; + +/* Enums */ + +/* google.api.Http */ + +UPB_INLINE google_api_Http *google_api_Http_new(upb_arena *arena) { + return (google_api_Http *)upb_msg_new(&google_api_Http_msginit, arena); +} +UPB_INLINE google_api_Http *google_api_Http_parsenew(upb_strview buf, upb_arena *arena) { + google_api_Http *ret = google_api_Http_new(arena); + return (ret && upb_decode(buf, ret, &google_api_Http_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_api_Http_serialize(const google_api_Http *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_api_Http_msginit, arena, len); +} + +UPB_INLINE const google_api_HttpRule* const* google_api_Http_rules(const google_api_Http *msg, size_t *len) { return (const google_api_HttpRule* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } +UPB_INLINE bool google_api_Http_fully_decode_reserved_expansion(const google_api_Http *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE google_api_HttpRule** google_api_Http_mutable_rules(google_api_Http *msg, size_t *len) { + return (google_api_HttpRule**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE google_api_HttpRule** google_api_Http_resize_rules(google_api_Http *msg, size_t len, upb_arena *arena) { + return (google_api_HttpRule**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_api_HttpRule* google_api_Http_add_rules(google_api_Http *msg, upb_arena *arena) { + struct google_api_HttpRule* sub = (struct google_api_HttpRule*)upb_msg_new(&google_api_HttpRule_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_api_Http_set_fully_decode_reserved_expansion(google_api_Http *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* google.api.HttpRule */ + +UPB_INLINE google_api_HttpRule *google_api_HttpRule_new(upb_arena *arena) { + return (google_api_HttpRule *)upb_msg_new(&google_api_HttpRule_msginit, arena); +} +UPB_INLINE google_api_HttpRule *google_api_HttpRule_parsenew(upb_strview buf, upb_arena *arena) { + google_api_HttpRule *ret = google_api_HttpRule_new(arena); + return (ret && upb_decode(buf, ret, &google_api_HttpRule_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_api_HttpRule_serialize(const google_api_HttpRule *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_api_HttpRule_msginit, arena, len); +} + +typedef enum { + google_api_HttpRule_pattern_get = 2, + google_api_HttpRule_pattern_put = 3, + google_api_HttpRule_pattern_post = 4, + google_api_HttpRule_pattern_delete = 5, + google_api_HttpRule_pattern_patch = 6, + google_api_HttpRule_pattern_custom = 8, + google_api_HttpRule_pattern_NOT_SET = 0, +} google_api_HttpRule_pattern_oneofcases; +UPB_INLINE google_api_HttpRule_pattern_oneofcases google_api_HttpRule_pattern_case(const google_api_HttpRule* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(36, 72)); } + +UPB_INLINE upb_strview google_api_HttpRule_selector(const google_api_HttpRule *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE bool google_api_HttpRule_has_get(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 2); } +UPB_INLINE upb_strview google_api_HttpRule_get(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 2, upb_strview_make("", strlen(""))); } +UPB_INLINE bool google_api_HttpRule_has_put(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 3); } +UPB_INLINE upb_strview google_api_HttpRule_put(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 3, upb_strview_make("", strlen(""))); } +UPB_INLINE bool google_api_HttpRule_has_post(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 4); } +UPB_INLINE upb_strview google_api_HttpRule_post(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 4, upb_strview_make("", strlen(""))); } +UPB_INLINE bool google_api_HttpRule_has_delete(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 5); } +UPB_INLINE upb_strview google_api_HttpRule_delete(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 5, upb_strview_make("", strlen(""))); } +UPB_INLINE bool google_api_HttpRule_has_patch(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 6); } +UPB_INLINE upb_strview google_api_HttpRule_patch(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 6, upb_strview_make("", strlen(""))); } +UPB_INLINE upb_strview google_api_HttpRule_body(const google_api_HttpRule *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE bool google_api_HttpRule_has_custom(const google_api_HttpRule *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 72), 8); } +UPB_INLINE const google_api_CustomHttpPattern* google_api_HttpRule_custom(const google_api_HttpRule *msg) { return UPB_READ_ONEOF(msg, const google_api_CustomHttpPattern*, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 8, NULL); } +UPB_INLINE const google_api_HttpRule* const* google_api_HttpRule_additional_bindings(const google_api_HttpRule *msg, size_t *len) { return (const google_api_HttpRule* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE upb_strview google_api_HttpRule_response_body(const google_api_HttpRule *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)); } + +UPB_INLINE void google_api_HttpRule_set_selector(google_api_HttpRule *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_api_HttpRule_set_get(google_api_HttpRule *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 2); +} +UPB_INLINE void google_api_HttpRule_set_put(google_api_HttpRule *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 3); +} +UPB_INLINE void google_api_HttpRule_set_post(google_api_HttpRule *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 4); +} +UPB_INLINE void google_api_HttpRule_set_delete(google_api_HttpRule *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 5); +} +UPB_INLINE void google_api_HttpRule_set_patch(google_api_HttpRule *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 6); +} +UPB_INLINE void google_api_HttpRule_set_body(google_api_HttpRule *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void google_api_HttpRule_set_custom(google_api_HttpRule *msg, google_api_CustomHttpPattern* value) { + UPB_WRITE_ONEOF(msg, google_api_CustomHttpPattern*, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 8); +} +UPB_INLINE struct google_api_CustomHttpPattern* google_api_HttpRule_mutable_custom(google_api_HttpRule *msg, upb_arena *arena) { + struct google_api_CustomHttpPattern* sub = (struct google_api_CustomHttpPattern*)google_api_HttpRule_custom(msg); + if (sub == NULL) { + sub = (struct google_api_CustomHttpPattern*)upb_msg_new(&google_api_CustomHttpPattern_msginit, arena); + if (!sub) return NULL; + google_api_HttpRule_set_custom(msg, sub); + } + return sub; +} +UPB_INLINE google_api_HttpRule** google_api_HttpRule_mutable_additional_bindings(google_api_HttpRule *msg, size_t *len) { + return (google_api_HttpRule**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE google_api_HttpRule** google_api_HttpRule_resize_additional_bindings(google_api_HttpRule *msg, size_t len, upb_arena *arena) { + return (google_api_HttpRule**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_api_HttpRule* google_api_HttpRule_add_additional_bindings(google_api_HttpRule *msg, upb_arena *arena) { + struct google_api_HttpRule* sub = (struct google_api_HttpRule*)upb_msg_new(&google_api_HttpRule_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void google_api_HttpRule_set_response_body(google_api_HttpRule *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)) = value; +} + + +/* google.api.CustomHttpPattern */ + +UPB_INLINE google_api_CustomHttpPattern *google_api_CustomHttpPattern_new(upb_arena *arena) { + return (google_api_CustomHttpPattern *)upb_msg_new(&google_api_CustomHttpPattern_msginit, arena); +} +UPB_INLINE google_api_CustomHttpPattern *google_api_CustomHttpPattern_parsenew(upb_strview buf, upb_arena *arena) { + google_api_CustomHttpPattern *ret = google_api_CustomHttpPattern_new(arena); + return (ret && upb_decode(buf, ret, &google_api_CustomHttpPattern_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_api_CustomHttpPattern_serialize(const google_api_CustomHttpPattern *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_api_CustomHttpPattern_msginit, arena, len); +} + +UPB_INLINE upb_strview google_api_CustomHttpPattern_kind(const google_api_CustomHttpPattern *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview google_api_CustomHttpPattern_path(const google_api_CustomHttpPattern *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } + +UPB_INLINE void google_api_CustomHttpPattern_set_kind(google_api_CustomHttpPattern *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_api_CustomHttpPattern_set_path(google_api_CustomHttpPattern *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_API_HTTP_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/rpc/status.upb.c b/src/core/ext/upb-generated/google/rpc/status.upb.c new file mode 100644 index 00000000000..25ac1461741 --- /dev/null +++ b/src/core/ext/upb-generated/google/rpc/status.upb.c @@ -0,0 +1,33 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/rpc/status.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/rpc/status.upb.h" +#include "google/protobuf/any.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const google_rpc_Status_submsgs[1] = { + &google_protobuf_Any_msginit, +}; + +static const upb_msglayout_field google_rpc_Status__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 5, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 9, 1}, + {3, UPB_SIZE(12, 24), 0, 0, 11, 3}, +}; + +const upb_msglayout google_rpc_Status_msginit = { + &google_rpc_Status_submsgs[0], + &google_rpc_Status__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/rpc/status.upb.h b/src/core/ext/upb-generated/google/rpc/status.upb.h new file mode 100644 index 00000000000..23f72447e4d --- /dev/null +++ b/src/core/ext/upb-generated/google/rpc/status.upb.h @@ -0,0 +1,75 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/rpc/status.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_RPC_STATUS_PROTO_UPB_H_ +#define GOOGLE_RPC_STATUS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_rpc_Status; +typedef struct google_rpc_Status google_rpc_Status; +extern const upb_msglayout google_rpc_Status_msginit; +struct google_protobuf_Any; +extern const upb_msglayout google_protobuf_Any_msginit; + +/* Enums */ + +/* google.rpc.Status */ + +UPB_INLINE google_rpc_Status *google_rpc_Status_new(upb_arena *arena) { + return (google_rpc_Status *)upb_msg_new(&google_rpc_Status_msginit, arena); +} +UPB_INLINE google_rpc_Status *google_rpc_Status_parsenew(upb_strview buf, upb_arena *arena) { + google_rpc_Status *ret = google_rpc_Status_new(arena); + return (ret && upb_decode(buf, ret, &google_rpc_Status_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_rpc_Status_serialize(const google_rpc_Status *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_rpc_Status_msginit, arena, len); +} + +UPB_INLINE int32_t google_rpc_Status_code(const google_rpc_Status *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview google_rpc_Status_message(const google_rpc_Status *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_Any* const* google_rpc_Status_details(const google_rpc_Status *msg, size_t *len) { return (const struct google_protobuf_Any* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); } + +UPB_INLINE void google_rpc_Status_set_code(google_rpc_Status *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void google_rpc_Status_set_message(google_rpc_Status *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_Any** google_rpc_Status_mutable_details(google_rpc_Status *msg, size_t *len) { + return (struct google_protobuf_Any**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len); +} +UPB_INLINE struct google_protobuf_Any** google_rpc_Status_resize_details(google_rpc_Status *msg, size_t len, upb_arena *arena) { + return (struct google_protobuf_Any**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Any* google_rpc_Status_add_details(google_rpc_Status *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_RPC_STATUS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/validate/validate.upb.c b/src/core/ext/upb-generated/validate/validate.upb.c new file mode 100644 index 00000000000..6d3c6be1461 --- /dev/null +++ b/src/core/ext/upb-generated/validate/validate.upb.c @@ -0,0 +1,443 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * validate/validate.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "validate/validate.upb.h" +#include "google/protobuf/descriptor.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/timestamp.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const validate_FieldRules_submsgs[22] = { + &validate_AnyRules_msginit, + &validate_BoolRules_msginit, + &validate_BytesRules_msginit, + &validate_DoubleRules_msginit, + &validate_DurationRules_msginit, + &validate_EnumRules_msginit, + &validate_Fixed32Rules_msginit, + &validate_Fixed64Rules_msginit, + &validate_FloatRules_msginit, + &validate_Int32Rules_msginit, + &validate_Int64Rules_msginit, + &validate_MapRules_msginit, + &validate_MessageRules_msginit, + &validate_RepeatedRules_msginit, + &validate_SFixed32Rules_msginit, + &validate_SFixed64Rules_msginit, + &validate_SInt32Rules_msginit, + &validate_SInt64Rules_msginit, + &validate_StringRules_msginit, + &validate_TimestampRules_msginit, + &validate_UInt32Rules_msginit, + &validate_UInt64Rules_msginit, +}; + +static const upb_msglayout_field validate_FieldRules__fields[22] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 8, 11, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 3, 11, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 9, 11, 1}, + {4, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 10, 11, 1}, + {5, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 20, 11, 1}, + {6, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 21, 11, 1}, + {7, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 16, 11, 1}, + {8, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 17, 11, 1}, + {9, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 6, 11, 1}, + {10, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 7, 11, 1}, + {11, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 14, 11, 1}, + {12, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 15, 11, 1}, + {13, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 1, 11, 1}, + {14, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 18, 11, 1}, + {15, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 2, 11, 1}, + {16, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 5, 11, 1}, + {17, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 12, 11, 1}, + {18, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 13, 11, 1}, + {19, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 11, 11, 1}, + {20, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 11, 1}, + {21, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 4, 11, 1}, + {22, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 19, 11, 1}, +}; + +const upb_msglayout validate_FieldRules_msginit = { + &validate_FieldRules_submsgs[0], + &validate_FieldRules__fields[0], + UPB_SIZE(8, 16), 22, false, +}; + +static const upb_msglayout_field validate_FloatRules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 2, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 2, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 2, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 2, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 2, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 2, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 2, 3}, +}; + +const upb_msglayout validate_FloatRules_msginit = { + NULL, + &validate_FloatRules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_DoubleRules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 1, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 1, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 1, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 1, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 1, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 1, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 1, 3}, +}; + +const upb_msglayout validate_DoubleRules_msginit = { + NULL, + &validate_DoubleRules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_Int32Rules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 5, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 5, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 5, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 5, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 5, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 5, 3}, +}; + +const upb_msglayout validate_Int32Rules_msginit = { + NULL, + &validate_Int32Rules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_Int64Rules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 3, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 3, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 3, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 3, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 3, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 3, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 3, 3}, +}; + +const upb_msglayout validate_Int64Rules_msginit = { + NULL, + &validate_Int64Rules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_UInt32Rules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 13, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 13, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 13, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 13, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 13, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 13, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 13, 3}, +}; + +const upb_msglayout validate_UInt32Rules_msginit = { + NULL, + &validate_UInt32Rules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_UInt64Rules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 4, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 4, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 4, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 4, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 4, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 4, 3}, +}; + +const upb_msglayout validate_UInt64Rules_msginit = { + NULL, + &validate_UInt64Rules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_SInt32Rules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 17, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 17, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 17, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 17, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 17, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 17, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 17, 3}, +}; + +const upb_msglayout validate_SInt32Rules_msginit = { + NULL, + &validate_SInt32Rules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_SInt64Rules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 18, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 18, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 18, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 18, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 18, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 18, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 18, 3}, +}; + +const upb_msglayout validate_SInt64Rules_msginit = { + NULL, + &validate_SInt64Rules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_Fixed32Rules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 7, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 7, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 7, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 7, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 7, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 7, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 7, 3}, +}; + +const upb_msglayout validate_Fixed32Rules_msginit = { + NULL, + &validate_Fixed32Rules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_Fixed64Rules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 6, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 6, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 6, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 6, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 6, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 6, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 6, 3}, +}; + +const upb_msglayout validate_Fixed64Rules_msginit = { + NULL, + &validate_Fixed64Rules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_SFixed32Rules__fields[7] = { + {1, UPB_SIZE(4, 4), 1, 0, 15, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 15, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 15, 1}, + {4, UPB_SIZE(16, 16), 4, 0, 15, 1}, + {5, UPB_SIZE(20, 20), 5, 0, 15, 1}, + {6, UPB_SIZE(24, 24), 0, 0, 15, 3}, + {7, UPB_SIZE(28, 32), 0, 0, 15, 3}, +}; + +const upb_msglayout validate_SFixed32Rules_msginit = { + NULL, + &validate_SFixed32Rules__fields[0], + UPB_SIZE(32, 40), 7, false, +}; + +static const upb_msglayout_field validate_SFixed64Rules__fields[7] = { + {1, UPB_SIZE(8, 8), 1, 0, 16, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 16, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 16, 1}, + {4, UPB_SIZE(32, 32), 4, 0, 16, 1}, + {5, UPB_SIZE(40, 40), 5, 0, 16, 1}, + {6, UPB_SIZE(48, 48), 0, 0, 16, 3}, + {7, UPB_SIZE(52, 56), 0, 0, 16, 3}, +}; + +const upb_msglayout validate_SFixed64Rules_msginit = { + NULL, + &validate_SFixed64Rules__fields[0], + UPB_SIZE(56, 64), 7, false, +}; + +static const upb_msglayout_field validate_BoolRules__fields[1] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, +}; + +const upb_msglayout validate_BoolRules_msginit = { + NULL, + &validate_BoolRules__fields[0], + UPB_SIZE(2, 2), 1, false, +}; + +static const upb_msglayout_field validate_StringRules__fields[20] = { + {1, UPB_SIZE(56, 56), 7, 0, 9, 1}, + {2, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {3, UPB_SIZE(16, 16), 2, 0, 4, 1}, + {4, UPB_SIZE(24, 24), 3, 0, 4, 1}, + {5, UPB_SIZE(32, 32), 4, 0, 4, 1}, + {6, UPB_SIZE(64, 72), 8, 0, 9, 1}, + {7, UPB_SIZE(72, 88), 9, 0, 9, 1}, + {8, UPB_SIZE(80, 104), 10, 0, 9, 1}, + {9, UPB_SIZE(88, 120), 11, 0, 9, 1}, + {10, UPB_SIZE(96, 136), 0, 0, 9, 3}, + {11, UPB_SIZE(100, 144), 0, 0, 9, 3}, + {12, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {13, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {14, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {15, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {16, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {17, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {18, UPB_SIZE(104, 152), UPB_SIZE(-109, -157), 0, 8, 1}, + {19, UPB_SIZE(40, 40), 5, 0, 4, 1}, + {20, UPB_SIZE(48, 48), 6, 0, 4, 1}, +}; + +const upb_msglayout validate_StringRules_msginit = { + NULL, + &validate_StringRules__fields[0], + UPB_SIZE(112, 160), 20, false, +}; + +static const upb_msglayout_field validate_BytesRules__fields[13] = { + {1, UPB_SIZE(32, 32), 4, 0, 12, 1}, + {2, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {3, UPB_SIZE(16, 16), 2, 0, 4, 1}, + {4, UPB_SIZE(40, 48), 5, 0, 9, 1}, + {5, UPB_SIZE(48, 64), 6, 0, 12, 1}, + {6, UPB_SIZE(56, 80), 7, 0, 12, 1}, + {7, UPB_SIZE(64, 96), 8, 0, 12, 1}, + {8, UPB_SIZE(72, 112), 0, 0, 12, 3}, + {9, UPB_SIZE(76, 120), 0, 0, 12, 3}, + {10, UPB_SIZE(80, 128), UPB_SIZE(-85, -133), 0, 8, 1}, + {11, UPB_SIZE(80, 128), UPB_SIZE(-85, -133), 0, 8, 1}, + {12, UPB_SIZE(80, 128), UPB_SIZE(-85, -133), 0, 8, 1}, + {13, UPB_SIZE(24, 24), 3, 0, 4, 1}, +}; + +const upb_msglayout validate_BytesRules_msginit = { + NULL, + &validate_BytesRules__fields[0], + UPB_SIZE(88, 144), 13, false, +}; + +static const upb_msglayout_field validate_EnumRules__fields[4] = { + {1, UPB_SIZE(4, 4), 1, 0, 5, 1}, + {2, UPB_SIZE(8, 8), 2, 0, 8, 1}, + {3, UPB_SIZE(12, 16), 0, 0, 5, 3}, + {4, UPB_SIZE(16, 24), 0, 0, 5, 3}, +}; + +const upb_msglayout validate_EnumRules_msginit = { + NULL, + &validate_EnumRules__fields[0], + UPB_SIZE(20, 32), 4, false, +}; + +static const upb_msglayout_field validate_MessageRules__fields[2] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {2, UPB_SIZE(2, 2), 2, 0, 8, 1}, +}; + +const upb_msglayout validate_MessageRules_msginit = { + NULL, + &validate_MessageRules__fields[0], + UPB_SIZE(3, 3), 2, false, +}; + +static const upb_msglayout *const validate_RepeatedRules_submsgs[1] = { + &validate_FieldRules_msginit, +}; + +static const upb_msglayout_field validate_RepeatedRules__fields[4] = { + {1, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 4, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 8, 1}, + {4, UPB_SIZE(28, 32), 4, 0, 11, 1}, +}; + +const upb_msglayout validate_RepeatedRules_msginit = { + &validate_RepeatedRules_submsgs[0], + &validate_RepeatedRules__fields[0], + UPB_SIZE(32, 40), 4, false, +}; + +static const upb_msglayout *const validate_MapRules_submsgs[2] = { + &validate_FieldRules_msginit, +}; + +static const upb_msglayout_field validate_MapRules__fields[5] = { + {1, UPB_SIZE(8, 8), 1, 0, 4, 1}, + {2, UPB_SIZE(16, 16), 2, 0, 4, 1}, + {3, UPB_SIZE(24, 24), 3, 0, 8, 1}, + {4, UPB_SIZE(28, 32), 4, 0, 11, 1}, + {5, UPB_SIZE(32, 40), 5, 0, 11, 1}, +}; + +const upb_msglayout validate_MapRules_msginit = { + &validate_MapRules_submsgs[0], + &validate_MapRules__fields[0], + UPB_SIZE(40, 48), 5, false, +}; + +static const upb_msglayout_field validate_AnyRules__fields[3] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 9, 3}, + {3, UPB_SIZE(8, 16), 0, 0, 9, 3}, +}; + +const upb_msglayout validate_AnyRules_msginit = { + NULL, + &validate_AnyRules__fields[0], + UPB_SIZE(12, 24), 3, false, +}; + +static const upb_msglayout *const validate_DurationRules_submsgs[7] = { + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field validate_DurationRules__fields[8] = { + {1, UPB_SIZE(1, 1), 1, 0, 8, 1}, + {2, UPB_SIZE(4, 8), 2, 0, 11, 1}, + {3, UPB_SIZE(8, 16), 3, 0, 11, 1}, + {4, UPB_SIZE(12, 24), 4, 0, 11, 1}, + {5, UPB_SIZE(16, 32), 5, 0, 11, 1}, + {6, UPB_SIZE(20, 40), 6, 0, 11, 1}, + {7, UPB_SIZE(24, 48), 0, 0, 11, 3}, + {8, UPB_SIZE(28, 56), 0, 0, 11, 3}, +}; + +const upb_msglayout validate_DurationRules_msginit = { + &validate_DurationRules_submsgs[0], + &validate_DurationRules__fields[0], + UPB_SIZE(32, 64), 8, false, +}; + +static const upb_msglayout *const validate_TimestampRules_submsgs[6] = { + &google_protobuf_Duration_msginit, + &google_protobuf_Timestamp_msginit, +}; + +static const upb_msglayout_field validate_TimestampRules__fields[9] = { + {1, UPB_SIZE(2, 2), 1, 0, 8, 1}, + {2, UPB_SIZE(8, 8), 4, 1, 11, 1}, + {3, UPB_SIZE(12, 16), 5, 1, 11, 1}, + {4, UPB_SIZE(16, 24), 6, 1, 11, 1}, + {5, UPB_SIZE(20, 32), 7, 1, 11, 1}, + {6, UPB_SIZE(24, 40), 8, 1, 11, 1}, + {7, UPB_SIZE(3, 3), 2, 0, 8, 1}, + {8, UPB_SIZE(4, 4), 3, 0, 8, 1}, + {9, UPB_SIZE(28, 48), 9, 0, 11, 1}, +}; + +const upb_msglayout validate_TimestampRules_msginit = { + &validate_TimestampRules_submsgs[0], + &validate_TimestampRules__fields[0], + UPB_SIZE(32, 56), 9, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/validate/validate.upb.h b/src/core/ext/upb-generated/validate/validate.upb.h new file mode 100644 index 00000000000..04b6cd431f5 --- /dev/null +++ b/src/core/ext/upb-generated/validate/validate.upb.h @@ -0,0 +1,2038 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * validate/validate.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef VALIDATE_VALIDATE_PROTO_UPB_H_ +#define VALIDATE_VALIDATE_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct validate_FieldRules; +struct validate_FloatRules; +struct validate_DoubleRules; +struct validate_Int32Rules; +struct validate_Int64Rules; +struct validate_UInt32Rules; +struct validate_UInt64Rules; +struct validate_SInt32Rules; +struct validate_SInt64Rules; +struct validate_Fixed32Rules; +struct validate_Fixed64Rules; +struct validate_SFixed32Rules; +struct validate_SFixed64Rules; +struct validate_BoolRules; +struct validate_StringRules; +struct validate_BytesRules; +struct validate_EnumRules; +struct validate_MessageRules; +struct validate_RepeatedRules; +struct validate_MapRules; +struct validate_AnyRules; +struct validate_DurationRules; +struct validate_TimestampRules; +typedef struct validate_FieldRules validate_FieldRules; +typedef struct validate_FloatRules validate_FloatRules; +typedef struct validate_DoubleRules validate_DoubleRules; +typedef struct validate_Int32Rules validate_Int32Rules; +typedef struct validate_Int64Rules validate_Int64Rules; +typedef struct validate_UInt32Rules validate_UInt32Rules; +typedef struct validate_UInt64Rules validate_UInt64Rules; +typedef struct validate_SInt32Rules validate_SInt32Rules; +typedef struct validate_SInt64Rules validate_SInt64Rules; +typedef struct validate_Fixed32Rules validate_Fixed32Rules; +typedef struct validate_Fixed64Rules validate_Fixed64Rules; +typedef struct validate_SFixed32Rules validate_SFixed32Rules; +typedef struct validate_SFixed64Rules validate_SFixed64Rules; +typedef struct validate_BoolRules validate_BoolRules; +typedef struct validate_StringRules validate_StringRules; +typedef struct validate_BytesRules validate_BytesRules; +typedef struct validate_EnumRules validate_EnumRules; +typedef struct validate_MessageRules validate_MessageRules; +typedef struct validate_RepeatedRules validate_RepeatedRules; +typedef struct validate_MapRules validate_MapRules; +typedef struct validate_AnyRules validate_AnyRules; +typedef struct validate_DurationRules validate_DurationRules; +typedef struct validate_TimestampRules validate_TimestampRules; +extern const upb_msglayout validate_FieldRules_msginit; +extern const upb_msglayout validate_FloatRules_msginit; +extern const upb_msglayout validate_DoubleRules_msginit; +extern const upb_msglayout validate_Int32Rules_msginit; +extern const upb_msglayout validate_Int64Rules_msginit; +extern const upb_msglayout validate_UInt32Rules_msginit; +extern const upb_msglayout validate_UInt64Rules_msginit; +extern const upb_msglayout validate_SInt32Rules_msginit; +extern const upb_msglayout validate_SInt64Rules_msginit; +extern const upb_msglayout validate_Fixed32Rules_msginit; +extern const upb_msglayout validate_Fixed64Rules_msginit; +extern const upb_msglayout validate_SFixed32Rules_msginit; +extern const upb_msglayout validate_SFixed64Rules_msginit; +extern const upb_msglayout validate_BoolRules_msginit; +extern const upb_msglayout validate_StringRules_msginit; +extern const upb_msglayout validate_BytesRules_msginit; +extern const upb_msglayout validate_EnumRules_msginit; +extern const upb_msglayout validate_MessageRules_msginit; +extern const upb_msglayout validate_RepeatedRules_msginit; +extern const upb_msglayout validate_MapRules_msginit; +extern const upb_msglayout validate_AnyRules_msginit; +extern const upb_msglayout validate_DurationRules_msginit; +extern const upb_msglayout validate_TimestampRules_msginit; +struct google_protobuf_Duration; +struct google_protobuf_Timestamp; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_Timestamp_msginit; + +/* Enums */ + +/* validate.FieldRules */ + +UPB_INLINE validate_FieldRules *validate_FieldRules_new(upb_arena *arena) { + return (validate_FieldRules *)upb_msg_new(&validate_FieldRules_msginit, arena); +} +UPB_INLINE validate_FieldRules *validate_FieldRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_FieldRules *ret = validate_FieldRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_FieldRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_FieldRules_serialize(const validate_FieldRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_FieldRules_msginit, arena, len); +} + +typedef enum { + validate_FieldRules_type_float = 1, + validate_FieldRules_type_double = 2, + validate_FieldRules_type_int32 = 3, + validate_FieldRules_type_int64 = 4, + validate_FieldRules_type_uint32 = 5, + validate_FieldRules_type_uint64 = 6, + validate_FieldRules_type_sint32 = 7, + validate_FieldRules_type_sint64 = 8, + validate_FieldRules_type_fixed32 = 9, + validate_FieldRules_type_fixed64 = 10, + validate_FieldRules_type_sfixed32 = 11, + validate_FieldRules_type_sfixed64 = 12, + validate_FieldRules_type_bool = 13, + validate_FieldRules_type_string = 14, + validate_FieldRules_type_bytes = 15, + validate_FieldRules_type_enum = 16, + validate_FieldRules_type_message = 17, + validate_FieldRules_type_repeated = 18, + validate_FieldRules_type_map = 19, + validate_FieldRules_type_any = 20, + validate_FieldRules_type_duration = 21, + validate_FieldRules_type_timestamp = 22, + validate_FieldRules_type_NOT_SET = 0, +} validate_FieldRules_type_oneofcases; +UPB_INLINE validate_FieldRules_type_oneofcases validate_FieldRules_type_case(const validate_FieldRules* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(4, 8)); } + +UPB_INLINE bool validate_FieldRules_has_float(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 1); } +UPB_INLINE const validate_FloatRules* validate_FieldRules_float(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_FloatRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 1, NULL); } +UPB_INLINE bool validate_FieldRules_has_double(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 2); } +UPB_INLINE const validate_DoubleRules* validate_FieldRules_double(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_DoubleRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 2, NULL); } +UPB_INLINE bool validate_FieldRules_has_int32(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 3); } +UPB_INLINE const validate_Int32Rules* validate_FieldRules_int32(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_Int32Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 3, NULL); } +UPB_INLINE bool validate_FieldRules_has_int64(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 4); } +UPB_INLINE const validate_Int64Rules* validate_FieldRules_int64(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_Int64Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 4, NULL); } +UPB_INLINE bool validate_FieldRules_has_uint32(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 5); } +UPB_INLINE const validate_UInt32Rules* validate_FieldRules_uint32(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_UInt32Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 5, NULL); } +UPB_INLINE bool validate_FieldRules_has_uint64(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 6); } +UPB_INLINE const validate_UInt64Rules* validate_FieldRules_uint64(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_UInt64Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 6, NULL); } +UPB_INLINE bool validate_FieldRules_has_sint32(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 7); } +UPB_INLINE const validate_SInt32Rules* validate_FieldRules_sint32(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_SInt32Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 7, NULL); } +UPB_INLINE bool validate_FieldRules_has_sint64(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 8); } +UPB_INLINE const validate_SInt64Rules* validate_FieldRules_sint64(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_SInt64Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 8, NULL); } +UPB_INLINE bool validate_FieldRules_has_fixed32(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 9); } +UPB_INLINE const validate_Fixed32Rules* validate_FieldRules_fixed32(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_Fixed32Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 9, NULL); } +UPB_INLINE bool validate_FieldRules_has_fixed64(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 10); } +UPB_INLINE const validate_Fixed64Rules* validate_FieldRules_fixed64(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_Fixed64Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 10, NULL); } +UPB_INLINE bool validate_FieldRules_has_sfixed32(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 11); } +UPB_INLINE const validate_SFixed32Rules* validate_FieldRules_sfixed32(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_SFixed32Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 11, NULL); } +UPB_INLINE bool validate_FieldRules_has_sfixed64(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 12); } +UPB_INLINE const validate_SFixed64Rules* validate_FieldRules_sfixed64(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_SFixed64Rules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 12, NULL); } +UPB_INLINE bool validate_FieldRules_has_bool(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 13); } +UPB_INLINE const validate_BoolRules* validate_FieldRules_bool(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_BoolRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 13, NULL); } +UPB_INLINE bool validate_FieldRules_has_string(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 14); } +UPB_INLINE const validate_StringRules* validate_FieldRules_string(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_StringRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 14, NULL); } +UPB_INLINE bool validate_FieldRules_has_bytes(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 15); } +UPB_INLINE const validate_BytesRules* validate_FieldRules_bytes(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_BytesRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 15, NULL); } +UPB_INLINE bool validate_FieldRules_has_enum(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 16); } +UPB_INLINE const validate_EnumRules* validate_FieldRules_enum(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_EnumRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 16, NULL); } +UPB_INLINE bool validate_FieldRules_has_message(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 17); } +UPB_INLINE const validate_MessageRules* validate_FieldRules_message(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_MessageRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 17, NULL); } +UPB_INLINE bool validate_FieldRules_has_repeated(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 18); } +UPB_INLINE const validate_RepeatedRules* validate_FieldRules_repeated(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_RepeatedRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 18, NULL); } +UPB_INLINE bool validate_FieldRules_has_map(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 19); } +UPB_INLINE const validate_MapRules* validate_FieldRules_map(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_MapRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 19, NULL); } +UPB_INLINE bool validate_FieldRules_has_any(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 20); } +UPB_INLINE const validate_AnyRules* validate_FieldRules_any(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_AnyRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 20, NULL); } +UPB_INLINE bool validate_FieldRules_has_duration(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 21); } +UPB_INLINE const validate_DurationRules* validate_FieldRules_duration(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_DurationRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 21, NULL); } +UPB_INLINE bool validate_FieldRules_has_timestamp(const validate_FieldRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 22); } +UPB_INLINE const validate_TimestampRules* validate_FieldRules_timestamp(const validate_FieldRules *msg) { return UPB_READ_ONEOF(msg, const validate_TimestampRules*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 22, NULL); } + +UPB_INLINE void validate_FieldRules_set_float(validate_FieldRules *msg, validate_FloatRules* value) { + UPB_WRITE_ONEOF(msg, validate_FloatRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 1); +} +UPB_INLINE struct validate_FloatRules* validate_FieldRules_mutable_float(validate_FieldRules *msg, upb_arena *arena) { + struct validate_FloatRules* sub = (struct validate_FloatRules*)validate_FieldRules_float(msg); + if (sub == NULL) { + sub = (struct validate_FloatRules*)upb_msg_new(&validate_FloatRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_float(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_double(validate_FieldRules *msg, validate_DoubleRules* value) { + UPB_WRITE_ONEOF(msg, validate_DoubleRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 2); +} +UPB_INLINE struct validate_DoubleRules* validate_FieldRules_mutable_double(validate_FieldRules *msg, upb_arena *arena) { + struct validate_DoubleRules* sub = (struct validate_DoubleRules*)validate_FieldRules_double(msg); + if (sub == NULL) { + sub = (struct validate_DoubleRules*)upb_msg_new(&validate_DoubleRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_double(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_int32(validate_FieldRules *msg, validate_Int32Rules* value) { + UPB_WRITE_ONEOF(msg, validate_Int32Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 3); +} +UPB_INLINE struct validate_Int32Rules* validate_FieldRules_mutable_int32(validate_FieldRules *msg, upb_arena *arena) { + struct validate_Int32Rules* sub = (struct validate_Int32Rules*)validate_FieldRules_int32(msg); + if (sub == NULL) { + sub = (struct validate_Int32Rules*)upb_msg_new(&validate_Int32Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_int32(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_int64(validate_FieldRules *msg, validate_Int64Rules* value) { + UPB_WRITE_ONEOF(msg, validate_Int64Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 4); +} +UPB_INLINE struct validate_Int64Rules* validate_FieldRules_mutable_int64(validate_FieldRules *msg, upb_arena *arena) { + struct validate_Int64Rules* sub = (struct validate_Int64Rules*)validate_FieldRules_int64(msg); + if (sub == NULL) { + sub = (struct validate_Int64Rules*)upb_msg_new(&validate_Int64Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_int64(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_uint32(validate_FieldRules *msg, validate_UInt32Rules* value) { + UPB_WRITE_ONEOF(msg, validate_UInt32Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 5); +} +UPB_INLINE struct validate_UInt32Rules* validate_FieldRules_mutable_uint32(validate_FieldRules *msg, upb_arena *arena) { + struct validate_UInt32Rules* sub = (struct validate_UInt32Rules*)validate_FieldRules_uint32(msg); + if (sub == NULL) { + sub = (struct validate_UInt32Rules*)upb_msg_new(&validate_UInt32Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_uint32(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_uint64(validate_FieldRules *msg, validate_UInt64Rules* value) { + UPB_WRITE_ONEOF(msg, validate_UInt64Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 6); +} +UPB_INLINE struct validate_UInt64Rules* validate_FieldRules_mutable_uint64(validate_FieldRules *msg, upb_arena *arena) { + struct validate_UInt64Rules* sub = (struct validate_UInt64Rules*)validate_FieldRules_uint64(msg); + if (sub == NULL) { + sub = (struct validate_UInt64Rules*)upb_msg_new(&validate_UInt64Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_uint64(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_sint32(validate_FieldRules *msg, validate_SInt32Rules* value) { + UPB_WRITE_ONEOF(msg, validate_SInt32Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 7); +} +UPB_INLINE struct validate_SInt32Rules* validate_FieldRules_mutable_sint32(validate_FieldRules *msg, upb_arena *arena) { + struct validate_SInt32Rules* sub = (struct validate_SInt32Rules*)validate_FieldRules_sint32(msg); + if (sub == NULL) { + sub = (struct validate_SInt32Rules*)upb_msg_new(&validate_SInt32Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_sint32(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_sint64(validate_FieldRules *msg, validate_SInt64Rules* value) { + UPB_WRITE_ONEOF(msg, validate_SInt64Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 8); +} +UPB_INLINE struct validate_SInt64Rules* validate_FieldRules_mutable_sint64(validate_FieldRules *msg, upb_arena *arena) { + struct validate_SInt64Rules* sub = (struct validate_SInt64Rules*)validate_FieldRules_sint64(msg); + if (sub == NULL) { + sub = (struct validate_SInt64Rules*)upb_msg_new(&validate_SInt64Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_sint64(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_fixed32(validate_FieldRules *msg, validate_Fixed32Rules* value) { + UPB_WRITE_ONEOF(msg, validate_Fixed32Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 9); +} +UPB_INLINE struct validate_Fixed32Rules* validate_FieldRules_mutable_fixed32(validate_FieldRules *msg, upb_arena *arena) { + struct validate_Fixed32Rules* sub = (struct validate_Fixed32Rules*)validate_FieldRules_fixed32(msg); + if (sub == NULL) { + sub = (struct validate_Fixed32Rules*)upb_msg_new(&validate_Fixed32Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_fixed32(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_fixed64(validate_FieldRules *msg, validate_Fixed64Rules* value) { + UPB_WRITE_ONEOF(msg, validate_Fixed64Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 10); +} +UPB_INLINE struct validate_Fixed64Rules* validate_FieldRules_mutable_fixed64(validate_FieldRules *msg, upb_arena *arena) { + struct validate_Fixed64Rules* sub = (struct validate_Fixed64Rules*)validate_FieldRules_fixed64(msg); + if (sub == NULL) { + sub = (struct validate_Fixed64Rules*)upb_msg_new(&validate_Fixed64Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_fixed64(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_sfixed32(validate_FieldRules *msg, validate_SFixed32Rules* value) { + UPB_WRITE_ONEOF(msg, validate_SFixed32Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 11); +} +UPB_INLINE struct validate_SFixed32Rules* validate_FieldRules_mutable_sfixed32(validate_FieldRules *msg, upb_arena *arena) { + struct validate_SFixed32Rules* sub = (struct validate_SFixed32Rules*)validate_FieldRules_sfixed32(msg); + if (sub == NULL) { + sub = (struct validate_SFixed32Rules*)upb_msg_new(&validate_SFixed32Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_sfixed32(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_sfixed64(validate_FieldRules *msg, validate_SFixed64Rules* value) { + UPB_WRITE_ONEOF(msg, validate_SFixed64Rules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 12); +} +UPB_INLINE struct validate_SFixed64Rules* validate_FieldRules_mutable_sfixed64(validate_FieldRules *msg, upb_arena *arena) { + struct validate_SFixed64Rules* sub = (struct validate_SFixed64Rules*)validate_FieldRules_sfixed64(msg); + if (sub == NULL) { + sub = (struct validate_SFixed64Rules*)upb_msg_new(&validate_SFixed64Rules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_sfixed64(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_bool(validate_FieldRules *msg, validate_BoolRules* value) { + UPB_WRITE_ONEOF(msg, validate_BoolRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 13); +} +UPB_INLINE struct validate_BoolRules* validate_FieldRules_mutable_bool(validate_FieldRules *msg, upb_arena *arena) { + struct validate_BoolRules* sub = (struct validate_BoolRules*)validate_FieldRules_bool(msg); + if (sub == NULL) { + sub = (struct validate_BoolRules*)upb_msg_new(&validate_BoolRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_bool(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_string(validate_FieldRules *msg, validate_StringRules* value) { + UPB_WRITE_ONEOF(msg, validate_StringRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 14); +} +UPB_INLINE struct validate_StringRules* validate_FieldRules_mutable_string(validate_FieldRules *msg, upb_arena *arena) { + struct validate_StringRules* sub = (struct validate_StringRules*)validate_FieldRules_string(msg); + if (sub == NULL) { + sub = (struct validate_StringRules*)upb_msg_new(&validate_StringRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_string(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_bytes(validate_FieldRules *msg, validate_BytesRules* value) { + UPB_WRITE_ONEOF(msg, validate_BytesRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 15); +} +UPB_INLINE struct validate_BytesRules* validate_FieldRules_mutable_bytes(validate_FieldRules *msg, upb_arena *arena) { + struct validate_BytesRules* sub = (struct validate_BytesRules*)validate_FieldRules_bytes(msg); + if (sub == NULL) { + sub = (struct validate_BytesRules*)upb_msg_new(&validate_BytesRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_bytes(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_enum(validate_FieldRules *msg, validate_EnumRules* value) { + UPB_WRITE_ONEOF(msg, validate_EnumRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 16); +} +UPB_INLINE struct validate_EnumRules* validate_FieldRules_mutable_enum(validate_FieldRules *msg, upb_arena *arena) { + struct validate_EnumRules* sub = (struct validate_EnumRules*)validate_FieldRules_enum(msg); + if (sub == NULL) { + sub = (struct validate_EnumRules*)upb_msg_new(&validate_EnumRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_enum(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_message(validate_FieldRules *msg, validate_MessageRules* value) { + UPB_WRITE_ONEOF(msg, validate_MessageRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 17); +} +UPB_INLINE struct validate_MessageRules* validate_FieldRules_mutable_message(validate_FieldRules *msg, upb_arena *arena) { + struct validate_MessageRules* sub = (struct validate_MessageRules*)validate_FieldRules_message(msg); + if (sub == NULL) { + sub = (struct validate_MessageRules*)upb_msg_new(&validate_MessageRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_message(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_repeated(validate_FieldRules *msg, validate_RepeatedRules* value) { + UPB_WRITE_ONEOF(msg, validate_RepeatedRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 18); +} +UPB_INLINE struct validate_RepeatedRules* validate_FieldRules_mutable_repeated(validate_FieldRules *msg, upb_arena *arena) { + struct validate_RepeatedRules* sub = (struct validate_RepeatedRules*)validate_FieldRules_repeated(msg); + if (sub == NULL) { + sub = (struct validate_RepeatedRules*)upb_msg_new(&validate_RepeatedRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_repeated(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_map(validate_FieldRules *msg, validate_MapRules* value) { + UPB_WRITE_ONEOF(msg, validate_MapRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 19); +} +UPB_INLINE struct validate_MapRules* validate_FieldRules_mutable_map(validate_FieldRules *msg, upb_arena *arena) { + struct validate_MapRules* sub = (struct validate_MapRules*)validate_FieldRules_map(msg); + if (sub == NULL) { + sub = (struct validate_MapRules*)upb_msg_new(&validate_MapRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_map(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_any(validate_FieldRules *msg, validate_AnyRules* value) { + UPB_WRITE_ONEOF(msg, validate_AnyRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 20); +} +UPB_INLINE struct validate_AnyRules* validate_FieldRules_mutable_any(validate_FieldRules *msg, upb_arena *arena) { + struct validate_AnyRules* sub = (struct validate_AnyRules*)validate_FieldRules_any(msg); + if (sub == NULL) { + sub = (struct validate_AnyRules*)upb_msg_new(&validate_AnyRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_any(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_duration(validate_FieldRules *msg, validate_DurationRules* value) { + UPB_WRITE_ONEOF(msg, validate_DurationRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 21); +} +UPB_INLINE struct validate_DurationRules* validate_FieldRules_mutable_duration(validate_FieldRules *msg, upb_arena *arena) { + struct validate_DurationRules* sub = (struct validate_DurationRules*)validate_FieldRules_duration(msg); + if (sub == NULL) { + sub = (struct validate_DurationRules*)upb_msg_new(&validate_DurationRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_duration(msg, sub); + } + return sub; +} +UPB_INLINE void validate_FieldRules_set_timestamp(validate_FieldRules *msg, validate_TimestampRules* value) { + UPB_WRITE_ONEOF(msg, validate_TimestampRules*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 22); +} +UPB_INLINE struct validate_TimestampRules* validate_FieldRules_mutable_timestamp(validate_FieldRules *msg, upb_arena *arena) { + struct validate_TimestampRules* sub = (struct validate_TimestampRules*)validate_FieldRules_timestamp(msg); + if (sub == NULL) { + sub = (struct validate_TimestampRules*)upb_msg_new(&validate_TimestampRules_msginit, arena); + if (!sub) return NULL; + validate_FieldRules_set_timestamp(msg, sub); + } + return sub; +} + + +/* validate.FloatRules */ + +UPB_INLINE validate_FloatRules *validate_FloatRules_new(upb_arena *arena) { + return (validate_FloatRules *)upb_msg_new(&validate_FloatRules_msginit, arena); +} +UPB_INLINE validate_FloatRules *validate_FloatRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_FloatRules *ret = validate_FloatRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_FloatRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_FloatRules_serialize(const validate_FloatRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_FloatRules_msginit, arena, len); +} + +UPB_INLINE bool validate_FloatRules_has_const(const validate_FloatRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE float validate_FloatRules_const(const validate_FloatRules *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_FloatRules_has_lt(const validate_FloatRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE float validate_FloatRules_lt(const validate_FloatRules *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_FloatRules_has_lte(const validate_FloatRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE float validate_FloatRules_lte(const validate_FloatRules *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_FloatRules_has_gt(const validate_FloatRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE float validate_FloatRules_gt(const validate_FloatRules *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_FloatRules_has_gte(const validate_FloatRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE float validate_FloatRules_gte(const validate_FloatRules *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(20, 20)); } +UPB_INLINE float const* validate_FloatRules_in(const validate_FloatRules *msg, size_t *len) { return (float const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE float const* validate_FloatRules_not_in(const validate_FloatRules *msg, size_t *len) { return (float const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_FloatRules_set_const(validate_FloatRules *msg, float value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, float, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_FloatRules_set_lt(validate_FloatRules *msg, float value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, float, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_FloatRules_set_lte(validate_FloatRules *msg, float value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, float, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_FloatRules_set_gt(validate_FloatRules *msg, float value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, float, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_FloatRules_set_gte(validate_FloatRules *msg, float value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, float, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE float* validate_FloatRules_mutable_in(validate_FloatRules *msg, size_t *len) { + return (float*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE float* validate_FloatRules_resize_in(validate_FloatRules *msg, size_t len, upb_arena *arena) { + return (float*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_FLOAT, arena); +} +UPB_INLINE bool validate_FloatRules_add_in(validate_FloatRules *msg, float val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_FLOAT, &val, arena); +} +UPB_INLINE float* validate_FloatRules_mutable_not_in(validate_FloatRules *msg, size_t *len) { + return (float*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE float* validate_FloatRules_resize_not_in(validate_FloatRules *msg, size_t len, upb_arena *arena) { + return (float*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_FLOAT, arena); +} +UPB_INLINE bool validate_FloatRules_add_not_in(validate_FloatRules *msg, float val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_FLOAT, &val, arena); +} + + +/* validate.DoubleRules */ + +UPB_INLINE validate_DoubleRules *validate_DoubleRules_new(upb_arena *arena) { + return (validate_DoubleRules *)upb_msg_new(&validate_DoubleRules_msginit, arena); +} +UPB_INLINE validate_DoubleRules *validate_DoubleRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_DoubleRules *ret = validate_DoubleRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_DoubleRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_DoubleRules_serialize(const validate_DoubleRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_DoubleRules_msginit, arena, len); +} + +UPB_INLINE bool validate_DoubleRules_has_const(const validate_DoubleRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE double validate_DoubleRules_const(const validate_DoubleRules *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_DoubleRules_has_lt(const validate_DoubleRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE double validate_DoubleRules_lt(const validate_DoubleRules *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_DoubleRules_has_lte(const validate_DoubleRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE double validate_DoubleRules_lte(const validate_DoubleRules *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_DoubleRules_has_gt(const validate_DoubleRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE double validate_DoubleRules_gt(const validate_DoubleRules *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_DoubleRules_has_gte(const validate_DoubleRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE double validate_DoubleRules_gte(const validate_DoubleRules *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(40, 40)); } +UPB_INLINE double const* validate_DoubleRules_in(const validate_DoubleRules *msg, size_t *len) { return (double const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE double const* validate_DoubleRules_not_in(const validate_DoubleRules *msg, size_t *len) { return (double const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_DoubleRules_set_const(validate_DoubleRules *msg, double value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, double, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_DoubleRules_set_lt(validate_DoubleRules *msg, double value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, double, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_DoubleRules_set_lte(validate_DoubleRules *msg, double value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_DoubleRules_set_gt(validate_DoubleRules *msg, double value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, double, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_DoubleRules_set_gte(validate_DoubleRules *msg, double value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, double, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE double* validate_DoubleRules_mutable_in(validate_DoubleRules *msg, size_t *len) { + return (double*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE double* validate_DoubleRules_resize_in(validate_DoubleRules *msg, size_t len, upb_arena *arena) { + return (double*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_DOUBLE, arena); +} +UPB_INLINE bool validate_DoubleRules_add_in(validate_DoubleRules *msg, double val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_DOUBLE, &val, arena); +} +UPB_INLINE double* validate_DoubleRules_mutable_not_in(validate_DoubleRules *msg, size_t *len) { + return (double*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE double* validate_DoubleRules_resize_not_in(validate_DoubleRules *msg, size_t len, upb_arena *arena) { + return (double*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_DOUBLE, arena); +} +UPB_INLINE bool validate_DoubleRules_add_not_in(validate_DoubleRules *msg, double val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_DOUBLE, &val, arena); +} + + +/* validate.Int32Rules */ + +UPB_INLINE validate_Int32Rules *validate_Int32Rules_new(upb_arena *arena) { + return (validate_Int32Rules *)upb_msg_new(&validate_Int32Rules_msginit, arena); +} +UPB_INLINE validate_Int32Rules *validate_Int32Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_Int32Rules *ret = validate_Int32Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_Int32Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_Int32Rules_serialize(const validate_Int32Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_Int32Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_Int32Rules_has_const(const validate_Int32Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t validate_Int32Rules_const(const validate_Int32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_Int32Rules_has_lt(const validate_Int32Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t validate_Int32Rules_lt(const validate_Int32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_Int32Rules_has_lte(const validate_Int32Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int32_t validate_Int32Rules_lte(const validate_Int32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_Int32Rules_has_gt(const validate_Int32Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int32_t validate_Int32Rules_gt(const validate_Int32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_Int32Rules_has_gte(const validate_Int32Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int32_t validate_Int32Rules_gte(const validate_Int32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)); } +UPB_INLINE int32_t const* validate_Int32Rules_in(const validate_Int32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE int32_t const* validate_Int32Rules_not_in(const validate_Int32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_Int32Rules_set_const(validate_Int32Rules *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_Int32Rules_set_lt(validate_Int32Rules *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_Int32Rules_set_lte(validate_Int32Rules *msg, int32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_Int32Rules_set_gt(validate_Int32Rules *msg, int32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_Int32Rules_set_gte(validate_Int32Rules *msg, int32_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE int32_t* validate_Int32Rules_mutable_in(validate_Int32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE int32_t* validate_Int32Rules_resize_in(validate_Int32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_Int32Rules_add_in(validate_Int32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* validate_Int32Rules_mutable_not_in(validate_Int32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE int32_t* validate_Int32Rules_resize_not_in(validate_Int32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_Int32Rules_add_not_in(validate_Int32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} + + +/* validate.Int64Rules */ + +UPB_INLINE validate_Int64Rules *validate_Int64Rules_new(upb_arena *arena) { + return (validate_Int64Rules *)upb_msg_new(&validate_Int64Rules_msginit, arena); +} +UPB_INLINE validate_Int64Rules *validate_Int64Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_Int64Rules *ret = validate_Int64Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_Int64Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_Int64Rules_serialize(const validate_Int64Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_Int64Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_Int64Rules_has_const(const validate_Int64Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int64_t validate_Int64Rules_const(const validate_Int64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_Int64Rules_has_lt(const validate_Int64Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int64_t validate_Int64Rules_lt(const validate_Int64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_Int64Rules_has_lte(const validate_Int64Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int64_t validate_Int64Rules_lte(const validate_Int64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_Int64Rules_has_gt(const validate_Int64Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int64_t validate_Int64Rules_gt(const validate_Int64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_Int64Rules_has_gte(const validate_Int64Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int64_t validate_Int64Rules_gte(const validate_Int64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)); } +UPB_INLINE int64_t const* validate_Int64Rules_in(const validate_Int64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE int64_t const* validate_Int64Rules_not_in(const validate_Int64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_Int64Rules_set_const(validate_Int64Rules *msg, int64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_Int64Rules_set_lt(validate_Int64Rules *msg, int64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_Int64Rules_set_lte(validate_Int64Rules *msg, int64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_Int64Rules_set_gt(validate_Int64Rules *msg, int64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_Int64Rules_set_gte(validate_Int64Rules *msg, int64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE int64_t* validate_Int64Rules_mutable_in(validate_Int64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE int64_t* validate_Int64Rules_resize_in(validate_Int64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_Int64Rules_add_in(validate_Int64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} +UPB_INLINE int64_t* validate_Int64Rules_mutable_not_in(validate_Int64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE int64_t* validate_Int64Rules_resize_not_in(validate_Int64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_Int64Rules_add_not_in(validate_Int64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} + + +/* validate.UInt32Rules */ + +UPB_INLINE validate_UInt32Rules *validate_UInt32Rules_new(upb_arena *arena) { + return (validate_UInt32Rules *)upb_msg_new(&validate_UInt32Rules_msginit, arena); +} +UPB_INLINE validate_UInt32Rules *validate_UInt32Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_UInt32Rules *ret = validate_UInt32Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_UInt32Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_UInt32Rules_serialize(const validate_UInt32Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_UInt32Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_UInt32Rules_has_const(const validate_UInt32Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint32_t validate_UInt32Rules_const(const validate_UInt32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_UInt32Rules_has_lt(const validate_UInt32Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint32_t validate_UInt32Rules_lt(const validate_UInt32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_UInt32Rules_has_lte(const validate_UInt32Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint32_t validate_UInt32Rules_lte(const validate_UInt32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_UInt32Rules_has_gt(const validate_UInt32Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE uint32_t validate_UInt32Rules_gt(const validate_UInt32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_UInt32Rules_has_gte(const validate_UInt32Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE uint32_t validate_UInt32Rules_gte(const validate_UInt32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(20, 20)); } +UPB_INLINE uint32_t const* validate_UInt32Rules_in(const validate_UInt32Rules *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE uint32_t const* validate_UInt32Rules_not_in(const validate_UInt32Rules *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_UInt32Rules_set_const(validate_UInt32Rules *msg, uint32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_UInt32Rules_set_lt(validate_UInt32Rules *msg, uint32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_UInt32Rules_set_lte(validate_UInt32Rules *msg, uint32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_UInt32Rules_set_gt(validate_UInt32Rules *msg, uint32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_UInt32Rules_set_gte(validate_UInt32Rules *msg, uint32_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE uint32_t* validate_UInt32Rules_mutable_in(validate_UInt32Rules *msg, size_t *len) { + return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE uint32_t* validate_UInt32Rules_resize_in(validate_UInt32Rules *msg, size_t len, upb_arena *arena) { + return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_UINT32, arena); +} +UPB_INLINE bool validate_UInt32Rules_add_in(validate_UInt32Rules *msg, uint32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val, arena); +} +UPB_INLINE uint32_t* validate_UInt32Rules_mutable_not_in(validate_UInt32Rules *msg, size_t *len) { + return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE uint32_t* validate_UInt32Rules_resize_not_in(validate_UInt32Rules *msg, size_t len, upb_arena *arena) { + return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_UINT32, arena); +} +UPB_INLINE bool validate_UInt32Rules_add_not_in(validate_UInt32Rules *msg, uint32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val, arena); +} + + +/* validate.UInt64Rules */ + +UPB_INLINE validate_UInt64Rules *validate_UInt64Rules_new(upb_arena *arena) { + return (validate_UInt64Rules *)upb_msg_new(&validate_UInt64Rules_msginit, arena); +} +UPB_INLINE validate_UInt64Rules *validate_UInt64Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_UInt64Rules *ret = validate_UInt64Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_UInt64Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_UInt64Rules_serialize(const validate_UInt64Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_UInt64Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_UInt64Rules_has_const(const validate_UInt64Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_UInt64Rules_const(const validate_UInt64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_UInt64Rules_has_lt(const validate_UInt64Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_UInt64Rules_lt(const validate_UInt64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_UInt64Rules_has_lte(const validate_UInt64Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint64_t validate_UInt64Rules_lte(const validate_UInt64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_UInt64Rules_has_gt(const validate_UInt64Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE uint64_t validate_UInt64Rules_gt(const validate_UInt64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_UInt64Rules_has_gte(const validate_UInt64Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE uint64_t validate_UInt64Rules_gte(const validate_UInt64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)); } +UPB_INLINE uint64_t const* validate_UInt64Rules_in(const validate_UInt64Rules *msg, size_t *len) { return (uint64_t const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE uint64_t const* validate_UInt64Rules_not_in(const validate_UInt64Rules *msg, size_t *len) { return (uint64_t const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_UInt64Rules_set_const(validate_UInt64Rules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_UInt64Rules_set_lt(validate_UInt64Rules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_UInt64Rules_set_lte(validate_UInt64Rules *msg, uint64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_UInt64Rules_set_gt(validate_UInt64Rules *msg, uint64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_UInt64Rules_set_gte(validate_UInt64Rules *msg, uint64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE uint64_t* validate_UInt64Rules_mutable_in(validate_UInt64Rules *msg, size_t *len) { + return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE uint64_t* validate_UInt64Rules_resize_in(validate_UInt64Rules *msg, size_t len, upb_arena *arena) { + return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_UINT64, arena); +} +UPB_INLINE bool validate_UInt64Rules_add_in(validate_UInt64Rules *msg, uint64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val, arena); +} +UPB_INLINE uint64_t* validate_UInt64Rules_mutable_not_in(validate_UInt64Rules *msg, size_t *len) { + return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE uint64_t* validate_UInt64Rules_resize_not_in(validate_UInt64Rules *msg, size_t len, upb_arena *arena) { + return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_UINT64, arena); +} +UPB_INLINE bool validate_UInt64Rules_add_not_in(validate_UInt64Rules *msg, uint64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val, arena); +} + + +/* validate.SInt32Rules */ + +UPB_INLINE validate_SInt32Rules *validate_SInt32Rules_new(upb_arena *arena) { + return (validate_SInt32Rules *)upb_msg_new(&validate_SInt32Rules_msginit, arena); +} +UPB_INLINE validate_SInt32Rules *validate_SInt32Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_SInt32Rules *ret = validate_SInt32Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_SInt32Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_SInt32Rules_serialize(const validate_SInt32Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_SInt32Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_SInt32Rules_has_const(const validate_SInt32Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t validate_SInt32Rules_const(const validate_SInt32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_SInt32Rules_has_lt(const validate_SInt32Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t validate_SInt32Rules_lt(const validate_SInt32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_SInt32Rules_has_lte(const validate_SInt32Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int32_t validate_SInt32Rules_lte(const validate_SInt32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_SInt32Rules_has_gt(const validate_SInt32Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int32_t validate_SInt32Rules_gt(const validate_SInt32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_SInt32Rules_has_gte(const validate_SInt32Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int32_t validate_SInt32Rules_gte(const validate_SInt32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)); } +UPB_INLINE int32_t const* validate_SInt32Rules_in(const validate_SInt32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE int32_t const* validate_SInt32Rules_not_in(const validate_SInt32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_SInt32Rules_set_const(validate_SInt32Rules *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_SInt32Rules_set_lt(validate_SInt32Rules *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_SInt32Rules_set_lte(validate_SInt32Rules *msg, int32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_SInt32Rules_set_gt(validate_SInt32Rules *msg, int32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_SInt32Rules_set_gte(validate_SInt32Rules *msg, int32_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE int32_t* validate_SInt32Rules_mutable_in(validate_SInt32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE int32_t* validate_SInt32Rules_resize_in(validate_SInt32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_SInt32Rules_add_in(validate_SInt32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* validate_SInt32Rules_mutable_not_in(validate_SInt32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE int32_t* validate_SInt32Rules_resize_not_in(validate_SInt32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_SInt32Rules_add_not_in(validate_SInt32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} + + +/* validate.SInt64Rules */ + +UPB_INLINE validate_SInt64Rules *validate_SInt64Rules_new(upb_arena *arena) { + return (validate_SInt64Rules *)upb_msg_new(&validate_SInt64Rules_msginit, arena); +} +UPB_INLINE validate_SInt64Rules *validate_SInt64Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_SInt64Rules *ret = validate_SInt64Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_SInt64Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_SInt64Rules_serialize(const validate_SInt64Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_SInt64Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_SInt64Rules_has_const(const validate_SInt64Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int64_t validate_SInt64Rules_const(const validate_SInt64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_SInt64Rules_has_lt(const validate_SInt64Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int64_t validate_SInt64Rules_lt(const validate_SInt64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_SInt64Rules_has_lte(const validate_SInt64Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int64_t validate_SInt64Rules_lte(const validate_SInt64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_SInt64Rules_has_gt(const validate_SInt64Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int64_t validate_SInt64Rules_gt(const validate_SInt64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_SInt64Rules_has_gte(const validate_SInt64Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int64_t validate_SInt64Rules_gte(const validate_SInt64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)); } +UPB_INLINE int64_t const* validate_SInt64Rules_in(const validate_SInt64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE int64_t const* validate_SInt64Rules_not_in(const validate_SInt64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_SInt64Rules_set_const(validate_SInt64Rules *msg, int64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_SInt64Rules_set_lt(validate_SInt64Rules *msg, int64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_SInt64Rules_set_lte(validate_SInt64Rules *msg, int64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_SInt64Rules_set_gt(validate_SInt64Rules *msg, int64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_SInt64Rules_set_gte(validate_SInt64Rules *msg, int64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE int64_t* validate_SInt64Rules_mutable_in(validate_SInt64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE int64_t* validate_SInt64Rules_resize_in(validate_SInt64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_SInt64Rules_add_in(validate_SInt64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} +UPB_INLINE int64_t* validate_SInt64Rules_mutable_not_in(validate_SInt64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE int64_t* validate_SInt64Rules_resize_not_in(validate_SInt64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_SInt64Rules_add_not_in(validate_SInt64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} + + +/* validate.Fixed32Rules */ + +UPB_INLINE validate_Fixed32Rules *validate_Fixed32Rules_new(upb_arena *arena) { + return (validate_Fixed32Rules *)upb_msg_new(&validate_Fixed32Rules_msginit, arena); +} +UPB_INLINE validate_Fixed32Rules *validate_Fixed32Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_Fixed32Rules *ret = validate_Fixed32Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_Fixed32Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_Fixed32Rules_serialize(const validate_Fixed32Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_Fixed32Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_Fixed32Rules_has_const(const validate_Fixed32Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint32_t validate_Fixed32Rules_const(const validate_Fixed32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_Fixed32Rules_has_lt(const validate_Fixed32Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint32_t validate_Fixed32Rules_lt(const validate_Fixed32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_Fixed32Rules_has_lte(const validate_Fixed32Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint32_t validate_Fixed32Rules_lte(const validate_Fixed32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_Fixed32Rules_has_gt(const validate_Fixed32Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE uint32_t validate_Fixed32Rules_gt(const validate_Fixed32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_Fixed32Rules_has_gte(const validate_Fixed32Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE uint32_t validate_Fixed32Rules_gte(const validate_Fixed32Rules *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(20, 20)); } +UPB_INLINE uint32_t const* validate_Fixed32Rules_in(const validate_Fixed32Rules *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE uint32_t const* validate_Fixed32Rules_not_in(const validate_Fixed32Rules *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_Fixed32Rules_set_const(validate_Fixed32Rules *msg, uint32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_Fixed32Rules_set_lt(validate_Fixed32Rules *msg, uint32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_Fixed32Rules_set_lte(validate_Fixed32Rules *msg, uint32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_Fixed32Rules_set_gt(validate_Fixed32Rules *msg, uint32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_Fixed32Rules_set_gte(validate_Fixed32Rules *msg, uint32_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE uint32_t* validate_Fixed32Rules_mutable_in(validate_Fixed32Rules *msg, size_t *len) { + return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE uint32_t* validate_Fixed32Rules_resize_in(validate_Fixed32Rules *msg, size_t len, upb_arena *arena) { + return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_UINT32, arena); +} +UPB_INLINE bool validate_Fixed32Rules_add_in(validate_Fixed32Rules *msg, uint32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val, arena); +} +UPB_INLINE uint32_t* validate_Fixed32Rules_mutable_not_in(validate_Fixed32Rules *msg, size_t *len) { + return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE uint32_t* validate_Fixed32Rules_resize_not_in(validate_Fixed32Rules *msg, size_t len, upb_arena *arena) { + return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_UINT32, arena); +} +UPB_INLINE bool validate_Fixed32Rules_add_not_in(validate_Fixed32Rules *msg, uint32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val, arena); +} + + +/* validate.Fixed64Rules */ + +UPB_INLINE validate_Fixed64Rules *validate_Fixed64Rules_new(upb_arena *arena) { + return (validate_Fixed64Rules *)upb_msg_new(&validate_Fixed64Rules_msginit, arena); +} +UPB_INLINE validate_Fixed64Rules *validate_Fixed64Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_Fixed64Rules *ret = validate_Fixed64Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_Fixed64Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_Fixed64Rules_serialize(const validate_Fixed64Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_Fixed64Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_Fixed64Rules_has_const(const validate_Fixed64Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_Fixed64Rules_const(const validate_Fixed64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_Fixed64Rules_has_lt(const validate_Fixed64Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_Fixed64Rules_lt(const validate_Fixed64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_Fixed64Rules_has_lte(const validate_Fixed64Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint64_t validate_Fixed64Rules_lte(const validate_Fixed64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_Fixed64Rules_has_gt(const validate_Fixed64Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE uint64_t validate_Fixed64Rules_gt(const validate_Fixed64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_Fixed64Rules_has_gte(const validate_Fixed64Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE uint64_t validate_Fixed64Rules_gte(const validate_Fixed64Rules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)); } +UPB_INLINE uint64_t const* validate_Fixed64Rules_in(const validate_Fixed64Rules *msg, size_t *len) { return (uint64_t const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE uint64_t const* validate_Fixed64Rules_not_in(const validate_Fixed64Rules *msg, size_t *len) { return (uint64_t const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_Fixed64Rules_set_const(validate_Fixed64Rules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_Fixed64Rules_set_lt(validate_Fixed64Rules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_Fixed64Rules_set_lte(validate_Fixed64Rules *msg, uint64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_Fixed64Rules_set_gt(validate_Fixed64Rules *msg, uint64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_Fixed64Rules_set_gte(validate_Fixed64Rules *msg, uint64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE uint64_t* validate_Fixed64Rules_mutable_in(validate_Fixed64Rules *msg, size_t *len) { + return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE uint64_t* validate_Fixed64Rules_resize_in(validate_Fixed64Rules *msg, size_t len, upb_arena *arena) { + return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_UINT64, arena); +} +UPB_INLINE bool validate_Fixed64Rules_add_in(validate_Fixed64Rules *msg, uint64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val, arena); +} +UPB_INLINE uint64_t* validate_Fixed64Rules_mutable_not_in(validate_Fixed64Rules *msg, size_t *len) { + return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE uint64_t* validate_Fixed64Rules_resize_not_in(validate_Fixed64Rules *msg, size_t len, upb_arena *arena) { + return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_UINT64, arena); +} +UPB_INLINE bool validate_Fixed64Rules_add_not_in(validate_Fixed64Rules *msg, uint64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val, arena); +} + + +/* validate.SFixed32Rules */ + +UPB_INLINE validate_SFixed32Rules *validate_SFixed32Rules_new(upb_arena *arena) { + return (validate_SFixed32Rules *)upb_msg_new(&validate_SFixed32Rules_msginit, arena); +} +UPB_INLINE validate_SFixed32Rules *validate_SFixed32Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_SFixed32Rules *ret = validate_SFixed32Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_SFixed32Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_SFixed32Rules_serialize(const validate_SFixed32Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_SFixed32Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_SFixed32Rules_has_const(const validate_SFixed32Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t validate_SFixed32Rules_const(const validate_SFixed32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_SFixed32Rules_has_lt(const validate_SFixed32Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int32_t validate_SFixed32Rules_lt(const validate_SFixed32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_SFixed32Rules_has_lte(const validate_SFixed32Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int32_t validate_SFixed32Rules_lte(const validate_SFixed32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)); } +UPB_INLINE bool validate_SFixed32Rules_has_gt(const validate_SFixed32Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int32_t validate_SFixed32Rules_gt(const validate_SFixed32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_SFixed32Rules_has_gte(const validate_SFixed32Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int32_t validate_SFixed32Rules_gte(const validate_SFixed32Rules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)); } +UPB_INLINE int32_t const* validate_SFixed32Rules_in(const validate_SFixed32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 24), len); } +UPB_INLINE int32_t const* validate_SFixed32Rules_not_in(const validate_SFixed32Rules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } + +UPB_INLINE void validate_SFixed32Rules_set_const(validate_SFixed32Rules *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_SFixed32Rules_set_lt(validate_SFixed32Rules *msg, int32_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_SFixed32Rules_set_lte(validate_SFixed32Rules *msg, int32_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(12, 12)) = value; +} +UPB_INLINE void validate_SFixed32Rules_set_gt(validate_SFixed32Rules *msg, int32_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_SFixed32Rules_set_gte(validate_SFixed32Rules *msg, int32_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(20, 20)) = value; +} +UPB_INLINE int32_t* validate_SFixed32Rules_mutable_in(validate_SFixed32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len); +} +UPB_INLINE int32_t* validate_SFixed32Rules_resize_in(validate_SFixed32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_SFixed32Rules_add_in(validate_SFixed32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* validate_SFixed32Rules_mutable_not_in(validate_SFixed32Rules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len); +} +UPB_INLINE int32_t* validate_SFixed32Rules_resize_not_in(validate_SFixed32Rules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_SFixed32Rules_add_not_in(validate_SFixed32Rules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} + + +/* validate.SFixed64Rules */ + +UPB_INLINE validate_SFixed64Rules *validate_SFixed64Rules_new(upb_arena *arena) { + return (validate_SFixed64Rules *)upb_msg_new(&validate_SFixed64Rules_msginit, arena); +} +UPB_INLINE validate_SFixed64Rules *validate_SFixed64Rules_parsenew(upb_strview buf, upb_arena *arena) { + validate_SFixed64Rules *ret = validate_SFixed64Rules_new(arena); + return (ret && upb_decode(buf, ret, &validate_SFixed64Rules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_SFixed64Rules_serialize(const validate_SFixed64Rules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_SFixed64Rules_msginit, arena, len); +} + +UPB_INLINE bool validate_SFixed64Rules_has_const(const validate_SFixed64Rules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int64_t validate_SFixed64Rules_const(const validate_SFixed64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_SFixed64Rules_has_lt(const validate_SFixed64Rules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE int64_t validate_SFixed64Rules_lt(const validate_SFixed64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_SFixed64Rules_has_lte(const validate_SFixed64Rules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE int64_t validate_SFixed64Rules_lte(const validate_SFixed64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_SFixed64Rules_has_gt(const validate_SFixed64Rules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE int64_t validate_SFixed64Rules_gt(const validate_SFixed64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_SFixed64Rules_has_gte(const validate_SFixed64Rules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE int64_t validate_SFixed64Rules_gte(const validate_SFixed64Rules *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)); } +UPB_INLINE int64_t const* validate_SFixed64Rules_in(const validate_SFixed64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(48, 48), len); } +UPB_INLINE int64_t const* validate_SFixed64Rules_not_in(const validate_SFixed64Rules *msg, size_t *len) { return (int64_t const*)_upb_array_accessor(msg, UPB_SIZE(52, 56), len); } + +UPB_INLINE void validate_SFixed64Rules_set_const(validate_SFixed64Rules *msg, int64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_SFixed64Rules_set_lt(validate_SFixed64Rules *msg, int64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_SFixed64Rules_set_lte(validate_SFixed64Rules *msg, int64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_SFixed64Rules_set_gt(validate_SFixed64Rules *msg, int64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_SFixed64Rules_set_gte(validate_SFixed64Rules *msg, int64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, int64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE int64_t* validate_SFixed64Rules_mutable_in(validate_SFixed64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len); +} +UPB_INLINE int64_t* validate_SFixed64Rules_resize_in(validate_SFixed64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_SFixed64Rules_add_in(validate_SFixed64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} +UPB_INLINE int64_t* validate_SFixed64Rules_mutable_not_in(validate_SFixed64Rules *msg, size_t *len) { + return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len); +} +UPB_INLINE int64_t* validate_SFixed64Rules_resize_not_in(validate_SFixed64Rules *msg, size_t len, upb_arena *arena) { + return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_SIZE(8, 8), UPB_TYPE_INT64, arena); +} +UPB_INLINE bool validate_SFixed64Rules_add_not_in(validate_SFixed64Rules *msg, int64_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val, arena); +} + + +/* validate.BoolRules */ + +UPB_INLINE validate_BoolRules *validate_BoolRules_new(upb_arena *arena) { + return (validate_BoolRules *)upb_msg_new(&validate_BoolRules_msginit, arena); +} +UPB_INLINE validate_BoolRules *validate_BoolRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_BoolRules *ret = validate_BoolRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_BoolRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_BoolRules_serialize(const validate_BoolRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_BoolRules_msginit, arena, len); +} + +UPB_INLINE bool validate_BoolRules_has_const(const validate_BoolRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool validate_BoolRules_const(const validate_BoolRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } + +UPB_INLINE void validate_BoolRules_set_const(validate_BoolRules *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} + + +/* validate.StringRules */ + +UPB_INLINE validate_StringRules *validate_StringRules_new(upb_arena *arena) { + return (validate_StringRules *)upb_msg_new(&validate_StringRules_msginit, arena); +} +UPB_INLINE validate_StringRules *validate_StringRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_StringRules *ret = validate_StringRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_StringRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_StringRules_serialize(const validate_StringRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_StringRules_msginit, arena, len); +} + +typedef enum { + validate_StringRules_well_known_email = 12, + validate_StringRules_well_known_hostname = 13, + validate_StringRules_well_known_ip = 14, + validate_StringRules_well_known_ipv4 = 15, + validate_StringRules_well_known_ipv6 = 16, + validate_StringRules_well_known_uri = 17, + validate_StringRules_well_known_uri_ref = 18, + validate_StringRules_well_known_NOT_SET = 0, +} validate_StringRules_well_known_oneofcases; +UPB_INLINE validate_StringRules_well_known_oneofcases validate_StringRules_well_known_case(const validate_StringRules* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(108, 156)); } + +UPB_INLINE bool validate_StringRules_has_const(const validate_StringRules *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE upb_strview validate_StringRules_const(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 56)); } +UPB_INLINE bool validate_StringRules_has_min_len(const validate_StringRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_StringRules_min_len(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_StringRules_has_max_len(const validate_StringRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_StringRules_max_len(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_StringRules_has_min_bytes(const validate_StringRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint64_t validate_StringRules_min_bytes(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_StringRules_has_max_bytes(const validate_StringRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE uint64_t validate_StringRules_max_bytes(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_StringRules_has_pattern(const validate_StringRules *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE upb_strview validate_StringRules_pattern(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 72)); } +UPB_INLINE bool validate_StringRules_has_prefix(const validate_StringRules *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE upb_strview validate_StringRules_prefix(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(72, 88)); } +UPB_INLINE bool validate_StringRules_has_suffix(const validate_StringRules *msg) { return _upb_has_field(msg, 10); } +UPB_INLINE upb_strview validate_StringRules_suffix(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(80, 104)); } +UPB_INLINE bool validate_StringRules_has_contains(const validate_StringRules *msg) { return _upb_has_field(msg, 11); } +UPB_INLINE upb_strview validate_StringRules_contains(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(88, 120)); } +UPB_INLINE upb_strview const* validate_StringRules_in(const validate_StringRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(96, 136), len); } +UPB_INLINE upb_strview const* validate_StringRules_not_in(const validate_StringRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(100, 144), len); } +UPB_INLINE bool validate_StringRules_has_email(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 12); } +UPB_INLINE bool validate_StringRules_email(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 12, false); } +UPB_INLINE bool validate_StringRules_has_hostname(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 13); } +UPB_INLINE bool validate_StringRules_hostname(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 13, false); } +UPB_INLINE bool validate_StringRules_has_ip(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 14); } +UPB_INLINE bool validate_StringRules_ip(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 14, false); } +UPB_INLINE bool validate_StringRules_has_ipv4(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 15); } +UPB_INLINE bool validate_StringRules_ipv4(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 15, false); } +UPB_INLINE bool validate_StringRules_has_ipv6(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 16); } +UPB_INLINE bool validate_StringRules_ipv6(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 16, false); } +UPB_INLINE bool validate_StringRules_has_uri(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 17); } +UPB_INLINE bool validate_StringRules_uri(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 17, false); } +UPB_INLINE bool validate_StringRules_has_uri_ref(const validate_StringRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(108, 156), 18); } +UPB_INLINE bool validate_StringRules_uri_ref(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(104, 152), UPB_SIZE(108, 156), 18, false); } +UPB_INLINE bool validate_StringRules_has_len(const validate_StringRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE uint64_t validate_StringRules_len(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)); } +UPB_INLINE bool validate_StringRules_has_len_bytes(const validate_StringRules *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE uint64_t validate_StringRules_len_bytes(const validate_StringRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(48, 48)); } + +UPB_INLINE void validate_StringRules_set_const(validate_StringRules *msg, upb_strview value) { + _upb_sethas(msg, 7); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 56)) = value; +} +UPB_INLINE void validate_StringRules_set_min_len(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_StringRules_set_max_len(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_StringRules_set_min_bytes(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_StringRules_set_max_bytes(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_StringRules_set_pattern(validate_StringRules *msg, upb_strview value) { + _upb_sethas(msg, 8); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 72)) = value; +} +UPB_INLINE void validate_StringRules_set_prefix(validate_StringRules *msg, upb_strview value) { + _upb_sethas(msg, 9); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(72, 88)) = value; +} +UPB_INLINE void validate_StringRules_set_suffix(validate_StringRules *msg, upb_strview value) { + _upb_sethas(msg, 10); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(80, 104)) = value; +} +UPB_INLINE void validate_StringRules_set_contains(validate_StringRules *msg, upb_strview value) { + _upb_sethas(msg, 11); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(88, 120)) = value; +} +UPB_INLINE upb_strview* validate_StringRules_mutable_in(validate_StringRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(96, 136), len); +} +UPB_INLINE upb_strview* validate_StringRules_resize_in(validate_StringRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(96, 136), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_StringRules_add_in(validate_StringRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(96, 136), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* validate_StringRules_mutable_not_in(validate_StringRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(100, 144), len); +} +UPB_INLINE upb_strview* validate_StringRules_resize_not_in(validate_StringRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(100, 144), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_StringRules_add_not_in(validate_StringRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(100, 144), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE void validate_StringRules_set_email(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 12); +} +UPB_INLINE void validate_StringRules_set_hostname(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 13); +} +UPB_INLINE void validate_StringRules_set_ip(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 14); +} +UPB_INLINE void validate_StringRules_set_ipv4(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 15); +} +UPB_INLINE void validate_StringRules_set_ipv6(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 16); +} +UPB_INLINE void validate_StringRules_set_uri(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 17); +} +UPB_INLINE void validate_StringRules_set_uri_ref(validate_StringRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(104, 152), value, UPB_SIZE(108, 156), 18); +} +UPB_INLINE void validate_StringRules_set_len(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(40, 40)) = value; +} +UPB_INLINE void validate_StringRules_set_len_bytes(validate_StringRules *msg, uint64_t value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(48, 48)) = value; +} + + +/* validate.BytesRules */ + +UPB_INLINE validate_BytesRules *validate_BytesRules_new(upb_arena *arena) { + return (validate_BytesRules *)upb_msg_new(&validate_BytesRules_msginit, arena); +} +UPB_INLINE validate_BytesRules *validate_BytesRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_BytesRules *ret = validate_BytesRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_BytesRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_BytesRules_serialize(const validate_BytesRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_BytesRules_msginit, arena, len); +} + +typedef enum { + validate_BytesRules_well_known_ip = 10, + validate_BytesRules_well_known_ipv4 = 11, + validate_BytesRules_well_known_ipv6 = 12, + validate_BytesRules_well_known_NOT_SET = 0, +} validate_BytesRules_well_known_oneofcases; +UPB_INLINE validate_BytesRules_well_known_oneofcases validate_BytesRules_well_known_case(const validate_BytesRules* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(84, 132)); } + +UPB_INLINE bool validate_BytesRules_has_const(const validate_BytesRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE upb_strview validate_BytesRules_const(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)); } +UPB_INLINE bool validate_BytesRules_has_min_len(const validate_BytesRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_BytesRules_min_len(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_BytesRules_has_max_len(const validate_BytesRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_BytesRules_max_len(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_BytesRules_has_pattern(const validate_BytesRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE upb_strview validate_BytesRules_pattern(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)); } +UPB_INLINE bool validate_BytesRules_has_prefix(const validate_BytesRules *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE upb_strview validate_BytesRules_prefix(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)); } +UPB_INLINE bool validate_BytesRules_has_suffix(const validate_BytesRules *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE upb_strview validate_BytesRules_suffix(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)); } +UPB_INLINE bool validate_BytesRules_has_contains(const validate_BytesRules *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE upb_strview validate_BytesRules_contains(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)); } +UPB_INLINE upb_strview const* validate_BytesRules_in(const validate_BytesRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(72, 112), len); } +UPB_INLINE upb_strview const* validate_BytesRules_not_in(const validate_BytesRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(76, 120), len); } +UPB_INLINE bool validate_BytesRules_has_ip(const validate_BytesRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(84, 132), 10); } +UPB_INLINE bool validate_BytesRules_ip(const validate_BytesRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(80, 128), UPB_SIZE(84, 132), 10, false); } +UPB_INLINE bool validate_BytesRules_has_ipv4(const validate_BytesRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(84, 132), 11); } +UPB_INLINE bool validate_BytesRules_ipv4(const validate_BytesRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(80, 128), UPB_SIZE(84, 132), 11, false); } +UPB_INLINE bool validate_BytesRules_has_ipv6(const validate_BytesRules *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(84, 132), 12); } +UPB_INLINE bool validate_BytesRules_ipv6(const validate_BytesRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(80, 128), UPB_SIZE(84, 132), 12, false); } +UPB_INLINE bool validate_BytesRules_has_len(const validate_BytesRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE uint64_t validate_BytesRules_len(const validate_BytesRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)); } + +UPB_INLINE void validate_BytesRules_set_const(validate_BytesRules *msg, upb_strview value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void validate_BytesRules_set_min_len(validate_BytesRules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_BytesRules_set_max_len(validate_BytesRules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_BytesRules_set_pattern(validate_BytesRules *msg, upb_strview value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)) = value; +} +UPB_INLINE void validate_BytesRules_set_prefix(validate_BytesRules *msg, upb_strview value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)) = value; +} +UPB_INLINE void validate_BytesRules_set_suffix(validate_BytesRules *msg, upb_strview value) { + _upb_sethas(msg, 7); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE void validate_BytesRules_set_contains(validate_BytesRules *msg, upb_strview value) { + _upb_sethas(msg, 8); + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)) = value; +} +UPB_INLINE upb_strview* validate_BytesRules_mutable_in(validate_BytesRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(72, 112), len); +} +UPB_INLINE upb_strview* validate_BytesRules_resize_in(validate_BytesRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(72, 112), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_BytesRules_add_in(validate_BytesRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(72, 112), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* validate_BytesRules_mutable_not_in(validate_BytesRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(76, 120), len); +} +UPB_INLINE upb_strview* validate_BytesRules_resize_not_in(validate_BytesRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(76, 120), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_BytesRules_add_not_in(validate_BytesRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(76, 120), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE void validate_BytesRules_set_ip(validate_BytesRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(80, 128), value, UPB_SIZE(84, 132), 10); +} +UPB_INLINE void validate_BytesRules_set_ipv4(validate_BytesRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(80, 128), value, UPB_SIZE(84, 132), 11); +} +UPB_INLINE void validate_BytesRules_set_ipv6(validate_BytesRules *msg, bool value) { + UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(80, 128), value, UPB_SIZE(84, 132), 12); +} +UPB_INLINE void validate_BytesRules_set_len(validate_BytesRules *msg, uint64_t value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(24, 24)) = value; +} + + +/* validate.EnumRules */ + +UPB_INLINE validate_EnumRules *validate_EnumRules_new(upb_arena *arena) { + return (validate_EnumRules *)upb_msg_new(&validate_EnumRules_msginit, arena); +} +UPB_INLINE validate_EnumRules *validate_EnumRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_EnumRules *ret = validate_EnumRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_EnumRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_EnumRules_serialize(const validate_EnumRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_EnumRules_msginit, arena, len); +} + +UPB_INLINE bool validate_EnumRules_has_const(const validate_EnumRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE int32_t validate_EnumRules_const(const validate_EnumRules *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_EnumRules_has_defined_only(const validate_EnumRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool validate_EnumRules_defined_only(const validate_EnumRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t const* validate_EnumRules_in(const validate_EnumRules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(12, 16), len); } +UPB_INLINE int32_t const* validate_EnumRules_not_in(const validate_EnumRules *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(16, 24), len); } + +UPB_INLINE void validate_EnumRules_set_const(validate_EnumRules *msg, int32_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_EnumRules_set_defined_only(validate_EnumRules *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE int32_t* validate_EnumRules_mutable_in(validate_EnumRules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 16), len); +} +UPB_INLINE int32_t* validate_EnumRules_resize_in(validate_EnumRules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(12, 16), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_EnumRules_add_in(validate_EnumRules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(12, 16), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} +UPB_INLINE int32_t* validate_EnumRules_mutable_not_in(validate_EnumRules *msg, size_t *len) { + return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 24), len); +} +UPB_INLINE int32_t* validate_EnumRules_resize_not_in(validate_EnumRules *msg, size_t len, upb_arena *arena) { + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(16, 24), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena); +} +UPB_INLINE bool validate_EnumRules_add_not_in(validate_EnumRules *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(16, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena); +} + + +/* validate.MessageRules */ + +UPB_INLINE validate_MessageRules *validate_MessageRules_new(upb_arena *arena) { + return (validate_MessageRules *)upb_msg_new(&validate_MessageRules_msginit, arena); +} +UPB_INLINE validate_MessageRules *validate_MessageRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_MessageRules *ret = validate_MessageRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_MessageRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_MessageRules_serialize(const validate_MessageRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_MessageRules_msginit, arena, len); +} + +UPB_INLINE bool validate_MessageRules_has_skip(const validate_MessageRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool validate_MessageRules_skip(const validate_MessageRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool validate_MessageRules_has_required(const validate_MessageRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool validate_MessageRules_required(const validate_MessageRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } + +UPB_INLINE void validate_MessageRules_set_skip(validate_MessageRules *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void validate_MessageRules_set_required(validate_MessageRules *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} + + +/* validate.RepeatedRules */ + +UPB_INLINE validate_RepeatedRules *validate_RepeatedRules_new(upb_arena *arena) { + return (validate_RepeatedRules *)upb_msg_new(&validate_RepeatedRules_msginit, arena); +} +UPB_INLINE validate_RepeatedRules *validate_RepeatedRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_RepeatedRules *ret = validate_RepeatedRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_RepeatedRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_RepeatedRules_serialize(const validate_RepeatedRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_RepeatedRules_msginit, arena, len); +} + +UPB_INLINE bool validate_RepeatedRules_has_min_items(const validate_RepeatedRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_RepeatedRules_min_items(const validate_RepeatedRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_RepeatedRules_has_max_items(const validate_RepeatedRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_RepeatedRules_max_items(const validate_RepeatedRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_RepeatedRules_has_unique(const validate_RepeatedRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool validate_RepeatedRules_unique(const validate_RepeatedRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_RepeatedRules_has_items(const validate_RepeatedRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE const validate_FieldRules* validate_RepeatedRules_items(const validate_RepeatedRules *msg) { return UPB_FIELD_AT(msg, const validate_FieldRules*, UPB_SIZE(28, 32)); } + +UPB_INLINE void validate_RepeatedRules_set_min_items(validate_RepeatedRules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_RepeatedRules_set_max_items(validate_RepeatedRules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_RepeatedRules_set_unique(validate_RepeatedRules *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_RepeatedRules_set_items(validate_RepeatedRules *msg, validate_FieldRules* value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, validate_FieldRules*, UPB_SIZE(28, 32)) = value; +} +UPB_INLINE struct validate_FieldRules* validate_RepeatedRules_mutable_items(validate_RepeatedRules *msg, upb_arena *arena) { + struct validate_FieldRules* sub = (struct validate_FieldRules*)validate_RepeatedRules_items(msg); + if (sub == NULL) { + sub = (struct validate_FieldRules*)upb_msg_new(&validate_FieldRules_msginit, arena); + if (!sub) return NULL; + validate_RepeatedRules_set_items(msg, sub); + } + return sub; +} + + +/* validate.MapRules */ + +UPB_INLINE validate_MapRules *validate_MapRules_new(upb_arena *arena) { + return (validate_MapRules *)upb_msg_new(&validate_MapRules_msginit, arena); +} +UPB_INLINE validate_MapRules *validate_MapRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_MapRules *ret = validate_MapRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_MapRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_MapRules_serialize(const validate_MapRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_MapRules_msginit, arena, len); +} + +UPB_INLINE bool validate_MapRules_has_min_pairs(const validate_MapRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE uint64_t validate_MapRules_min_pairs(const validate_MapRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_MapRules_has_max_pairs(const validate_MapRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE uint64_t validate_MapRules_max_pairs(const validate_MapRules *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)); } +UPB_INLINE bool validate_MapRules_has_no_sparse(const validate_MapRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool validate_MapRules_no_sparse(const validate_MapRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } +UPB_INLINE bool validate_MapRules_has_keys(const validate_MapRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE const validate_FieldRules* validate_MapRules_keys(const validate_MapRules *msg) { return UPB_FIELD_AT(msg, const validate_FieldRules*, UPB_SIZE(28, 32)); } +UPB_INLINE bool validate_MapRules_has_values(const validate_MapRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE const validate_FieldRules* validate_MapRules_values(const validate_MapRules *msg) { return UPB_FIELD_AT(msg, const validate_FieldRules*, UPB_SIZE(32, 40)); } + +UPB_INLINE void validate_MapRules_set_min_pairs(validate_MapRules *msg, uint64_t value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void validate_MapRules_set_max_pairs(validate_MapRules *msg, uint64_t value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE void validate_MapRules_set_no_sparse(validate_MapRules *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void validate_MapRules_set_keys(validate_MapRules *msg, validate_FieldRules* value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, validate_FieldRules*, UPB_SIZE(28, 32)) = value; +} +UPB_INLINE struct validate_FieldRules* validate_MapRules_mutable_keys(validate_MapRules *msg, upb_arena *arena) { + struct validate_FieldRules* sub = (struct validate_FieldRules*)validate_MapRules_keys(msg); + if (sub == NULL) { + sub = (struct validate_FieldRules*)upb_msg_new(&validate_FieldRules_msginit, arena); + if (!sub) return NULL; + validate_MapRules_set_keys(msg, sub); + } + return sub; +} +UPB_INLINE void validate_MapRules_set_values(validate_MapRules *msg, validate_FieldRules* value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, validate_FieldRules*, UPB_SIZE(32, 40)) = value; +} +UPB_INLINE struct validate_FieldRules* validate_MapRules_mutable_values(validate_MapRules *msg, upb_arena *arena) { + struct validate_FieldRules* sub = (struct validate_FieldRules*)validate_MapRules_values(msg); + if (sub == NULL) { + sub = (struct validate_FieldRules*)upb_msg_new(&validate_FieldRules_msginit, arena); + if (!sub) return NULL; + validate_MapRules_set_values(msg, sub); + } + return sub; +} + + +/* validate.AnyRules */ + +UPB_INLINE validate_AnyRules *validate_AnyRules_new(upb_arena *arena) { + return (validate_AnyRules *)upb_msg_new(&validate_AnyRules_msginit, arena); +} +UPB_INLINE validate_AnyRules *validate_AnyRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_AnyRules *ret = validate_AnyRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_AnyRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_AnyRules_serialize(const validate_AnyRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_AnyRules_msginit, arena, len); +} + +UPB_INLINE bool validate_AnyRules_has_required(const validate_AnyRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool validate_AnyRules_required(const validate_AnyRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE upb_strview const* validate_AnyRules_in(const validate_AnyRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } +UPB_INLINE upb_strview const* validate_AnyRules_not_in(const validate_AnyRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); } + +UPB_INLINE void validate_AnyRules_set_required(validate_AnyRules *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE upb_strview* validate_AnyRules_mutable_in(validate_AnyRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE upb_strview* validate_AnyRules_resize_in(validate_AnyRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_AnyRules_add_in(validate_AnyRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* validate_AnyRules_mutable_not_in(validate_AnyRules *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len); +} +UPB_INLINE upb_strview* validate_AnyRules_resize_not_in(validate_AnyRules *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool validate_AnyRules_add_not_in(validate_AnyRules *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(8, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* validate.DurationRules */ + +UPB_INLINE validate_DurationRules *validate_DurationRules_new(upb_arena *arena) { + return (validate_DurationRules *)upb_msg_new(&validate_DurationRules_msginit, arena); +} +UPB_INLINE validate_DurationRules *validate_DurationRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_DurationRules *ret = validate_DurationRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_DurationRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_DurationRules_serialize(const validate_DurationRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_DurationRules_msginit, arena, len); +} + +UPB_INLINE bool validate_DurationRules_has_required(const validate_DurationRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool validate_DurationRules_required(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); } +UPB_INLINE bool validate_DurationRules_has_const(const validate_DurationRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE const struct google_protobuf_Duration* validate_DurationRules_const(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(4, 8)); } +UPB_INLINE bool validate_DurationRules_has_lt(const validate_DurationRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE const struct google_protobuf_Duration* validate_DurationRules_lt(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(8, 16)); } +UPB_INLINE bool validate_DurationRules_has_lte(const validate_DurationRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE const struct google_protobuf_Duration* validate_DurationRules_lte(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(12, 24)); } +UPB_INLINE bool validate_DurationRules_has_gt(const validate_DurationRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE const struct google_protobuf_Duration* validate_DurationRules_gt(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(16, 32)); } +UPB_INLINE bool validate_DurationRules_has_gte(const validate_DurationRules *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE const struct google_protobuf_Duration* validate_DurationRules_gte(const validate_DurationRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(20, 40)); } +UPB_INLINE const struct google_protobuf_Duration* const* validate_DurationRules_in(const validate_DurationRules *msg, size_t *len) { return (const struct google_protobuf_Duration* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE const struct google_protobuf_Duration* const* validate_DurationRules_not_in(const validate_DurationRules *msg, size_t *len) { return (const struct google_protobuf_Duration* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } + +UPB_INLINE void validate_DurationRules_set_required(validate_DurationRules *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value; +} +UPB_INLINE void validate_DurationRules_set_const(validate_DurationRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_mutable_const(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_DurationRules_const(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_DurationRules_set_const(msg, sub); + } + return sub; +} +UPB_INLINE void validate_DurationRules_set_lt(validate_DurationRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_mutable_lt(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_DurationRules_lt(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_DurationRules_set_lt(msg, sub); + } + return sub; +} +UPB_INLINE void validate_DurationRules_set_lte(validate_DurationRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_mutable_lte(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_DurationRules_lte(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_DurationRules_set_lte(msg, sub); + } + return sub; +} +UPB_INLINE void validate_DurationRules_set_gt(validate_DurationRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_mutable_gt(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_DurationRules_gt(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_DurationRules_set_gt(msg, sub); + } + return sub; +} +UPB_INLINE void validate_DurationRules_set_gte(validate_DurationRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_mutable_gte(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_DurationRules_gte(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_DurationRules_set_gte(msg, sub); + } + return sub; +} +UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_mutable_in(validate_DurationRules *msg, size_t *len) { + return (struct google_protobuf_Duration**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_resize_in(validate_DurationRules *msg, size_t len, upb_arena *arena) { + return (struct google_protobuf_Duration**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_add_in(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_mutable_not_in(validate_DurationRules *msg, size_t *len) { + return (struct google_protobuf_Duration**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_resize_not_in(validate_DurationRules *msg, size_t len, upb_arena *arena) { + return (struct google_protobuf_Duration**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_add_not_in(validate_DurationRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* validate.TimestampRules */ + +UPB_INLINE validate_TimestampRules *validate_TimestampRules_new(upb_arena *arena) { + return (validate_TimestampRules *)upb_msg_new(&validate_TimestampRules_msginit, arena); +} +UPB_INLINE validate_TimestampRules *validate_TimestampRules_parsenew(upb_strview buf, upb_arena *arena) { + validate_TimestampRules *ret = validate_TimestampRules_new(arena); + return (ret && upb_decode(buf, ret, &validate_TimestampRules_msginit)) ? ret : NULL; +} +UPB_INLINE char *validate_TimestampRules_serialize(const validate_TimestampRules *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &validate_TimestampRules_msginit, arena, len); +} + +UPB_INLINE bool validate_TimestampRules_has_required(const validate_TimestampRules *msg) { return _upb_has_field(msg, 1); } +UPB_INLINE bool validate_TimestampRules_required(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); } +UPB_INLINE bool validate_TimestampRules_has_const(const validate_TimestampRules *msg) { return _upb_has_field(msg, 4); } +UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_const(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Timestamp*, UPB_SIZE(8, 8)); } +UPB_INLINE bool validate_TimestampRules_has_lt(const validate_TimestampRules *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_lt(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Timestamp*, UPB_SIZE(12, 16)); } +UPB_INLINE bool validate_TimestampRules_has_lte(const validate_TimestampRules *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_lte(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Timestamp*, UPB_SIZE(16, 24)); } +UPB_INLINE bool validate_TimestampRules_has_gt(const validate_TimestampRules *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_gt(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Timestamp*, UPB_SIZE(20, 32)); } +UPB_INLINE bool validate_TimestampRules_has_gte(const validate_TimestampRules *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_gte(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Timestamp*, UPB_SIZE(24, 40)); } +UPB_INLINE bool validate_TimestampRules_has_lt_now(const validate_TimestampRules *msg) { return _upb_has_field(msg, 2); } +UPB_INLINE bool validate_TimestampRules_lt_now(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); } +UPB_INLINE bool validate_TimestampRules_has_gt_now(const validate_TimestampRules *msg) { return _upb_has_field(msg, 3); } +UPB_INLINE bool validate_TimestampRules_gt_now(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)); } +UPB_INLINE bool validate_TimestampRules_has_within(const validate_TimestampRules *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE const struct google_protobuf_Duration* validate_TimestampRules_within(const validate_TimestampRules *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(28, 48)); } + +UPB_INLINE void validate_TimestampRules_set_required(validate_TimestampRules *msg, bool value) { + _upb_sethas(msg, 1); + UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value; +} +UPB_INLINE void validate_TimestampRules_set_const(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) { + _upb_sethas(msg, 4); + UPB_FIELD_AT(msg, struct google_protobuf_Timestamp*, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_const(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)validate_TimestampRules_const(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_const(msg, sub); + } + return sub; +} +UPB_INLINE void validate_TimestampRules_set_lt(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) { + _upb_sethas(msg, 5); + UPB_FIELD_AT(msg, struct google_protobuf_Timestamp*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_lt(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)validate_TimestampRules_lt(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_lt(msg, sub); + } + return sub; +} +UPB_INLINE void validate_TimestampRules_set_lte(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) { + _upb_sethas(msg, 6); + UPB_FIELD_AT(msg, struct google_protobuf_Timestamp*, UPB_SIZE(16, 24)) = value; +} +UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_lte(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)validate_TimestampRules_lte(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_lte(msg, sub); + } + return sub; +} +UPB_INLINE void validate_TimestampRules_set_gt(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) { + _upb_sethas(msg, 7); + UPB_FIELD_AT(msg, struct google_protobuf_Timestamp*, UPB_SIZE(20, 32)) = value; +} +UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_gt(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)validate_TimestampRules_gt(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_gt(msg, sub); + } + return sub; +} +UPB_INLINE void validate_TimestampRules_set_gte(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) { + _upb_sethas(msg, 8); + UPB_FIELD_AT(msg, struct google_protobuf_Timestamp*, UPB_SIZE(24, 40)) = value; +} +UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_gte(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)validate_TimestampRules_gte(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Timestamp*)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_gte(msg, sub); + } + return sub; +} +UPB_INLINE void validate_TimestampRules_set_lt_now(validate_TimestampRules *msg, bool value) { + _upb_sethas(msg, 2); + UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)) = value; +} +UPB_INLINE void validate_TimestampRules_set_gt_now(validate_TimestampRules *msg, bool value) { + _upb_sethas(msg, 3); + UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)) = value; +} +UPB_INLINE void validate_TimestampRules_set_within(validate_TimestampRules *msg, struct google_protobuf_Duration* value) { + _upb_sethas(msg, 9); + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(28, 48)) = value; +} +UPB_INLINE struct google_protobuf_Duration* validate_TimestampRules_mutable_within(validate_TimestampRules *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)validate_TimestampRules_within(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + validate_TimestampRules_set_within(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* VALIDATE_VALIDATE_PROTO_UPB_H_ */ diff --git a/tools/codegen/core/gen_upb_api.sh b/tools/codegen/core/gen_upb_api.sh index 9457e06f124..b3466c70566 100755 --- a/tools/codegen/core/gen_upb_api.sh +++ b/tools/codegen/core/gen_upb_api.sh @@ -25,12 +25,25 @@ bazel build :protoc-gen-upb cd ../.. proto_files=( \ + "google/api/annotations.proto" \ + "google/api/http.proto" \ "google/protobuf/any.proto" \ "google/protobuf/struct.proto" \ "google/protobuf/wrappers.proto" \ "google/protobuf/descriptor.proto" \ "google/protobuf/duration.proto" \ - "google/protobuf/timestamp.proto" ) + "google/protobuf/timestamp.proto" \ + "google/rpc/status.proto" \ + "gogoproto/gogo.proto" \ + "validate/validate.proto" \ + "envoy/type/percent.proto" \ + "envoy/type/range.proto" \ + "envoy/api/v2/core/address.proto" \ + "envoy/api/v2/core/base.proto" \ + "envoy/api/v2/core/health_check.proto" \ + "envoy/api/v2/discovery.proto" \ + "envoy/api/v2/eds.proto" \ + "envoy/api/v2/endpoint/endpoint.proto") for i in "${proto_files[@]}" do diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py index fd93cf31e05..aed63474b2d 100755 --- a/tools/distrib/check_copyright.py +++ b/tools/distrib/check_copyright.py @@ -104,20 +104,6 @@ _EXEMPT = frozenset(( # Designer-generated source 'examples/csharp/HelloworldXamarin/Droid/Resources/Resource.designer.cs', 'examples/csharp/HelloworldXamarin/iOS/ViewController.designer.cs', - - # Upb generated source - 'src/core/ext/upb-generated/google/protobuf/any.upb.h', - 'src/core/ext/upb-generated/google/protobuf/any.upb.c', - 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.h', - 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.c', - 'src/core/ext/upb-generated/google/protobuf/duration.upb.h', - 'src/core/ext/upb-generated/google/protobuf/duration.upb.c', - 'src/core/ext/upb-generated/google/protobuf/struct.upb.h', - 'src/core/ext/upb-generated/google/protobuf/struct.upb.c', - 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.h', - 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.c', - 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.h', - 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.c', )) RE_YEAR = r'Copyright (?P[0-9]+\-)?(?P[0-9]+) ([Tt]he )?gRPC [Aa]uthors(\.|)' @@ -168,6 +154,9 @@ except subprocess.CalledProcessError: for filename in filename_list: if filename in _EXEMPT: continue + # Skip check for upb generated code. + if filename.endswith('.upb.h') or filename.endswith('.upb.c'): + continue ext = os.path.splitext(filename)[1] base = os.path.basename(filename) if ext in RE_LICENSE: diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py index ac166ef3844..94794b1e43f 100755 --- a/tools/distrib/check_include_guards.py +++ b/tools/distrib/check_include_guards.py @@ -165,20 +165,6 @@ KNOWN_BAD = set([ 'src/core/tsi/alts/handshaker/transport_security_common.pb.h', 'include/grpc++/ext/reflection.grpc.pb.h', 'include/grpc++/ext/reflection.pb.h', - - # Upb generated code. - 'src/core/ext/upb-generated/google/protobuf/any.upb.h', - 'src/core/ext/upb-generated/google/protobuf/any.upb.c', - 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.h', - 'src/core/ext/upb-generated/google/protobuf/descriptor.upb.c', - 'src/core/ext/upb-generated/google/protobuf/duration.upb.h', - 'src/core/ext/upb-generated/google/protobuf/duration.upb.c', - 'src/core/ext/upb-generated/google/protobuf/struct.upb.h', - 'src/core/ext/upb-generated/google/protobuf/struct.upb.c', - 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.h', - 'src/core/ext/upb-generated/google/protobuf/timestamp.upb.c', - 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.h', - 'src/core/ext/upb-generated/google/protobuf/wrappers.upb.c', ]) grep_filter = r"grep -E '^(include|src/core)/.*\.h$'" @@ -204,6 +190,9 @@ validator = GuardValidator() for filename in filename_list: if filename in KNOWN_BAD: continue + # Skip check for upb generated code. + if filename.endswith('.upb.h') or filename.endswith('.upb.c'): + continue ok = ok and validator.check(filename, args.fix) sys.exit(0 if ok else 1) From 84cb531b72cd7f355a493b4eaa460afb7defea0f Mon Sep 17 00:00:00 2001 From: Moses Koledoye Date: Fri, 15 Mar 2019 22:23:52 +0000 Subject: [PATCH 711/814] Fix typo --- examples/cpp/helloworld/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cpp/helloworld/README.md b/examples/cpp/helloworld/README.md index c598658b1d7..813a80f288f 100644 --- a/examples/cpp/helloworld/README.md +++ b/examples/cpp/helloworld/README.md @@ -98,7 +98,7 @@ $ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto ``` - Create a stub. A stub implements the rpc methods of a service and in the - generated code, a method is provided to created a stub with a channel: + generated code, a method is provided to create a stub with a channel: ```cpp auto stub = helloworld::Greeter::NewStub(channel); From 957f674fff402e1cab5030f342db728dae5eed30 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 15 Mar 2019 23:29:00 +0100 Subject: [PATCH 712/814] Removing a few more non-trivial struct memsets, part 3. --- src/core/lib/http/httpcli_security_connector.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 3f288e045a6..762cbe41bcf 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -59,7 +59,6 @@ class grpc_httpcli_ssl_channel_security_connector final tsi_result InitHandshakerFactory(const char* pem_root_certs, const tsi_ssl_root_certs_store* root_store) { tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); options.pem_root_certs = pem_root_certs; options.root_store = root_store; return tsi_create_ssl_client_handshaker_factory_with_options( From 582ecc8fc4995a300b3f5318144fb198ff7a6f3d Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 15 Mar 2019 16:03:15 -0700 Subject: [PATCH 713/814] Fix tests to use grpc namespace --- test/cpp/interop/interop_server.cc | 2 +- test/cpp/qps/qps_server_builder.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index 7a72ff2b877..6570bbf9696 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -46,6 +46,7 @@ DEFINE_int32(port, 0, "Server port."); DEFINE_int32(max_send_message_size, -1, "The maximum send message size."); using grpc::Server; +using grpc::ServerBuilder; using grpc::ServerContext; using grpc::ServerCredentials; using grpc::ServerReader; @@ -63,7 +64,6 @@ using grpc::testing::StreamingInputCallResponse; using grpc::testing::StreamingOutputCallRequest; using grpc::testing::StreamingOutputCallResponse; using grpc::testing::TestService; -using grpc_impl::ServerBuilder; const char kEchoInitialMetadataKey[] = "x-grpc-test-echo-initial"; const char kEchoTrailingBinMetadataKey[] = "x-grpc-test-echo-trailing-bin"; diff --git a/test/cpp/qps/qps_server_builder.cc b/test/cpp/qps/qps_server_builder.cc index adfb4de6d98..5fbc682b756 100644 --- a/test/cpp/qps/qps_server_builder.cc +++ b/test/cpp/qps/qps_server_builder.cc @@ -18,7 +18,7 @@ #include "qps_server_builder.h" -using grpc_impl::ServerBuilder; +using grpc::ServerBuilder; namespace grpc { namespace testing { From 48ce4ca939181b46e5893618711e391fe94828b9 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 14 Feb 2019 16:52:15 -0800 Subject: [PATCH 714/814] Add support for extra-reaction operations via Holds --- include/grpcpp/impl/codegen/client_callback.h | 47 ++++++++++++ .../end2end/client_callback_end2end_test.cc | 76 +++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 0b2631014a2..89629c079af 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -112,6 +112,8 @@ class ClientCallbackReaderWriter { virtual void Write(const Request* req, WriteOptions options) = 0; virtual void WritesDone() = 0; virtual void Read(Response* resp) = 0; + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; protected: void BindReactor(ClientBidiReactor* reactor) { @@ -125,6 +127,8 @@ class ClientCallbackReader { virtual ~ClientCallbackReader() {} virtual void StartCall() = 0; virtual void Read(Response* resp) = 0; + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; protected: void BindReactor(ClientReadReactor* reactor) { @@ -144,6 +148,9 @@ class ClientCallbackWriter { } virtual void WritesDone() = 0; + virtual void AddHold(int holds) = 0; + virtual void RemoveHold() = 0; + protected: void BindReactor(ClientWriteReactor* reactor) { reactor->BindWriter(this); @@ -174,6 +181,29 @@ class ClientBidiReactor { } void StartWritesDone() { stream_->WritesDone(); } + /// Holds are needed if (and only if) this stream has operations that take + /// place on it after StartCall but from outside one of the reactions + /// (OnReadDone, etc). This is _not_ a common use of the streaming API. + /// + /// Holds must be added before calling StartCall. If a stream still has a hold + /// in place, its resources will not be destroyed even if the status has + /// already come in from the wire and there are currently no active callbacks + /// outstanding. Similarly, the stream will not call OnDone if there are still + /// holds on it. + /// + /// For example, if a StartRead or StartWrite operation is going to be + /// initiated from elsewhere in the application, the application should call + /// AddHold or AddMultipleHolds before StartCall. If there is going to be, + /// for example, a read-flow and a write-flow taking place outside the + /// reactions, then call AddMultipleHolds(2) before StartCall. When the + /// application knows that it won't issue any more Read operations (such as + /// when a read comes back as not ok), it should issue a RemoveHold(). It + /// should also call RemoveHold() again after it does StartWriteLast or + /// StartWritesDone that indicates that there will be no more Write ops. + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { stream_->AddHold(holds); } + void RemoveHold() { stream_->RemoveHold(); } + private: friend class ClientCallbackReaderWriter; void BindStream(ClientCallbackReaderWriter* stream) { @@ -193,6 +223,10 @@ class ClientReadReactor { void StartCall() { reader_->StartCall(); } void StartRead(Response* resp) { reader_->Read(resp); } + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { reader_->AddHold(holds); } + void RemoveHold() { reader_->RemoveHold(); } + private: friend class ClientCallbackReader; void BindReader(ClientCallbackReader* reader) { reader_ = reader; } @@ -218,6 +252,10 @@ class ClientWriteReactor { } void StartWritesDone() { writer_->WritesDone(); } + void AddHold() { AddMultipleHolds(1); } + void AddMultipleHolds(int holds) { writer_->AddHold(holds); } + void RemoveHold() { writer_->RemoveHold(); } + private: friend class ClientCallbackWriter; void BindWriter(ClientCallbackWriter* writer) { writer_ = writer; } @@ -374,6 +412,9 @@ class ClientCallbackReaderWriterImpl } } + virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; } + virtual void RemoveHold() override { MaybeFinish(); } + private: friend class ClientCallbackReaderWriterFactory; @@ -509,6 +550,9 @@ class ClientCallbackReaderImpl } } + virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; } + virtual void RemoveHold() override { MaybeFinish(); } + private: friend class ClientCallbackReaderFactory; @@ -677,6 +721,9 @@ class ClientCallbackWriterImpl } } + virtual void AddHold(int holds) override { callbacks_outstanding_ += holds; } + virtual void RemoveHold() override { MaybeFinish(); } + private: friend class ClientCallbackWriterFactory; diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 3845c4c0b2a..e1e898275b3 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -1117,6 +1117,82 @@ TEST_P(ClientCallbackEnd2endTest, UnimplementedRpc) { } } +TEST_P(ClientCallbackEnd2endTest, + ResponseStreamExtraReactionFlowReadsUntilDone) { + MAYBE_SKIP_TEST; + ResetStub(); + class ReadAllIncomingDataClient + : public grpc::experimental::ClientReadReactor { + public: + ReadAllIncomingDataClient(grpc::testing::EchoTestService::Stub* stub) { + request_.set_message("Hello client "); + stub->experimental_async()->ResponseStream(&context_, &request_, this); + } + bool WaitForReadDone() { + std::unique_lock l(mu_); + while (!read_done_) { + read_cv_.wait(l); + } + read_done_ = false; + return read_ok_; + } + void Await() { + std::unique_lock l(mu_); + while (!done_) { + done_cv_.wait(l); + } + } + const Status& status() { + std::unique_lock l(mu_); + return status_; + } + + private: + void OnReadDone(bool ok) override { + std::unique_lock l(mu_); + read_ok_ = ok; + read_done_ = true; + read_cv_.notify_one(); + } + void OnDone(const Status& s) override { + std::unique_lock l(mu_); + done_ = true; + status_ = s; + done_cv_.notify_one(); + } + + EchoRequest request_; + EchoResponse response_; + ClientContext context_; + bool read_ok_ = false; + bool read_done_ = false; + std::mutex mu_; + std::condition_variable read_cv_; + std::condition_variable done_cv_; + bool done_ = false; + Status status_; + } client{stub_.get()}; + + int reads_complete = 0; + client.AddHold(); + client.StartCall(); + + EchoResponse response; + bool read_ok = true; + while (read_ok) { + client.StartRead(&response); + read_ok = client.WaitForReadDone(); + if (read_ok) { + ++reads_complete; + } + } + client.RemoveHold(); + client.Await(); + + EXPECT_EQ(kServerDefaultResponseStreamsToSend, reads_complete); + EXPECT_EQ(client.status().error_code(), grpc::StatusCode::OK); +} + std::vector CreateTestScenarios(bool test_insecure) { std::vector scenarios; std::vector credentials_types{ From 4c3b577650590afcdcfd57e72b9b5faa67c6f7a8 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 15 Mar 2019 17:42:50 -0700 Subject: [PATCH 715/814] Add expectation to negative timeout test case --- src/python/grpcio_tests/tests/unit/_cython/_channel_test.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py b/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py index 9fd9ede144d..54f620523ea 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/_channel_test.py @@ -62,6 +62,8 @@ class ChannelTest(unittest.TestCase): connectivity = channel.check_connectivity_state(True) channel.watch_connectivity_state(connectivity, -3.14) channel.close(cygrpc.StatusCode.ok, 'Channel close!') + # NOTE(lidiz) The negative timeout should not trigger SIGABRT. + # Bug report: https://github.com/grpc/grpc/issues/18244 if __name__ == '__main__': From 14bffe549ef722acd23a8d1896bacd98031e46ca Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 15 Mar 2019 17:45:27 -0700 Subject: [PATCH 716/814] submodule dependency update --- third_party/benchmark | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/benchmark b/third_party/benchmark index 5b7683f49e1..e776aa0275e 160000 --- a/third_party/benchmark +++ b/third_party/benchmark @@ -1 +1 @@ -Subproject commit 5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8 +Subproject commit e776aa0275e293707b6a0901e0e8d8a8a3679508 From eff99b1d76038b25e4b5aa394492979496f78d2a Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 15 Mar 2019 18:13:45 -0700 Subject: [PATCH 717/814] dependency bump for gflags --- third_party/gflags | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/gflags b/third_party/gflags index 30dbc81fb5f..28f50e0fed1 160000 --- a/third_party/gflags +++ b/third_party/gflags @@ -1 +1 @@ -Subproject commit 30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e +Subproject commit 28f50e0fed19872e0fd50dd23ce2ee8cd759338e From 472613c3bc71dafb1afd489bc10bea81837dd3c8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 18 Mar 2019 14:20:31 +0100 Subject: [PATCH 718/814] check dotnet SDK version before building ASP.NET core interop image --- .../grpc_interop_aspnetcore/build_interop.sh.template | 1 + .../interoptest/grpc_interop_aspnetcore/build_interop.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template index 69e2ed387b2..449383c0d6f 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template @@ -25,6 +25,7 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-dotnet + ./build/get-dotnet.sh ./build/get-grpc.sh cd testassets/InteropTestsWebsite diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh index 38feae39623..ed82440ba3c 100644 --- a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh @@ -23,6 +23,7 @@ git clone /var/local/jenkins/grpc-dotnet /var/local/git/grpc-dotnet cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-dotnet +./build/get-dotnet.sh ./build/get-grpc.sh cd testassets/InteropTestsWebsite From 0f8a3aeeb7e171db1eeb4023f6e918aa6caf9d6f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 18 Mar 2019 14:30:23 +0100 Subject: [PATCH 719/814] install jq --- .../interoptest/grpc_interop_aspnetcore/Dockerfile.template | 3 +++ .../dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile | 3 +++ 2 files changed, 6 insertions(+) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template index e8f962403f7..4f6c52b19af 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile.template @@ -16,5 +16,8 @@ FROM mcr.microsoft.com/dotnet/core/sdk:3.0.100-preview3-stretch + # needed by get-dotnet.sh script + RUN apt-get update && apt-get install -y jq && apt-get clean + # Define the default command. CMD ["bash"] diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile index 26a21384911..9ad6c1f28ea 100644 --- a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/Dockerfile @@ -14,5 +14,8 @@ FROM mcr.microsoft.com/dotnet/core/sdk:3.0.100-preview3-stretch +# needed by get-dotnet.sh script +RUN apt-get update && apt-get install -y jq && apt-get clean + # Define the default command. CMD ["bash"] From 86991f633d09bdc7e217c3ebefc139100e540cb9 Mon Sep 17 00:00:00 2001 From: Evan Jones Date: Mon, 18 Mar 2019 10:54:56 -0400 Subject: [PATCH 720/814] python docs: details are UTF-8 encodable, not just ASCII. Context detail messages are Unicode strings in both the implementation and specification. Fix the documentation to make this clearer. The specification for the Status-Message response field says "Status-Message is [...] a Unicode string [...] encoded as UTF-8" [1]. The implementation seems to call _common.encode(), so anything that is UTF-8 encodable works. For example: context.set_code(grpc.StatusCode.ABORTED) context.set_details('emoji error: \U0001F600') Correctly returns a smiley face emoji to the client. --- src/python/grpcio/grpc/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 68e5361bb99..76314106ca4 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -282,7 +282,7 @@ class Status(six.with_metaclass(abc.ABCMeta)): Attributes: code: A StatusCode object to be sent to the client. - details: An ASCII-encodable string to be sent to the client upon + details: A UTF-8-encodable string to be sent to the client upon termination of the RPC. trailing_metadata: The trailing :term:`metadata` in the RPC. """ @@ -1131,7 +1131,7 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): Args: code: A StatusCode object to be sent to the client. It must not be StatusCode.OK. - details: An ASCII-encodable string to be sent to the client upon + details: A UTF-8-encodable string to be sent to the client upon termination of the RPC. Raises: @@ -1179,7 +1179,7 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): no details to transmit. Args: - details: An ASCII-encodable string to be sent to the client upon + details: A UTF-8-encodable string to be sent to the client upon termination of the RPC. """ raise NotImplementedError() From 38b82fb7c3e843e24b9090e2ab14e6ed7ebde364 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 18 Mar 2019 08:55:15 -0700 Subject: [PATCH 721/814] Update opencensus to fix build --- bazel/grpc_deps.bzl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index e2e47292242..0c92f25d021 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -196,8 +196,8 @@ def grpc_deps(): if "io_opencensus_cpp" not in native.existing_rules(): http_archive( name = "io_opencensus_cpp", - strip_prefix = "opencensus-cpp-03dff0352522983ffdee48cedbf87cbe37f1bb7f", - url = "https://github.com/census-instrumentation/opencensus-cpp/archive/03dff0352522983ffdee48cedbf87cbe37f1bb7f.tar.gz", + strip_prefix = "opencensus-cpp-9b1e354e89bf3d92aedc00af45b418ce870f3d77", + url = "https://github.com/census-instrumentation/opencensus-cpp/archive/9b1e354e89bf3d92aedc00af45b418ce870f3d77.tar.gz", ) if "upb" not in native.existing_rules(): From adc2163038e563ed326f48db1d921ef3bb9da168 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 18 Mar 2019 09:08:38 -0700 Subject: [PATCH 722/814] Go into fallback mode when losing contact with balancer and backends. --- .../client_channel/lb_policy/grpclb/grpclb.cc | 162 +++++++++++------- test/cpp/end2end/grpclb_end2end_test.cc | 133 ++++++++++++-- 2 files changed, 225 insertions(+), 70 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 34fe88215fe..cca490fef98 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -148,6 +148,7 @@ class GrpcLb : public LoadBalancingPolicy { GrpcLbClientStats* client_stats() const { return client_stats_.get(); } bool seen_initial_response() const { return seen_initial_response_; } + bool seen_serverlist() const { return seen_serverlist_; } private: // So Delete() can access our private dtor. @@ -188,6 +189,7 @@ class GrpcLb : public LoadBalancingPolicy { grpc_byte_buffer* recv_message_payload_ = nullptr; grpc_closure lb_on_balancer_message_received_; bool seen_initial_response_ = false; + bool seen_serverlist_ = false; // recv_trailing_metadata grpc_closure lb_on_balancer_status_received_; @@ -298,9 +300,12 @@ class GrpcLb : public LoadBalancingPolicy { static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); + // Methods for dealing with fallback state. + void MaybeEnterFallbackMode(); + static void OnFallbackTimerLocked(void* arg, grpc_error* error); + // Methods for dealing with the balancer call. void StartBalancerCallLocked(); - static void OnFallbackTimerLocked(void* arg, grpc_error* error); void StartBalancerCallRetryTimerLocked(); static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error); @@ -347,11 +352,13 @@ class GrpcLb : public LoadBalancingPolicy { // such response has arrived. RefCountedPtr serverlist_; + // Whether we're in fallback mode. + bool fallback_mode_ = false; // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. - UniquePtr fallback_backend_addresses_; + ServerAddressList fallback_backend_addresses_; // Fallback timer. bool fallback_timer_callback_pending_ = false; grpc_timer lb_fallback_timer_; @@ -367,6 +374,8 @@ class GrpcLb : public LoadBalancingPolicy { OrphanablePtr pending_child_policy_; // The child policy config. RefCountedPtr child_policy_config_; + // Child policy in state READY. + bool child_policy_ready_ = false; }; // @@ -635,6 +644,10 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, GRPC_ERROR_UNREF(state_error); return; } + // Record whether child policy reports READY. + parent_->child_policy_ready_ = state == GRPC_CHANNEL_READY; + // Enter fallback mode if needed. + parent_->MaybeEnterFallbackMode(); // There are three cases to consider here: // 1. We're in fallback mode. In this case, we're always going to use // the child policy's result, so we pass its picker through as-is. @@ -1014,16 +1027,14 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( grpclb_policy, lb_calld, serverlist->num_servers, serverlist_text.get()); } + lb_calld->seen_serverlist_ = true; // Start sending client load report only after we start using the // serverlist returned from the current LB call. if (lb_calld->client_stats_report_interval_ > 0 && lb_calld->client_stats_ == nullptr) { lb_calld->client_stats_ = MakeRefCounted(); - // TODO(roth): We currently track this ref manually. Once the - // ClosureRef API is ready, we should pass the RefCountedPtr<> along - // with the callback. - auto self = lb_calld->Ref(DEBUG_LOCATION, "client_load_report"); - self.release(); + // Ref held by callback. + lb_calld->Ref(DEBUG_LOCATION, "client_load_report").release(); lb_calld->ScheduleNextClientLoadReportLocked(); } // Check if the serverlist differs from the previous one. @@ -1036,18 +1047,34 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( grpclb_policy, lb_calld); } } else { // New serverlist. - if (grpclb_policy->serverlist_ == nullptr) { - // Dispose of the fallback. - if (grpclb_policy->child_policy_ != nullptr) { - gpr_log(GPR_INFO, - "[grpclb %p] Received response from balancer; exiting " - "fallback mode", - grpclb_policy); - } - grpclb_policy->fallback_backend_addresses_.reset(); - if (grpclb_policy->fallback_timer_callback_pending_) { - grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); - } + // Dispose of the fallback. + // TODO(roth): Ideally, we should stay in fallback mode until we + // know that we can reach at least one of the backends in the new + // serverlist. Unfortunately, we can't do that, since we need to + // send the new addresses to the child policy in order to determine + // if they are reachable, and if we don't exit fallback mode now, + // CreateOrUpdateChildPolicyLocked() will use the fallback + // addresses instead of the addresses from the new serverlist. + // However, if we can't reach any of the servers in the new + // serverlist, then the child policy will never switch away from + // the fallback addresses, but the grpclb policy will still think + // that we're not in fallback mode, which means that we won't send + // updates to the child policy when the fallback addresses are + // updated by the resolver. This is sub-optimal, but the only way + // to fix it is to maintain a completely separate child policy for + // fallback mode, and that's more work than we want to put into + // the grpclb implementation at this point, since we're deprecating + // it in favor of the xds policy. We will implement this the + // right way in the xds policy instead. + if (grpclb_policy->fallback_mode_) { + gpr_log(GPR_INFO, + "[grpclb %p] Received response from balancer; exiting " + "fallback mode", + grpclb_policy); + grpclb_policy->fallback_mode_ = false; + } + if (grpclb_policy->fallback_timer_callback_pending_) { + grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); } // Update the serverlist in the GrpcLb instance. This serverlist // instance will be destroyed either upon the next update or when the @@ -1103,6 +1130,7 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( // we want to retry connecting. Otherwise, we have deliberately ended this // call and no further action is required. if (lb_calld == grpclb_policy->lb_calld_.get()) { + grpclb_policy->MaybeEnterFallbackMode(); grpclb_policy->lb_calld_.reset(); GPR_ASSERT(!grpclb_policy->shutting_down_); grpclb_policy->channel_control_helper()->RequestReresolution(); @@ -1379,16 +1407,15 @@ void GrpcLb::UpdateLocked(const grpc_channel_args& args, // // Returns the backend addresses extracted from the given addresses. -UniquePtr ExtractBackendAddresses( - const ServerAddressList& addresses) { +ServerAddressList ExtractBackendAddresses(const ServerAddressList& addresses) { void* lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload; grpc_arg arg = grpc_channel_arg_pointer_create( const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token, &lb_token_arg_vtable); - auto backend_addresses = MakeUnique(); + ServerAddressList backend_addresses; for (size_t i = 0; i < addresses.size(); ++i) { if (!addresses[i].IsBalancer()) { - backend_addresses->emplace_back( + backend_addresses.emplace_back( addresses[i].address(), grpc_channel_args_copy_and_add(addresses[i].args(), &arg, 1)); } @@ -1485,6 +1512,7 @@ void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, "entering fallback mode", self); grpc_timer_cancel(&self->lb_fallback_timer_); + self->fallback_mode_ = true; self->CreateOrUpdateChildPolicyLocked(); } // Done watching connectivity state, so drop ref. @@ -1509,32 +1537,6 @@ void GrpcLb::StartBalancerCallLocked() { lb_calld_->StartQuery(); } -void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { - GrpcLb* grpclb_policy = static_cast(arg); - grpclb_policy->fallback_timer_callback_pending_ = false; - // If we receive a serverlist after the timer fires but before this callback - // actually runs, don't fall back. - if (grpclb_policy->serverlist_ == nullptr && !grpclb_policy->shutting_down_ && - error == GRPC_ERROR_NONE) { - gpr_log(GPR_INFO, - "[grpclb %p] No response from balancer after fallback timeout; " - "entering fallback mode", - grpclb_policy); - GPR_ASSERT(grpclb_policy->fallback_backend_addresses_ != nullptr); - grpclb_policy->CreateOrUpdateChildPolicyLocked(); - // Cancel connectivity watch, since we no longer need it. - grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(grpclb_policy->lb_channel_)); - GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); - grpc_client_channel_watch_connectivity_state( - client_channel_elem, - grpc_polling_entity_create_from_pollset_set( - grpclb_policy->interested_parties()), - nullptr, &grpclb_policy->lb_channel_on_connectivity_changed_, nullptr); - } - grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); -} - void GrpcLb::StartBalancerCallRetryTimerLocked() { grpc_millis next_try = lb_call_backoff_.NextAttemptTime(); if (grpc_lb_glb_trace.enabled()) { @@ -1573,6 +1575,54 @@ void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) { grpclb_policy->Unref(DEBUG_LOCATION, "on_balancer_call_retry_timer"); } +// +// code for handling fallback mode +// + +void GrpcLb::MaybeEnterFallbackMode() { + // Enter fallback mode if all of the following are true: + // - We are not currently in fallback mode. + // - We are not currently waiting for the initial fallback timeout. + // - We are not currently in contact with the balancer. + // - The child policy is not in state READY. + if (!fallback_mode_ && !fallback_timer_callback_pending_ && + (lb_calld_ == nullptr || !lb_calld_->seen_serverlist()) && + !child_policy_ready_) { + gpr_log(GPR_INFO, + "[grpclb %p] lost contact with balancer and backends from " + "most recent serverlist; entering fallback mode", + this); + fallback_mode_ = true; + CreateOrUpdateChildPolicyLocked(); + } +} + +void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { + GrpcLb* grpclb_policy = static_cast(arg); + grpclb_policy->fallback_timer_callback_pending_ = false; + // If we receive a serverlist after the timer fires but before this callback + // actually runs, don't fall back. + if (grpclb_policy->serverlist_ == nullptr && !grpclb_policy->shutting_down_ && + error == GRPC_ERROR_NONE) { + gpr_log(GPR_INFO, + "[grpclb %p] No response from balancer after fallback timeout; " + "entering fallback mode", + grpclb_policy); + grpclb_policy->fallback_mode_ = true; + grpclb_policy->CreateOrUpdateChildPolicyLocked(); + // Cancel connectivity watch, since we no longer need it. + grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(grpclb_policy->lb_channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set( + grpclb_policy->interested_parties()), + nullptr, &grpclb_policy->lb_channel_on_connectivity_changed_, nullptr); + } + grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); +} + // // code for interacting with the child policy // @@ -1581,18 +1631,14 @@ grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked() { ServerAddressList tmp_addresses; ServerAddressList* addresses = &tmp_addresses; bool is_backend_from_grpclb_load_balancer = false; - if (serverlist_ != nullptr) { + if (fallback_mode_) { + // Note: If fallback backend address list is empty, the child policy + // will go into state TRANSIENT_FAILURE. + addresses = &fallback_backend_addresses_; + } else { tmp_addresses = serverlist_->GetServerAddressList( lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats()); is_backend_from_grpclb_load_balancer = true; - } else { - // If CreateOrUpdateChildPolicyLocked() is invoked when we haven't - // received any serverlist from the balancer, we use the fallback backends - // returned by the resolver. Note that the fallback backend list may be - // empty, in which case the new round_robin policy will keep the requested - // picks pending. - GPR_ASSERT(fallback_backend_addresses_ != nullptr); - addresses = fallback_backend_addresses_.get(); } GPR_ASSERT(addresses != nullptr); // Replace the server address list in the channel args that we pass down to diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 761b6ec39d3..1eb43266182 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -142,6 +142,8 @@ class BackendServiceImpl : public BackendService { return status; } + void Start() {} + void Shutdown() {} std::set clients() { @@ -278,11 +280,16 @@ class BalancerServiceImpl : public BalancerService { responses_and_delays_.push_back(std::make_pair(response, send_after_ms)); } - void Shutdown() { - std::unique_lock lock(mu_); - NotifyDoneWithServerlistsLocked(); + void Start() { + std::lock_guard lock(mu_); + serverlist_done_ = false; + load_report_ready_ = false; responses_and_delays_.clear(); client_stats_.Reset(); + } + + void Shutdown() { + NotifyDoneWithServerlists(); gpr_log(GPR_INFO, "LB[%p]: shut down", this); } @@ -319,10 +326,6 @@ class BalancerServiceImpl : public BalancerService { void NotifyDoneWithServerlists() { std::lock_guard lock(mu_); - NotifyDoneWithServerlistsLocked(); - } - - void NotifyDoneWithServerlistsLocked() { if (!serverlist_done_) { serverlist_done_ = true; serverlist_cond_.notify_all(); @@ -617,6 +620,7 @@ class GrpclbEnd2endTest : public ::testing::Test { gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); GPR_ASSERT(!running_); running_ = true; + service_.Start(); std::mutex mu; // We need to acquire the lock here in order to prevent the notify_one // by ServerThread::Serve from firing before the wait below is hit. @@ -1197,6 +1201,112 @@ TEST_F(SingleBalancerTest, FallbackUpdate) { EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } +TEST_F(SingleBalancerTest, + FallbackAfterStartup_LoseContactWithBalancerThenBackends) { + // First two backends are fallback, last two are pointed to by balancer. + const size_t kNumFallbackBackends = 2; + const size_t kNumBalancerBackends = backends_.size() - kNumFallbackBackends; + std::vector addresses; + for (size_t i = 0; i < kNumFallbackBackends; ++i) { + addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); + } + for (size_t i = 0; i < balancers_.size(); ++i) { + addresses.emplace_back(AddressData{balancers_[i]->port_, true, ""}); + } + SetNextResolution(addresses); + ScheduleResponseForBalancer(0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumFallbackBackends), {}), + 0); + // Try to connect. + channel_->GetState(true /* try_to_connect */); + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumFallbackBackends /* start_index */); + // Stop balancer. RPCs should continue going to backends from balancer. + balancers_[0]->Shutdown(); + CheckRpcSendOk(100 * kNumBalancerBackends); + for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { + EXPECT_EQ(100UL, backends_[i]->service_.request_count()); + } + // Stop backends from balancer. This should put us in fallback mode. + for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { + ShutdownBackend(i); + } + WaitForAllBackends(1 /* num_requests_multiple_of */, 0 /* start_index */, + kNumFallbackBackends /* stop_index */); + // Restart the backends from the balancer. We should *not* start + // sending traffic back to them at this point (although the behavior + // in xds may be different). + for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { + StartBackend(i); + } + CheckRpcSendOk(100 * kNumBalancerBackends); + for (size_t i = 0; i < kNumFallbackBackends; ++i) { + EXPECT_EQ(100UL, backends_[i]->service_.request_count()); + } + // Now start the balancer again. This should cause us to exit + // fallback mode. + balancers_[0]->Start(server_host_); + ScheduleResponseForBalancer(0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumFallbackBackends), {}), + 0); + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumFallbackBackends /* start_index */); +} + +TEST_F(SingleBalancerTest, + FallbackAfterStartup_LoseContactWithBackendsThenBalancer) { + // First two backends are fallback, last two are pointed to by balancer. + const size_t kNumFallbackBackends = 2; + const size_t kNumBalancerBackends = backends_.size() - kNumFallbackBackends; + std::vector addresses; + for (size_t i = 0; i < kNumFallbackBackends; ++i) { + addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); + } + for (size_t i = 0; i < balancers_.size(); ++i) { + addresses.emplace_back(AddressData{balancers_[i]->port_, true, ""}); + } + SetNextResolution(addresses); + ScheduleResponseForBalancer(0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumFallbackBackends), {}), + 0); + // Try to connect. + channel_->GetState(true /* try_to_connect */); + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumFallbackBackends /* start_index */); + // Stop backends from balancer. Since we are still in contact with + // the balancer at this point, RPCs should be failing. + for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { + ShutdownBackend(i); + } + CheckRpcSendFailure(); + // Stop balancer. This should put us in fallback mode. + balancers_[0]->Shutdown(); + WaitForAllBackends(1 /* num_requests_multiple_of */, 0 /* start_index */, + kNumFallbackBackends /* stop_index */); + // Restart the backends from the balancer. We should *not* start + // sending traffic back to them at this point (although the behavior + // in xds may be different). + for (size_t i = kNumFallbackBackends; i < backends_.size(); ++i) { + StartBackend(i); + } + CheckRpcSendOk(100 * kNumBalancerBackends); + for (size_t i = 0; i < kNumFallbackBackends; ++i) { + EXPECT_EQ(100UL, backends_[i]->service_.request_count()); + } + // Now start the balancer again. This should cause us to exit + // fallback mode. + balancers_[0]->Start(server_host_); + ScheduleResponseForBalancer(0, + BalancerServiceImpl::BuildResponseForBackends( + GetBackendPorts(kNumFallbackBackends), {}), + 0); + WaitForAllBackends(1 /* num_requests_multiple_of */, + kNumFallbackBackends /* start_index */); +} + TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerChannelFails) { const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); ResetStub(kFallbackTimeoutMs); @@ -1221,11 +1331,6 @@ TEST_F(SingleBalancerTest, BackendsRestart) { channel_->GetState(true /* try_to_connect */); // Send kNumRpcsPerAddress RPCs per server. CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); - balancers_[0]->service_.NotifyDoneWithServerlists(); - // The balancer got a single request. - EXPECT_EQ(1U, balancers_[0]->service_.request_count()); - // and sent a single response. - EXPECT_EQ(1U, balancers_[0]->service_.response_count()); // Stop backends. RPCs should fail. ShutdownAllBackends(); CheckRpcSendFailure(); @@ -1233,6 +1338,10 @@ TEST_F(SingleBalancerTest, BackendsRestart) { StartAllBackends(); CheckRpcSendOk(1 /* times */, 1000 /* timeout_ms */, true /* wait_for_ready */); + // The balancer got a single request. + EXPECT_EQ(1U, balancers_[0]->service_.request_count()); + // and sent a single response. + EXPECT_EQ(1U, balancers_[0]->service_.response_count()); } class UpdatesTest : public GrpclbEnd2endTest { From 6c9951680e86d565b286130c7fa3ad5443140b37 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 18 Mar 2019 10:40:27 -0700 Subject: [PATCH 723/814] Fix clang_format_code.sh errors. --- include/grpcpp/server_builder_impl.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h index d4de4d582da..fb91428173d 100644 --- a/include/grpcpp/server_builder_impl.h +++ b/include/grpcpp/server_builder_impl.h @@ -51,7 +51,7 @@ class ServerBuilderPluginTest; namespace experimental { class CallbackGenericService; -} +} } // namespace grpc namespace grpc_impl { @@ -325,7 +325,8 @@ class ServerBuilder { std::vector> plugins_; grpc_resource_quota* resource_quota_; grpc::AsyncGenericService* generic_service_; - grpc::experimental::CallbackGenericService* callback_generic_service_{nullptr}; + grpc::experimental::CallbackGenericService* callback_generic_service_{ + nullptr}; struct { bool is_set; grpc_compression_level level; From f6479caf2ab36528f1b572d9fab4270a3e105c2d Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 15 Mar 2019 17:23:30 -0700 Subject: [PATCH 724/814] Fix CFStreamTests - Pass extra param to grpc_endpoint_read() as the API has changed. - Fixed build error seen with Xcode 10. - Enable pipefail to xcodebuild errors are propagated to the caller. --- .../ios/CFStreamTests/CFStreamEndpointTests.mm | 8 ++++---- .../CFStreamTests.xcodeproj/project.pbxproj | 13 ------------- test/core/iomgr/ios/CFStreamTests/run_tests.sh | 1 + 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm index 528f4b1cdad..c882479a8d5 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm @@ -187,7 +187,7 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch grpc_slice_buffer_init(&read_one_slice); while (read_slices.length < kBufferSize) { init_event_closure(&read_done, &read); - grpc_endpoint_read(ep_, &read_one_slice, &read_done); + grpc_endpoint_read(ep_, &read_one_slice, &read_done, /*urgent=*/false); XCTAssertEqual([self waitForEvent:&read timeout:kReadTimeout], YES); XCTAssertEqual(reinterpret_cast(read), GRPC_ERROR_NONE); grpc_slice_buffer_move_into(&read_one_slice, &read_slices); @@ -218,7 +218,7 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch grpc_slice_buffer_init(&read_slices); init_event_closure(&read_done, &read); - grpc_endpoint_read(ep_, &read_slices, &read_done); + grpc_endpoint_read(ep_, &read_slices, &read_done, /*urgent=*/false); grpc_slice_buffer_init(&write_slices); slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize); @@ -267,7 +267,7 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch init_event_closure(&read_done, &read); grpc_slice_buffer_init(&read_slices); - grpc_endpoint_read(ep_, &read_slices, &read_done); + grpc_endpoint_read(ep_, &read_slices, &read_done, /*urgent=*/false); grpc_slice_buffer_init(&write_slices); slice = grpc_slice_from_static_buffer(write_buffer, kBufferSize); @@ -306,7 +306,7 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch init_event_closure(&read_done, &read); grpc_slice_buffer_init(&read_slices); - grpc_endpoint_read(ep_, &read_slices, &read_done); + grpc_endpoint_read(ep_, &read_slices, &read_done, /*urgent=*/false); struct linger so_linger; so_linger.l_onoff = 1; diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj index 2218f129ae5..c24151f0fa7 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamTests.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 5E143B892069D72200715A6E /* CFStreamClientTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E143B882069D72200715A6E /* CFStreamClientTests.mm */; }; - 5E143B8C206B5F9F00715A6E /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5E143B8A2069D72700715A6E /* Info.plist */; }; 5E143B8E206C5B9A00715A6E /* CFStreamEndpointTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E143B8D206C5B9A00715A6E /* CFStreamEndpointTests.mm */; }; 604EA96D9CD477A8EA411BDF /* libPods-CFStreamTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AFFA154D492751CEAC05D591 /* libPods-CFStreamTests.a */; }; /* End PBXBuildFile section */ @@ -82,7 +81,6 @@ 4EBA55D3E23FC6C84596E3D5 /* [CP] Check Pods Manifest.lock */, 5E143B752069D67300715A6E /* Sources */, 5E143B762069D67300715A6E /* Frameworks */, - 5E143B772069D67300715A6E /* Resources */, ); buildRules = ( ); @@ -126,17 +124,6 @@ }; /* End PBXProject section */ -/* Begin PBXResourcesBuildPhase section */ - 5E143B772069D67300715A6E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5E143B8C206B5F9F00715A6E /* Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - /* Begin PBXShellScriptBuildPhase section */ 4EBA55D3E23FC6C84596E3D5 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; diff --git a/test/core/iomgr/ios/CFStreamTests/run_tests.sh b/test/core/iomgr/ios/CFStreamTests/run_tests.sh index 1045ec10a82..e49a2e0b65e 100755 --- a/test/core/iomgr/ios/CFStreamTests/run_tests.sh +++ b/test/core/iomgr/ios/CFStreamTests/run_tests.sh @@ -17,6 +17,7 @@ # ./tools/run_tests/run_tests.py -l objc set -ev +set -o pipefail cd "$(dirname "$0")" From afc2e36803be75e8cbe066ca1d2003926adababa Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 18 Mar 2019 19:06:52 +0100 Subject: [PATCH 725/814] use GCHandle.FromIntPtr --- .../Internal/NativeCallbackDispatcher.cs | 48 ++++++------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs index 36df8a5ede1..97d3fb81c9c 100644 --- a/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs +++ b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs @@ -35,8 +35,6 @@ namespace Grpc.Core.Internal { static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); static readonly object staticLock = new object(); - static readonly AtomicCounter atomicCounter = new AtomicCounter(); - static readonly ConcurrentDictionary registry = new ConcurrentDictionary(); static NativeCallbackDispatcherCallback dispatcherCallback; @@ -54,30 +52,14 @@ namespace Grpc.Core.Internal public static NativeCallbackRegistration RegisterCallback(UniversalNativeCallback callback) { - while (true) - { - // TODO: retries might not work well on 32-bit - var tag = NextTag(); - if (registry.TryAdd(tag, callback)) - { - return new NativeCallbackRegistration(tag); - } - } + var gcHandle = GCHandle.Alloc(callback); + return new NativeCallbackRegistration(gcHandle); } - public static void UnregisterCallback(IntPtr tag) + private static UniversalNativeCallback GetCallback(IntPtr tag) { - registry.TryRemove(tag, out UniversalNativeCallback callback); - } - - private static bool TryGetCallback(IntPtr tag, out UniversalNativeCallback callback) - { - return registry.TryGetValue(tag, out callback); - } - - private static IntPtr NextTag() - { - return (IntPtr) atomicCounter.Increment(); + var gcHandle = GCHandle.FromIntPtr(tag); + return (UniversalNativeCallback) gcHandle.Target; } [MonoPInvokeCallback(typeof(NativeCallbackDispatcherCallback))] @@ -85,12 +67,7 @@ namespace Grpc.Core.Internal { try { - UniversalNativeCallback callback; - if (!TryGetCallback(tag, out callback)) - { - Logger.Error("No native callback handler registered for tag {0}.", tag); - return 0; - } + var callback = GetCallback(tag); return callback(arg0, arg1, arg2, arg3, arg4, arg5); } catch (Exception e) @@ -104,18 +81,21 @@ namespace Grpc.Core.Internal internal class NativeCallbackRegistration : IDisposable { - readonly IntPtr tag; + readonly GCHandle handle; - public NativeCallbackRegistration(IntPtr tag) + public NativeCallbackRegistration(GCHandle handle) { - this.tag = tag; + this.handle = handle; } - public IntPtr Tag => tag; + public IntPtr Tag => GCHandle.ToIntPtr(handle); public void Dispose() { - NativeCallbackDispatcher.UnregisterCallback(tag); + if (handle.IsAllocated) + { + handle.Free(); + } } } } From d9fc63f42f00a661cfc458e1929f50e6382c066f Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 18 Mar 2019 11:08:12 -0700 Subject: [PATCH 726/814] generated project for updated submodule --- Makefile | 2 ++ grpc.gyp | 2 ++ tools/run_tests/generated/sources_and_headers.json | 8 ++++---- tools/run_tests/sanity/check_submodules.sh | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 69a2abbc8ca..0b664d496b7 100644 --- a/Makefile +++ b/Makefile @@ -10146,6 +10146,7 @@ endif LIBBENCHMARK_SRC = \ third_party/benchmark/src/benchmark.cc \ + third_party/benchmark/src/benchmark_main.cc \ third_party/benchmark/src/benchmark_register.cc \ third_party/benchmark/src/colorprint.cc \ third_party/benchmark/src/commandlineflags.cc \ @@ -10156,6 +10157,7 @@ LIBBENCHMARK_SRC = \ third_party/benchmark/src/json_reporter.cc \ third_party/benchmark/src/reporter.cc \ third_party/benchmark/src/sleep.cc \ + third_party/benchmark/src/statistics.cc \ third_party/benchmark/src/string_util.cc \ third_party/benchmark/src/sysinfo.cc \ third_party/benchmark/src/timers.cc \ diff --git a/grpc.gyp b/grpc.gyp index b3795cbfd06..9fa8d8d0e01 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -2626,6 +2626,7 @@ ], 'sources': [ 'third_party/benchmark/src/benchmark.cc', + 'third_party/benchmark/src/benchmark_main.cc', 'third_party/benchmark/src/benchmark_register.cc', 'third_party/benchmark/src/colorprint.cc', 'third_party/benchmark/src/commandlineflags.cc', @@ -2636,6 +2637,7 @@ 'third_party/benchmark/src/json_reporter.cc', 'third_party/benchmark/src/reporter.cc', 'third_party/benchmark/src/sleep.cc', + 'third_party/benchmark/src/statistics.cc', 'third_party/benchmark/src/string_util.cc', 'third_party/benchmark/src/sysinfo.cc', 'third_party/benchmark/src/timers.cc', diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 2d427804d07..499adc74abd 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8729,10 +8729,9 @@ "deps": [], "headers": [ "third_party/benchmark/include/benchmark/benchmark.h", - "third_party/benchmark/include/benchmark/benchmark_api.h", - "third_party/benchmark/include/benchmark/reporter.h", "third_party/benchmark/src/arraysize.h", "third_party/benchmark/src/benchmark_api_internal.h", + "third_party/benchmark/src/benchmark_register.h", "third_party/benchmark/src/check.h", "third_party/benchmark/src/colorprint.h", "third_party/benchmark/src/commandlineflags.h", @@ -8744,9 +8743,10 @@ "third_party/benchmark/src/mutex.h", "third_party/benchmark/src/re.h", "third_party/benchmark/src/sleep.h", - "third_party/benchmark/src/stat.h", + "third_party/benchmark/src/statistics.h", "third_party/benchmark/src/string_util.h", - "third_party/benchmark/src/sysinfo.h", + "third_party/benchmark/src/thread_manager.h", + "third_party/benchmark/src/thread_timer.h", "third_party/benchmark/src/timers.h" ], "is_filegroup": false, diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index 12e4c157193..c01d22ba74b 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -27,13 +27,13 @@ want_submodules=$(mktemp /tmp/submXXXXXX) git submodule | awk '{ print $1 }' | sort > "$submodules" cat << EOF | awk '{ print $1 }' | sort > "$want_submodules" cc4bed2d74f7c8717e31f9579214ab52a9c9c610 third_party/abseil-cpp (cc4bed2) - 5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8 third_party/benchmark (v1.2.0) + e776aa0275e293707b6a0901e0e8d8a8a3679508 third_party/benchmark (v1.2.0) 73594cde8c9a52a102c4341c244c833aa61b9c06 third_party/bloaty (remotes/origin/wide-14-g73594cd) b29b21a81b32ec273f118f589f46d56ad3332420 third_party/boringssl (remotes/origin/chromium-stable) afc30d43eef92979b05776ec0963c9cede5fb80f third_party/boringssl-with-bazel (fips-20180716-116-gafc30d43e) 3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0) 911001cdca003337bdb93fab32740cde61bafee3 third_party/data-plane-api (heads/master) - 30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0-5-g30dbc81) + 28f50e0fed19872e0fd50dd23ce2ee8cd759338e third_party/gflags (v2.2.0-5-g30dbc81) 80ed4d0bbf65d57cc267dfc63bd2584557f11f9b third_party/googleapis (common-protos-1_3_1-915-g80ed4d0bb) ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0) 6599cac0965be8e5a835ab7a5684bbef033d5ad0 third_party/libcxx (heads/release_60) From 1ef8bd094483eb5a0696e5c38843d08c399ee2f1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 18 Mar 2019 19:13:30 +0100 Subject: [PATCH 727/814] fix cast warnings --- src/csharp/ext/grpc_csharp_ext.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index fcd4caf5f49..26a92708e8c 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -1041,13 +1041,13 @@ static int grpcsharp_get_metadata_handler( grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], size_t* num_creds_md, grpc_status_code* status, const char** error_details) { - native_callback_dispatcher(state, context.service_url, context.method_name, cb, user_data, - 0, NULL); + native_callback_dispatcher(state, (void*)context.service_url, (void*)context.method_name, cb, user_data, + (void*)0, NULL); return 0; /* Asynchronous return. */ } static void grpcsharp_metadata_credentials_destroy_handler(void* state) { - native_callback_dispatcher(state, NULL, NULL, NULL, NULL, 1, NULL); + native_callback_dispatcher(state, NULL, NULL, NULL, NULL, (void*)1, NULL); } GPR_EXPORT grpc_call_credentials* GPR_CALLTYPE From 04a6b8467c4d2ac0d30561f75e1260a9e9ede983 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 12 Mar 2019 10:23:49 -0700 Subject: [PATCH 728/814] Support callback on cancellation of server-side unary RPCs --- include/grpcpp/impl/codegen/server_callback.h | 34 +++++++++ include/grpcpp/impl/codegen/server_context.h | 3 + src/cpp/server/server_context.cc | 33 ++++++++- test/cpp/end2end/BUILD | 5 ++ test/cpp/end2end/end2end_test.cc | 59 +++++++++++++++- test/cpp/end2end/test_service_impl.cc | 70 ++++++++++++------- test/cpp/end2end/test_service_impl.h | 13 +++- 7 files changed, 189 insertions(+), 28 deletions(-) diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 60c308b22e7..274a00e0556 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -69,6 +69,31 @@ class ServerCallbackRpcController { // Allow the method handler to push out the initial metadata before // the response and status are ready virtual void SendInitialMetadata(std::function) = 0; + + /// SetCancelCallback passes in a callback to be called when the RPC is + /// canceled for whatever reason (streaming calls have OnCancel instead). This + /// is an advanced and uncommon use with several important restrictions. + /// + /// If code calls SetCancelCallback on an RPC, it must also call + /// ClearCancelCallback before calling Finish on the RPC controller. + /// + /// The callback should generally be lightweight and nonblocking and primarily + /// concerned with clearing application state related to the RPC or causing + /// operations (such as cancellations) to happen on dependent RPCs. + /// + /// If the RPC is already canceled at the time that SetCancelCallback is + /// called, the callback is invoked immediately. + /// + /// The cancellation callback may be executed concurrently with the method + /// handler that invokes it but will certainly not issue or execute after the + /// return of ClearCancelCallback. + /// + /// The callback is called under a lock that is also used for + /// ClearCancelCallback and ServerContext::IsCancelled, so the callback CANNOT + /// call either of those operations on this RPC or any other function that + /// causes those operations to be called before the callback completes. + virtual void SetCancelCallback(std::function callback) = 0; + virtual void ClearCancelCallback() = 0; }; // NOTE: The actual streaming object classes are provided @@ -349,6 +374,15 @@ class CallbackUnaryHandler : public MethodHandler { call_.PerformOps(&meta_ops_); } + // Neither SetCancelCallback nor ClearCancelCallback should affect the + // callbacks_outstanding_ count since they are paired and both must precede + // the invocation of Finish (if they are used at all) + void SetCancelCallback(std::function callback) override { + ctx_->SetCancelCallback(std::move(callback)); + } + + void ClearCancelCallback() override { ctx_->ClearCancelCallback(); } + private: friend class CallbackUnaryHandler; diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index fb82186d69e..591a9ff9549 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -329,6 +329,9 @@ class ServerContext { uint32_t initial_metadata_flags() const { return 0; } + void SetCancelCallback(std::function callback); + void ClearCancelCallback(); + experimental::ServerRpcInfo* set_server_rpc_info( const char* method, internal::RpcMethod::RpcType type, const std::vector< diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index d38b46822ae..73fd6a62c48 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -95,6 +95,22 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { tag_ = tag; } + void SetCancelCallback(std::function callback) { + std::lock_guard lock(mu_); + + if (finalized_ && (cancelled_ != 0)) { + callback(); + return; + } + + cancel_callback_ = std::move(callback); + } + + void ClearCancelCallback() { + std::lock_guard g(mu_); + cancel_callback_ = nullptr; + } + void set_core_cq_tag(void* core_cq_tag) { core_cq_tag_ = core_cq_tag; } void* core_cq_tag() override { return core_cq_tag_; } @@ -141,6 +157,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { std::mutex mu_; bool finalized_; int cancelled_; // This is an int (not bool) because it is passed to core + std::function cancel_callback_; bool done_intercepting_; internal::InterceptorBatchMethodsImpl interceptor_methods_; }; @@ -191,11 +208,17 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { // Decide whether to call the cancel callback before releasing the lock bool call_cancel = (cancelled_ != 0); + // If it's a unary cancel callback, call it under the lock so that it doesn't + // race with ClearCancelCallback + if (cancel_callback_) { + cancel_callback_(); + } + // Release the lock since we are going to be calling a callback and // interceptors now lock.unlock(); - if (call_cancel && (reactor_ != nullptr)) { + if (call_cancel && reactor_ != nullptr) { reactor_->OnCancel(); } @@ -315,6 +338,14 @@ void ServerContext::TryCancel() const { } } +void ServerContext::SetCancelCallback(std::function callback) { + completion_op_->SetCancelCallback(std::move(callback)); +} + +void ServerContext::ClearCancelCallback() { + completion_op_->ClearCancelCallback(); +} + bool ServerContext::IsCancelled() const { if (completion_tag_) { // When using callback API, this result is always valid. diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index de7725d163d..a51f833a3e0 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -89,6 +89,7 @@ grpc_cc_test( external_deps = [ "gtest", ], + tags = ["no_windows"], deps = [ ":test_service_impl", "//:gpr", @@ -245,6 +246,9 @@ grpc_cc_test( size = "large", deps = [ ":end2end_test_lib", + # DO NOT REMOVE THE grpc++ dependence below since the internal build + # system uses it to specialize targets + "//:grpc++", ], ) @@ -620,6 +624,7 @@ grpc_cc_test( external_deps = [ "gtest", ], + tags = ["no_windows"], deps = [ "//:gpr", "//:grpc", diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index f58a472bfaf..1726a7b189a 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1381,6 +1381,61 @@ TEST_P(End2endTest, ExpectErrorTest) { } } +TEST_P(End2endTest, DelayedRpcCanceledUsingCancelCallback) { + MAYBE_SKIP_TEST; + // This test case is only relevant with callback server. + // Additionally, using interceptors makes this test subject to + // timing-dependent failures if the interceptors take too long to run. + if (!GetParam().callback_server || GetParam().use_interceptors) { + return; + } + + ResetStub(); + ClientContext context; + context.AddMetadata(kServerUseCancelCallback, + grpc::to_string(MAYBE_USE_CALLBACK_CANCEL)); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + request.mutable_param()->set_skip_cancelled_check(true); + // Let server sleep for 40 ms first to give the cancellation a chance. + // 40 ms might seem a bit extreme but the timer manager would have been just + // initialized (when ResetStub() was called) and there are some warmup costs + // i.e the timer thread many not have even started. There might also be + // other delays in the timer manager thread (in acquiring locks, timer data + // structure manipulations, starting backup timer threads) that add to the + // delays. 40ms is still not enough in some cases but this significantly + // reduces the test flakes + request.mutable_param()->set_server_sleep_us(40 * 1000); + + std::thread echo_thread{[this, &context, &request, &response] { + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); + }}; + std::this_thread::sleep_for(std::chrono::microseconds(500)); + context.TryCancel(); + echo_thread.join(); +} + +TEST_P(End2endTest, DelayedRpcNonCanceledUsingCancelCallback) { + MAYBE_SKIP_TEST; + if (!GetParam().callback_server) { + return; + } + + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + + ClientContext context; + context.AddMetadata(kServerUseCancelCallback, + grpc::to_string(MAYBE_USE_CALLBACK_NO_CANCEL)); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_TRUE(s.ok()); +} + ////////////////////////////////////////////////////////////////////////// // Test with and without a proxy. class ProxyEnd2endTest : public End2endTest { @@ -2015,7 +2070,7 @@ INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P( ProxyEnd2end, ProxyEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(true, true, true, true, false))); + ::testing::ValuesIn(CreateTestScenarios(true, true, true, true, true))); INSTANTIATE_TEST_CASE_P( SecureEnd2end, SecureEnd2endTest, @@ -2023,7 +2078,7 @@ INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P( ResourceQuotaEnd2end, ResourceQuotaEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, false))); + ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, true))); } // namespace } // namespace testing diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 159ea33c2bc..afc0cb0d8fd 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -126,13 +126,14 @@ void ServerTryCancelNonblocking(ServerContext* context) { } void LoopUntilCancelled(Alarm* alarm, ServerContext* context, - experimental::ServerCallbackRpcController* controller) { + experimental::ServerCallbackRpcController* controller, + int loop_delay_us) { if (!context->IsCancelled()) { alarm->experimental().Set( gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(1000, GPR_TIMESPAN)), - [alarm, context, controller](bool) { - LoopUntilCancelled(alarm, context, controller); + gpr_time_from_micros(loop_delay_us, GPR_TIMESPAN)), + [alarm, context, controller, loop_delay_us](bool) { + LoopUntilCancelled(alarm, context, controller, loop_delay_us); }); } else { controller->Finish(Status::CANCELLED); @@ -249,6 +250,16 @@ Status TestServiceImpl::CheckClientInitialMetadata(ServerContext* context, void CallbackTestServiceImpl::Echo( ServerContext* context, const EchoRequest* request, EchoResponse* response, experimental::ServerCallbackRpcController* controller) { + CancelState* cancel_state = new CancelState; + int server_use_cancel_callback = + GetIntValueFromMetadata(kServerUseCancelCallback, + context->client_metadata(), DO_NOT_USE_CALLBACK); + if (server_use_cancel_callback != DO_NOT_USE_CALLBACK) { + controller->SetCancelCallback([cancel_state] { + EXPECT_FALSE(cancel_state->callback_invoked.exchange( + true, std::memory_order_relaxed)); + }); + } // A bit of sleep to make sure that short deadline tests fail if (request->has_param() && request->param().server_sleep_us() > 0) { // Set an alarm for that much time @@ -256,11 +267,11 @@ void CallbackTestServiceImpl::Echo( gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_micros(request->param().server_sleep_us(), GPR_TIMESPAN)), - [this, context, request, response, controller](bool) { - EchoNonDelayed(context, request, response, controller); + [this, context, request, response, controller, cancel_state](bool) { + EchoNonDelayed(context, request, response, controller, cancel_state); }); } else { - EchoNonDelayed(context, request, response, controller); + EchoNonDelayed(context, request, response, controller, cancel_state); } } @@ -279,7 +290,25 @@ void CallbackTestServiceImpl::CheckClientInitialMetadata( void CallbackTestServiceImpl::EchoNonDelayed( ServerContext* context, const EchoRequest* request, EchoResponse* response, - experimental::ServerCallbackRpcController* controller) { + experimental::ServerCallbackRpcController* controller, + CancelState* cancel_state) { + int server_use_cancel_callback = + GetIntValueFromMetadata(kServerUseCancelCallback, + context->client_metadata(), DO_NOT_USE_CALLBACK); + + // Safe to clear cancel callback even if it wasn't set + controller->ClearCancelCallback(); + if (server_use_cancel_callback == MAYBE_USE_CALLBACK_CANCEL) { + EXPECT_TRUE(context->IsCancelled()); + EXPECT_TRUE(cancel_state->callback_invoked.load(std::memory_order_relaxed)); + delete cancel_state; + controller->Finish(Status::CANCELLED); + return; + } + + EXPECT_FALSE(cancel_state->callback_invoked.load(std::memory_order_relaxed)); + delete cancel_state; + if (request->has_param() && request->param().server_die()) { gpr_log(GPR_ERROR, "The request should not reach application handler."); GPR_ASSERT(0); @@ -301,9 +330,11 @@ void CallbackTestServiceImpl::EchoNonDelayed( EXPECT_FALSE(context->IsCancelled()); context->TryCancel(); gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); - // Now wait until it's really canceled - LoopUntilCancelled(&alarm_, context, controller); + if (server_use_cancel_callback == DO_NOT_USE_CALLBACK) { + // Now wait until it's really canceled + LoopUntilCancelled(&alarm_, context, controller, 1000); + } return; } @@ -318,20 +349,11 @@ void CallbackTestServiceImpl::EchoNonDelayed( std::unique_lock lock(mu_); signal_client_ = true; } - std::function recurrence = [this, context, request, controller, - &recurrence](bool) { - if (!context->IsCancelled()) { - alarm_.experimental().Set( - gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_micros(request->param().client_cancel_after_us(), - GPR_TIMESPAN)), - recurrence); - } else { - controller->Finish(Status::CANCELLED); - } - }; - recurrence(true); + if (server_use_cancel_callback == DO_NOT_USE_CALLBACK) { + // Now wait until it's really canceled + LoopUntilCancelled(&alarm_, context, controller, + request->param().client_cancel_after_us()); + } return; } else if (request->has_param() && request->param().server_cancel_after_us()) { diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h index e36423d44e4..9a52bed1ea7 100644 --- a/test/cpp/end2end/test_service_impl.h +++ b/test/cpp/end2end/test_service_impl.h @@ -33,6 +33,7 @@ namespace testing { const int kServerDefaultResponseStreamsToSend = 3; const char* const kServerResponseStreamsToSend = "server_responses_to_send"; const char* const kServerTryCancelRequest = "server_try_cancel"; +const char* const kServerUseCancelCallback = "server_use_cancel_callback"; const char* const kDebugInfoTrailerKey = "debug-info-bin"; const char* const kServerFinishAfterNReads = "server_finish_after_n_reads"; const char* const kServerUseCoalescingApi = "server_use_coalescing_api"; @@ -46,6 +47,12 @@ typedef enum { CANCEL_AFTER_PROCESSING } ServerTryCancelRequestPhase; +typedef enum { + DO_NOT_USE_CALLBACK = 0, + MAYBE_USE_CALLBACK_CANCEL, + MAYBE_USE_CALLBACK_NO_CANCEL, +} ServerUseCancelCallback; + class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { public: TestServiceImpl() : signal_client_(false), host_() {} @@ -115,9 +122,13 @@ class CallbackTestServiceImpl } private: + struct CancelState { + std::atomic_bool callback_invoked{false}; + }; void EchoNonDelayed(ServerContext* context, const EchoRequest* request, EchoResponse* response, - experimental::ServerCallbackRpcController* controller); + experimental::ServerCallbackRpcController* controller, + CancelState* cancel_state); Alarm alarm_; bool signal_client_; From 233d3e27ff0f7fe1cc8ad5a3e9c271123e4f0bc3 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 18 Mar 2019 11:45:14 -0700 Subject: [PATCH 729/814] grpclb fallback-at-startup improvements --- .../client_channel/lb_policy/grpclb/grpclb.cc | 133 ++++++++++-------- test/cpp/end2end/grpclb_end2end_test.cc | 22 ++- 2 files changed, 96 insertions(+), 59 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 22c62661c5c..5906ecafc2a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -299,9 +299,10 @@ class GrpcLb : public LoadBalancingPolicy { void ParseLbConfig(Config* grpclb_config); static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); + void CancelBalancerChannelConnectivityWatchLocked(); // Methods for dealing with fallback state. - void MaybeEnterFallbackMode(); + void MaybeEnterFallbackModeAfterStartup(); static void OnFallbackTimerLocked(void* arg, grpc_error* error); // Methods for dealing with the balancer call. @@ -330,9 +331,6 @@ class GrpcLb : public LoadBalancingPolicy { gpr_atm lb_channel_uuid_ = 0; // Response generator to inject address updates into lb_channel_. RefCountedPtr response_generator_; - // Connectivity state notification. - grpc_connectivity_state lb_channel_connectivity_ = GRPC_CHANNEL_IDLE; - grpc_closure lb_channel_on_connectivity_changed_; // The data associated with the current LB call. It holds a ref to this LB // policy. It's initialized every time we query for backends. It's reset to @@ -354,15 +352,17 @@ class GrpcLb : public LoadBalancingPolicy { // Whether we're in fallback mode. bool fallback_mode_ = false; - // Timeout in milliseconds for before using fallback backend addresses. - // 0 means not using fallback. - int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. ServerAddressList fallback_backend_addresses_; - // Fallback timer. - bool fallback_timer_callback_pending_ = false; + // State for fallback-at-startup checks. + // Timeout after startup after which we will go into fallback mode if + // we have not received a serverlist from the balancer. + int fallback_at_startup_timeout_ = 0; + bool fallback_at_startup_checks_pending_ = false; grpc_timer lb_fallback_timer_; grpc_closure lb_on_fallback_; + grpc_connectivity_state lb_channel_connectivity_ = GRPC_CHANNEL_IDLE; + grpc_closure lb_channel_on_connectivity_changed_; // Lock held when modifying the value of child_policy_ or // pending_child_policy_. @@ -647,7 +647,7 @@ void GrpcLb::Helper::UpdateState(grpc_connectivity_state state, // Record whether child policy reports READY. parent_->child_policy_ready_ = state == GRPC_CHANNEL_READY; // Enter fallback mode if needed. - parent_->MaybeEnterFallbackMode(); + parent_->MaybeEnterFallbackModeAfterStartup(); // There are three cases to consider here: // 1. We're in fallback mode. In this case, we're always going to use // the child policy's result, so we pass its picker through as-is. @@ -804,7 +804,8 @@ void GrpcLb::BalancerCallState::StartQuery() { grpc_op* op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; - op->flags = 0; + op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY | + GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET; op->reserved = nullptr; op++; // Op: send request message. @@ -1073,8 +1074,10 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( grpclb_policy); grpclb_policy->fallback_mode_ = false; } - if (grpclb_policy->fallback_timer_callback_pending_) { + if (grpclb_policy->fallback_at_startup_checks_pending_) { + grpclb_policy->fallback_at_startup_checks_pending_ = false; grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); + grpclb_policy->CancelBalancerChannelConnectivityWatchLocked(); } // Update the serverlist in the GrpcLb instance. This serverlist // instance will be destroyed either upon the next update or when the @@ -1130,7 +1133,24 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( // we want to retry connecting. Otherwise, we have deliberately ended this // call and no further action is required. if (lb_calld == grpclb_policy->lb_calld_.get()) { - grpclb_policy->MaybeEnterFallbackMode(); + // If we did not receive a serverlist and the fallback-at-startup checks + // are pending, go into fallback mode immediately. This short-circuits + // the timeout for the fallback-at-startup case. + if (!lb_calld->seen_serverlist_ && + grpclb_policy->fallback_at_startup_checks_pending_) { + gpr_log(GPR_INFO, + "[grpclb %p] balancer call finished without receiving " + "serverlist; entering fallback mode", + grpclb_policy); + grpclb_policy->fallback_at_startup_checks_pending_ = false; + grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_); + grpclb_policy->CancelBalancerChannelConnectivityWatchLocked(); + grpclb_policy->fallback_mode_ = true; + grpclb_policy->CreateOrUpdateChildPolicyLocked(); + } else { + // This handles the fallback-after-startup case. + grpclb_policy->MaybeEnterFallbackModeAfterStartup(); + } grpclb_policy->lb_calld_.reset(); GPR_ASSERT(!grpclb_policy->shutting_down_); grpclb_policy->channel_control_helper()->RequestReresolution(); @@ -1262,6 +1282,8 @@ GrpcLb::GrpcLb(Args args) .set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) { // Initialization. + GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, + grpc_combiner_scheduler(combiner())); GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_, &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this, grpc_combiner_scheduler(args.combiner)); @@ -1282,9 +1304,9 @@ GrpcLb::GrpcLb(Args args) // Record LB call timeout. arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS); lb_call_timeout_ms_ = grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX}); - // Record fallback timeout. + // Record fallback-at-startup timeout. arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS); - lb_fallback_timeout_ms_ = grpc_channel_arg_get_integer( + fallback_at_startup_timeout_ = grpc_channel_arg_get_integer( arg, {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX}); } @@ -1300,8 +1322,9 @@ void GrpcLb::ShutdownLocked() { if (retry_timer_callback_pending_) { grpc_timer_cancel(&lb_call_retry_timer_); } - if (fallback_timer_callback_pending_) { + if (fallback_at_startup_checks_pending_) { grpc_timer_cancel(&lb_fallback_timer_); + CancelBalancerChannelConnectivityWatchLocked(); } if (child_policy_ != nullptr) { grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(), @@ -1373,31 +1396,28 @@ void GrpcLb::UpdateLocked(const grpc_channel_args& args, ProcessChannelArgsLocked(args); // Update the existing child policy. if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); - // If this is the initial update, start the fallback timer. + // If this is the initial update, start the fallback-at-startup checks + // and the balancer call. if (is_initial_update) { - if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr && - !fallback_timer_callback_pending_) { - grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_; - Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Ref for callback - GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this, - grpc_combiner_scheduler(combiner())); - fallback_timer_callback_pending_ = true; - grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); - // Start watching the channel's connectivity state. If the channel - // goes into state TRANSIENT_FAILURE, we go into fallback mode even if - // the fallback timeout has not elapsed. - grpc_channel_element* client_channel_elem = - grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(lb_channel_)); - GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); - // Ref held by callback. - Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity").release(); - grpc_client_channel_watch_connectivity_state( - client_channel_elem, - grpc_polling_entity_create_from_pollset_set(interested_parties()), - &lb_channel_connectivity_, &lb_channel_on_connectivity_changed_, - nullptr); - } + fallback_at_startup_checks_pending_ = true; + // Start timer. + grpc_millis deadline = ExecCtx::Get()->Now() + fallback_at_startup_timeout_; + Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Ref for callback + grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_); + // Start watching the channel's connectivity state. If the channel + // goes into state TRANSIENT_FAILURE before the timer fires, we go into + // fallback mode even if the fallback timeout has not elapsed. + grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(lb_channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + // Ref held by callback. + Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity").release(); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set(interested_parties()), + &lb_channel_connectivity_, &lb_channel_on_connectivity_changed_, + nullptr); + // Start balancer call. StartBalancerCallLocked(); } } @@ -1490,7 +1510,7 @@ void GrpcLb::ParseLbConfig(Config* grpclb_config) { void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error) { GrpcLb* self = static_cast(arg); - if (!self->shutting_down_ && self->fallback_timer_callback_pending_) { + if (!self->shutting_down_ && self->fallback_at_startup_checks_pending_) { if (self->lb_channel_connectivity_ != GRPC_CHANNEL_TRANSIENT_FAILURE) { // Not in TRANSIENT_FAILURE. Renew connectivity watch. grpc_channel_element* client_channel_elem = @@ -1511,6 +1531,7 @@ void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, "[grpclb %p] balancer channel in state TRANSIENT_FAILURE; " "entering fallback mode", self); + self->fallback_at_startup_checks_pending_ = false; grpc_timer_cancel(&self->lb_fallback_timer_); self->fallback_mode_ = true; self->CreateOrUpdateChildPolicyLocked(); @@ -1519,6 +1540,16 @@ void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, self->Unref(DEBUG_LOCATION, "watch_lb_channel_connectivity"); } +void GrpcLb::CancelBalancerChannelConnectivityWatchLocked() { + grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( + grpc_channel_get_channel_stack(lb_channel_)); + GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); + grpc_client_channel_watch_connectivity_state( + client_channel_elem, + grpc_polling_entity_create_from_pollset_set(interested_parties()), + nullptr, &lb_channel_on_connectivity_changed_, nullptr); +} + // // code for balancer channel and call // @@ -1579,13 +1610,13 @@ void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) { // code for handling fallback mode // -void GrpcLb::MaybeEnterFallbackMode() { +void GrpcLb::MaybeEnterFallbackModeAfterStartup() { // Enter fallback mode if all of the following are true: // - We are not currently in fallback mode. // - We are not currently waiting for the initial fallback timeout. // - We are not currently in contact with the balancer. // - The child policy is not in state READY. - if (!fallback_mode_ && !fallback_timer_callback_pending_ && + if (!fallback_mode_ && !fallback_at_startup_checks_pending_ && (lb_calld_ == nullptr || !lb_calld_->seen_serverlist()) && !child_policy_ready_) { gpr_log(GPR_INFO, @@ -1599,26 +1630,18 @@ void GrpcLb::MaybeEnterFallbackMode() { void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { GrpcLb* grpclb_policy = static_cast(arg); - grpclb_policy->fallback_timer_callback_pending_ = false; // If we receive a serverlist after the timer fires but before this callback // actually runs, don't fall back. - if (grpclb_policy->serverlist_ == nullptr && !grpclb_policy->shutting_down_ && - error == GRPC_ERROR_NONE) { + if (grpclb_policy->fallback_at_startup_checks_pending_ && + !grpclb_policy->shutting_down_ && error == GRPC_ERROR_NONE) { gpr_log(GPR_INFO, "[grpclb %p] No response from balancer after fallback timeout; " "entering fallback mode", grpclb_policy); + grpclb_policy->fallback_at_startup_checks_pending_ = false; + grpclb_policy->CancelBalancerChannelConnectivityWatchLocked(); grpclb_policy->fallback_mode_ = true; grpclb_policy->CreateOrUpdateChildPolicyLocked(); - // Cancel connectivity watch, since we no longer need it. - grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element( - grpc_channel_get_channel_stack(grpclb_policy->lb_channel_)); - GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter); - grpc_client_channel_watch_connectivity_state( - client_channel_elem, - grpc_polling_entity_create_from_pollset_set( - grpclb_policy->interested_parties()), - nullptr, &grpclb_policy->lb_channel_on_connectivity_changed_, nullptr); } grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer"); } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 1eb43266182..3afcd0c578f 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -406,7 +406,7 @@ class GrpclbEnd2endTest : public ::testing::Test { void ResetStub(int fallback_timeout = 0, const grpc::string& expected_targets = "") { ChannelArguments args; - args.SetGrpclbFallbackTimeout(fallback_timeout); + if (fallback_timeout > 0) args.SetGrpclbFallbackTimeout(fallback_timeout); args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_.get()); if (!expected_targets.empty()) { @@ -1321,6 +1321,22 @@ TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerChannelFails) { /* wait_for_ready */ false); } +TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerCallFails) { + const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); + ResetStub(kFallbackTimeoutMs); + // Return an unreachable balancer and one fallback backend. + std::vector addresses; + addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); + SetNextResolution(addresses); + // Balancer drops call without sending a serverlist. + balancers_[0]->service_.NotifyDoneWithServerlists(); + // Send RPC with deadline less than the fallback timeout and make sure it + // succeeds. + CheckRpcSendOk(/* times */ 1, /* timeout_ms */ 1000, + /* wait_for_ready */ false); +} + TEST_F(SingleBalancerTest, BackendsRestart) { SetNextResolutionAllBalancers(); const size_t kNumRpcsPerAddress = 100; @@ -1336,7 +1352,7 @@ TEST_F(SingleBalancerTest, BackendsRestart) { CheckRpcSendFailure(); // Restart backends. RPCs should start succeeding again. StartAllBackends(); - CheckRpcSendOk(1 /* times */, 1000 /* timeout_ms */, + CheckRpcSendOk(1 /* times */, 2000 /* timeout_ms */, true /* wait_for_ready */); // The balancer got a single request. EXPECT_EQ(1U, balancers_[0]->service_.request_count()); @@ -1867,8 +1883,6 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, BalancerRestart) { // Send one RPC per backend. CheckRpcSendOk(kNumBackendsSecondPass); balancers_[0]->service_.NotifyDoneWithServerlists(); - EXPECT_EQ(2U, balancers_[0]->service_.request_count()); - EXPECT_EQ(2U, balancers_[0]->service_.response_count()); // Check client stats. client_stats = WaitForLoadReports(); EXPECT_EQ(kNumBackendsSecondPass + 1, client_stats.num_calls_started); From c24acc3d4a3754fca1a6ac55452b3c5f1a649b68 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 18 Mar 2019 22:29:08 +0100 Subject: [PATCH 730/814] fix grpc-dotnet interop tests --- .../grpc_interop_aspnetcore/build_interop.sh.template | 2 ++ .../interoptest/grpc_interop_aspnetcore/build_interop.sh | 2 ++ 2 files changed, 4 insertions(+) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template index 449383c0d6f..4125d712acb 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template @@ -26,6 +26,8 @@ cd /var/local/git/grpc-dotnet ./build/get-dotnet.sh + export PATH="$HOME/.dotnet/:$PATH" + ./build/get-grpc.sh cd testassets/InteropTestsWebsite diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh index ed82440ba3c..444aec169a1 100644 --- a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh @@ -24,6 +24,8 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-dotnet ./build/get-dotnet.sh +export PATH="$HOME/.dotnet/:$PATH" + ./build/get-grpc.sh cd testassets/InteropTestsWebsite From 0a8fbd2a67396f65a4c6087d9577556bbc3689b2 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Mon, 18 Mar 2019 13:59:33 -0700 Subject: [PATCH 731/814] Fix broken php7 performance benchmarks build --- src/ruby/qps/proxy-worker.rb | 2 +- tools/run_tests/performance/build_performance_php7.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ruby/qps/proxy-worker.rb b/src/ruby/qps/proxy-worker.rb index 5f23d896cc5..f09b5c3475a 100755 --- a/src/ruby/qps/proxy-worker.rb +++ b/src/ruby/qps/proxy-worker.rb @@ -48,7 +48,7 @@ class ProxyBenchmarkClientServiceImpl < Grpc::Testing::ProxyClientService::Servi if @use_c_ext puts "Use protobuf c extension" command = "php -d extension=" + File.expand_path(File.dirname(__FILE__)) + - "/../../php/tests/qps/vendor/google/protobuf/php/ext/google/protobuf/modules/protobuf.so " + + "/../../../third_party/protobuf/php/ext/google/protobuf/modules/protobuf.so " + "-d extension=" + File.expand_path(File.dirname(__FILE__)) + "/../../php/ext/grpc/modules/grpc.so " + File.expand_path(File.dirname(__FILE__)) + "/" + @php_client_bin + " " + @mytarget + " #{chan%@config.server_targets.length}" else diff --git a/tools/run_tests/performance/build_performance_php7.sh b/tools/run_tests/performance/build_performance_php7.sh index 37ca9ee8770..386c7862abd 100755 --- a/tools/run_tests/performance/build_performance_php7.sh +++ b/tools/run_tests/performance/build_performance_php7.sh @@ -23,7 +23,7 @@ python tools/run_tests/run_tests.py -l php7 -c "$CONFIG" --build_only -j 8 cd src/php/tests/qps composer install # Install protobuf C-extension for php -cd vendor/google/protobuf/php/ext/google/protobuf +cd ../../../../third_party/protobuf/php/ext/google/protobuf phpize ./configure make From 93f0a3f6530a581e22a74614a36aeb442f853313 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 18 Mar 2019 15:37:35 -0700 Subject: [PATCH 732/814] Address reviewer comments --- include/grpcpp/impl/codegen/server_callback.h | 20 +++++++++++++------ test/cpp/end2end/BUILD | 2 -- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 274a00e0556..d1878af9b0a 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -72,10 +72,17 @@ class ServerCallbackRpcController { /// SetCancelCallback passes in a callback to be called when the RPC is /// canceled for whatever reason (streaming calls have OnCancel instead). This - /// is an advanced and uncommon use with several important restrictions. + /// is an advanced and uncommon use with several important restrictions. (This + /// function may be called multiple times on the same RPC but only that last + /// registered callback is actually used.) /// /// If code calls SetCancelCallback on an RPC, it must also call - /// ClearCancelCallback before calling Finish on the RPC controller. + /// ClearCancelCallback before calling Finish on the RPC controller. That + /// method makes sure that no cancellation callback is executed for this RPC + /// beyond the point of its return. ClearCancelCallback may be called even if + /// SetCancelCallback was not called for this RPC, and it may be called + /// multiple times. It _must_ be called if SetCancelCallback was called for + /// this RPC. /// /// The callback should generally be lightweight and nonblocking and primarily /// concerned with clearing application state related to the RPC or causing @@ -88,10 +95,11 @@ class ServerCallbackRpcController { /// handler that invokes it but will certainly not issue or execute after the /// return of ClearCancelCallback. /// - /// The callback is called under a lock that is also used for - /// ClearCancelCallback and ServerContext::IsCancelled, so the callback CANNOT - /// call either of those operations on this RPC or any other function that - /// causes those operations to be called before the callback completes. + /// To preserve the orderings described above, the callback may be called + /// under a lock that is also used for ClearCancelCallback and + /// ServerContext::IsCancelled, so the callback CANNOT call either of those + /// operations on this RPC or any other function that causes those operations + /// to be called before the callback completes. virtual void SetCancelCallback(std::function callback) = 0; virtual void ClearCancelCallback() = 0; }; diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index a51f833a3e0..d945dd3f7f7 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -89,7 +89,6 @@ grpc_cc_test( external_deps = [ "gtest", ], - tags = ["no_windows"], deps = [ ":test_service_impl", "//:gpr", @@ -624,7 +623,6 @@ grpc_cc_test( external_deps = [ "gtest", ], - tags = ["no_windows"], deps = [ "//:gpr", "//:grpc", From 0cb0cdb7e3bde71bd712f199fc346c7f05392c5b Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 18 Mar 2019 15:46:27 -0700 Subject: [PATCH 733/814] Address reviewer comments on test --- test/cpp/end2end/end2end_test.cc | 40 +++++++++++++++++++-------- test/cpp/end2end/test_service_impl.cc | 8 +++++- test/cpp/end2end/test_service_impl.h | 3 +- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 1726a7b189a..a7b672074e3 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1381,7 +1381,26 @@ TEST_P(End2endTest, ExpectErrorTest) { } } -TEST_P(End2endTest, DelayedRpcCanceledUsingCancelCallback) { +TEST_P(End2endTest, DelayedRpcEarlyCanceledUsingCancelCallback) { + MAYBE_SKIP_TEST; + if (!GetParam().callback_server || GetParam().use_interceptors) { + return; + } + + ResetStub(); + ClientContext context; + context.AddMetadata(kServerUseCancelCallback, + grpc::to_string(MAYBE_USE_CALLBACK_EARLY_CANCEL)); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + request.mutable_param()->set_skip_cancelled_check(true); + context.TryCancel(); + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); +} + +TEST_P(End2endTest, DelayedRpcLateCanceledUsingCancelCallback) { MAYBE_SKIP_TEST; // This test case is only relevant with callback server. // Additionally, using interceptors makes this test subject to @@ -1393,26 +1412,23 @@ TEST_P(End2endTest, DelayedRpcCanceledUsingCancelCallback) { ResetStub(); ClientContext context; context.AddMetadata(kServerUseCancelCallback, - grpc::to_string(MAYBE_USE_CALLBACK_CANCEL)); + grpc::to_string(MAYBE_USE_CALLBACK_LATE_CANCEL)); EchoRequest request; EchoResponse response; request.set_message("Hello"); request.mutable_param()->set_skip_cancelled_check(true); - // Let server sleep for 40 ms first to give the cancellation a chance. - // 40 ms might seem a bit extreme but the timer manager would have been just - // initialized (when ResetStub() was called) and there are some warmup costs - // i.e the timer thread many not have even started. There might also be - // other delays in the timer manager thread (in acquiring locks, timer data - // structure manipulations, starting backup timer threads) that add to the - // delays. 40ms is still not enough in some cases but this significantly - // reduces the test flakes - request.mutable_param()->set_server_sleep_us(40 * 1000); + // Let server sleep for 80 ms first to give the cancellation a chance. + // This is split into 40 ms to start the cancel and 40 ms extra time for + // it to make it to the server, to make it highly probable that the server + // RPC would have already started by the time the cancellation is sent + // and the server-side gets enough time to react to it. + request.mutable_param()->set_server_sleep_us(80 * 1000); std::thread echo_thread{[this, &context, &request, &response] { Status s = stub_->Echo(&context, request, &response); EXPECT_EQ(StatusCode::CANCELLED, s.error_code()); }}; - std::this_thread::sleep_for(std::chrono::microseconds(500)); + std::this_thread::sleep_for(std::chrono::microseconds(40000)); context.TryCancel(); echo_thread.join(); } diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index afc0cb0d8fd..3fe66b1e8c6 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -259,6 +259,11 @@ void CallbackTestServiceImpl::Echo( EXPECT_FALSE(cancel_state->callback_invoked.exchange( true, std::memory_order_relaxed)); }); + if (server_use_cancel_callback == MAYBE_USE_CALLBACK_EARLY_CANCEL) { + EXPECT_TRUE(context->IsCancelled()); + EXPECT_TRUE( + cancel_state->callback_invoked.load(std::memory_order_relaxed)); + } } // A bit of sleep to make sure that short deadline tests fail if (request->has_param() && request->param().server_sleep_us() > 0) { @@ -298,7 +303,8 @@ void CallbackTestServiceImpl::EchoNonDelayed( // Safe to clear cancel callback even if it wasn't set controller->ClearCancelCallback(); - if (server_use_cancel_callback == MAYBE_USE_CALLBACK_CANCEL) { + if (server_use_cancel_callback == MAYBE_USE_CALLBACK_EARLY_CANCEL || + server_use_cancel_callback == MAYBE_USE_CALLBACK_LATE_CANCEL) { EXPECT_TRUE(context->IsCancelled()); EXPECT_TRUE(cancel_state->callback_invoked.load(std::memory_order_relaxed)); delete cancel_state; diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h index 9a52bed1ea7..81b0234e213 100644 --- a/test/cpp/end2end/test_service_impl.h +++ b/test/cpp/end2end/test_service_impl.h @@ -49,7 +49,8 @@ typedef enum { typedef enum { DO_NOT_USE_CALLBACK = 0, - MAYBE_USE_CALLBACK_CANCEL, + MAYBE_USE_CALLBACK_EARLY_CANCEL, + MAYBE_USE_CALLBACK_LATE_CANCEL, MAYBE_USE_CALLBACK_NO_CANCEL, } ServerUseCancelCallback; From f12f862d288bb2fac15c139caeffe3655d961ad7 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 18 Mar 2019 15:52:58 -0700 Subject: [PATCH 734/814] Strengthen test --- test/cpp/end2end/test_service_impl.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 3fe66b1e8c6..1cbbc703076 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -263,6 +263,10 @@ void CallbackTestServiceImpl::Echo( EXPECT_TRUE(context->IsCancelled()); EXPECT_TRUE( cancel_state->callback_invoked.load(std::memory_order_relaxed)); + } else { + EXPECT_FALSE(context->IsCancelled()); + EXPECT_FALSE( + cancel_state->callback_invoked.load(std::memory_order_relaxed)); } } // A bit of sleep to make sure that short deadline tests fail From 7f9670371089d768aaa5e80ac7f3ab4be5df1b47 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 18 Mar 2019 16:39:22 -0700 Subject: [PATCH 735/814] google benchmark compilation fix attempt --- cmake/benchmark.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/benchmark.cmake b/cmake/benchmark.cmake index 2b4c20f2db4..f6b7bebd47c 100644 --- a/cmake/benchmark.cmake +++ b/cmake/benchmark.cmake @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +set(BENCHMARK_ENABLE_GTEST_TESTS OFF) + if("${gRPC_BENCHMARK_PROVIDER}" STREQUAL "module") if(NOT BENCHMARK_ROOT_DIR) set(BENCHMARK_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/benchmark) @@ -35,3 +37,4 @@ elseif("${gRPC_BENCHMARK_PROVIDER}" STREQUAL "package") endif() set(_gRPC_FIND_BENCHMARK "if(NOT benchmark_FOUND)\n find_package(benchmark CONFIG)\nendif()") endif() + From 7b3a1202954ccc325f284e0c678cbee74c74a8e2 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 18 Mar 2019 16:51:15 -0700 Subject: [PATCH 736/814] Address reviewer comments --- include/grpcpp/impl/codegen/server_callback.h | 9 +++++---- test/cpp/end2end/end2end_test.cc | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index d1878af9b0a..33988fb6c23 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -72,9 +72,8 @@ class ServerCallbackRpcController { /// SetCancelCallback passes in a callback to be called when the RPC is /// canceled for whatever reason (streaming calls have OnCancel instead). This - /// is an advanced and uncommon use with several important restrictions. (This - /// function may be called multiple times on the same RPC but only that last - /// registered callback is actually used.) + /// is an advanced and uncommon use with several important restrictions. This + /// function may not be called more than once on the same RPC. /// /// If code calls SetCancelCallback on an RPC, it must also call /// ClearCancelCallback before calling Finish on the RPC controller. That @@ -93,7 +92,9 @@ class ServerCallbackRpcController { /// /// The cancellation callback may be executed concurrently with the method /// handler that invokes it but will certainly not issue or execute after the - /// return of ClearCancelCallback. + /// return of ClearCancelCallback. If ClearCancelCallback is invoked while the + /// callback is already executing, the callback will complete its execution + /// before ClearCancelCallback takes effect. /// /// To preserve the orderings described above, the callback may be called /// under a lock that is also used for ClearCancelCallback and diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index a7b672074e3..40023c72f62 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1383,6 +1383,9 @@ TEST_P(End2endTest, ExpectErrorTest) { TEST_P(End2endTest, DelayedRpcEarlyCanceledUsingCancelCallback) { MAYBE_SKIP_TEST; + // This test case is only relevant with callback server. + // Additionally, using interceptors makes this test subject to + // timing-dependent failures if the interceptors take too long to run. if (!GetParam().callback_server || GetParam().use_interceptors) { return; } From e5a5a5b5ee461b8dabada97b49daeca68cdeb62b Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 18 Mar 2019 17:24:40 -0700 Subject: [PATCH 737/814] attempt #2 at fixing CMake builds --- cmake/benchmark.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/benchmark.cmake b/cmake/benchmark.cmake index f6b7bebd47c..ff95ed86a25 100644 --- a/cmake/benchmark.cmake +++ b/cmake/benchmark.cmake @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(BENCHMARK_ENABLE_GTEST_TESTS OFF) +set(BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE BOOL "Turn off gTest in gBenchmark") if("${gRPC_BENCHMARK_PROVIDER}" STREQUAL "module") if(NOT BENCHMARK_ROOT_DIR) From b82913c752a5618a4c3f5eeb49b5a4cc77e1c86d Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Mon, 18 Mar 2019 16:11:27 -0700 Subject: [PATCH 738/814] Fix PHP mac build --- src/php/tests/unit_tests/InterceptorTest.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/php/tests/unit_tests/InterceptorTest.php b/src/php/tests/unit_tests/InterceptorTest.php index 0ad49fc2bd1..acd68fc45a2 100644 --- a/src/php/tests/unit_tests/InterceptorTest.php +++ b/src/php/tests/unit_tests/InterceptorTest.php @@ -103,7 +103,11 @@ class ChangeMetadataInterceptor extends Grpc\Interceptor $metadata["foo"] = array('interceptor_from_unary_request'); return $continuation($method, $argument, $deserialize, $metadata, $options); } - public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) + public function interceptStreamUnary($method, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) { $metadata["foo"] = array('interceptor_from_stream_request'); return $continuation($method, $deserialize, $metadata, $options); @@ -178,7 +182,11 @@ class ChangeRequestInterceptor extends Grpc\Interceptor $argument->setData('intercepted_unary_request'); return $continuation($method, $argument, $deserialize, $metadata, $options); } - public function interceptStreamUnary($method, $deserialize, array $metadata = [], array $options = [], $continuation) + public function interceptStreamUnary($method, + $deserialize, + array $metadata = [], + array $options = [], + $continuation) { return new ChangeRequestCall( $continuation($method, $deserialize, $metadata, $options) @@ -190,6 +198,7 @@ class StopCallInterceptor extends Grpc\Interceptor { public function interceptUnaryUnary($method, $argument, + $deserialize, array $metadata = [], array $options = [], $continuation) @@ -197,6 +206,7 @@ class StopCallInterceptor extends Grpc\Interceptor $metadata["foo"] = array('interceptor_from_request_response'); } public function interceptStreamUnary($method, + $deserialize, array $metadata = [], array $options = [], $continuation) From 385af3bc61dcb00a2875493a24d02b91edb984dc Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 19 Mar 2019 07:25:23 -0400 Subject: [PATCH 739/814] fixup --- .../grpc_interop_aspnetcore/build_interop.sh.template | 7 ++++++- .../interoptest/grpc_interop_aspnetcore/build_interop.sh | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template index 4125d712acb..53c5adae0d1 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh.template @@ -25,8 +25,13 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-dotnet + + # If needed, update dotnet SDK and put it on path ./build/get-dotnet.sh - export PATH="$HOME/.dotnet/:$PATH" + if [ -f $HOME/.dotnet/dotnet ] + then + ln -s $HOME/.dotnet/dotnet /usr/local/bin/dotnet + fi ./build/get-grpc.sh diff --git a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh index 444aec169a1..ce21e0f335d 100644 --- a/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_aspnetcore/build_interop.sh @@ -23,8 +23,13 @@ git clone /var/local/jenkins/grpc-dotnet /var/local/git/grpc-dotnet cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-dotnet + +# If needed, update dotnet SDK and put it on path ./build/get-dotnet.sh -export PATH="$HOME/.dotnet/:$PATH" +if [ -f $HOME/.dotnet/dotnet ] +then + ln -s $HOME/.dotnet/dotnet /usr/local/bin/dotnet +fi ./build/get-grpc.sh From 6e2ad131fcb18cadb2fc5ba63b4e5082088ce382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Kr=C3=A4mer?= Date: Tue, 19 Mar 2019 14:45:04 +0100 Subject: [PATCH 740/814] Update README.md Fixed misleading information about supported VS version --- examples/csharp/HelloworldLegacyCsproj/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/csharp/HelloworldLegacyCsproj/README.md b/examples/csharp/HelloworldLegacyCsproj/README.md index 60b09e09257..4435faeb086 100644 --- a/examples/csharp/HelloworldLegacyCsproj/README.md +++ b/examples/csharp/HelloworldLegacyCsproj/README.md @@ -6,7 +6,7 @@ BACKGROUND This is a different version of the helloworld example, using the "classic" .csproj files, the only format supported by VS2013 (and older versions of mono). You can still use gRPC with the classic .csproj files, but [using the new-style -.csproj projects](../helloworld/README.md) (supported by VS2015 Update3 and above, +.csproj projects](../Helloworld/README.md) (supported by VS2017 v15.3 and above, and dotnet SDK) is recommended. Example projects depend on the [Grpc](https://www.nuget.org/packages/Grpc/), From 8dcd98ef8c13c5b9f7d28e5545e035710681e74a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 19 Mar 2019 10:19:39 -0700 Subject: [PATCH 741/814] Fix server unit test errors. --- include/grpcpp/server_builder_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h index fb91428173d..a8323c38510 100644 --- a/include/grpcpp/server_builder_impl.h +++ b/include/grpcpp/server_builder_impl.h @@ -324,7 +324,7 @@ class ServerBuilder { std::shared_ptr creds_; std::vector> plugins_; grpc_resource_quota* resource_quota_; - grpc::AsyncGenericService* generic_service_; + grpc::AsyncGenericService* generic_service_{nullptr}; grpc::experimental::CallbackGenericService* callback_generic_service_{ nullptr}; struct { From 271807df79b2f2dc7c7b6d18367f52fb6d906d78 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Tue, 19 Mar 2019 11:16:24 -0700 Subject: [PATCH 742/814] Build BoringSSL tests as BoringSSL does. BoringSSL builds its crypto_test and ssl_test as single targets, while gRPC was building them with a target per file. This no longer works with tip-of-tree BoringSSL. This change aligns gRPC with the way that BoringSSL builds its tests. The changes to boringssl/gen_build_yaml.py were done by hand, all other changes result from generate_projects.sh. --- Makefile | 4289 +---------------- grpc.gyp | 561 --- src/boringssl/gen_build_yaml.py | 29 +- .../generated/sources_and_headers.json | 1381 +----- tools/run_tests/generated/tests.json | 1326 +---- 5 files changed, 243 insertions(+), 7343 deletions(-) diff --git a/Makefile b/Makefile index 69a2abbc8ca..d5a019d5650 100644 --- a/Makefile +++ b/Makefile @@ -1280,57 +1280,8 @@ public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 gen_hpack_tables: $(BINDIR)/$(CONFIG)/gen_hpack_tables gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters gen_percent_encoding_tables: $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables -boringssl_crypto_test_data: $(BINDIR)/$(CONFIG)/boringssl_crypto_test_data -boringssl_asn1_test: $(BINDIR)/$(CONFIG)/boringssl_asn1_test -boringssl_base64_test: $(BINDIR)/$(CONFIG)/boringssl_base64_test -boringssl_bio_test: $(BINDIR)/$(CONFIG)/boringssl_bio_test -boringssl_buf_test: $(BINDIR)/$(CONFIG)/boringssl_buf_test -boringssl_bytestring_test: $(BINDIR)/$(CONFIG)/boringssl_bytestring_test -boringssl_chacha_test: $(BINDIR)/$(CONFIG)/boringssl_chacha_test -boringssl_aead_test: $(BINDIR)/$(CONFIG)/boringssl_aead_test -boringssl_cipher_test: $(BINDIR)/$(CONFIG)/boringssl_cipher_test -boringssl_cmac_test: $(BINDIR)/$(CONFIG)/boringssl_cmac_test -boringssl_compiler_test: $(BINDIR)/$(CONFIG)/boringssl_compiler_test -boringssl_constant_time_test: $(BINDIR)/$(CONFIG)/boringssl_constant_time_test -boringssl_ed25519_test: $(BINDIR)/$(CONFIG)/boringssl_ed25519_test -boringssl_spake25519_test: $(BINDIR)/$(CONFIG)/boringssl_spake25519_test -boringssl_x25519_test: $(BINDIR)/$(CONFIG)/boringssl_x25519_test -boringssl_dh_test: $(BINDIR)/$(CONFIG)/boringssl_dh_test -boringssl_digest_test: $(BINDIR)/$(CONFIG)/boringssl_digest_test -boringssl_dsa_test: $(BINDIR)/$(CONFIG)/boringssl_dsa_test -boringssl_ecdh_test: $(BINDIR)/$(CONFIG)/boringssl_ecdh_test -boringssl_err_test: $(BINDIR)/$(CONFIG)/boringssl_err_test -boringssl_evp_extra_test: $(BINDIR)/$(CONFIG)/boringssl_evp_extra_test -boringssl_evp_test: $(BINDIR)/$(CONFIG)/boringssl_evp_test -boringssl_pbkdf_test: $(BINDIR)/$(CONFIG)/boringssl_pbkdf_test -boringssl_scrypt_test: $(BINDIR)/$(CONFIG)/boringssl_scrypt_test -boringssl_aes_test: $(BINDIR)/$(CONFIG)/boringssl_aes_test -boringssl_bn_test: $(BINDIR)/$(CONFIG)/boringssl_bn_test -boringssl_ec_test: $(BINDIR)/$(CONFIG)/boringssl_ec_test -boringssl_p256-x86_64_test: $(BINDIR)/$(CONFIG)/boringssl_p256-x86_64_test -boringssl_ecdsa_test: $(BINDIR)/$(CONFIG)/boringssl_ecdsa_test -boringssl_gcm_test: $(BINDIR)/$(CONFIG)/boringssl_gcm_test -boringssl_ctrdrbg_test: $(BINDIR)/$(CONFIG)/boringssl_ctrdrbg_test -boringssl_hkdf_test: $(BINDIR)/$(CONFIG)/boringssl_hkdf_test -boringssl_hmac_test: $(BINDIR)/$(CONFIG)/boringssl_hmac_test -boringssl_lhash_test: $(BINDIR)/$(CONFIG)/boringssl_lhash_test -boringssl_obj_test: $(BINDIR)/$(CONFIG)/boringssl_obj_test -boringssl_pkcs7_test: $(BINDIR)/$(CONFIG)/boringssl_pkcs7_test -boringssl_pkcs12_test: $(BINDIR)/$(CONFIG)/boringssl_pkcs12_test -boringssl_pkcs8_test: $(BINDIR)/$(CONFIG)/boringssl_pkcs8_test -boringssl_poly1305_test: $(BINDIR)/$(CONFIG)/boringssl_poly1305_test -boringssl_pool_test: $(BINDIR)/$(CONFIG)/boringssl_pool_test -boringssl_refcount_test: $(BINDIR)/$(CONFIG)/boringssl_refcount_test -boringssl_rsa_test: $(BINDIR)/$(CONFIG)/boringssl_rsa_test -boringssl_self_test: $(BINDIR)/$(CONFIG)/boringssl_self_test -boringssl_file_test_gtest: $(BINDIR)/$(CONFIG)/boringssl_file_test_gtest -boringssl_gtest_main: $(BINDIR)/$(CONFIG)/boringssl_gtest_main -boringssl_thread_test: $(BINDIR)/$(CONFIG)/boringssl_thread_test -boringssl_x509_test: $(BINDIR)/$(CONFIG)/boringssl_x509_test -boringssl_tab_test: $(BINDIR)/$(CONFIG)/boringssl_tab_test -boringssl_v3name_test: $(BINDIR)/$(CONFIG)/boringssl_v3name_test -boringssl_span_test: $(BINDIR)/$(CONFIG)/boringssl_span_test boringssl_ssl_test: $(BINDIR)/$(CONFIG)/boringssl_ssl_test +boringssl_crypto_test: $(BINDIR)/$(CONFIG)/boringssl_crypto_test badreq_bad_client_test: $(BINDIR)/$(CONFIG)/badreq_bad_client_test connection_prefix_bad_client_test: $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test duplicate_header_bad_client_test: $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test @@ -1454,7 +1405,7 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc ifeq ($(EMBED_OPENSSL),true) -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libbenchmark.a else privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_core_stats.a $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a endif @@ -1789,57 +1740,8 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/transport_security_common_api_test \ $(BINDIR)/$(CONFIG)/writes_per_rpc_test \ $(BINDIR)/$(CONFIG)/xds_end2end_test \ - $(BINDIR)/$(CONFIG)/boringssl_crypto_test_data \ - $(BINDIR)/$(CONFIG)/boringssl_asn1_test \ - $(BINDIR)/$(CONFIG)/boringssl_base64_test \ - $(BINDIR)/$(CONFIG)/boringssl_bio_test \ - $(BINDIR)/$(CONFIG)/boringssl_buf_test \ - $(BINDIR)/$(CONFIG)/boringssl_bytestring_test \ - $(BINDIR)/$(CONFIG)/boringssl_chacha_test \ - $(BINDIR)/$(CONFIG)/boringssl_aead_test \ - $(BINDIR)/$(CONFIG)/boringssl_cipher_test \ - $(BINDIR)/$(CONFIG)/boringssl_cmac_test \ - $(BINDIR)/$(CONFIG)/boringssl_compiler_test \ - $(BINDIR)/$(CONFIG)/boringssl_constant_time_test \ - $(BINDIR)/$(CONFIG)/boringssl_ed25519_test \ - $(BINDIR)/$(CONFIG)/boringssl_spake25519_test \ - $(BINDIR)/$(CONFIG)/boringssl_x25519_test \ - $(BINDIR)/$(CONFIG)/boringssl_dh_test \ - $(BINDIR)/$(CONFIG)/boringssl_digest_test \ - $(BINDIR)/$(CONFIG)/boringssl_dsa_test \ - $(BINDIR)/$(CONFIG)/boringssl_ecdh_test \ - $(BINDIR)/$(CONFIG)/boringssl_err_test \ - $(BINDIR)/$(CONFIG)/boringssl_evp_extra_test \ - $(BINDIR)/$(CONFIG)/boringssl_evp_test \ - $(BINDIR)/$(CONFIG)/boringssl_pbkdf_test \ - $(BINDIR)/$(CONFIG)/boringssl_scrypt_test \ - $(BINDIR)/$(CONFIG)/boringssl_aes_test \ - $(BINDIR)/$(CONFIG)/boringssl_bn_test \ - $(BINDIR)/$(CONFIG)/boringssl_ec_test \ - $(BINDIR)/$(CONFIG)/boringssl_p256-x86_64_test \ - $(BINDIR)/$(CONFIG)/boringssl_ecdsa_test \ - $(BINDIR)/$(CONFIG)/boringssl_gcm_test \ - $(BINDIR)/$(CONFIG)/boringssl_ctrdrbg_test \ - $(BINDIR)/$(CONFIG)/boringssl_hkdf_test \ - $(BINDIR)/$(CONFIG)/boringssl_hmac_test \ - $(BINDIR)/$(CONFIG)/boringssl_lhash_test \ - $(BINDIR)/$(CONFIG)/boringssl_obj_test \ - $(BINDIR)/$(CONFIG)/boringssl_pkcs7_test \ - $(BINDIR)/$(CONFIG)/boringssl_pkcs12_test \ - $(BINDIR)/$(CONFIG)/boringssl_pkcs8_test \ - $(BINDIR)/$(CONFIG)/boringssl_poly1305_test \ - $(BINDIR)/$(CONFIG)/boringssl_pool_test \ - $(BINDIR)/$(CONFIG)/boringssl_refcount_test \ - $(BINDIR)/$(CONFIG)/boringssl_rsa_test \ - $(BINDIR)/$(CONFIG)/boringssl_self_test \ - $(BINDIR)/$(CONFIG)/boringssl_file_test_gtest \ - $(BINDIR)/$(CONFIG)/boringssl_gtest_main \ - $(BINDIR)/$(CONFIG)/boringssl_thread_test \ - $(BINDIR)/$(CONFIG)/boringssl_x509_test \ - $(BINDIR)/$(CONFIG)/boringssl_tab_test \ - $(BINDIR)/$(CONFIG)/boringssl_v3name_test \ - $(BINDIR)/$(CONFIG)/boringssl_span_test \ $(BINDIR)/$(CONFIG)/boringssl_ssl_test \ + $(BINDIR)/$(CONFIG)/boringssl_crypto_test \ $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure \ $(BINDIR)/$(CONFIG)/resolver_component_test \ $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure \ @@ -8155,1995 +8057,6 @@ ifneq ($(NO_DEPS),true) endif -LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_SRC = \ - src/boringssl/crypto_test_data.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_SRC)))) - -$(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CRYPTO_TEST_DATA_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_ASN1_TEST_LIB_SRC = \ - third_party/boringssl/crypto/asn1/asn1_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_ASN1_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ASN1_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_ASN1_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_ASN1_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_ASN1_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_BASE64_TEST_LIB_SRC = \ - third_party/boringssl/crypto/base64/base64_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_BASE64_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BASE64_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_BASE64_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_BASE64_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_BASE64_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_BIO_TEST_LIB_SRC = \ - third_party/boringssl/crypto/bio/bio_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_BIO_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BIO_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_BIO_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_BIO_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_BIO_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_BIO_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBBORINGSSL_BIO_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_BIO_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_BUF_TEST_LIB_SRC = \ - third_party/boringssl/crypto/buf/buf_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_BUF_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BUF_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_BUF_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_BUF_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_BUF_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_BUF_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBBORINGSSL_BUF_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_BUF_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_BYTESTRING_TEST_LIB_SRC = \ - third_party/boringssl/crypto/bytestring/bytestring_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BYTESTRING_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_CHACHA_TEST_LIB_SRC = \ - third_party/boringssl/crypto/chacha/chacha_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CHACHA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CHACHA_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CHACHA_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_AEAD_TEST_LIB_SRC = \ - third_party/boringssl/crypto/cipher_extra/aead_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_AEAD_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_AEAD_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_AEAD_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_AEAD_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_AEAD_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_CIPHER_TEST_LIB_SRC = \ - third_party/boringssl/crypto/cipher_extra/cipher_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CIPHER_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CIPHER_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_CMAC_TEST_LIB_SRC = \ - third_party/boringssl/crypto/cmac/cmac_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CMAC_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CMAC_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_CMAC_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CMAC_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CMAC_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_COMPILER_TEST_LIB_SRC = \ - third_party/boringssl/crypto/compiler_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_COMPILER_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_COMPILER_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_COMPILER_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_SRC = \ - third_party/boringssl/crypto/constant_time_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_ED25519_TEST_LIB_SRC = \ - third_party/boringssl/crypto/curve25519/ed25519_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_ED25519_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ED25519_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_ED25519_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_ED25519_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_ED25519_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_SPAKE25519_TEST_LIB_SRC = \ - third_party/boringssl/crypto/curve25519/spake25519_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SPAKE25519_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_SPAKE25519_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_X25519_TEST_LIB_SRC = \ - third_party/boringssl/crypto/curve25519/x25519_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_X25519_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_X25519_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_X25519_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_X25519_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_X25519_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_X25519_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBBORINGSSL_X25519_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_X25519_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_DH_TEST_LIB_SRC = \ - third_party/boringssl/crypto/dh/dh_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_DH_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_DH_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_DH_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_DH_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_DH_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_DH_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBBORINGSSL_DH_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_DH_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_DIGEST_TEST_LIB_SRC = \ - third_party/boringssl/crypto/digest_extra/digest_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_DIGEST_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_DIGEST_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_DSA_TEST_LIB_SRC = \ - third_party/boringssl/crypto/dsa/dsa_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_DSA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_DSA_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_DSA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_DSA_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBBORINGSSL_DSA_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_DSA_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_ECDH_TEST_LIB_SRC = \ - third_party/boringssl/crypto/ecdh/ecdh_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_ECDH_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ECDH_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_ECDH_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_ECDH_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_ECDH_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDH_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBBORINGSSL_ECDH_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_ECDH_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_ERR_TEST_LIB_SRC = \ - third_party/boringssl/crypto/err/err_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_ERR_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ERR_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_ERR_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_ERR_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_ERR_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_ERR_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBBORINGSSL_ERR_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_ERR_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_EVP_EXTRA_TEST_LIB_SRC = \ - third_party/boringssl/crypto/evp/evp_extra_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_EVP_TEST_LIB_SRC = \ - third_party/boringssl/crypto/evp/evp_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_EVP_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_EVP_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_EVP_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_EVP_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_EVP_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_EVP_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBBORINGSSL_EVP_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_EVP_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_PBKDF_TEST_LIB_SRC = \ - third_party/boringssl/crypto/evp/pbkdf_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_PBKDF_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PBKDF_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_SCRYPT_TEST_LIB_SRC = \ - third_party/boringssl/crypto/evp/scrypt_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SCRYPT_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_SCRYPT_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_AES_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/aes/aes_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_AES_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_AES_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_AES_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_AES_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_AES_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_AES_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBBORINGSSL_AES_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_AES_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_BN_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/bn/bn_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_BN_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_BN_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_BN_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_BN_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_BN_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_BN_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBBORINGSSL_BN_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_BN_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_EC_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/ec/ec_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_EC_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_EC_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_EC_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_EC_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_EC_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_EC_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBBORINGSSL_EC_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_EC_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_P256-X86_64_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_P256-X86_64_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_P256-X86_64_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_ECDSA_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_ECDSA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_ECDSA_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_GCM_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/modes/gcm_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_GCM_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_GCM_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_GCM_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_GCM_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_GCM_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_GCM_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBBORINGSSL_GCM_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_GCM_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_CTRDRBG_TEST_LIB_SRC = \ - third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_CTRDRBG_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_CTRDRBG_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_HKDF_TEST_LIB_SRC = \ - third_party/boringssl/crypto/hkdf/hkdf_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_HKDF_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_HKDF_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_HKDF_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_HMAC_TEST_LIB_SRC = \ - third_party/boringssl/crypto/hmac_extra/hmac_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_HMAC_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_HMAC_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_HMAC_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_HMAC_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_HMAC_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_LHASH_TEST_LIB_SRC = \ - third_party/boringssl/crypto/lhash/lhash_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_LHASH_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_LHASH_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_LHASH_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_OBJ_TEST_LIB_SRC = \ - third_party/boringssl/crypto/obj/obj_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_OBJ_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_OBJ_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_OBJ_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_OBJ_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_OBJ_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_OBJ_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBBORINGSSL_OBJ_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_OBJ_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_PKCS7_TEST_LIB_SRC = \ - third_party/boringssl/crypto/pkcs7/pkcs7_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_PKCS7_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PKCS7_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_PKCS12_TEST_LIB_SRC = \ - third_party/boringssl/crypto/pkcs8/pkcs12_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_PKCS12_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PKCS12_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_PKCS8_TEST_LIB_SRC = \ - third_party/boringssl/crypto/pkcs8/pkcs8_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_PKCS8_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_PKCS8_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_POLY1305_TEST_LIB_SRC = \ - third_party/boringssl/crypto/poly1305/poly1305_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_POLY1305_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_POLY1305_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_POOL_TEST_LIB_SRC = \ - third_party/boringssl/crypto/pool/pool_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_POOL_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_POOL_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_POOL_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_POOL_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_POOL_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_POOL_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBBORINGSSL_POOL_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_POOL_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_REFCOUNT_TEST_LIB_SRC = \ - third_party/boringssl/crypto/refcount_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_REFCOUNT_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_RSA_TEST_LIB_SRC = \ - third_party/boringssl/crypto/rsa_extra/rsa_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_RSA_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_RSA_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_RSA_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_RSA_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_RSA_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_RSA_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBBORINGSSL_RSA_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_RSA_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_SELF_TEST_LIB_SRC = \ - third_party/boringssl/crypto/self_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_SELF_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SELF_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_SELF_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_SELF_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_SELF_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_SELF_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBBORINGSSL_SELF_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_SELF_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_FILE_TEST_GTEST_LIB_SRC = \ - third_party/boringssl/crypto/test/file_test_gtest.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_FILE_TEST_GTEST_LIB_SRC)))) - -$(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_FILE_TEST_GTEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_GTEST_MAIN_LIB_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_GTEST_MAIN_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_GTEST_MAIN_LIB_SRC)))) - -$(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_GTEST_MAIN_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_THREAD_TEST_LIB_SRC = \ - third_party/boringssl/crypto/thread_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_THREAD_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_THREAD_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_THREAD_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_X509_TEST_LIB_SRC = \ - third_party/boringssl/crypto/x509/x509_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_X509_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_X509_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_X509_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_X509_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_X509_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_X509_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBBORINGSSL_X509_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_X509_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_TAB_TEST_LIB_SRC = \ - third_party/boringssl/crypto/x509v3/tab_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_TAB_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_TAB_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_TAB_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_TAB_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBBORINGSSL_TAB_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_TAB_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_V3NAME_TEST_LIB_SRC = \ - third_party/boringssl/crypto/x509v3/v3name_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_V3NAME_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_V3NAME_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_SPAN_TEST_LIB_SRC = \ - third_party/boringssl/ssl/span_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_SPAN_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SPAN_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_SPAN_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_SPAN_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_SPAN_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_SPAN_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBBORINGSSL_SPAN_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_SPAN_TEST_LIB_OBJS:.o=.dep) -endif - - -LIBBORINGSSL_SSL_TEST_LIB_SRC = \ - third_party/boringssl/ssl/ssl_test.cc \ - -PUBLIC_HEADERS_CXX += \ - -LIBBORINGSSL_SSL_TEST_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBORINGSSL_SSL_TEST_LIB_SRC)))) - -$(LIBBORINGSSL_SSL_TEST_LIB_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(LIBBORINGSSL_SSL_TEST_LIB_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(LIBBORINGSSL_SSL_TEST_LIB_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) - -ifeq ($(NO_PROTOBUF),true) - -# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. - -$(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a: protobuf_dep_error - - -else - -$(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBBORINGSSL_SSL_TEST_LIB_OBJS) - $(E) "[AR] Creating $@" - $(Q) mkdir -p `dirname $@` - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a - $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBBORINGSSL_SSL_TEST_LIB_OBJS) -ifeq ($(SYSTEM),Darwin) - $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a -endif - - - - -endif - -ifneq ($(NO_DEPS),true) --include $(LIBBORINGSSL_SSL_TEST_LIB_OBJS:.o=.dep) -endif - - LIBBENCHMARK_SRC = \ third_party/benchmark/src/benchmark.cc \ third_party/benchmark/src/benchmark_register.cc \ @@ -21491,2008 +19404,10 @@ endif endif -BORINGSSL_CRYPTO_TEST_DATA_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CRYPTO_TEST_DATA_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CRYPTO_TEST_DATA_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_crypto_test_data: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_crypto_test_data: $(PROTOBUF_DEP) $(BORINGSSL_CRYPTO_TEST_DATA_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CRYPTO_TEST_DATA_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_crypto_test_data - -endif - -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CRYPTO_TEST_DATA_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_crypto_test_data_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_crypto_test_data: $(BORINGSSL_CRYPTO_TEST_DATA_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CRYPTO_TEST_DATA_OBJS:.o=.dep) -endif - - -BORINGSSL_ASN1_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_ASN1_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_ASN1_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_ASN1_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_ASN1_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_ASN1_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_asn1_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_asn1_test: $(PROTOBUF_DEP) $(BORINGSSL_ASN1_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_ASN1_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_asn1_test - -endif - -$(BORINGSSL_ASN1_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_ASN1_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_ASN1_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_asn1_test: $(BORINGSSL_ASN1_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_ASN1_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_BASE64_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_BASE64_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_BASE64_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_BASE64_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_BASE64_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_BASE64_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_base64_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_base64_test: $(PROTOBUF_DEP) $(BORINGSSL_BASE64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_BASE64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_base64_test - -endif - -$(BORINGSSL_BASE64_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_BASE64_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_BASE64_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_base64_test: $(BORINGSSL_BASE64_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_BASE64_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_BIO_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_BIO_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_BIO_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_BIO_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_BIO_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_BIO_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_bio_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_bio_test: $(PROTOBUF_DEP) $(BORINGSSL_BIO_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_BIO_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_bio_test - -endif - -$(BORINGSSL_BIO_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_BIO_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_BIO_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_bio_test: $(BORINGSSL_BIO_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_BIO_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_BUF_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_BUF_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_BUF_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_BUF_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_BUF_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_BUF_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_buf_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_buf_test: $(PROTOBUF_DEP) $(BORINGSSL_BUF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_BUF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_buf_test - -endif - -$(BORINGSSL_BUF_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_BUF_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_BUF_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_buf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_buf_test: $(BORINGSSL_BUF_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_BUF_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_BYTESTRING_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_BYTESTRING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_BYTESTRING_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_BYTESTRING_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_BYTESTRING_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_BYTESTRING_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_bytestring_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_bytestring_test: $(PROTOBUF_DEP) $(BORINGSSL_BYTESTRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_BYTESTRING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_bytestring_test - -endif - -$(BORINGSSL_BYTESTRING_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_BYTESTRING_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_BYTESTRING_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_bytestring_test: $(BORINGSSL_BYTESTRING_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_BYTESTRING_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_CHACHA_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CHACHA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CHACHA_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CHACHA_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CHACHA_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CHACHA_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_chacha_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_chacha_test: $(PROTOBUF_DEP) $(BORINGSSL_CHACHA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CHACHA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_chacha_test - -endif - -$(BORINGSSL_CHACHA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CHACHA_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CHACHA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_chacha_test: $(BORINGSSL_CHACHA_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CHACHA_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_AEAD_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_AEAD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_AEAD_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_AEAD_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_AEAD_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_AEAD_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_aead_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_aead_test: $(PROTOBUF_DEP) $(BORINGSSL_AEAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_AEAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_aead_test - -endif - -$(BORINGSSL_AEAD_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_AEAD_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_AEAD_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_aead_test: $(BORINGSSL_AEAD_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_AEAD_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_CIPHER_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CIPHER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CIPHER_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CIPHER_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CIPHER_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CIPHER_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_cipher_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_cipher_test: $(PROTOBUF_DEP) $(BORINGSSL_CIPHER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CIPHER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_cipher_test - -endif - -$(BORINGSSL_CIPHER_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CIPHER_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CIPHER_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_cipher_test: $(BORINGSSL_CIPHER_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CIPHER_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_CMAC_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CMAC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CMAC_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CMAC_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CMAC_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CMAC_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_cmac_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_cmac_test: $(PROTOBUF_DEP) $(BORINGSSL_CMAC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CMAC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_cmac_test - -endif - -$(BORINGSSL_CMAC_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CMAC_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CMAC_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_cmac_test: $(BORINGSSL_CMAC_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CMAC_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_COMPILER_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_COMPILER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_COMPILER_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_COMPILER_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_COMPILER_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_COMPILER_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_compiler_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_compiler_test: $(PROTOBUF_DEP) $(BORINGSSL_COMPILER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_COMPILER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_compiler_test - -endif - -$(BORINGSSL_COMPILER_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_COMPILER_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_COMPILER_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_compiler_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_compiler_test: $(BORINGSSL_COMPILER_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_COMPILER_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_CONSTANT_TIME_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CONSTANT_TIME_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CONSTANT_TIME_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_constant_time_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_constant_time_test: $(PROTOBUF_DEP) $(BORINGSSL_CONSTANT_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CONSTANT_TIME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_constant_time_test - -endif - -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CONSTANT_TIME_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_constant_time_test: $(BORINGSSL_CONSTANT_TIME_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CONSTANT_TIME_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_ED25519_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_ED25519_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_ED25519_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_ED25519_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_ED25519_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_ED25519_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_ed25519_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_ed25519_test: $(PROTOBUF_DEP) $(BORINGSSL_ED25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_ED25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ed25519_test - -endif - -$(BORINGSSL_ED25519_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_ED25519_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_ED25519_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_ed25519_test: $(BORINGSSL_ED25519_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_ED25519_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_SPAKE25519_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_SPAKE25519_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_SPAKE25519_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_SPAKE25519_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_SPAKE25519_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_SPAKE25519_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_spake25519_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_spake25519_test: $(PROTOBUF_DEP) $(BORINGSSL_SPAKE25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SPAKE25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_spake25519_test - -endif - -$(BORINGSSL_SPAKE25519_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_SPAKE25519_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_SPAKE25519_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_spake25519_test: $(BORINGSSL_SPAKE25519_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_SPAKE25519_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_X25519_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_X25519_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_X25519_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_X25519_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_X25519_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_X25519_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_x25519_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_x25519_test: $(PROTOBUF_DEP) $(BORINGSSL_X25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_X25519_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_x25519_test - -endif - -$(BORINGSSL_X25519_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_X25519_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_X25519_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_x25519_test: $(BORINGSSL_X25519_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_X25519_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_DH_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_DH_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_DH_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_DH_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_DH_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_DH_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_dh_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_dh_test: $(PROTOBUF_DEP) $(BORINGSSL_DH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_DH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_dh_test - -endif - -$(BORINGSSL_DH_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_DH_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_DH_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_dh_test: $(BORINGSSL_DH_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_DH_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_DIGEST_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_DIGEST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_DIGEST_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_DIGEST_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_DIGEST_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_DIGEST_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_digest_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_digest_test: $(PROTOBUF_DEP) $(BORINGSSL_DIGEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_DIGEST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_digest_test - -endif - -$(BORINGSSL_DIGEST_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_DIGEST_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_DIGEST_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_digest_test: $(BORINGSSL_DIGEST_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_DIGEST_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_DSA_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_DSA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_DSA_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_DSA_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_DSA_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_DSA_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_dsa_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_dsa_test: $(PROTOBUF_DEP) $(BORINGSSL_DSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_DSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_dsa_test - -endif - -$(BORINGSSL_DSA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_DSA_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_DSA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_dsa_test: $(BORINGSSL_DSA_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_DSA_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_ECDH_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_ECDH_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_ECDH_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_ECDH_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_ECDH_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_ECDH_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_ecdh_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_ecdh_test: $(PROTOBUF_DEP) $(BORINGSSL_ECDH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_ECDH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ecdh_test - -endif - -$(BORINGSSL_ECDH_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_ECDH_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_ECDH_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_ecdh_test: $(BORINGSSL_ECDH_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_ECDH_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_ERR_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_ERR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_ERR_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_ERR_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_ERR_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_ERR_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_err_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_err_test: $(PROTOBUF_DEP) $(BORINGSSL_ERR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_ERR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_err_test - -endif - -$(BORINGSSL_ERR_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_ERR_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_ERR_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_err_test: $(BORINGSSL_ERR_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_ERR_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_EVP_EXTRA_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_EVP_EXTRA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_EVP_EXTRA_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_evp_extra_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_evp_extra_test: $(PROTOBUF_DEP) $(BORINGSSL_EVP_EXTRA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_EVP_EXTRA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_evp_extra_test - -endif - -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_EVP_EXTRA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_evp_extra_test: $(BORINGSSL_EVP_EXTRA_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_EVP_EXTRA_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_EVP_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_EVP_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_EVP_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_EVP_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_EVP_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_EVP_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_evp_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_evp_test: $(PROTOBUF_DEP) $(BORINGSSL_EVP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_EVP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_evp_test - -endif - -$(BORINGSSL_EVP_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_EVP_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_EVP_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_evp_test: $(BORINGSSL_EVP_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_EVP_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_PBKDF_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_PBKDF_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_PBKDF_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_PBKDF_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_PBKDF_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_PBKDF_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_pbkdf_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_pbkdf_test: $(PROTOBUF_DEP) $(BORINGSSL_PBKDF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_PBKDF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_pbkdf_test - -endif - -$(BORINGSSL_PBKDF_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_PBKDF_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_PBKDF_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_pbkdf_test: $(BORINGSSL_PBKDF_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_PBKDF_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_SCRYPT_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_SCRYPT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_SCRYPT_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_SCRYPT_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_SCRYPT_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_SCRYPT_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_scrypt_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_scrypt_test: $(PROTOBUF_DEP) $(BORINGSSL_SCRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SCRYPT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_scrypt_test - -endif - -$(BORINGSSL_SCRYPT_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_SCRYPT_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_SCRYPT_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_scrypt_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_scrypt_test: $(BORINGSSL_SCRYPT_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_SCRYPT_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_AES_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_AES_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_AES_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_AES_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_AES_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_AES_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_aes_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_aes_test: $(PROTOBUF_DEP) $(BORINGSSL_AES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_AES_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_aes_test - -endif - -$(BORINGSSL_AES_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_AES_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_AES_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_aes_test: $(BORINGSSL_AES_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_AES_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_BN_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_BN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_BN_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_BN_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_BN_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_BN_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_bn_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_bn_test: $(PROTOBUF_DEP) $(BORINGSSL_BN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_BN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_bn_test - -endif - -$(BORINGSSL_BN_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_BN_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_BN_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_bn_test: $(BORINGSSL_BN_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_BN_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_EC_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_EC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_EC_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_EC_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_EC_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_EC_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_ec_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_ec_test: $(PROTOBUF_DEP) $(BORINGSSL_EC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_EC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ec_test - -endif - -$(BORINGSSL_EC_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_EC_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_EC_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_ec_test: $(BORINGSSL_EC_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_EC_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_P256-X86_64_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_P256-X86_64_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_P256-X86_64_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_P256-X86_64_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_P256-X86_64_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_P256-X86_64_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_p256-x86_64_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_p256-x86_64_test: $(PROTOBUF_DEP) $(BORINGSSL_P256-X86_64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_P256-X86_64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_p256-x86_64_test - -endif - -$(BORINGSSL_P256-X86_64_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_P256-X86_64_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_P256-X86_64_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_p256-x86_64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_p256-x86_64_test: $(BORINGSSL_P256-X86_64_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_P256-X86_64_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_ECDSA_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_ECDSA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_ECDSA_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_ECDSA_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_ECDSA_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_ECDSA_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_ecdsa_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_ecdsa_test: $(PROTOBUF_DEP) $(BORINGSSL_ECDSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_ECDSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ecdsa_test - -endif - -$(BORINGSSL_ECDSA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_ECDSA_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_ECDSA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_ecdsa_test: $(BORINGSSL_ECDSA_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_ECDSA_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_GCM_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_GCM_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_GCM_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_GCM_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_GCM_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_GCM_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_gcm_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_gcm_test: $(PROTOBUF_DEP) $(BORINGSSL_GCM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_GCM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_gcm_test - -endif - -$(BORINGSSL_GCM_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_GCM_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_GCM_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_gcm_test: $(BORINGSSL_GCM_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_GCM_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_CTRDRBG_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_CTRDRBG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CTRDRBG_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_CTRDRBG_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_CTRDRBG_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_CTRDRBG_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_ctrdrbg_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_ctrdrbg_test: $(PROTOBUF_DEP) $(BORINGSSL_CTRDRBG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CTRDRBG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ctrdrbg_test - -endif - -$(BORINGSSL_CTRDRBG_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_CTRDRBG_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_CTRDRBG_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ctrdrbg_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_ctrdrbg_test: $(BORINGSSL_CTRDRBG_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_CTRDRBG_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_HKDF_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_HKDF_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_HKDF_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_HKDF_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_HKDF_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_HKDF_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_hkdf_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_hkdf_test: $(PROTOBUF_DEP) $(BORINGSSL_HKDF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_HKDF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_hkdf_test - -endif - -$(BORINGSSL_HKDF_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_HKDF_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_HKDF_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_hkdf_test: $(BORINGSSL_HKDF_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_HKDF_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_HMAC_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_HMAC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_HMAC_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_HMAC_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_HMAC_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_HMAC_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_hmac_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_hmac_test: $(PROTOBUF_DEP) $(BORINGSSL_HMAC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_HMAC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_hmac_test - -endif - -$(BORINGSSL_HMAC_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_HMAC_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_HMAC_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_hmac_test: $(BORINGSSL_HMAC_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_HMAC_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_LHASH_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_LHASH_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_LHASH_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_LHASH_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_LHASH_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_LHASH_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_lhash_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_lhash_test: $(PROTOBUF_DEP) $(BORINGSSL_LHASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_LHASH_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_lhash_test - -endif - -$(BORINGSSL_LHASH_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_LHASH_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_LHASH_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_lhash_test: $(BORINGSSL_LHASH_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_LHASH_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_OBJ_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_OBJ_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_OBJ_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_OBJ_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_OBJ_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_OBJ_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_obj_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_obj_test: $(PROTOBUF_DEP) $(BORINGSSL_OBJ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_OBJ_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_obj_test - -endif - -$(BORINGSSL_OBJ_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_OBJ_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_OBJ_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_obj_test: $(BORINGSSL_OBJ_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_OBJ_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_PKCS7_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_PKCS7_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_PKCS7_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_PKCS7_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_PKCS7_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_PKCS7_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_pkcs7_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_pkcs7_test: $(PROTOBUF_DEP) $(BORINGSSL_PKCS7_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_PKCS7_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_pkcs7_test - -endif - -$(BORINGSSL_PKCS7_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_PKCS7_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_PKCS7_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_pkcs7_test: $(BORINGSSL_PKCS7_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_PKCS7_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_PKCS12_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_PKCS12_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_PKCS12_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_PKCS12_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_PKCS12_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_PKCS12_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_pkcs12_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_pkcs12_test: $(PROTOBUF_DEP) $(BORINGSSL_PKCS12_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_PKCS12_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_pkcs12_test - -endif - -$(BORINGSSL_PKCS12_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_PKCS12_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_PKCS12_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_pkcs12_test: $(BORINGSSL_PKCS12_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_PKCS12_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_PKCS8_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_PKCS8_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_PKCS8_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_PKCS8_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_PKCS8_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_PKCS8_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_pkcs8_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_pkcs8_test: $(PROTOBUF_DEP) $(BORINGSSL_PKCS8_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_PKCS8_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_pkcs8_test - -endif - -$(BORINGSSL_PKCS8_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_PKCS8_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_PKCS8_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_pkcs8_test: $(BORINGSSL_PKCS8_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_PKCS8_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_POLY1305_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_POLY1305_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_POLY1305_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_POLY1305_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_POLY1305_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_POLY1305_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_poly1305_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_poly1305_test: $(PROTOBUF_DEP) $(BORINGSSL_POLY1305_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_POLY1305_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_poly1305_test - -endif - -$(BORINGSSL_POLY1305_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_POLY1305_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_POLY1305_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_poly1305_test: $(BORINGSSL_POLY1305_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_POLY1305_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_POOL_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_POOL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_POOL_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_POOL_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_POOL_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_POOL_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_pool_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_pool_test: $(PROTOBUF_DEP) $(BORINGSSL_POOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_POOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_pool_test - -endif - -$(BORINGSSL_POOL_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_POOL_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_POOL_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_pool_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_pool_test: $(BORINGSSL_POOL_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_POOL_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_REFCOUNT_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_REFCOUNT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_REFCOUNT_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_REFCOUNT_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_REFCOUNT_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_REFCOUNT_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_refcount_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_refcount_test: $(PROTOBUF_DEP) $(BORINGSSL_REFCOUNT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_REFCOUNT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_refcount_test - -endif - -$(BORINGSSL_REFCOUNT_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_REFCOUNT_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_REFCOUNT_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_refcount_test: $(BORINGSSL_REFCOUNT_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_REFCOUNT_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_RSA_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_RSA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_RSA_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_RSA_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_RSA_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_RSA_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_rsa_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_rsa_test: $(PROTOBUF_DEP) $(BORINGSSL_RSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_RSA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_rsa_test - -endif - -$(BORINGSSL_RSA_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_RSA_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_RSA_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_rsa_test: $(BORINGSSL_RSA_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_RSA_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_SELF_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_SELF_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_SELF_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_SELF_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_SELF_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_SELF_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_self_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_self_test: $(PROTOBUF_DEP) $(BORINGSSL_SELF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SELF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_self_test - -endif - -$(BORINGSSL_SELF_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_SELF_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_SELF_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_self_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_self_test: $(BORINGSSL_SELF_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_SELF_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_FILE_TEST_GTEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_FILE_TEST_GTEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_FILE_TEST_GTEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_file_test_gtest: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_file_test_gtest: $(PROTOBUF_DEP) $(BORINGSSL_FILE_TEST_GTEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_FILE_TEST_GTEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_file_test_gtest - -endif - -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_FILE_TEST_GTEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_file_test_gtest_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_file_test_gtest: $(BORINGSSL_FILE_TEST_GTEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_FILE_TEST_GTEST_OBJS:.o=.dep) -endif - - -BORINGSSL_GTEST_MAIN_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_GTEST_MAIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_GTEST_MAIN_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_GTEST_MAIN_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_GTEST_MAIN_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_GTEST_MAIN_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_gtest_main: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_gtest_main: $(PROTOBUF_DEP) $(BORINGSSL_GTEST_MAIN_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_GTEST_MAIN_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_gtest_main - -endif - -$(BORINGSSL_GTEST_MAIN_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_GTEST_MAIN_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_GTEST_MAIN_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_gtest_main_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_gtest_main: $(BORINGSSL_GTEST_MAIN_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_GTEST_MAIN_OBJS:.o=.dep) -endif - - -BORINGSSL_THREAD_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_THREAD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_THREAD_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_THREAD_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_THREAD_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_THREAD_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_thread_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_thread_test: $(PROTOBUF_DEP) $(BORINGSSL_THREAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_THREAD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_thread_test - -endif - -$(BORINGSSL_THREAD_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_THREAD_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_THREAD_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_thread_test: $(BORINGSSL_THREAD_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_THREAD_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_X509_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_X509_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_X509_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_X509_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_X509_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_X509_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_x509_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_x509_test: $(PROTOBUF_DEP) $(BORINGSSL_X509_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_X509_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_x509_test - -endif - -$(BORINGSSL_X509_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_X509_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_X509_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_x509_test: $(BORINGSSL_X509_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_X509_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_TAB_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_TAB_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_TAB_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_TAB_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_TAB_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_TAB_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_tab_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_tab_test: $(PROTOBUF_DEP) $(BORINGSSL_TAB_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_TAB_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_tab_test - -endif - -$(BORINGSSL_TAB_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_TAB_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_TAB_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_tab_test: $(BORINGSSL_TAB_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_TAB_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_V3NAME_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_V3NAME_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_V3NAME_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_V3NAME_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_V3NAME_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_V3NAME_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_v3name_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_v3name_test: $(PROTOBUF_DEP) $(BORINGSSL_V3NAME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_V3NAME_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_v3name_test - -endif - -$(BORINGSSL_V3NAME_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_V3NAME_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_V3NAME_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_v3name_test: $(BORINGSSL_V3NAME_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_V3NAME_TEST_OBJS:.o=.dep) -endif - - -BORINGSSL_SPAN_TEST_SRC = \ - third_party/boringssl/crypto/test/gtest_main.cc \ - -BORINGSSL_SPAN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_SPAN_TEST_SRC)))) - -# boringssl needs an override to ensure that it does not include -# system openssl headers regardless of other configuration -# we do so here with a target specific variable assignment -$(BORINGSSL_SPAN_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) -$(BORINGSSL_SPAN_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) -$(BORINGSSL_SPAN_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE - - -ifeq ($(NO_PROTOBUF),true) - -# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. - -$(BINDIR)/$(CONFIG)/boringssl_span_test: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/boringssl_span_test: $(PROTOBUF_DEP) $(BORINGSSL_SPAN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SPAN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_span_test - -endif - -$(BORINGSSL_SPAN_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -$(BORINGSSL_SPAN_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions -$(BORINGSSL_SPAN_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_span_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a - -deps_boringssl_span_test: $(BORINGSSL_SPAN_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(BORINGSSL_SPAN_TEST_OBJS:.o=.dep) -endif - - BORINGSSL_SSL_TEST_SRC = \ third_party/boringssl/crypto/test/gtest_main.cc \ + third_party/boringssl/ssl/span_test.cc \ + third_party/boringssl/ssl/ssl_test.cc \ BORINGSSL_SSL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_SSL_TEST_SRC)))) @@ -23512,17 +19427,21 @@ $(BINDIR)/$(CONFIG)/boringssl_ssl_test: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/boringssl_ssl_test: $(PROTOBUF_DEP) $(BORINGSSL_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a +$(BINDIR)/$(CONFIG)/boringssl_ssl_test: $(PROTOBUF_DEP) $(BORINGSSL_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ssl_test + $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_ssl_test endif $(BORINGSSL_SSL_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(BORINGSSL_SSL_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions $(BORINGSSL_SSL_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) -$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/ssl/span_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/ssl/ssl_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a deps_boringssl_ssl_test: $(BORINGSSL_SSL_TEST_OBJS:.o=.dep) @@ -23531,6 +19450,190 @@ ifneq ($(NO_DEPS),true) endif +BORINGSSL_CRYPTO_TEST_SRC = \ + src/boringssl/crypto_test_data.cc \ + third_party/boringssl/crypto/asn1/asn1_test.cc \ + third_party/boringssl/crypto/base64/base64_test.cc \ + third_party/boringssl/crypto/bio/bio_test.cc \ + third_party/boringssl/crypto/buf/buf_test.cc \ + third_party/boringssl/crypto/bytestring/bytestring_test.cc \ + third_party/boringssl/crypto/chacha/chacha_test.cc \ + third_party/boringssl/crypto/cipher_extra/aead_test.cc \ + third_party/boringssl/crypto/cipher_extra/cipher_test.cc \ + third_party/boringssl/crypto/cmac/cmac_test.cc \ + third_party/boringssl/crypto/compiler_test.cc \ + third_party/boringssl/crypto/constant_time_test.cc \ + third_party/boringssl/crypto/curve25519/ed25519_test.cc \ + third_party/boringssl/crypto/curve25519/spake25519_test.cc \ + third_party/boringssl/crypto/curve25519/x25519_test.cc \ + third_party/boringssl/crypto/dh/dh_test.cc \ + third_party/boringssl/crypto/digest_extra/digest_test.cc \ + third_party/boringssl/crypto/dsa/dsa_test.cc \ + third_party/boringssl/crypto/ecdh/ecdh_test.cc \ + third_party/boringssl/crypto/err/err_test.cc \ + third_party/boringssl/crypto/evp/evp_extra_test.cc \ + third_party/boringssl/crypto/evp/evp_test.cc \ + third_party/boringssl/crypto/evp/pbkdf_test.cc \ + third_party/boringssl/crypto/evp/scrypt_test.cc \ + third_party/boringssl/crypto/fipsmodule/aes/aes_test.cc \ + third_party/boringssl/crypto/fipsmodule/bn/bn_test.cc \ + third_party/boringssl/crypto/fipsmodule/ec/ec_test.cc \ + third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64_test.cc \ + third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa_test.cc \ + third_party/boringssl/crypto/fipsmodule/modes/gcm_test.cc \ + third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg_test.cc \ + third_party/boringssl/crypto/hkdf/hkdf_test.cc \ + third_party/boringssl/crypto/hmac_extra/hmac_test.cc \ + third_party/boringssl/crypto/lhash/lhash_test.cc \ + third_party/boringssl/crypto/obj/obj_test.cc \ + third_party/boringssl/crypto/pkcs7/pkcs7_test.cc \ + third_party/boringssl/crypto/pkcs8/pkcs12_test.cc \ + third_party/boringssl/crypto/pkcs8/pkcs8_test.cc \ + third_party/boringssl/crypto/poly1305/poly1305_test.cc \ + third_party/boringssl/crypto/pool/pool_test.cc \ + third_party/boringssl/crypto/refcount_test.cc \ + third_party/boringssl/crypto/rsa_extra/rsa_test.cc \ + third_party/boringssl/crypto/self_test.cc \ + third_party/boringssl/crypto/test/file_test_gtest.cc \ + third_party/boringssl/crypto/test/gtest_main.cc \ + third_party/boringssl/crypto/thread_test.cc \ + third_party/boringssl/crypto/x509/x509_test.cc \ + third_party/boringssl/crypto/x509v3/tab_test.cc \ + third_party/boringssl/crypto/x509v3/v3name_test.cc \ + +BORINGSSL_CRYPTO_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BORINGSSL_CRYPTO_TEST_SRC)))) + +# boringssl needs an override to ensure that it does not include +# system openssl headers regardless of other configuration +# we do so here with a target specific variable assignment +$(BORINGSSL_CRYPTO_TEST_OBJS): CFLAGS := -Ithird_party/boringssl/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI) +$(BORINGSSL_CRYPTO_TEST_OBJS): CXXFLAGS := -Ithird_party/boringssl/include $(CXXFLAGS) +$(BORINGSSL_CRYPTO_TEST_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/boringssl_crypto_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/boringssl_crypto_test: $(PROTOBUF_DEP) $(BORINGSSL_CRYPTO_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(BORINGSSL_CRYPTO_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/boringssl_crypto_test + +endif + +$(BORINGSSL_CRYPTO_TEST_OBJS): CPPFLAGS += -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX +$(BORINGSSL_CRYPTO_TEST_OBJS): CXXFLAGS += -fno-rtti -fno-exceptions +$(BORINGSSL_CRYPTO_TEST_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough $(NO_W_EXTRA_SEMI) +$(OBJDIR)/$(CONFIG)/src/boringssl/crypto_test_data.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/asn1/asn1_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/base64/base64_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/bio/bio_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/buf/buf_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/bytestring/bytestring_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/chacha/chacha_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/cipher_extra/aead_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/cipher_extra/cipher_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/cmac/cmac_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/compiler_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/constant_time_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/curve25519/ed25519_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/curve25519/spake25519_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/curve25519/x25519_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/dh/dh_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/digest_extra/digest_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/dsa/dsa_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/ecdh/ecdh_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/err/err_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/evp/evp_extra_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/evp/evp_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/evp/pbkdf_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/evp/scrypt_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/aes/aes_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/bn/bn_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/ec/ec_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/modes/gcm_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/hkdf/hkdf_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/hmac_extra/hmac_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/lhash/lhash_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/obj/obj_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/pkcs7/pkcs7_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/pkcs8/pkcs12_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/pkcs8/pkcs8_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/poly1305/poly1305_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/pool/pool_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/refcount_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/rsa_extra/rsa_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/self_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/file_test_gtest.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/test/gtest_main.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/thread_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/x509/x509_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/x509v3/tab_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +$(OBJDIR)/$(CONFIG)/third_party/boringssl/crypto/x509v3/v3name_test.o: $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl.a + +deps_boringssl_crypto_test: $(BORINGSSL_CRYPTO_TEST_OBJS:.o=.dep) + +ifneq ($(NO_DEPS),true) +-include $(BORINGSSL_CRYPTO_TEST_OBJS:.o=.dep) +endif + + BADREQ_BAD_CLIENT_TEST_SRC = \ test/core/bad_client/tests/badreq.cc \ diff --git a/grpc.gyp b/grpc.gyp index b3795cbfd06..528a382bea0 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -2058,567 +2058,6 @@ 'third_party/boringssl/crypto/test/test_util.cc', ], }, - { - 'target_name': 'boringssl_crypto_test_data_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'src/boringssl/crypto_test_data.cc', - ], - }, - { - 'target_name': 'boringssl_asn1_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/asn1/asn1_test.cc', - ], - }, - { - 'target_name': 'boringssl_base64_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/base64/base64_test.cc', - ], - }, - { - 'target_name': 'boringssl_bio_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/bio/bio_test.cc', - ], - }, - { - 'target_name': 'boringssl_buf_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/buf/buf_test.cc', - ], - }, - { - 'target_name': 'boringssl_bytestring_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/bytestring/bytestring_test.cc', - ], - }, - { - 'target_name': 'boringssl_chacha_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/chacha/chacha_test.cc', - ], - }, - { - 'target_name': 'boringssl_aead_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/cipher_extra/aead_test.cc', - ], - }, - { - 'target_name': 'boringssl_cipher_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/cipher_extra/cipher_test.cc', - ], - }, - { - 'target_name': 'boringssl_cmac_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/cmac/cmac_test.cc', - ], - }, - { - 'target_name': 'boringssl_compiler_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/compiler_test.cc', - ], - }, - { - 'target_name': 'boringssl_constant_time_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/constant_time_test.cc', - ], - }, - { - 'target_name': 'boringssl_ed25519_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/curve25519/ed25519_test.cc', - ], - }, - { - 'target_name': 'boringssl_spake25519_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/curve25519/spake25519_test.cc', - ], - }, - { - 'target_name': 'boringssl_x25519_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/curve25519/x25519_test.cc', - ], - }, - { - 'target_name': 'boringssl_dh_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/dh/dh_test.cc', - ], - }, - { - 'target_name': 'boringssl_digest_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/digest_extra/digest_test.cc', - ], - }, - { - 'target_name': 'boringssl_dsa_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/dsa/dsa_test.cc', - ], - }, - { - 'target_name': 'boringssl_ecdh_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/ecdh/ecdh_test.cc', - ], - }, - { - 'target_name': 'boringssl_err_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/err/err_test.cc', - ], - }, - { - 'target_name': 'boringssl_evp_extra_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/evp/evp_extra_test.cc', - ], - }, - { - 'target_name': 'boringssl_evp_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/evp/evp_test.cc', - ], - }, - { - 'target_name': 'boringssl_pbkdf_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/evp/pbkdf_test.cc', - ], - }, - { - 'target_name': 'boringssl_scrypt_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/evp/scrypt_test.cc', - ], - }, - { - 'target_name': 'boringssl_aes_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/aes/aes_test.cc', - ], - }, - { - 'target_name': 'boringssl_bn_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/bn/bn_test.cc', - ], - }, - { - 'target_name': 'boringssl_ec_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/ec/ec_test.cc', - ], - }, - { - 'target_name': 'boringssl_p256-x86_64_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64_test.cc', - ], - }, - { - 'target_name': 'boringssl_ecdsa_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa_test.cc', - ], - }, - { - 'target_name': 'boringssl_gcm_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/modes/gcm_test.cc', - ], - }, - { - 'target_name': 'boringssl_ctrdrbg_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg_test.cc', - ], - }, - { - 'target_name': 'boringssl_hkdf_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/hkdf/hkdf_test.cc', - ], - }, - { - 'target_name': 'boringssl_hmac_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/hmac_extra/hmac_test.cc', - ], - }, - { - 'target_name': 'boringssl_lhash_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/lhash/lhash_test.cc', - ], - }, - { - 'target_name': 'boringssl_obj_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/obj/obj_test.cc', - ], - }, - { - 'target_name': 'boringssl_pkcs7_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/pkcs7/pkcs7_test.cc', - ], - }, - { - 'target_name': 'boringssl_pkcs12_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/pkcs8/pkcs12_test.cc', - ], - }, - { - 'target_name': 'boringssl_pkcs8_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/pkcs8/pkcs8_test.cc', - ], - }, - { - 'target_name': 'boringssl_poly1305_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/poly1305/poly1305_test.cc', - ], - }, - { - 'target_name': 'boringssl_pool_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/pool/pool_test.cc', - ], - }, - { - 'target_name': 'boringssl_refcount_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/refcount_test.cc', - ], - }, - { - 'target_name': 'boringssl_rsa_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/rsa_extra/rsa_test.cc', - ], - }, - { - 'target_name': 'boringssl_self_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/self_test.cc', - ], - }, - { - 'target_name': 'boringssl_file_test_gtest_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/test/file_test_gtest.cc', - ], - }, - { - 'target_name': 'boringssl_gtest_main_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/test/gtest_main.cc', - ], - }, - { - 'target_name': 'boringssl_thread_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/thread_test.cc', - ], - }, - { - 'target_name': 'boringssl_x509_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/x509/x509_test.cc', - ], - }, - { - 'target_name': 'boringssl_tab_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/x509v3/tab_test.cc', - ], - }, - { - 'target_name': 'boringssl_v3name_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/crypto/x509v3/v3name_test.cc', - ], - }, - { - 'target_name': 'boringssl_span_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/ssl/span_test.cc', - ], - }, - { - 'target_name': 'boringssl_ssl_test_lib', - 'type': 'static_library', - 'dependencies': [ - 'boringssl_test_util', - 'boringssl', - ], - 'sources': [ - 'third_party/boringssl/ssl/ssl_test.cc', - ], - }, { 'target_name': 'benchmark', 'type': 'static_library', diff --git a/src/boringssl/gen_build_yaml.py b/src/boringssl/gen_build_yaml.py index 593b66dc4d9..c25a4ed3c94 100755 --- a/src/boringssl/gen_build_yaml.py +++ b/src/boringssl/gen_build_yaml.py @@ -48,6 +48,7 @@ class Grpc(object): yaml = None def WriteFiles(self, files, asm_outputs): + test_binaries = ['ssl_test', 'crypto_test'] self.yaml = { '#': 'generated with tools/buildgen/gen_boring_ssl_build_yaml.py', @@ -86,45 +87,28 @@ class Grpc(object): for f in sorted(files['test_support']) ], } - ] + [ - { - 'name': 'boringssl_%s_lib' % os.path.splitext(os.path.basename(test))[0], - 'build': 'private', - 'secure': 'no', - 'language': 'c' if os.path.splitext(test)[1] == '.c' else 'c++', - 'src': [map_dir(test)], - 'vs_proj_dir': 'test/boringssl', - 'boringssl': True, - 'defaults': 'boringssl', - 'deps': [ - 'boringssl_test_util', - 'boringssl', - ] - } - for test in list(sorted(set(files['ssl_test'] + files['crypto_test']))) ], 'targets': [ { - 'name': 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0], + 'name': 'boringssl_%s' % test, 'build': 'test', 'run': False, 'secure': 'no', 'language': 'c++', - 'src': ["third_party/boringssl/crypto/test/gtest_main.cc"], + 'src': sorted(map_dir(f) for f in files[test]), 'vs_proj_dir': 'test/boringssl', 'boringssl': True, 'defaults': 'boringssl', 'deps': [ - 'boringssl_%s_lib' % os.path.splitext(os.path.basename(test))[0], 'boringssl_test_util', 'boringssl', ] } - for test in list(sorted(set(files['ssl_test'] + files['crypto_test']))) + for test in test_binaries ], 'tests': [ { - 'name': 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0], + 'name': 'boringssl_%s' % test, 'args': [], 'exclude_configs': ['asan', 'ubsan'], 'ci_platforms': ['linux', 'mac', 'posix', 'windows'], @@ -136,9 +120,8 @@ class Grpc(object): 'defaults': 'boringssl', 'cpu_cost': 1.0 } - for test in list(sorted(set(files['ssl_test'] + files['crypto_test']))) + for test in test_binaries ] - } diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 2d427804d07..4e6481e8f80 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -5065,707 +5065,6 @@ { "deps": [ "boringssl", - "boringssl_crypto_test_data_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_crypto_test_data", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_asn1_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_asn1_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_base64_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_base64_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_bio_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bio_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_buf_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_buf_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_bytestring_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bytestring_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_chacha_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_chacha_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_aead_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_aead_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_cipher_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_cipher_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_cmac_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_cmac_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_compiler_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_compiler_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_constant_time_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_constant_time_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ed25519_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ed25519_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_spake25519_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_spake25519_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util", - "boringssl_x25519_test_lib" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_x25519_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_dh_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_dh_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_digest_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_digest_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_dsa_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_dsa_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ecdh_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ecdh_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_err_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_err_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_evp_extra_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_evp_extra_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_evp_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_evp_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_pbkdf_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pbkdf_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_scrypt_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_scrypt_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_aes_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_aes_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_bn_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bn_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ec_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ec_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_p256-x86_64_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_p256-x86_64_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ecdsa_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ecdsa_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_gcm_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_gcm_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ctrdrbg_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ctrdrbg_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_hkdf_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_hkdf_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_hmac_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_hmac_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_lhash_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_lhash_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_obj_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_obj_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_pkcs7_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs7_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_pkcs12_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs12_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_pkcs8_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs8_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_poly1305_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_poly1305_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_pool_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pool_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_refcount_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_refcount_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_rsa_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_rsa_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_self_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_self_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_file_test_gtest_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_file_test_gtest", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_gtest_main_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_gtest_main", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util", - "boringssl_thread_test_lib" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_thread_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util", - "boringssl_x509_test_lib" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_x509_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_tab_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_tab_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util", - "boringssl_v3name_test_lib" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_v3name_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_span_test_lib", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_span_test", - "src": [], - "third_party": true, - "type": "target" - }, - { - "deps": [ - "boringssl", - "boringssl_ssl_test_lib", "boringssl_test_util" ], "headers": [], @@ -5776,6 +5075,21 @@ "third_party": true, "type": "target" }, + { + "deps": [ + "boringssl", + "boringssl_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "boringssl_crypto_test", + "src": [ + "src/boringssl/crypto_test_data.cc" + ], + "third_party": true, + "type": "target" + }, { "deps": [ "bad_client_test", @@ -8060,671 +7374,6 @@ "third_party": true, "type": "lib" }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_crypto_test_data_lib", - "src": [ - "src/boringssl/crypto_test_data.cc" - ], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_asn1_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_base64_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bio_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_buf_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bytestring_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_chacha_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_aead_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_cipher_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_cmac_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_compiler_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_constant_time_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ed25519_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_spake25519_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_x25519_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_dh_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_digest_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_dsa_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ecdh_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_err_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_evp_extra_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_evp_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pbkdf_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_scrypt_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_aes_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_bn_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ec_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_p256-x86_64_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ecdsa_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_gcm_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ctrdrbg_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_hkdf_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_hmac_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_lhash_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_obj_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs7_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs12_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pkcs8_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_poly1305_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_pool_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_refcount_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_rsa_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_self_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_file_test_gtest_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_gtest_main_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_thread_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_x509_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_tab_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_v3name_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_span_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, - { - "deps": [ - "boringssl", - "boringssl_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c++", - "name": "boringssl_ssl_test_lib", - "src": [], - "third_party": true, - "type": "lib" - }, { "deps": [], "headers": [ diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index cffc8b98764..cf0e574b09d 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -6136,1306 +6136,6 @@ ], "uses_polling": true }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_crypto_test_data", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_asn1_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_base64_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_bio_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_buf_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_bytestring_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_chacha_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_aead_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_cipher_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_cmac_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_compiler_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_constant_time_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_ed25519_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_spake25519_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_x25519_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_dh_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_digest_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_dsa_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_ecdh_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_err_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_evp_extra_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_evp_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_pbkdf_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_scrypt_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_aes_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_bn_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_ec_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_p256-x86_64_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_ecdsa_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_gcm_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_ctrdrbg_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_hkdf_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_hmac_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_lhash_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_obj_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_pkcs7_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_pkcs12_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_pkcs8_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_poly1305_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_pool_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_refcount_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_rsa_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_self_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_file_test_gtest", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_gtest_main", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_thread_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_x509_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_tab_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_v3name_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, - { - "args": [], - "boringssl": true, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "defaults": "boringssl", - "exclude_configs": [ - "asan", - "ubsan" - ], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "boringssl_span_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ] - }, { "args": [], "boringssl": true, @@ -7462,6 +6162,32 @@ "windows" ] }, + { + "args": [], + "boringssl": true, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "defaults": "boringssl", + "exclude_configs": [ + "asan", + "ubsan" + ], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "boringssl_crypto_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [ "authority_not_supported" From 79c240ae049bb1185ef7015eb9e36ef05e99c906 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 19 Mar 2019 11:54:08 -0700 Subject: [PATCH 743/814] attempt at fixing portability test --- cmake/gflags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/gflags.cmake b/cmake/gflags.cmake index c301b1cdb6d..0afdae82957 100644 --- a/cmake/gflags.cmake +++ b/cmake/gflags.cmake @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +set(gRPC_GFLAGS_PROVIDER "module" CACHE STRING "portability fix") if("${gRPC_GFLAGS_PROVIDER}" STREQUAL "module") if(NOT GFLAGS_ROOT_DIR) set(GFLAGS_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gflags) From 1dbaf5f4df2d31012ae8cac5dcfb08655f61866a Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 19 Mar 2019 14:13:05 -0700 Subject: [PATCH 744/814] debug output for cmake --- cmake/gflags.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/gflags.cmake b/cmake/gflags.cmake index 0afdae82957..e17972b3657 100644 --- a/cmake/gflags.cmake +++ b/cmake/gflags.cmake @@ -13,10 +13,12 @@ # limitations under the License. set(gRPC_GFLAGS_PROVIDER "module" CACHE STRING "portability fix") if("${gRPC_GFLAGS_PROVIDER}" STREQUAL "module") + message("gRPC GFLAGS is MODULE") if(NOT GFLAGS_ROOT_DIR) set(GFLAGS_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gflags) endif() if(EXISTS "${GFLAGS_ROOT_DIR}/CMakeLists.txt") + message("gRPC GFLAGS adding subdirectory") add_subdirectory(${GFLAGS_ROOT_DIR} third_party/gflags) if(TARGET gflags_static) set(_gRPC_GFLAGS_LIBRARIES gflags_static) @@ -26,6 +28,7 @@ if("${gRPC_GFLAGS_PROVIDER}" STREQUAL "module") message(WARNING "gRPC_GFLAGS_PROVIDER is \"module\" but GFLAGS_ROOT_DIR is wrong") endif() elseif("${gRPC_GFLAGS_PROVIDER}" STREQUAL "package") + message("gRPC GFLAGS is PACKAGE") # Use "CONFIG" as there is no built-in cmake module for gflags. find_package(gflags REQUIRED CONFIG) if(TARGET gflags) From ec82dbae39003892114c4207595154a029b4d2d0 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 19 Mar 2019 15:05:54 -0700 Subject: [PATCH 745/814] Add the actual peer in the error message --- src/core/lib/surface/call.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index d53eb704420..ccb37c51641 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1035,9 +1035,15 @@ static void recv_trailing_filter(void* args, grpc_metadata_batch* b, grpc_get_status_code_from_metadata(b->idx.named.grpc_status->md); grpc_error* error = GRPC_ERROR_NONE; if (status_code != GRPC_STATUS_OK) { - error = grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error received from peer"), - GRPC_ERROR_INT_GRPC_STATUS, static_cast(status_code)); + char* peer_msg = nullptr; + char* peer = grpc_call_get_peer(call); + gpr_asprintf(&peer_msg, "Error received from peer %s", + grpc_call_get_peer(call)); + error = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(peer_msg), + GRPC_ERROR_INT_GRPC_STATUS, + static_cast(status_code)); + gpr_free(peer); + gpr_free(peer_msg); } if (b->idx.named.grpc_message != nullptr) { error = grpc_error_set_str( From 2c6849af7bf1929b196d8e337954d45b5f0df41c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 19 Mar 2019 15:49:17 -0700 Subject: [PATCH 746/814] s/peer/grpc_call_get_peer --- src/core/lib/surface/call.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index ccb37c51641..8aaff4a67d5 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1037,8 +1037,7 @@ static void recv_trailing_filter(void* args, grpc_metadata_batch* b, if (status_code != GRPC_STATUS_OK) { char* peer_msg = nullptr; char* peer = grpc_call_get_peer(call); - gpr_asprintf(&peer_msg, "Error received from peer %s", - grpc_call_get_peer(call)); + gpr_asprintf(&peer_msg, "Error received from peer %s", peer); error = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(peer_msg), GRPC_ERROR_INT_GRPC_STATUS, static_cast(status_code)); From 6ecf74f641665741248c404b4dc260748b72d4e6 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 19 Mar 2019 16:32:41 -0700 Subject: [PATCH 747/814] Increase timeout for test --- test/cpp/end2end/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index d945dd3f7f7..998ba8e1e4e 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -637,6 +637,7 @@ grpc_cc_test( grpc_cc_test( name = "thread_stress_test", + timeout = "long", srcs = ["thread_stress_test.cc"], external_deps = [ "gtest", From 235fa490556c090aba961379e09bf208139add10 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Tue, 19 Mar 2019 18:38:08 -0700 Subject: [PATCH 748/814] fail-fast if no pem root certs are available. --- .../security_connector/ssl/ssl_security_connector.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index 39c5434208b..fbf59d23b9d 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -319,6 +319,11 @@ grpc_ssl_channel_security_connector_create( gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); return nullptr; } + if (config->pem_root_certs == nullptr && + grpc_core::DefaultSslRootStore::GetPemRootCerts() == nullptr) { + gpr_log(GPR_ERROR, "Could not get pem root certs."); + return nullptr; + } grpc_core::RefCountedPtr c = grpc_core::MakeRefCounted( std::move(channel_creds), std::move(request_metadata_creds), config, From e6cae04e5f77f2f5f113fc9cc6a5e7b09ede644e Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 20 Mar 2019 10:44:07 -0400 Subject: [PATCH 749/814] Fix a typo in CompareExchangeStrong() Use compare_exchange_strong() instead of compare_exchange_weak(), which can be spuriously fail on some platforms. Thanks to Mark Roth to pointing this out! --- src/core/lib/gprpp/atomic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/gprpp/atomic.h b/src/core/lib/gprpp/atomic.h index aec283c50dc..80412ef9583 100644 --- a/src/core/lib/gprpp/atomic.h +++ b/src/core/lib/gprpp/atomic.h @@ -58,7 +58,7 @@ class Atomic { bool CompareExchangeStrong(T* expected, T desired, MemoryOrder success, MemoryOrder failure) { - return GPR_ATM_INC_CAS_THEN(storage_.compare_exchange_weak( + return GPR_ATM_INC_CAS_THEN(storage_.compare_exchange_strong( *expected, desired, static_cast(success), static_cast(failure))); } From ca69f911a77deb00186abc2cdf2e659c9b0f7d8c Mon Sep 17 00:00:00 2001 From: Arjun Date: Tue, 19 Mar 2019 18:07:27 -0700 Subject: [PATCH 750/814] Add initial Fuchsia support. 1. Add a BUILD.gn file 2. Support fuchsia as a platform This is heavily based on the changes in https://fuchsia.googlesource.com/third_party/grpc/ --- BUILD.gn | 1393 +++++++++++++++++++++ include/grpc/impl/codegen/port_platform.h | 20 + src/core/lib/iomgr/port.h | 16 + templates/BUILD.gn.template | 220 ++++ 4 files changed, 1649 insertions(+) create mode 100644 BUILD.gn create mode 100644 templates/BUILD.gn.template diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 00000000000..eb831f5b7b6 --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,1393 @@ +# GRPC Fuchsia GN build file + +# This file has been automatically generated from a template file. +# Please look at the templates directory instead. +# This file can be regenerated from the template by running +# tools/buildgen/generate_projects.sh + +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +config("grpc_config") { + include_dirs = [ + ".", + "include/", + ] + defines = [ + "GRPC_USE_PROTO_LITE", + "GPR_SUPPORT_CHANNELS_FROM_FD", + "PB_FIELD_16BIT", + ] +} + + + + source_set("health_proto") { + sources = [ + "src/core/ext/filters/client_channel/health/health.pb.c", + "src/core/ext/filters/client_channel/health/health.pb.h", + ] + deps = [ + ":nanopb", + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/nanopb", + ] + } + + + + source_set("nanopb") { + sources = [ + "third_party/nanopb/pb.h", + "third_party/nanopb/pb_common.c", + "third_party/nanopb/pb_common.h", + "third_party/nanopb/pb_decode.c", + "third_party/nanopb/pb_decode.h", + "third_party/nanopb/pb_encode.c", + "third_party/nanopb/pb_encode.h", + ] + deps = [ + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/nanopb", + ] + } + + + + source_set("address_sorting") { + sources = [ + "third_party/address_sorting/address_sorting.c", + "third_party/address_sorting/address_sorting_internal.h", + "third_party/address_sorting/address_sorting_posix.c", + "third_party/address_sorting/address_sorting_windows.c", + "third_party/address_sorting/include/address_sorting/address_sorting.h", + ] + deps = [ + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/address_sorting/include", + ] + } + + + + source_set("gpr") { + sources = [ + "include/grpc/impl/codegen/atm.h", + "include/grpc/impl/codegen/atm_gcc_atomic.h", + "include/grpc/impl/codegen/atm_gcc_sync.h", + "include/grpc/impl/codegen/atm_windows.h", + "include/grpc/impl/codegen/fork.h", + "include/grpc/impl/codegen/gpr_slice.h", + "include/grpc/impl/codegen/gpr_types.h", + "include/grpc/impl/codegen/log.h", + "include/grpc/impl/codegen/port_platform.h", + "include/grpc/impl/codegen/sync.h", + "include/grpc/impl/codegen/sync_custom.h", + "include/grpc/impl/codegen/sync_generic.h", + "include/grpc/impl/codegen/sync_posix.h", + "include/grpc/impl/codegen/sync_windows.h", + "include/grpc/support/alloc.h", + "include/grpc/support/atm.h", + "include/grpc/support/atm_gcc_atomic.h", + "include/grpc/support/atm_gcc_sync.h", + "include/grpc/support/atm_windows.h", + "include/grpc/support/cpu.h", + "include/grpc/support/log.h", + "include/grpc/support/log_windows.h", + "include/grpc/support/port_platform.h", + "include/grpc/support/string_util.h", + "include/grpc/support/sync.h", + "include/grpc/support/sync_custom.h", + "include/grpc/support/sync_generic.h", + "include/grpc/support/sync_posix.h", + "include/grpc/support/sync_windows.h", + "include/grpc/support/thd_id.h", + "include/grpc/support/time.h", + "src/core/lib/gpr/alloc.cc", + "src/core/lib/gpr/alloc.h", + "src/core/lib/gpr/arena.cc", + "src/core/lib/gpr/arena.h", + "src/core/lib/gpr/atm.cc", + "src/core/lib/gpr/cpu_iphone.cc", + "src/core/lib/gpr/cpu_linux.cc", + "src/core/lib/gpr/cpu_posix.cc", + "src/core/lib/gpr/cpu_windows.cc", + "src/core/lib/gpr/env.h", + "src/core/lib/gpr/env_linux.cc", + "src/core/lib/gpr/env_posix.cc", + "src/core/lib/gpr/env_windows.cc", + "src/core/lib/gpr/host_port.cc", + "src/core/lib/gpr/host_port.h", + "src/core/lib/gpr/log.cc", + "src/core/lib/gpr/log_android.cc", + "src/core/lib/gpr/log_linux.cc", + "src/core/lib/gpr/log_posix.cc", + "src/core/lib/gpr/log_windows.cc", + "src/core/lib/gpr/mpscq.cc", + "src/core/lib/gpr/mpscq.h", + "src/core/lib/gpr/murmur_hash.cc", + "src/core/lib/gpr/murmur_hash.h", + "src/core/lib/gpr/spinlock.h", + "src/core/lib/gpr/string.cc", + "src/core/lib/gpr/string.h", + "src/core/lib/gpr/string_posix.cc", + "src/core/lib/gpr/string_util_windows.cc", + "src/core/lib/gpr/string_windows.cc", + "src/core/lib/gpr/string_windows.h", + "src/core/lib/gpr/sync.cc", + "src/core/lib/gpr/sync_posix.cc", + "src/core/lib/gpr/sync_windows.cc", + "src/core/lib/gpr/time.cc", + "src/core/lib/gpr/time_posix.cc", + "src/core/lib/gpr/time_precise.cc", + "src/core/lib/gpr/time_precise.h", + "src/core/lib/gpr/time_windows.cc", + "src/core/lib/gpr/tls.h", + "src/core/lib/gpr/tls_gcc.h", + "src/core/lib/gpr/tls_msvc.h", + "src/core/lib/gpr/tls_pthread.cc", + "src/core/lib/gpr/tls_pthread.h", + "src/core/lib/gpr/tmpfile.h", + "src/core/lib/gpr/tmpfile_msys.cc", + "src/core/lib/gpr/tmpfile_posix.cc", + "src/core/lib/gpr/tmpfile_windows.cc", + "src/core/lib/gpr/useful.h", + "src/core/lib/gpr/wrap_memcpy.cc", + "src/core/lib/gprpp/abstract.h", + "src/core/lib/gprpp/atomic.h", + "src/core/lib/gprpp/fork.cc", + "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/manual_constructor.h", + "src/core/lib/gprpp/memory.h", + "src/core/lib/gprpp/mutex_lock.h", + "src/core/lib/gprpp/thd.h", + "src/core/lib/gprpp/thd_posix.cc", + "src/core/lib/gprpp/thd_windows.cc", + "src/core/lib/profiling/basic_timers.cc", + "src/core/lib/profiling/stap_timers.cc", + "src/core/lib/profiling/timers.h", + ] + deps = [ + ] + + public_configs = [ + ":grpc_config", + ] + } + + + + source_set("grpc") { + sources = [ + "include/grpc/byte_buffer.h", + "include/grpc/byte_buffer_reader.h", + "include/grpc/census.h", + "include/grpc/compression.h", + "include/grpc/fork.h", + "include/grpc/grpc.h", + "include/grpc/grpc_posix.h", + "include/grpc/grpc_security.h", + "include/grpc/grpc_security_constants.h", + "include/grpc/impl/codegen/atm.h", + "include/grpc/impl/codegen/atm_gcc_atomic.h", + "include/grpc/impl/codegen/atm_gcc_sync.h", + "include/grpc/impl/codegen/atm_windows.h", + "include/grpc/impl/codegen/byte_buffer.h", + "include/grpc/impl/codegen/byte_buffer_reader.h", + "include/grpc/impl/codegen/compression_types.h", + "include/grpc/impl/codegen/connectivity_state.h", + "include/grpc/impl/codegen/fork.h", + "include/grpc/impl/codegen/gpr_slice.h", + "include/grpc/impl/codegen/gpr_types.h", + "include/grpc/impl/codegen/grpc_types.h", + "include/grpc/impl/codegen/log.h", + "include/grpc/impl/codegen/port_platform.h", + "include/grpc/impl/codegen/propagation_bits.h", + "include/grpc/impl/codegen/slice.h", + "include/grpc/impl/codegen/status.h", + "include/grpc/impl/codegen/sync.h", + "include/grpc/impl/codegen/sync_custom.h", + "include/grpc/impl/codegen/sync_generic.h", + "include/grpc/impl/codegen/sync_posix.h", + "include/grpc/impl/codegen/sync_windows.h", + "include/grpc/load_reporting.h", + "include/grpc/slice.h", + "include/grpc/slice_buffer.h", + "include/grpc/status.h", + "include/grpc/support/workaround_list.h", + "src/core/ext/filters/census/grpc_context.cc", + "src/core/ext/filters/client_channel/backup_poller.cc", + "src/core/ext/filters/client_channel/backup_poller.h", + "src/core/ext/filters/client_channel/channel_connectivity.cc", + "src/core/ext/filters/client_channel/client_channel.cc", + "src/core/ext/filters/client_channel/client_channel.h", + "src/core/ext/filters/client_channel/client_channel_channelz.cc", + "src/core/ext/filters/client_channel/client_channel_channelz.h", + "src/core/ext/filters/client_channel/client_channel_factory.cc", + "src/core/ext/filters/client_channel/client_channel_factory.h", + "src/core/ext/filters/client_channel/client_channel_plugin.cc", + "src/core/ext/filters/client_channel/connector.cc", + "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/global_subchannel_pool.cc", + "src/core/ext/filters/client_channel/global_subchannel_pool.h", + "src/core/ext/filters/client_channel/health/health_check_client.cc", + "src/core/ext/filters/client_channel/health/health_check_client.h", + "src/core/ext/filters/client_channel/http_connect_handshaker.cc", + "src/core/ext/filters/client_channel/http_connect_handshaker.h", + "src/core/ext/filters/client_channel/http_proxy.cc", + "src/core/ext/filters/client_channel/http_proxy.h", + "src/core/ext/filters/client_channel/lb_policy.cc", + "src/core/ext/filters/client_channel/lb_policy.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", + "src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc", + "src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc", + "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h", + "src/core/ext/filters/client_channel/lb_policy_factory.h", + "src/core/ext/filters/client_channel/lb_policy_registry.cc", + "src/core/ext/filters/client_channel/lb_policy_registry.h", + "src/core/ext/filters/client_channel/local_subchannel_pool.cc", + "src/core/ext/filters/client_channel/local_subchannel_pool.h", + "src/core/ext/filters/client_channel/parse_address.cc", + "src/core/ext/filters/client_channel/parse_address.h", + "src/core/ext/filters/client_channel/proxy_mapper.cc", + "src/core/ext/filters/client_channel/proxy_mapper.h", + "src/core/ext/filters/client_channel/proxy_mapper_registry.cc", + "src/core/ext/filters/client_channel/proxy_mapper_registry.h", + "src/core/ext/filters/client_channel/resolver.cc", + "src/core/ext/filters/client_channel/resolver.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc", + "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc", + "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h", + "src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc", + "src/core/ext/filters/client_channel/resolver_factory.h", + "src/core/ext/filters/client_channel/resolver_registry.cc", + "src/core/ext/filters/client_channel/resolver_registry.h", + "src/core/ext/filters/client_channel/resolver_result_parsing.cc", + "src/core/ext/filters/client_channel/resolver_result_parsing.h", + "src/core/ext/filters/client_channel/resolving_lb_policy.cc", + "src/core/ext/filters/client_channel/resolving_lb_policy.h", + "src/core/ext/filters/client_channel/retry_throttle.cc", + "src/core/ext/filters/client_channel/retry_throttle.h", + "src/core/ext/filters/client_channel/server_address.cc", + "src/core/ext/filters/client_channel/server_address.h", + "src/core/ext/filters/client_channel/subchannel.cc", + "src/core/ext/filters/client_channel/subchannel.h", + "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", + "src/core/ext/filters/client_channel/subchannel_pool_interface.h", + "src/core/ext/filters/deadline/deadline_filter.cc", + "src/core/ext/filters/deadline/deadline_filter.h", + "src/core/ext/filters/http/client/http_client_filter.cc", + "src/core/ext/filters/http/client/http_client_filter.h", + "src/core/ext/filters/http/client_authority_filter.cc", + "src/core/ext/filters/http/client_authority_filter.h", + "src/core/ext/filters/http/http_filters_plugin.cc", + "src/core/ext/filters/http/message_compress/message_compress_filter.cc", + "src/core/ext/filters/http/message_compress/message_compress_filter.h", + "src/core/ext/filters/http/server/http_server_filter.cc", + "src/core/ext/filters/http/server/http_server_filter.h", + "src/core/ext/filters/max_age/max_age_filter.cc", + "src/core/ext/filters/max_age/max_age_filter.h", + "src/core/ext/filters/message_size/message_size_filter.cc", + "src/core/ext/filters/message_size/message_size_filter.h", + "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc", + "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h", + "src/core/ext/filters/workarounds/workaround_utils.cc", + "src/core/ext/filters/workarounds/workaround_utils.h", + "src/core/ext/transport/chttp2/alpn/alpn.cc", + "src/core/ext/transport/chttp2/alpn/alpn.h", + "src/core/ext/transport/chttp2/client/authority.cc", + "src/core/ext/transport/chttp2/client/authority.h", + "src/core/ext/transport/chttp2/client/chttp2_connector.cc", + "src/core/ext/transport/chttp2/client/chttp2_connector.h", + "src/core/ext/transport/chttp2/client/insecure/channel_create.cc", + "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc", + "src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc", + "src/core/ext/transport/chttp2/server/chttp2_server.cc", + "src/core/ext/transport/chttp2/server/chttp2_server.h", + "src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc", + "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc", + "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc", + "src/core/ext/transport/chttp2/transport/bin_decoder.cc", + "src/core/ext/transport/chttp2/transport/bin_decoder.h", + "src/core/ext/transport/chttp2/transport/bin_encoder.cc", + "src/core/ext/transport/chttp2/transport/bin_encoder.h", + "src/core/ext/transport/chttp2/transport/chttp2_plugin.cc", + "src/core/ext/transport/chttp2/transport/chttp2_transport.cc", + "src/core/ext/transport/chttp2/transport/chttp2_transport.h", + "src/core/ext/transport/chttp2/transport/context_list.cc", + "src/core/ext/transport/chttp2/transport/context_list.h", + "src/core/ext/transport/chttp2/transport/flow_control.cc", + "src/core/ext/transport/chttp2/transport/flow_control.h", + "src/core/ext/transport/chttp2/transport/frame.h", + "src/core/ext/transport/chttp2/transport/frame_data.cc", + "src/core/ext/transport/chttp2/transport/frame_data.h", + "src/core/ext/transport/chttp2/transport/frame_goaway.cc", + "src/core/ext/transport/chttp2/transport/frame_goaway.h", + "src/core/ext/transport/chttp2/transport/frame_ping.cc", + "src/core/ext/transport/chttp2/transport/frame_ping.h", + "src/core/ext/transport/chttp2/transport/frame_rst_stream.cc", + "src/core/ext/transport/chttp2/transport/frame_rst_stream.h", + "src/core/ext/transport/chttp2/transport/frame_settings.cc", + "src/core/ext/transport/chttp2/transport/frame_settings.h", + "src/core/ext/transport/chttp2/transport/frame_window_update.cc", + "src/core/ext/transport/chttp2/transport/frame_window_update.h", + "src/core/ext/transport/chttp2/transport/hpack_encoder.cc", + "src/core/ext/transport/chttp2/transport/hpack_encoder.h", + "src/core/ext/transport/chttp2/transport/hpack_parser.cc", + "src/core/ext/transport/chttp2/transport/hpack_parser.h", + "src/core/ext/transport/chttp2/transport/hpack_table.cc", + "src/core/ext/transport/chttp2/transport/hpack_table.h", + "src/core/ext/transport/chttp2/transport/http2_settings.cc", + "src/core/ext/transport/chttp2/transport/http2_settings.h", + "src/core/ext/transport/chttp2/transport/huffsyms.cc", + "src/core/ext/transport/chttp2/transport/huffsyms.h", + "src/core/ext/transport/chttp2/transport/incoming_metadata.cc", + "src/core/ext/transport/chttp2/transport/incoming_metadata.h", + "src/core/ext/transport/chttp2/transport/internal.h", + "src/core/ext/transport/chttp2/transport/parsing.cc", + "src/core/ext/transport/chttp2/transport/stream_lists.cc", + "src/core/ext/transport/chttp2/transport/stream_map.cc", + "src/core/ext/transport/chttp2/transport/stream_map.h", + "src/core/ext/transport/chttp2/transport/varint.cc", + "src/core/ext/transport/chttp2/transport/varint.h", + "src/core/ext/transport/chttp2/transport/writing.cc", + "src/core/ext/transport/inproc/inproc_plugin.cc", + "src/core/ext/transport/inproc/inproc_transport.cc", + "src/core/ext/transport/inproc/inproc_transport.h", + "src/core/lib/avl/avl.cc", + "src/core/lib/avl/avl.h", + "src/core/lib/backoff/backoff.cc", + "src/core/lib/backoff/backoff.h", + "src/core/lib/channel/channel_args.cc", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.cc", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.cc", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/channel_trace.cc", + "src/core/lib/channel/channel_trace.h", + "src/core/lib/channel/channelz.cc", + "src/core/lib/channel/channelz.h", + "src/core/lib/channel/channelz_registry.cc", + "src/core/lib/channel/channelz_registry.h", + "src/core/lib/channel/connected_channel.cc", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.cc", + "src/core/lib/channel/handshaker.h", + "src/core/lib/channel/handshaker_factory.h", + "src/core/lib/channel/handshaker_registry.cc", + "src/core/lib/channel/handshaker_registry.h", + "src/core/lib/channel/status_util.cc", + "src/core/lib/channel/status_util.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/compression.cc", + "src/core/lib/compression/compression_internal.cc", + "src/core/lib/compression/compression_internal.h", + "src/core/lib/compression/message_compress.cc", + "src/core/lib/compression/message_compress.h", + "src/core/lib/compression/stream_compression.cc", + "src/core/lib/compression/stream_compression.h", + "src/core/lib/compression/stream_compression_gzip.cc", + "src/core/lib/compression/stream_compression_gzip.h", + "src/core/lib/compression/stream_compression_identity.cc", + "src/core/lib/compression/stream_compression_identity.h", + "src/core/lib/debug/stats.cc", + "src/core/lib/debug/stats.h", + "src/core/lib/debug/stats_data.cc", + "src/core/lib/debug/stats_data.h", + "src/core/lib/debug/trace.cc", + "src/core/lib/debug/trace.h", + "src/core/lib/gprpp/debug_location.h", + "src/core/lib/gprpp/inlined_vector.h", + "src/core/lib/gprpp/optional.h", + "src/core/lib/gprpp/orphanable.h", + "src/core/lib/gprpp/ref_counted.h", + "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/http/format_request.cc", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.cc", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/httpcli_security_connector.cc", + "src/core/lib/http/parser.cc", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/block_annotate.h", + "src/core/lib/iomgr/buffer_list.cc", + "src/core/lib/iomgr/buffer_list.h", + "src/core/lib/iomgr/call_combiner.cc", + "src/core/lib/iomgr/call_combiner.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/combiner.cc", + "src/core/lib/iomgr/combiner.h", + "src/core/lib/iomgr/dynamic_annotations.h", + "src/core/lib/iomgr/endpoint.cc", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/endpoint_pair_posix.cc", + "src/core/lib/iomgr/endpoint_pair_uv.cc", + "src/core/lib/iomgr/endpoint_pair_windows.cc", + "src/core/lib/iomgr/error.cc", + "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/error_internal.h", + "src/core/lib/iomgr/ev_epoll1_linux.cc", + "src/core/lib/iomgr/ev_epoll1_linux.h", + "src/core/lib/iomgr/ev_epollex_linux.cc", + "src/core/lib/iomgr/ev_epollex_linux.h", + "src/core/lib/iomgr/ev_poll_posix.cc", + "src/core/lib/iomgr/ev_poll_posix.h", + "src/core/lib/iomgr/ev_posix.cc", + "src/core/lib/iomgr/ev_posix.h", + "src/core/lib/iomgr/ev_windows.cc", + "src/core/lib/iomgr/exec_ctx.cc", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.cc", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/fork_posix.cc", + "src/core/lib/iomgr/fork_windows.cc", + "src/core/lib/iomgr/gethostname.h", + "src/core/lib/iomgr/gethostname_fallback.cc", + "src/core/lib/iomgr/gethostname_host_name_max.cc", + "src/core/lib/iomgr/gethostname_sysconf.cc", + "src/core/lib/iomgr/grpc_if_nametoindex.h", + "src/core/lib/iomgr/grpc_if_nametoindex_posix.cc", + "src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc", + "src/core/lib/iomgr/internal_errqueue.cc", + "src/core/lib/iomgr/internal_errqueue.h", + "src/core/lib/iomgr/iocp_windows.cc", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.cc", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_custom.cc", + "src/core/lib/iomgr/iomgr_custom.h", + "src/core/lib/iomgr/iomgr_internal.cc", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.cc", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/iomgr_uv.cc", + "src/core/lib/iomgr/iomgr_windows.cc", + "src/core/lib/iomgr/is_epollexclusive_available.cc", + "src/core/lib/iomgr/is_epollexclusive_available.h", + "src/core/lib/iomgr/load_file.cc", + "src/core/lib/iomgr/load_file.h", + "src/core/lib/iomgr/lockfree_event.cc", + "src/core/lib/iomgr/lockfree_event.h", + "src/core/lib/iomgr/nameser.h", + "src/core/lib/iomgr/polling_entity.cc", + "src/core/lib/iomgr/polling_entity.h", + "src/core/lib/iomgr/pollset.cc", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_custom.cc", + "src/core/lib/iomgr/pollset_custom.h", + "src/core/lib/iomgr/pollset_set.cc", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_custom.cc", + "src/core/lib/iomgr/pollset_set_custom.h", + "src/core/lib/iomgr/pollset_set_windows.cc", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_uv.cc", + "src/core/lib/iomgr/pollset_windows.cc", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/port.h", + "src/core/lib/iomgr/resolve_address.cc", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/resolve_address_custom.cc", + "src/core/lib/iomgr/resolve_address_custom.h", + "src/core/lib/iomgr/resolve_address_posix.cc", + "src/core/lib/iomgr/resolve_address_windows.cc", + "src/core/lib/iomgr/resource_quota.cc", + "src/core/lib/iomgr/resource_quota.h", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_custom.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.cc", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_windows.h", + "src/core/lib/iomgr/socket_factory_posix.cc", + "src/core/lib/iomgr/socket_factory_posix.h", + "src/core/lib/iomgr/socket_mutator.cc", + "src/core/lib/iomgr/socket_mutator.h", + "src/core/lib/iomgr/socket_utils.h", + "src/core/lib/iomgr/socket_utils_common_posix.cc", + "src/core/lib/iomgr/socket_utils_linux.cc", + "src/core/lib/iomgr/socket_utils_posix.cc", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_utils_uv.cc", + "src/core/lib/iomgr/socket_utils_windows.cc", + "src/core/lib/iomgr/socket_windows.cc", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/sys_epoll_wrapper.h", + "src/core/lib/iomgr/tcp_client.cc", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_client_custom.cc", + "src/core/lib/iomgr/tcp_client_posix.cc", + "src/core/lib/iomgr/tcp_client_posix.h", + "src/core/lib/iomgr/tcp_client_windows.cc", + "src/core/lib/iomgr/tcp_custom.cc", + "src/core/lib/iomgr/tcp_custom.h", + "src/core/lib/iomgr/tcp_posix.cc", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.cc", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_server_custom.cc", + "src/core/lib/iomgr/tcp_server_posix.cc", + "src/core/lib/iomgr/tcp_server_utils_posix.h", + "src/core/lib/iomgr/tcp_server_utils_posix_common.cc", + "src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc", + "src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc", + "src/core/lib/iomgr/tcp_server_windows.cc", + "src/core/lib/iomgr/tcp_uv.cc", + "src/core/lib/iomgr/tcp_windows.cc", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.cc", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.cc", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_custom.cc", + "src/core/lib/iomgr/timer_custom.h", + "src/core/lib/iomgr/timer_generic.cc", + "src/core/lib/iomgr/timer_heap.cc", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/timer_manager.cc", + "src/core/lib/iomgr/timer_manager.h", + "src/core/lib/iomgr/timer_uv.cc", + "src/core/lib/iomgr/udp_server.cc", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.cc", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/unix_sockets_posix_noop.cc", + "src/core/lib/iomgr/wakeup_fd_eventfd.cc", + "src/core/lib/iomgr/wakeup_fd_nospecial.cc", + "src/core/lib/iomgr/wakeup_fd_pipe.cc", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.cc", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/json/json.cc", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.cc", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_string.cc", + "src/core/lib/json/json_writer.cc", + "src/core/lib/json/json_writer.h", + "src/core/lib/security/context/security_context.cc", + "src/core/lib/security/context/security_context.h", + "src/core/lib/security/credentials/alts/alts_credentials.cc", + "src/core/lib/security/credentials/alts/alts_credentials.h", + "src/core/lib/security/credentials/alts/check_gcp_environment.cc", + "src/core/lib/security/credentials/alts/check_gcp_environment.h", + "src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc", + "src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc", + "src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc", + "src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc", + "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc", + "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h", + "src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc", + "src/core/lib/security/credentials/composite/composite_credentials.cc", + "src/core/lib/security/credentials/composite/composite_credentials.h", + "src/core/lib/security/credentials/credentials.cc", + "src/core/lib/security/credentials/credentials.h", + "src/core/lib/security/credentials/credentials_metadata.cc", + "src/core/lib/security/credentials/fake/fake_credentials.cc", + "src/core/lib/security/credentials/fake/fake_credentials.h", + "src/core/lib/security/credentials/google_default/credentials_generic.cc", + "src/core/lib/security/credentials/google_default/google_default_credentials.cc", + "src/core/lib/security/credentials/google_default/google_default_credentials.h", + "src/core/lib/security/credentials/iam/iam_credentials.cc", + "src/core/lib/security/credentials/iam/iam_credentials.h", + "src/core/lib/security/credentials/jwt/json_token.cc", + "src/core/lib/security/credentials/jwt/json_token.h", + "src/core/lib/security/credentials/jwt/jwt_credentials.cc", + "src/core/lib/security/credentials/jwt/jwt_credentials.h", + "src/core/lib/security/credentials/jwt/jwt_verifier.cc", + "src/core/lib/security/credentials/jwt/jwt_verifier.h", + "src/core/lib/security/credentials/local/local_credentials.cc", + "src/core/lib/security/credentials/local/local_credentials.h", + "src/core/lib/security/credentials/oauth2/oauth2_credentials.cc", + "src/core/lib/security/credentials/oauth2/oauth2_credentials.h", + "src/core/lib/security/credentials/plugin/plugin_credentials.cc", + "src/core/lib/security/credentials/plugin/plugin_credentials.h", + "src/core/lib/security/credentials/ssl/ssl_credentials.cc", + "src/core/lib/security/credentials/ssl/ssl_credentials.h", + "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc", + "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h", + "src/core/lib/security/credentials/tls/spiffe_credentials.cc", + "src/core/lib/security/credentials/tls/spiffe_credentials.h", + "src/core/lib/security/security_connector/alts/alts_security_connector.cc", + "src/core/lib/security/security_connector/alts/alts_security_connector.h", + "src/core/lib/security/security_connector/fake/fake_security_connector.cc", + "src/core/lib/security/security_connector/fake/fake_security_connector.h", + "src/core/lib/security/security_connector/load_system_roots.h", + "src/core/lib/security/security_connector/load_system_roots_fallback.cc", + "src/core/lib/security/security_connector/load_system_roots_linux.cc", + "src/core/lib/security/security_connector/load_system_roots_linux.h", + "src/core/lib/security/security_connector/local/local_security_connector.cc", + "src/core/lib/security/security_connector/local/local_security_connector.h", + "src/core/lib/security/security_connector/security_connector.cc", + "src/core/lib/security/security_connector/security_connector.h", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.cc", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", + "src/core/lib/security/security_connector/ssl_utils.cc", + "src/core/lib/security/security_connector/ssl_utils.h", + "src/core/lib/security/security_connector/tls/spiffe_security_connector.cc", + "src/core/lib/security/security_connector/tls/spiffe_security_connector.h", + "src/core/lib/security/transport/auth_filters.h", + "src/core/lib/security/transport/client_auth_filter.cc", + "src/core/lib/security/transport/secure_endpoint.cc", + "src/core/lib/security/transport/secure_endpoint.h", + "src/core/lib/security/transport/security_handshaker.cc", + "src/core/lib/security/transport/security_handshaker.h", + "src/core/lib/security/transport/server_auth_filter.cc", + "src/core/lib/security/transport/target_authority_table.cc", + "src/core/lib/security/transport/target_authority_table.h", + "src/core/lib/security/transport/tsi_error.cc", + "src/core/lib/security/transport/tsi_error.h", + "src/core/lib/security/util/json_util.cc", + "src/core/lib/security/util/json_util.h", + "src/core/lib/slice/b64.cc", + "src/core/lib/slice/b64.h", + "src/core/lib/slice/percent_encoding.cc", + "src/core/lib/slice/percent_encoding.h", + "src/core/lib/slice/slice.cc", + "src/core/lib/slice/slice_buffer.cc", + "src/core/lib/slice/slice_hash_table.h", + "src/core/lib/slice/slice_intern.cc", + "src/core/lib/slice/slice_internal.h", + "src/core/lib/slice/slice_string_helpers.cc", + "src/core/lib/slice/slice_string_helpers.h", + "src/core/lib/slice/slice_weak_hash_table.h", + "src/core/lib/surface/api_trace.cc", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/byte_buffer.cc", + "src/core/lib/surface/byte_buffer_reader.cc", + "src/core/lib/surface/call.cc", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_details.cc", + "src/core/lib/surface/call_log_batch.cc", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.cc", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.cc", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_ping.cc", + "src/core/lib/surface/channel_stack_type.cc", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.cc", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/completion_queue_factory.cc", + "src/core/lib/surface/completion_queue_factory.h", + "src/core/lib/surface/event_string.cc", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.cc", + "src/core/lib/surface/init.h", + "src/core/lib/surface/init_secure.cc", + "src/core/lib/surface/lame_client.cc", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/metadata_array.cc", + "src/core/lib/surface/server.cc", + "src/core/lib/surface/server.h", + "src/core/lib/surface/validate_metadata.cc", + "src/core/lib/surface/validate_metadata.h", + "src/core/lib/surface/version.cc", + "src/core/lib/transport/bdp_estimator.cc", + "src/core/lib/transport/bdp_estimator.h", + "src/core/lib/transport/byte_stream.cc", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/connectivity_state.cc", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/error_utils.cc", + "src/core/lib/transport/error_utils.h", + "src/core/lib/transport/http2_errors.h", + "src/core/lib/transport/metadata.cc", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.cc", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/pid_controller.cc", + "src/core/lib/transport/pid_controller.h", + "src/core/lib/transport/service_config.cc", + "src/core/lib/transport/service_config.h", + "src/core/lib/transport/static_metadata.cc", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/status_conversion.cc", + "src/core/lib/transport/status_conversion.h", + "src/core/lib/transport/status_metadata.cc", + "src/core/lib/transport/status_metadata.h", + "src/core/lib/transport/timeout_encoding.cc", + "src/core/lib/transport/timeout_encoding.h", + "src/core/lib/transport/transport.cc", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", + "src/core/lib/transport/transport_op_string.cc", + "src/core/lib/uri/uri_parser.cc", + "src/core/lib/uri/uri_parser.h", + "src/core/plugin_registry/grpc_plugin_registry.cc", + "src/core/tsi/alts/crypt/aes_gcm.cc", + "src/core/tsi/alts/crypt/gsec.cc", + "src/core/tsi/alts/crypt/gsec.h", + "src/core/tsi/alts/frame_protector/alts_counter.cc", + "src/core/tsi/alts/frame_protector/alts_counter.h", + "src/core/tsi/alts/frame_protector/alts_crypter.cc", + "src/core/tsi/alts/frame_protector/alts_crypter.h", + "src/core/tsi/alts/frame_protector/alts_frame_protector.cc", + "src/core/tsi/alts/frame_protector/alts_frame_protector.h", + "src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc", + "src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h", + "src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc", + "src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc", + "src/core/tsi/alts/frame_protector/frame_handler.cc", + "src/core/tsi/alts/frame_protector/frame_handler.h", + "src/core/tsi/alts/handshaker/alts_handshaker_client.cc", + "src/core/tsi/alts/handshaker/alts_handshaker_client.h", + "src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc", + "src/core/tsi/alts/handshaker/alts_handshaker_service_api.h", + "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc", + "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h", + "src/core/tsi/alts/handshaker/alts_shared_resource.cc", + "src/core/tsi/alts/handshaker/alts_shared_resource.h", + "src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc", + "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h", + "src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h", + "src/core/tsi/alts/handshaker/alts_tsi_utils.cc", + "src/core/tsi/alts/handshaker/alts_tsi_utils.h", + "src/core/tsi/alts/handshaker/altscontext.pb.c", + "src/core/tsi/alts/handshaker/altscontext.pb.h", + "src/core/tsi/alts/handshaker/handshaker.pb.c", + "src/core/tsi/alts/handshaker/handshaker.pb.h", + "src/core/tsi/alts/handshaker/transport_security_common.pb.c", + "src/core/tsi/alts/handshaker/transport_security_common.pb.h", + "src/core/tsi/alts/handshaker/transport_security_common_api.cc", + "src/core/tsi/alts/handshaker/transport_security_common_api.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc", + "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc", + "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h", + "src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc", + "src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h", + "src/core/tsi/fake_transport_security.cc", + "src/core/tsi/fake_transport_security.h", + "src/core/tsi/grpc_shadow_boringssl.h", + "src/core/tsi/local_transport_security.cc", + "src/core/tsi/local_transport_security.h", + "src/core/tsi/ssl/session_cache/ssl_session.h", + "src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc", + "src/core/tsi/ssl/session_cache/ssl_session_cache.cc", + "src/core/tsi/ssl/session_cache/ssl_session_cache.h", + "src/core/tsi/ssl/session_cache/ssl_session_openssl.cc", + "src/core/tsi/ssl_transport_security.cc", + "src/core/tsi/ssl_transport_security.h", + "src/core/tsi/ssl_types.h", + "src/core/tsi/transport_security.cc", + "src/core/tsi/transport_security.h", + "src/core/tsi/transport_security_grpc.cc", + "src/core/tsi/transport_security_grpc.h", + "src/core/tsi/transport_security_interface.h", + ] + deps = [ + "//third_party/boringssl", + "//third_party/zlib", + ":gpr", + "//third_party/cares", + ":address_sorting", + ":nanopb", + ":health_proto", + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/cares", + "third_party/address_sorting/include", + "third_party/nanopb", + ] + } + + + + source_set("grpc++") { + sources = [ + "include/grpc++/alarm.h", + "include/grpc++/channel.h", + "include/grpc++/client_context.h", + "include/grpc++/completion_queue.h", + "include/grpc++/create_channel.h", + "include/grpc++/create_channel_posix.h", + "include/grpc++/ext/health_check_service_server_builder_option.h", + "include/grpc++/generic/async_generic_service.h", + "include/grpc++/generic/generic_stub.h", + "include/grpc++/grpc++.h", + "include/grpc++/health_check_service_interface.h", + "include/grpc++/impl/call.h", + "include/grpc++/impl/channel_argument_option.h", + "include/grpc++/impl/client_unary_call.h", + "include/grpc++/impl/codegen/async_stream.h", + "include/grpc++/impl/codegen/async_unary_call.h", + "include/grpc++/impl/codegen/byte_buffer.h", + "include/grpc++/impl/codegen/call.h", + "include/grpc++/impl/codegen/call_hook.h", + "include/grpc++/impl/codegen/channel_interface.h", + "include/grpc++/impl/codegen/client_context.h", + "include/grpc++/impl/codegen/client_unary_call.h", + "include/grpc++/impl/codegen/completion_queue.h", + "include/grpc++/impl/codegen/completion_queue_tag.h", + "include/grpc++/impl/codegen/config.h", + "include/grpc++/impl/codegen/config_protobuf.h", + "include/grpc++/impl/codegen/core_codegen.h", + "include/grpc++/impl/codegen/core_codegen.h", + "include/grpc++/impl/codegen/core_codegen_interface.h", + "include/grpc++/impl/codegen/create_auth_context.h", + "include/grpc++/impl/codegen/grpc_library.h", + "include/grpc++/impl/codegen/metadata_map.h", + "include/grpc++/impl/codegen/method_handler_impl.h", + "include/grpc++/impl/codegen/proto_utils.h", + "include/grpc++/impl/codegen/rpc_method.h", + "include/grpc++/impl/codegen/rpc_service_method.h", + "include/grpc++/impl/codegen/security/auth_context.h", + "include/grpc++/impl/codegen/serialization_traits.h", + "include/grpc++/impl/codegen/server_context.h", + "include/grpc++/impl/codegen/server_interface.h", + "include/grpc++/impl/codegen/service_type.h", + "include/grpc++/impl/codegen/slice.h", + "include/grpc++/impl/codegen/status.h", + "include/grpc++/impl/codegen/status_code_enum.h", + "include/grpc++/impl/codegen/string_ref.h", + "include/grpc++/impl/codegen/stub_options.h", + "include/grpc++/impl/codegen/sync_stream.h", + "include/grpc++/impl/codegen/time.h", + "include/grpc++/impl/grpc_library.h", + "include/grpc++/impl/method_handler_impl.h", + "include/grpc++/impl/rpc_method.h", + "include/grpc++/impl/rpc_service_method.h", + "include/grpc++/impl/serialization_traits.h", + "include/grpc++/impl/server_builder_option.h", + "include/grpc++/impl/server_builder_plugin.h", + "include/grpc++/impl/server_initializer.h", + "include/grpc++/impl/service_type.h", + "include/grpc++/resource_quota.h", + "include/grpc++/security/auth_context.h", + "include/grpc++/security/auth_metadata_processor.h", + "include/grpc++/security/credentials.h", + "include/grpc++/security/server_credentials.h", + "include/grpc++/server.h", + "include/grpc++/server_builder.h", + "include/grpc++/server_context.h", + "include/grpc++/server_posix.h", + "include/grpc++/support/async_stream.h", + "include/grpc++/support/async_unary_call.h", + "include/grpc++/support/byte_buffer.h", + "include/grpc++/support/channel_arguments.h", + "include/grpc++/support/config.h", + "include/grpc++/support/slice.h", + "include/grpc++/support/status.h", + "include/grpc++/support/status_code_enum.h", + "include/grpc++/support/string_ref.h", + "include/grpc++/support/stub_options.h", + "include/grpc++/support/sync_stream.h", + "include/grpc++/support/time.h", + "include/grpc/byte_buffer.h", + "include/grpc/byte_buffer_reader.h", + "include/grpc/compression.h", + "include/grpc/fork.h", + "include/grpc/grpc.h", + "include/grpc/grpc_posix.h", + "include/grpc/grpc_security_constants.h", + "include/grpc/impl/codegen/atm.h", + "include/grpc/impl/codegen/atm_gcc_atomic.h", + "include/grpc/impl/codegen/atm_gcc_sync.h", + "include/grpc/impl/codegen/atm_windows.h", + "include/grpc/impl/codegen/byte_buffer.h", + "include/grpc/impl/codegen/byte_buffer_reader.h", + "include/grpc/impl/codegen/compression_types.h", + "include/grpc/impl/codegen/connectivity_state.h", + "include/grpc/impl/codegen/fork.h", + "include/grpc/impl/codegen/gpr_slice.h", + "include/grpc/impl/codegen/gpr_types.h", + "include/grpc/impl/codegen/grpc_types.h", + "include/grpc/impl/codegen/log.h", + "include/grpc/impl/codegen/port_platform.h", + "include/grpc/impl/codegen/propagation_bits.h", + "include/grpc/impl/codegen/slice.h", + "include/grpc/impl/codegen/status.h", + "include/grpc/impl/codegen/sync.h", + "include/grpc/impl/codegen/sync_custom.h", + "include/grpc/impl/codegen/sync_generic.h", + "include/grpc/impl/codegen/sync_posix.h", + "include/grpc/impl/codegen/sync_windows.h", + "include/grpc/load_reporting.h", + "include/grpc/slice.h", + "include/grpc/slice_buffer.h", + "include/grpc/status.h", + "include/grpc/support/alloc.h", + "include/grpc/support/atm.h", + "include/grpc/support/atm_gcc_atomic.h", + "include/grpc/support/atm_gcc_sync.h", + "include/grpc/support/atm_windows.h", + "include/grpc/support/cpu.h", + "include/grpc/support/log.h", + "include/grpc/support/log_windows.h", + "include/grpc/support/port_platform.h", + "include/grpc/support/string_util.h", + "include/grpc/support/sync.h", + "include/grpc/support/sync_custom.h", + "include/grpc/support/sync_generic.h", + "include/grpc/support/sync_posix.h", + "include/grpc/support/sync_windows.h", + "include/grpc/support/thd_id.h", + "include/grpc/support/time.h", + "include/grpc/support/workaround_list.h", + "include/grpcpp/alarm.h", + "include/grpcpp/alarm_impl.h", + "include/grpcpp/channel.h", + "include/grpcpp/client_context.h", + "include/grpcpp/completion_queue.h", + "include/grpcpp/create_channel.h", + "include/grpcpp/create_channel_posix.h", + "include/grpcpp/ext/health_check_service_server_builder_option.h", + "include/grpcpp/generic/async_generic_service.h", + "include/grpcpp/generic/generic_stub.h", + "include/grpcpp/grpcpp.h", + "include/grpcpp/health_check_service_interface.h", + "include/grpcpp/impl/call.h", + "include/grpcpp/impl/channel_argument_option.h", + "include/grpcpp/impl/client_unary_call.h", + "include/grpcpp/impl/codegen/async_generic_service.h", + "include/grpcpp/impl/codegen/async_stream.h", + "include/grpcpp/impl/codegen/async_unary_call.h", + "include/grpcpp/impl/codegen/byte_buffer.h", + "include/grpcpp/impl/codegen/call.h", + "include/grpcpp/impl/codegen/call_hook.h", + "include/grpcpp/impl/codegen/call_op_set.h", + "include/grpcpp/impl/codegen/call_op_set_interface.h", + "include/grpcpp/impl/codegen/callback_common.h", + "include/grpcpp/impl/codegen/channel_interface.h", + "include/grpcpp/impl/codegen/client_callback.h", + "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_interceptor.h", + "include/grpcpp/impl/codegen/client_unary_call.h", + "include/grpcpp/impl/codegen/completion_queue.h", + "include/grpcpp/impl/codegen/completion_queue_tag.h", + "include/grpcpp/impl/codegen/config.h", + "include/grpcpp/impl/codegen/config_protobuf.h", + "include/grpcpp/impl/codegen/core_codegen.h", + "include/grpcpp/impl/codegen/core_codegen.h", + "include/grpcpp/impl/codegen/core_codegen_interface.h", + "include/grpcpp/impl/codegen/create_auth_context.h", + "include/grpcpp/impl/codegen/grpc_library.h", + "include/grpcpp/impl/codegen/intercepted_channel.h", + "include/grpcpp/impl/codegen/interceptor.h", + "include/grpcpp/impl/codegen/interceptor_common.h", + "include/grpcpp/impl/codegen/metadata_map.h", + "include/grpcpp/impl/codegen/method_handler_impl.h", + "include/grpcpp/impl/codegen/proto_buffer_reader.h", + "include/grpcpp/impl/codegen/proto_buffer_writer.h", + "include/grpcpp/impl/codegen/proto_utils.h", + "include/grpcpp/impl/codegen/rpc_method.h", + "include/grpcpp/impl/codegen/rpc_service_method.h", + "include/grpcpp/impl/codegen/security/auth_context.h", + "include/grpcpp/impl/codegen/serialization_traits.h", + "include/grpcpp/impl/codegen/server_callback.h", + "include/grpcpp/impl/codegen/server_context.h", + "include/grpcpp/impl/codegen/server_interceptor.h", + "include/grpcpp/impl/codegen/server_interface.h", + "include/grpcpp/impl/codegen/service_type.h", + "include/grpcpp/impl/codegen/slice.h", + "include/grpcpp/impl/codegen/status.h", + "include/grpcpp/impl/codegen/status_code_enum.h", + "include/grpcpp/impl/codegen/string_ref.h", + "include/grpcpp/impl/codegen/stub_options.h", + "include/grpcpp/impl/codegen/sync_stream.h", + "include/grpcpp/impl/codegen/time.h", + "include/grpcpp/impl/grpc_library.h", + "include/grpcpp/impl/method_handler_impl.h", + "include/grpcpp/impl/rpc_method.h", + "include/grpcpp/impl/rpc_service_method.h", + "include/grpcpp/impl/serialization_traits.h", + "include/grpcpp/impl/server_builder_option.h", + "include/grpcpp/impl/server_builder_plugin.h", + "include/grpcpp/impl/server_initializer.h", + "include/grpcpp/impl/service_type.h", + "include/grpcpp/resource_quota.h", + "include/grpcpp/security/auth_context.h", + "include/grpcpp/security/auth_metadata_processor.h", + "include/grpcpp/security/credentials.h", + "include/grpcpp/security/server_credentials.h", + "include/grpcpp/server.h", + "include/grpcpp/server_builder.h", + "include/grpcpp/server_context.h", + "include/grpcpp/server_posix.h", + "include/grpcpp/support/async_stream.h", + "include/grpcpp/support/async_unary_call.h", + "include/grpcpp/support/byte_buffer.h", + "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/client_callback.h", + "include/grpcpp/support/client_interceptor.h", + "include/grpcpp/support/config.h", + "include/grpcpp/support/interceptor.h", + "include/grpcpp/support/proto_buffer_reader.h", + "include/grpcpp/support/proto_buffer_writer.h", + "include/grpcpp/support/server_callback.h", + "include/grpcpp/support/server_interceptor.h", + "include/grpcpp/support/slice.h", + "include/grpcpp/support/status.h", + "include/grpcpp/support/status_code_enum.h", + "include/grpcpp/support/string_ref.h", + "include/grpcpp/support/stub_options.h", + "include/grpcpp/support/sync_stream.h", + "include/grpcpp/support/time.h", + "src/core/ext/transport/inproc/inproc_transport.h", + "src/core/lib/avl/avl.h", + "src/core/lib/backoff/backoff.h", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/channel_trace.h", + "src/core/lib/channel/channelz.h", + "src/core/lib/channel/channelz_registry.h", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", + "src/core/lib/channel/handshaker_factory.h", + "src/core/lib/channel/handshaker_registry.h", + "src/core/lib/channel/status_util.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/compression_internal.h", + "src/core/lib/compression/message_compress.h", + "src/core/lib/compression/stream_compression.h", + "src/core/lib/compression/stream_compression_gzip.h", + "src/core/lib/compression/stream_compression_identity.h", + "src/core/lib/debug/stats.h", + "src/core/lib/debug/stats_data.h", + "src/core/lib/debug/trace.h", + "src/core/lib/gpr/alloc.h", + "src/core/lib/gpr/arena.h", + "src/core/lib/gpr/env.h", + "src/core/lib/gpr/host_port.h", + "src/core/lib/gpr/mpscq.h", + "src/core/lib/gpr/murmur_hash.h", + "src/core/lib/gpr/spinlock.h", + "src/core/lib/gpr/string.h", + "src/core/lib/gpr/string_windows.h", + "src/core/lib/gpr/time_precise.h", + "src/core/lib/gpr/tls.h", + "src/core/lib/gpr/tls_gcc.h", + "src/core/lib/gpr/tls_msvc.h", + "src/core/lib/gpr/tls_pthread.h", + "src/core/lib/gpr/tmpfile.h", + "src/core/lib/gpr/useful.h", + "src/core/lib/gprpp/abstract.h", + "src/core/lib/gprpp/atomic.h", + "src/core/lib/gprpp/debug_location.h", + "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/inlined_vector.h", + "src/core/lib/gprpp/manual_constructor.h", + "src/core/lib/gprpp/memory.h", + "src/core/lib/gprpp/mutex_lock.h", + "src/core/lib/gprpp/optional.h", + "src/core/lib/gprpp/orphanable.h", + "src/core/lib/gprpp/ref_counted.h", + "src/core/lib/gprpp/ref_counted_ptr.h", + "src/core/lib/gprpp/thd.h", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/block_annotate.h", + "src/core/lib/iomgr/buffer_list.h", + "src/core/lib/iomgr/call_combiner.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/combiner.h", + "src/core/lib/iomgr/dynamic_annotations.h", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/error_internal.h", + "src/core/lib/iomgr/ev_epoll1_linux.h", + "src/core/lib/iomgr/ev_epollex_linux.h", + "src/core/lib/iomgr/ev_poll_posix.h", + "src/core/lib/iomgr/ev_posix.h", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/gethostname.h", + "src/core/lib/iomgr/grpc_if_nametoindex.h", + "src/core/lib/iomgr/internal_errqueue.h", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_custom.h", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/is_epollexclusive_available.h", + "src/core/lib/iomgr/load_file.h", + "src/core/lib/iomgr/lockfree_event.h", + "src/core/lib/iomgr/nameser.h", + "src/core/lib/iomgr/polling_entity.h", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_custom.h", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_custom.h", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/port.h", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/resolve_address_custom.h", + "src/core/lib/iomgr/resource_quota.h", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_custom.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_windows.h", + "src/core/lib/iomgr/socket_factory_posix.h", + "src/core/lib/iomgr/socket_mutator.h", + "src/core/lib/iomgr/socket_utils.h", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/sys_epoll_wrapper.h", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_client_posix.h", + "src/core/lib/iomgr/tcp_custom.h", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_server_utils_posix.h", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_custom.h", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/timer_manager.h", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_writer.h", + "src/core/lib/profiling/timers.h", + "src/core/lib/slice/b64.h", + "src/core/lib/slice/percent_encoding.h", + "src/core/lib/slice/slice_hash_table.h", + "src/core/lib/slice/slice_internal.h", + "src/core/lib/slice/slice_string_helpers.h", + "src/core/lib/slice/slice_weak_hash_table.h", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/completion_queue_factory.h", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.h", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/server.h", + "src/core/lib/surface/validate_metadata.h", + "src/core/lib/transport/bdp_estimator.h", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/error_utils.h", + "src/core/lib/transport/http2_errors.h", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/pid_controller.h", + "src/core/lib/transport/service_config.h", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/status_conversion.h", + "src/core/lib/transport/status_metadata.h", + "src/core/lib/transport/timeout_encoding.h", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", + "src/core/lib/uri/uri_parser.h", + "src/cpp/client/channel_cc.cc", + "src/cpp/client/client_context.cc", + "src/cpp/client/client_interceptor.cc", + "src/cpp/client/create_channel.cc", + "src/cpp/client/create_channel_internal.cc", + "src/cpp/client/create_channel_internal.h", + "src/cpp/client/create_channel_posix.cc", + "src/cpp/client/credentials_cc.cc", + "src/cpp/client/generic_stub.cc", + "src/cpp/client/insecure_credentials.cc", + "src/cpp/client/secure_credentials.cc", + "src/cpp/client/secure_credentials.h", + "src/cpp/codegen/codegen_init.cc", + "src/cpp/common/alarm.cc", + "src/cpp/common/auth_property_iterator.cc", + "src/cpp/common/channel_arguments.cc", + "src/cpp/common/channel_filter.cc", + "src/cpp/common/channel_filter.h", + "src/cpp/common/completion_queue_cc.cc", + "src/cpp/common/core_codegen.cc", + "src/cpp/common/resource_quota_cc.cc", + "src/cpp/common/rpc_method.cc", + "src/cpp/common/secure_auth_context.cc", + "src/cpp/common/secure_auth_context.h", + "src/cpp/common/secure_channel_arguments.cc", + "src/cpp/common/secure_create_auth_context.cc", + "src/cpp/common/version_cc.cc", + "src/cpp/server/async_generic_service.cc", + "src/cpp/server/channel_argument_option.cc", + "src/cpp/server/create_default_thread_pool.cc", + "src/cpp/server/dynamic_thread_pool.cc", + "src/cpp/server/dynamic_thread_pool.h", + "src/cpp/server/health/default_health_check_service.cc", + "src/cpp/server/health/default_health_check_service.h", + "src/cpp/server/health/health_check_service.cc", + "src/cpp/server/health/health_check_service_server_builder_option.cc", + "src/cpp/server/insecure_server_credentials.cc", + "src/cpp/server/secure_server_credentials.cc", + "src/cpp/server/secure_server_credentials.h", + "src/cpp/server/server_builder.cc", + "src/cpp/server/server_cc.cc", + "src/cpp/server/server_context.cc", + "src/cpp/server/server_credentials.cc", + "src/cpp/server/server_posix.cc", + "src/cpp/server/thread_pool_interface.h", + "src/cpp/thread_manager/thread_manager.cc", + "src/cpp/thread_manager/thread_manager.h", + "src/cpp/util/byte_buffer_cc.cc", + "src/cpp/util/status.cc", + "src/cpp/util/string_ref.cc", + "src/cpp/util/time_cc.cc", + ] + deps = [ + "//third_party/boringssl", + "//third_party/protobuf:protobuf_lite", + ":grpc", + ":gpr", + ":nanopb", + ":health_proto", + ] + + public_configs = [ + ":grpc_config", + ] + include_dirs = [ + "third_party/nanopb", + ] + } + + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) { + + + source_set("grpc_plugin_support") { + sources = [ + "include/grpc++/impl/codegen/config_protobuf.h", + "include/grpcpp/impl/codegen/config_protobuf.h", + "src/compiler/config.h", + "src/compiler/cpp_generator.cc", + "src/compiler/cpp_generator.h", + "src/compiler/cpp_generator_helpers.h", + "src/compiler/csharp_generator.cc", + "src/compiler/csharp_generator.h", + "src/compiler/csharp_generator_helpers.h", + "src/compiler/generator_helpers.h", + "src/compiler/node_generator.cc", + "src/compiler/node_generator.h", + "src/compiler/node_generator_helpers.h", + "src/compiler/objective_c_generator.cc", + "src/compiler/objective_c_generator.h", + "src/compiler/objective_c_generator_helpers.h", + "src/compiler/php_generator.cc", + "src/compiler/php_generator.h", + "src/compiler/php_generator_helpers.h", + "src/compiler/protobuf_plugin.h", + "src/compiler/python_generator.cc", + "src/compiler/python_generator.h", + "src/compiler/python_generator_helpers.h", + "src/compiler/python_private_generator.h", + "src/compiler/schema_interface.h", + ] + deps = [ + "//third_party/protobuf:protoc_lib", + ] + + public_configs = [ + ":grpc_config", + ] + } + + } + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) { + + executable("grpc_cpp_plugin") { + sources = [ + "src/compiler/cpp_plugin.cc", + ] + deps = [ + "//third_party/protobuf:protoc_lib", + ":grpc_plugin_support", + ] + + configs += [ + "//third_party/protobuf:protobuf_config", + ] + public_configs = [ ":grpc_config" ] + } + + } + + diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index a6bbe66e248..b62bfcbb61a 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -359,6 +359,26 @@ #else /* _LP64 */ #define GPR_ARCH_32 1 #endif /* _LP64 */ +#elif defined(__Fuchsia__) +#define GPR_FUCHSIA 1 +#define GPR_ARCH_64 1 +#define GPR_PLATFORM_STRING "fuchsia" +#include +// Specifying musl libc affects wrap_memcpy.c. It causes memmove() to be +// invoked. +#define GPR_MUSL_LIBC_COMPAT 1 +#define GPR_CPU_POSIX 1 +#define GPR_GCC_ATOMIC 1 +#define GPR_PTHREAD_TLS 1 +#define GPR_POSIX_LOG 1 +#define GPR_POSIX_SYNC 1 +#define GPR_POSIX_ENV 1 +#define GPR_POSIX_TMPFILE 1 +#define GPR_POSIX_SUBPROCESS 1 +#define GPR_POSIX_SYNC 1 +#define GPR_POSIX_STRING 1 +#define GPR_POSIX_TIME 1 +#define GPR_GETPID_IN_UNISTD_H 1 #else #error "Could not auto-detect platform" #endif diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 3248343e27c..ccb4c31e8c9 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -170,6 +170,22 @@ #define GRPC_POSIX_SOCKET 1 #define GRPC_POSIX_SOCKETUTILS 1 #define GRPC_POSIX_WAKEUP_FD 1 +#elif defined(GPR_FUCHSIA) +#define GRPC_HAVE_IFADDRS 1 +#define GRPC_HAVE_IPV6_RECVPKTINFO 1 +#define GRPC_HAVE_IP_PKTINFO 1 +// Zircon does not support the MSG_NOSIGNAL flag since it doesn't support +// signals. +#undef GRPC_HAVE_MSG_NOSIGNAL +#define GRPC_HAVE_UNIX_SOCKET 1 +#define GRPC_POSIX_WAKEUP_FD 1 +// TODO(rudominer) Check that this does something we want. +#define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1 +#define GRPC_POSIX_SOCKET 1 +#define GRPC_POSIX_SOCKETADDR 1 +// TODO(rudominer) Check this does something we want. +#define GRPC_POSIX_SOCKETUTILS 1 +#define GRPC_TIMER_USE_GENERIC 1 #elif !defined(GPR_NO_AUTODETECT_PLATFORM) #error "Platform not recognized" #endif diff --git a/templates/BUILD.gn.template b/templates/BUILD.gn.template new file mode 100644 index 00000000000..ab78308d135 --- /dev/null +++ b/templates/BUILD.gn.template @@ -0,0 +1,220 @@ +%YAML 1.2 +--- | + # GRPC Fuchsia GN build file + + # This file has been automatically generated from a template file. + # Please look at the templates directory instead. + # This file can be regenerated from the template by running + # tools/buildgen/generate_projects.sh + + # Copyright 2019 gRPC authors. + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + config("grpc_config") { + include_dirs = [ + ".", + "include/", + ] + defines = [ + "GRPC_USE_PROTO_LITE", + "GPR_SUPPORT_CHANNELS_FROM_FD", + "PB_FIELD_16BIT", + ] + } + <%! + def get_deps(target_dict): + deps = [] + if target_dict.get("secure", False): + deps = ["//third_party/boringssl"] + if target_dict.get("build", None) == "protoc": + deps.append("//third_party/protobuf:protoc_lib") + name = target_dict.get("name", None) + if name in ("grpc++", "grpc++_codegen_lib"): + deps.append("//third_party/protobuf:protobuf_lite") + elif name in ("grpc", "grpc_unsecure"): + deps.append("//third_party/zlib") + for d in target_dict.get("deps", []): + if d.startswith(("//", ":")): + deps.append(d) + else: + deps.append(":%s" % d) + if needs_ares(target_dict.src): + deps.append("//third_party/cares") + deps.append(":address_sorting") + if needs_nanopb(target_dict.src) and target_dict.name != "nanopb": + deps.append(":nanopb") + if needs_health_proto(target_dict.src) and target_dict.name != "health_proto": + deps.append(":health_proto") + return deps + + %><%! + def needs_ares(srcs): + return any("/c_ares/" in f for f in srcs) if srcs else False + + %><%! + def needs_nanopb(srcs): + return any(f.startswith("third_party/nanopb") + or f.endswith(".pb.h") + or f.endswith(".pb.c") + or f.endswith(".pb.cc") + or f.endswith("load_balancer_api.h") + or f.endswith("load_balancer_api.c") + for f in srcs) + + %><%! + def needs_address_sorting(sources): + return needs_ares(sources) or any("address_sorting" in s for s in sources) + + %><%! + def needs_health_proto(srcs): + return any("health.pb" in f for f in srcs) + + %><%! + def get_include_dirs(sources): + dirs = [] + if needs_ares(sources): + dirs = ["third_party/cares"] + if needs_address_sorting(sources): + dirs.append("third_party/address_sorting/include") + if needs_nanopb(sources): + dirs.append("third_party/nanopb") + return dirs + + %><%! + def strip_sources(sources, name): + return [f for f in sources + if "ruby_generator" not in f + and ("third_party/nanopb" not in f or name == "nanopb") + and ("health.pb" not in f or name == "health_proto")] + + %><%! + def get_sources(target): + return ((target.public_headers or []) + + (target.headers or []) + + (target.src or [])) + + %><%! + def get_extra_configs(target_dict): + if target_dict.get("name", "") == "grpc_cpp_plugin": + return ["//third_party/protobuf:protobuf_config"] + return [] + + %><%! + def wanted_lib(lib): + wanted_libs = ("gpr", "grpc", "grpc++", "grpc_plugin_support", "address_sorting") + return lib.build in ("all", "protoc") and lib.get("name", "") in wanted_libs + + %><%! + def wanted_binary(tgt): + wanted_binaries = ("grpc_cpp_plugin",) + return tgt.build == "protoc" and tgt.get("name", "") in wanted_binaries + + %><%! + def only_on_host_toolchain(tgt): + return tgt.get("name", "") in ("grpc_plugin_support", "grpc_cpp_plugin") + + %> + % for lib in filegroups: + % if lib.name in ("nanopb", "health_proto"): + ${cc_library(lib)} + %endif + %endfor + % for lib in libs: + % if wanted_lib(lib): + % if only_on_host_toolchain(lib): + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) { + ${cc_library(lib)} + } + % else: + ${cc_library(lib)} + % endif + % endif + % endfor + % for tgt in targets: + % if wanted_binary(tgt): + % if only_on_host_toolchain(tgt): + # Only compile the plugin for the host architecture. + if (current_toolchain == host_toolchain) { + ${cc_binary(tgt)} + } + % else: + ${cc_binary(tgt)} + % endif + % endif + % endfor + <%def name="cc_library(lib)"> + <% + sources = get_sources(lib) + include_dirs = get_include_dirs(sources) + sources = strip_sources(sources, lib.name) + sources.sort() + %> + source_set("${lib.name}") { + %if sources: + sources = [ + % for src in sources: + "${src}", + % endfor + ] + %endif + deps = [ + % for dep in get_deps(lib): + "${dep}", + % endfor + ] + <% extra_configs = get_extra_configs(lib) %> + % if extra_configs: + configs += [ + % for config in extra_configs: + "${config}", + % endfor + ] + % endif + public_configs = [ + ":grpc_config", + ] + %if include_dirs: + include_dirs = [ + %for d in include_dirs: + "${d}", + %endfor + ] + %endif + } + + <%def name="cc_binary(tgt)"> + executable("${tgt.name}") { + sources = [ + % for src in tgt.src: + "${src}", + % endfor + ] + deps = [ + % for dep in get_deps(tgt): + "${dep}", + % endfor + ] + <% extra_configs = get_extra_configs(tgt) %> + % if extra_configs: + configs += [ + % for config in extra_configs: + "${config}", + % endfor + ] + % endif + public_configs = [ ":grpc_config" ] + } + + ## vim: set ft=mako:ts=2:et:sw=2 From a4a5c43a6f3e10f541bd733321130b9828d29ad0 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 20 Mar 2019 10:45:57 -0700 Subject: [PATCH 751/814] updated cmake gflags target --- cmake/gflags.cmake | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cmake/gflags.cmake b/cmake/gflags.cmake index e17972b3657..fb5a7a975ea 100644 --- a/cmake/gflags.cmake +++ b/cmake/gflags.cmake @@ -11,17 +11,15 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -set(gRPC_GFLAGS_PROVIDER "module" CACHE STRING "portability fix") + if("${gRPC_GFLAGS_PROVIDER}" STREQUAL "module") - message("gRPC GFLAGS is MODULE") if(NOT GFLAGS_ROOT_DIR) set(GFLAGS_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gflags) endif() if(EXISTS "${GFLAGS_ROOT_DIR}/CMakeLists.txt") - message("gRPC GFLAGS adding subdirectory") add_subdirectory(${GFLAGS_ROOT_DIR} third_party/gflags) if(TARGET gflags_static) - set(_gRPC_GFLAGS_LIBRARIES gflags_static) + set(_gRPC_GFLAGS_LIBRARIES gflags::gflags) set(_gRPC_GFLAGS_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include") endif() else() @@ -32,7 +30,7 @@ elseif("${gRPC_GFLAGS_PROVIDER}" STREQUAL "package") # Use "CONFIG" as there is no built-in cmake module for gflags. find_package(gflags REQUIRED CONFIG) if(TARGET gflags) - set(_gRPC_GFLAGS_LIBRARIES gflags) + set(_gRPC_GFLAGS_LIBRARIES gflags::gflags) set(_gRPC_GFLAGS_INCLUDE_DIR ${GFLAGS_INCLUDE_DIR}) endif() set(_gRPC_FIND_GFLAGS "if(NOT gflags_FOUND)\n find_package(gflags CONFIG)\nendif()") From 3de283c665387a569b139d589c2409d51ceafee8 Mon Sep 17 00:00:00 2001 From: Jared Hance Date: Wed, 20 Mar 2019 10:23:22 -0700 Subject: [PATCH 752/814] Make gil handling in completion queue more robust It turns out that the code generation for "with gil" is a bit more complicated than the logic for re-obtaining the gil at the end of "with nogil." This is because PyGILState_Ensure seems to, during interpreter finalization, think it needs to call a new thread (resulting in a call to cpython new_threadstate) which then segfaults. Because "with nogil" knows that, prior to executing, it already had the gil, it doesn't need to set up as much state, and thus the segfault does not occur. To avoid this, we just only use "with nogil" within the infinite loop, and then end the "nogil" block before we check signals. This avoids needing any "with gil" call at all. I was able to reliably reproduce the segfault within a few minutes before the patch by running a binary in a loop (with py3) while maxing out my machines cpu usage. After the patch, I have not been able to reproduce the segfault after two hours. Note that this race can only occur when the user does not properly clean up all their channels, and is relying on garbage collection to do so (which isn't guaranteed). However, we want to avoid a segfault on failure to close because this isn't a good user error and makes it hard to debug. --- .../grpc/_cython/_cygrpc/completion_queue.pyx.pxi | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi index a4d425ac564..212d27dc2b7 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -30,19 +30,20 @@ cdef grpc_event _next(grpc_completion_queue *c_completion_queue, deadline): else: c_deadline = _timespec_from_time(deadline) - with nogil: - while True: + while True: + with nogil: c_timeout = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c_increment) if gpr_time_cmp(c_timeout, c_deadline) > 0: c_timeout = c_deadline + c_event = grpc_completion_queue_next(c_completion_queue, c_timeout, NULL) + if (c_event.type != GRPC_QUEUE_TIMEOUT or gpr_time_cmp(c_timeout, c_deadline) == 0): break - # Handle any signals - with gil: - cpython.PyErr_CheckSignals() + # Handle any signals + cpython.PyErr_CheckSignals() return c_event From 3ddcbb2aceda52529888006e35b4189454b018fa Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 20 Mar 2019 14:34:34 -0700 Subject: [PATCH 753/814] fixing CMake bug by adding gflags dependency to grpc++_test_config --- CMakeLists.txt | 8 ++------ cmake/gflags.cmake | 8 +++----- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2308582c2f4..a2b16173018 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2371,6 +2371,7 @@ target_include_directories(grpc_test_util_unsecure endif() target_link_libraries(grpc_test_util_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} + ${_gRPC_GFLAGS_LIBRARIES} gpr grpc_unsecure ) @@ -4014,6 +4015,7 @@ target_include_directories(grpc++_test_config target_link_libraries(grpc++_test_config ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + ${_gRPC_GFLAGS_LIBRARIES} ) @@ -16042,7 +16044,6 @@ target_link_libraries(thread_manager_test grpc_unsecure gpr grpc++_test_config - ${_gRPC_GFLAGS_LIBRARIES} ) @@ -18893,11 +18894,6 @@ target_link_libraries(uri_fuzzer_test_one_entry endif (gRPC_BUILD_TESTS) - - - - - if (gRPC_INSTALL) install(EXPORT gRPCTargets DESTINATION ${gRPC_INSTALL_CMAKEDIR} diff --git a/cmake/gflags.cmake b/cmake/gflags.cmake index fb5a7a975ea..5f0fd8f21e3 100644 --- a/cmake/gflags.cmake +++ b/cmake/gflags.cmake @@ -18,15 +18,12 @@ if("${gRPC_GFLAGS_PROVIDER}" STREQUAL "module") endif() if(EXISTS "${GFLAGS_ROOT_DIR}/CMakeLists.txt") add_subdirectory(${GFLAGS_ROOT_DIR} third_party/gflags) - if(TARGET gflags_static) - set(_gRPC_GFLAGS_LIBRARIES gflags::gflags) - set(_gRPC_GFLAGS_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include") - endif() + set(_gRPC_GFLAGS_LIBRARIES gflags::gflags) + set(_gRPC_GFLAGS_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include") else() message(WARNING "gRPC_GFLAGS_PROVIDER is \"module\" but GFLAGS_ROOT_DIR is wrong") endif() elseif("${gRPC_GFLAGS_PROVIDER}" STREQUAL "package") - message("gRPC GFLAGS is PACKAGE") # Use "CONFIG" as there is no built-in cmake module for gflags. find_package(gflags REQUIRED CONFIG) if(TARGET gflags) @@ -35,3 +32,4 @@ elseif("${gRPC_GFLAGS_PROVIDER}" STREQUAL "package") endif() set(_gRPC_FIND_GFLAGS "if(NOT gflags_FOUND)\n find_package(gflags CONFIG)\nendif()") endif() + From a7449a3808bcce25e6fc7d3a3e2748bff95597e7 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 20 Mar 2019 15:07:21 -0700 Subject: [PATCH 754/814] generated projects using script --- CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a2b16173018..2308582c2f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2371,7 +2371,6 @@ target_include_directories(grpc_test_util_unsecure endif() target_link_libraries(grpc_test_util_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} - ${_gRPC_GFLAGS_LIBRARIES} gpr grpc_unsecure ) @@ -4015,7 +4014,6 @@ target_include_directories(grpc++_test_config target_link_libraries(grpc++_test_config ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} - ${_gRPC_GFLAGS_LIBRARIES} ) @@ -16044,6 +16042,7 @@ target_link_libraries(thread_manager_test grpc_unsecure gpr grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} ) @@ -18894,6 +18893,11 @@ target_link_libraries(uri_fuzzer_test_one_entry endif (gRPC_BUILD_TESTS) + + + + + if (gRPC_INSTALL) install(EXPORT gRPCTargets DESTINATION ${gRPC_INSTALL_CMAKEDIR} From d963ef91f124b14a9f542107aa99dd918f6cb347 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 20 Mar 2019 16:07:37 -0700 Subject: [PATCH 755/814] updated if condition to match latest gflags changes --- cmake/gflags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/gflags.cmake b/cmake/gflags.cmake index 5f0fd8f21e3..52c054ca762 100644 --- a/cmake/gflags.cmake +++ b/cmake/gflags.cmake @@ -26,7 +26,7 @@ if("${gRPC_GFLAGS_PROVIDER}" STREQUAL "module") elseif("${gRPC_GFLAGS_PROVIDER}" STREQUAL "package") # Use "CONFIG" as there is no built-in cmake module for gflags. find_package(gflags REQUIRED CONFIG) - if(TARGET gflags) + if(TARGET gflags::gflags) set(_gRPC_GFLAGS_LIBRARIES gflags::gflags) set(_gRPC_GFLAGS_INCLUDE_DIR ${GFLAGS_INCLUDE_DIR}) endif() From 3a8e9bd46559ec1fed44c9bf16cf0918706f4dbf Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 20 Mar 2019 16:41:12 -0700 Subject: [PATCH 756/814] added inclusion of gflags to template --- CMakeLists.txt | 206 ++++++++++++++++++++++++++++++ templates/CMakeLists.txt.template | 2 +- 2 files changed, 207 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2308582c2f4..762917821b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3238,6 +3238,7 @@ target_link_libraries(grpc++_core_stats ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} grpc++ + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -3892,6 +3893,7 @@ target_link_libraries(grpc++_proto_reflection_desc_db ${_gRPC_ALLTARGETS_LIBRARIES} grpc++ grpc + ${_gRPC_GFLAGS_LIBRARIES} ) foreach(_hdr @@ -4014,6 +4016,7 @@ target_include_directories(grpc++_test_config target_link_libraries(grpc++_test_config ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} + ${_gRPC_GFLAGS_LIBRARIES} ) @@ -4111,6 +4114,7 @@ target_link_libraries(grpc++_test_util grpc++ grpc_test_util grpc + ${_gRPC_GFLAGS_LIBRARIES} ) foreach(_hdr @@ -4306,6 +4310,7 @@ target_link_libraries(grpc++_test_util_unsecure grpc++_unsecure grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) foreach(_hdr @@ -4834,6 +4839,7 @@ target_link_libraries(grpc_cli_libs grpc++_proto_reflection_desc_db grpc++ grpc + ${_gRPC_GFLAGS_LIBRARIES} ) foreach(_hdr @@ -5044,6 +5050,7 @@ target_link_libraries(http2_client_main grpc++ grpc grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -5100,6 +5107,7 @@ target_link_libraries(interop_client_helper grpc++ grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -5173,6 +5181,7 @@ target_link_libraries(interop_client_main grpc gpr grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -5221,6 +5230,7 @@ target_link_libraries(interop_server_helper grpc++ grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) @@ -5292,6 +5302,7 @@ target_link_libraries(interop_server_lib grpc gpr grpc++_test_config + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -5336,6 +5347,7 @@ target_link_libraries(interop_server_main ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} interop_server_lib + ${_gRPC_GFLAGS_LIBRARIES} ) @@ -5445,6 +5457,7 @@ target_link_libraries(qps grpc++_core_stats grpc++ grpc + ${_gRPC_GFLAGS_LIBRARIES} ) endif (gRPC_BUILD_CODEGEN) @@ -5919,6 +5932,7 @@ target_link_libraries(algorithm_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -5953,6 +5967,7 @@ target_link_libraries(alloc_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -5987,6 +6002,7 @@ target_link_libraries(alpn_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6021,6 +6037,7 @@ target_link_libraries(arena_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6055,6 +6072,7 @@ target_link_libraries(avl_test gpr grpc_test_util grpc + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6090,6 +6108,7 @@ target_link_libraries(bad_server_response_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6123,6 +6142,7 @@ target_link_libraries(bin_decoder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6156,6 +6176,7 @@ target_link_libraries(bin_encoder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6191,6 +6212,7 @@ target_link_libraries(buffer_list_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6226,6 +6248,7 @@ target_link_libraries(channel_create_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6291,6 +6314,7 @@ target_link_libraries(chttp2_hpack_encoder_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6325,6 +6349,7 @@ target_link_libraries(chttp2_stream_map_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6359,6 +6384,7 @@ target_link_libraries(chttp2_varint_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6394,6 +6420,7 @@ target_link_libraries(close_fd_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6429,6 +6456,7 @@ target_link_libraries(cmdline_test gpr grpc_test_util grpc + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6463,6 +6491,7 @@ target_link_libraries(combiner_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6497,6 +6526,7 @@ target_link_libraries(compression_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6531,6 +6561,7 @@ target_link_libraries(concurrent_connectivity_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6565,6 +6596,7 @@ target_link_libraries(connection_refused_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6599,6 +6631,7 @@ target_link_libraries(dns_resolver_connectivity_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6633,6 +6666,7 @@ target_link_libraries(dns_resolver_cooldown_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6667,6 +6701,7 @@ target_link_libraries(dns_resolver_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6702,6 +6737,7 @@ target_link_libraries(dualstack_socket_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6737,6 +6773,7 @@ target_link_libraries(endpoint_pair_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6771,6 +6808,7 @@ target_link_libraries(error_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6806,6 +6844,7 @@ target_link_libraries(ev_epollex_linux_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6841,6 +6880,7 @@ target_link_libraries(fake_resolver_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6877,6 +6917,7 @@ target_link_libraries(fake_transport_security_test gpr grpc_test_util grpc + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6913,6 +6954,7 @@ target_link_libraries(fd_conservation_posix_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6949,6 +6991,7 @@ target_link_libraries(fd_posix_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6984,6 +7027,7 @@ target_link_libraries(fling_client grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7018,6 +7062,7 @@ target_link_libraries(fling_server grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7053,6 +7098,7 @@ target_link_libraries(fling_stream_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7089,6 +7135,7 @@ target_link_libraries(fling_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7125,6 +7172,7 @@ target_link_libraries(fork_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7161,6 +7209,7 @@ target_link_libraries(goaway_server_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7196,6 +7245,7 @@ target_link_libraries(gpr_cpu_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7230,6 +7280,7 @@ target_link_libraries(gpr_env_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7264,6 +7315,7 @@ target_link_libraries(gpr_host_port_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7298,6 +7350,7 @@ target_link_libraries(gpr_log_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7332,6 +7385,7 @@ target_link_libraries(gpr_manual_constructor_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7366,6 +7420,7 @@ target_link_libraries(gpr_mpscq_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7400,6 +7455,7 @@ target_link_libraries(gpr_spinlock_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7434,6 +7490,7 @@ target_link_libraries(gpr_string_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7468,6 +7525,7 @@ target_link_libraries(gpr_sync_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7502,6 +7560,7 @@ target_link_libraries(gpr_thd_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7536,6 +7595,7 @@ target_link_libraries(gpr_time_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7570,6 +7630,7 @@ target_link_libraries(gpr_tls_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7604,6 +7665,7 @@ target_link_libraries(gpr_useful_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7638,6 +7700,7 @@ target_link_libraries(grpc_auth_context_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7672,6 +7735,7 @@ target_link_libraries(grpc_b64_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7706,6 +7770,7 @@ target_link_libraries(grpc_byte_buffer_reader_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7740,6 +7805,7 @@ target_link_libraries(grpc_channel_args_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7774,6 +7840,7 @@ target_link_libraries(grpc_channel_stack_builder_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7808,6 +7875,7 @@ target_link_libraries(grpc_channel_stack_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7842,6 +7910,7 @@ target_link_libraries(grpc_completion_queue_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7876,6 +7945,7 @@ target_link_libraries(grpc_completion_queue_threading_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7943,6 +8013,7 @@ target_link_libraries(grpc_credentials_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7977,6 +8048,7 @@ target_link_libraries(grpc_fetch_oauth2 grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8011,6 +8083,7 @@ target_link_libraries(grpc_ipv6_loopback_available_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8046,6 +8119,7 @@ target_link_libraries(grpc_json_token_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8081,6 +8155,7 @@ target_link_libraries(grpc_jwt_verifier_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8147,6 +8222,7 @@ target_link_libraries(grpc_security_connector_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8181,6 +8257,7 @@ target_link_libraries(grpc_ssl_credentials_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8249,6 +8326,7 @@ target_link_libraries(handshake_client_ssl grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8287,6 +8365,7 @@ target_link_libraries(handshake_server_ssl grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8325,6 +8404,7 @@ target_link_libraries(handshake_server_with_readahead_handshaker grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8362,6 +8442,7 @@ target_link_libraries(handshake_verify_peer_options grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8396,6 +8477,7 @@ target_link_libraries(histogram_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8430,6 +8512,7 @@ target_link_libraries(hpack_parser_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8464,6 +8547,7 @@ target_link_libraries(hpack_table_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8498,6 +8582,7 @@ target_link_libraries(http_parser_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8532,6 +8617,7 @@ target_link_libraries(httpcli_format_request_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8567,6 +8653,7 @@ target_link_libraries(httpcli_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8603,6 +8690,7 @@ target_link_libraries(httpscli_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8638,6 +8726,7 @@ target_link_libraries(init_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8672,6 +8761,7 @@ target_link_libraries(inproc_callback_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8706,6 +8796,7 @@ target_link_libraries(invalid_call_argument_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8740,6 +8831,7 @@ target_link_libraries(json_rewrite grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8774,6 +8866,7 @@ target_link_libraries(json_rewrite_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8808,6 +8901,7 @@ target_link_libraries(json_stream_error_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8842,6 +8936,7 @@ target_link_libraries(json_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8876,6 +8971,7 @@ target_link_libraries(lame_client_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8910,6 +9006,7 @@ target_link_libraries(load_file_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8944,6 +9041,7 @@ target_link_libraries(memory_usage_client grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8978,6 +9076,7 @@ target_link_libraries(memory_usage_server grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9013,6 +9112,7 @@ target_link_libraries(memory_usage_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9048,6 +9148,7 @@ target_link_libraries(message_compress_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9082,6 +9183,7 @@ target_link_libraries(minimal_stack_is_minimal_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9116,6 +9218,7 @@ target_link_libraries(multiple_server_queues_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9150,6 +9253,7 @@ target_link_libraries(murmur_hash_test gpr grpc_test_util_unsecure grpc_unsecure + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9184,6 +9288,7 @@ target_link_libraries(no_server_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9218,6 +9323,7 @@ target_link_libraries(num_external_connectivity_watchers_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9252,6 +9358,7 @@ target_link_libraries(parse_address_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9287,6 +9394,7 @@ target_link_libraries(parse_address_with_named_scope_id_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9322,6 +9430,7 @@ target_link_libraries(percent_encoding_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9357,6 +9466,7 @@ target_link_libraries(resolve_address_using_ares_resolver_posix_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9392,6 +9502,7 @@ target_link_libraries(resolve_address_using_ares_resolver_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9427,6 +9538,7 @@ target_link_libraries(resolve_address_using_native_resolver_posix_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9462,6 +9574,7 @@ target_link_libraries(resolve_address_using_native_resolver_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9496,6 +9609,7 @@ target_link_libraries(resource_quota_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9530,6 +9644,7 @@ target_link_libraries(secure_channel_create_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9564,6 +9679,7 @@ target_link_libraries(secure_endpoint_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9598,6 +9714,7 @@ target_link_libraries(sequential_connectivity_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9632,6 +9749,7 @@ target_link_libraries(server_chttp2_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9666,6 +9784,7 @@ target_link_libraries(server_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9700,6 +9819,7 @@ target_link_libraries(slice_buffer_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9734,6 +9854,7 @@ target_link_libraries(slice_string_helpers_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9768,6 +9889,7 @@ target_link_libraries(slice_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9802,6 +9924,7 @@ target_link_libraries(sockaddr_resolver_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9836,6 +9959,7 @@ target_link_libraries(sockaddr_utils_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9871,6 +9995,7 @@ target_link_libraries(socket_utils_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9908,6 +10033,7 @@ target_link_libraries(ssl_transport_security_test gpr grpc_test_util grpc + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9943,6 +10069,7 @@ target_link_libraries(status_conversion_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9977,6 +10104,7 @@ target_link_libraries(stream_compression_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10011,6 +10139,7 @@ target_link_libraries(stream_owned_slice_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10046,6 +10175,7 @@ target_link_libraries(tcp_client_posix_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10081,6 +10211,7 @@ target_link_libraries(tcp_client_uv_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10116,6 +10247,7 @@ target_link_libraries(tcp_posix_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10152,6 +10284,7 @@ target_link_libraries(tcp_server_posix_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10187,6 +10320,7 @@ target_link_libraries(tcp_server_uv_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10221,6 +10355,7 @@ target_link_libraries(time_averaged_stats_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10255,6 +10390,7 @@ target_link_libraries(timeout_encoding_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10289,6 +10425,7 @@ target_link_libraries(timer_heap_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10323,6 +10460,7 @@ target_link_libraries(timer_list_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10357,6 +10495,7 @@ target_link_libraries(transport_connectivity_state_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10391,6 +10530,7 @@ target_link_libraries(transport_metadata_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10426,6 +10566,7 @@ target_link_libraries(transport_security_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10462,6 +10603,7 @@ target_link_libraries(udp_server_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10497,6 +10639,7 @@ target_link_libraries(uri_parser_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16320,6 +16463,7 @@ target_link_libraries(public_headers_must_be_c89 ${_gRPC_ALLTARGETS_LIBRARIES} grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) @@ -16425,6 +16569,7 @@ target_link_libraries(badreq_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16461,6 +16606,7 @@ target_link_libraries(connection_prefix_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16497,6 +16643,7 @@ target_link_libraries(duplicate_header_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16533,6 +16680,7 @@ target_link_libraries(head_of_line_blocking_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16569,6 +16717,7 @@ target_link_libraries(headers_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16605,6 +16754,7 @@ target_link_libraries(initial_settings_frame_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16641,6 +16791,7 @@ target_link_libraries(large_metadata_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16677,6 +16828,7 @@ target_link_libraries(server_registered_method_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16713,6 +16865,7 @@ target_link_libraries(simple_request_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16749,6 +16902,7 @@ target_link_libraries(unknown_frame_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16785,6 +16939,7 @@ target_link_libraries(window_overflow_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16821,6 +16976,7 @@ target_link_libraries(bad_ssl_cert_server grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16857,6 +17013,7 @@ target_link_libraries(bad_ssl_cert_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16893,6 +17050,7 @@ target_link_libraries(h2_census_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16928,6 +17086,7 @@ target_link_libraries(h2_compress_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16963,6 +17122,7 @@ target_link_libraries(h2_fakesec_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16999,6 +17159,7 @@ target_link_libraries(h2_fd_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17035,6 +17196,7 @@ target_link_libraries(h2_full_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17071,6 +17233,7 @@ target_link_libraries(h2_full+pipe_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17107,6 +17270,7 @@ target_link_libraries(h2_full+trace_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17142,6 +17306,7 @@ target_link_libraries(h2_full+workarounds_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17177,6 +17342,7 @@ target_link_libraries(h2_http_proxy_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17213,6 +17379,7 @@ target_link_libraries(h2_local_ipv4_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17250,6 +17417,7 @@ target_link_libraries(h2_local_ipv6_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17287,6 +17455,7 @@ target_link_libraries(h2_local_uds_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17323,6 +17492,7 @@ target_link_libraries(h2_oauth2_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17358,6 +17528,7 @@ target_link_libraries(h2_proxy_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17393,6 +17564,7 @@ target_link_libraries(h2_sockpair_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17428,6 +17600,7 @@ target_link_libraries(h2_sockpair+trace_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17463,6 +17636,7 @@ target_link_libraries(h2_sockpair_1byte_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17498,6 +17672,7 @@ target_link_libraries(h2_spiffe_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17533,6 +17708,7 @@ target_link_libraries(h2_ssl_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17568,6 +17744,7 @@ target_link_libraries(h2_ssl_proxy_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17604,6 +17781,7 @@ target_link_libraries(h2_uds_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17640,6 +17818,7 @@ target_link_libraries(inproc_test grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17675,6 +17854,7 @@ target_link_libraries(h2_census_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17710,6 +17890,7 @@ target_link_libraries(h2_compress_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17746,6 +17927,7 @@ target_link_libraries(h2_fd_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17782,6 +17964,7 @@ target_link_libraries(h2_full_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17818,6 +18001,7 @@ target_link_libraries(h2_full+pipe_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17854,6 +18038,7 @@ target_link_libraries(h2_full+trace_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17889,6 +18074,7 @@ target_link_libraries(h2_full+workarounds_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17924,6 +18110,7 @@ target_link_libraries(h2_http_proxy_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17959,6 +18146,7 @@ target_link_libraries(h2_proxy_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17994,6 +18182,7 @@ target_link_libraries(h2_sockpair_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18029,6 +18218,7 @@ target_link_libraries(h2_sockpair+trace_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18064,6 +18254,7 @@ target_link_libraries(h2_sockpair_1byte_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18100,6 +18291,7 @@ target_link_libraries(h2_uds_nosec_test grpc_test_util_unsecure grpc_unsecure gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18427,6 +18619,7 @@ target_link_libraries(alts_credentials_fuzzer_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18462,6 +18655,7 @@ target_link_libraries(api_fuzzer_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18497,6 +18691,7 @@ target_link_libraries(client_fuzzer_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18532,6 +18727,7 @@ target_link_libraries(hpack_parser_fuzzer_test_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18567,6 +18763,7 @@ target_link_libraries(http_request_fuzzer_test_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18602,6 +18799,7 @@ target_link_libraries(http_response_fuzzer_test_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18637,6 +18835,7 @@ target_link_libraries(json_fuzzer_test_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18672,6 +18871,7 @@ target_link_libraries(nanopb_fuzzer_response_test_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18707,6 +18907,7 @@ target_link_libraries(nanopb_fuzzer_serverlist_test_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18742,6 +18943,7 @@ target_link_libraries(percent_decode_fuzzer_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18777,6 +18979,7 @@ target_link_libraries(percent_encode_fuzzer_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18812,6 +19015,7 @@ target_link_libraries(server_fuzzer_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18847,6 +19051,7 @@ target_link_libraries(ssl_server_fuzzer_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18882,6 +19087,7 @@ target_link_libraries(uri_fuzzer_test_one_entry grpc_test_util grpc gpr + ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index dd996d736ac..59410f7bdf3 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -53,7 +53,7 @@ deps.append("${_gRPC_BENCHMARK_LIBRARIES}") else: deps.append(d) - if target_dict.build == 'test' and target_dict.language == 'c++': + if target_dict.build == 'test' or target_dict.build == 'private' and target_dict.language == 'c++': deps.append("${_gRPC_GFLAGS_LIBRARIES}") return deps From 3954b3ef5dd62ea67611715db03f568940ff48fd Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 20 Mar 2019 17:37:36 -0700 Subject: [PATCH 757/814] Remove unnecessary else condition --- src/core/lib/gprpp/fork.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/lib/gprpp/fork.cc b/src/core/lib/gprpp/fork.cc index 3b9c16510a7..c4b1cbc2233 100644 --- a/src/core/lib/gprpp/fork.cc +++ b/src/core/lib/gprpp/fork.cc @@ -160,8 +160,6 @@ void Fork::GlobalInit() { if (!override_enabled_) { #ifdef GRPC_ENABLE_FORK_SUPPORT support_enabled_ = true; -#else - support_enabled_ = false; #endif bool env_var_set = false; char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT"); From ad1b3e5094de2c8193cf23714460f99b3ec21507 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 27 Feb 2019 23:41:18 -0500 Subject: [PATCH 758/814] Introduce grpc_byte_buffer_reader_peek and use it for Protobuf parsing. grpc_byte_buffer_reader_next() copies and references the slice. This is not always necessary since the caller will not use the slice after destroying the byte buffer. A prominent example is the protobuf parser, which calls grpc_byte_buffer_reader_next() and immediately unrefs the slice after the call. This ref() and unref() calls can be very expensive in the hot path. This commit introduces grpc_byte_buffer_reader_peek() which essentialy return a pointer to the slice in the buffer, i.e., no copies, and no refs. QPS of 1MiB 1 Channel callback benchmark increases by 5%. More importantly insructions per cycle is increased by 10%. Also add tests and benchmarks for byte_buffer_reader_peek() This commit reaplies 509e77a5a32 --- grpc.def | 1 + include/grpc/impl/codegen/byte_buffer.h | 13 ++++ include/grpcpp/impl/codegen/core_codegen.h | 2 + .../impl/codegen/core_codegen_interface.h | 2 + .../grpcpp/impl/codegen/proto_buffer_reader.h | 18 ++--- src/core/lib/surface/byte_buffer_reader.cc | 17 +++++ src/cpp/common/core_codegen.cc | 5 ++ src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 + src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 + test/core/surface/byte_buffer_reader_test.cc | 70 ++++++++++++++++++ .../core/surface/public_headers_must_be_c89.c | 1 + test/cpp/microbenchmarks/bm_byte_buffer.cc | 71 ++++++++++++++++++- 12 files changed, 194 insertions(+), 11 deletions(-) diff --git a/grpc.def b/grpc.def index e0a08d22c19..922f95383a3 100644 --- a/grpc.def +++ b/grpc.def @@ -149,6 +149,7 @@ EXPORTS grpc_byte_buffer_reader_init grpc_byte_buffer_reader_destroy grpc_byte_buffer_reader_next + grpc_byte_buffer_reader_peek grpc_byte_buffer_reader_readall grpc_raw_byte_buffer_from_reader gpr_log_severity_string diff --git a/include/grpc/impl/codegen/byte_buffer.h b/include/grpc/impl/codegen/byte_buffer.h index 774655ed66f..12479068155 100644 --- a/include/grpc/impl/codegen/byte_buffer.h +++ b/include/grpc/impl/codegen/byte_buffer.h @@ -73,6 +73,19 @@ GRPCAPI void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader); GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice); +/** EXPERIMENTAL API - This function may be removed and changed, in the future. + * + * Updates \a slice with the next piece of data from from \a reader and returns + * 1. Returns 0 at the end of the stream. Caller is responsible for making sure + * the slice pointer remains valid when accessed. + * + * NOTE: Do not use this function unless the caller can guarantee that the + * underlying grpc_byte_buffer outlasts the use of the slice. This is only + * safe when the underlying grpc_byte_buffer remains immutable while slice + * is being accessed. */ +GRPCAPI int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice); + /** Merge all data from \a reader into single slice */ GRPCAPI grpc_slice grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader* reader); diff --git a/include/grpcpp/impl/codegen/core_codegen.h b/include/grpcpp/impl/codegen/core_codegen.h index b7ddb0c791c..27729e0d5db 100644 --- a/include/grpcpp/impl/codegen/core_codegen.h +++ b/include/grpcpp/impl/codegen/core_codegen.h @@ -85,6 +85,8 @@ class CoreCodegen final : public CoreCodegenInterface { grpc_byte_buffer_reader* reader) override; int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) override; + int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) override; grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) override; diff --git a/include/grpcpp/impl/codegen/core_codegen_interface.h b/include/grpcpp/impl/codegen/core_codegen_interface.h index 1d92b4f0dff..3792c3d4693 100644 --- a/include/grpcpp/impl/codegen/core_codegen_interface.h +++ b/include/grpcpp/impl/codegen/core_codegen_interface.h @@ -92,6 +92,8 @@ class CoreCodegenInterface { grpc_byte_buffer_reader* reader) = 0; virtual int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) = 0; + virtual int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) = 0; virtual grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) = 0; diff --git a/include/grpcpp/impl/codegen/proto_buffer_reader.h b/include/grpcpp/impl/codegen/proto_buffer_reader.h index 9acae476b11..734da366f3a 100644 --- a/include/grpcpp/impl/codegen/proto_buffer_reader.h +++ b/include/grpcpp/impl/codegen/proto_buffer_reader.h @@ -73,7 +73,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { } /// If we have backed up previously, we need to return the backed-up slice if (backup_count_ > 0) { - *data = GRPC_SLICE_START_PTR(slice_) + GRPC_SLICE_LENGTH(slice_) - + *data = GRPC_SLICE_START_PTR(*slice_) + GRPC_SLICE_LENGTH(*slice_) - backup_count_; GPR_CODEGEN_ASSERT(backup_count_ <= INT_MAX); *size = (int)backup_count_; @@ -81,15 +81,14 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { return true; } /// Otherwise get the next slice from the byte buffer reader - if (!g_core_codegen_interface->grpc_byte_buffer_reader_next(&reader_, + if (!g_core_codegen_interface->grpc_byte_buffer_reader_peek(&reader_, &slice_)) { return false; } - g_core_codegen_interface->grpc_slice_unref(slice_); - *data = GRPC_SLICE_START_PTR(slice_); + *data = GRPC_SLICE_START_PTR(*slice_); // On win x64, int is only 32bit - GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX); - byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_); + GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(*slice_) <= INT_MAX); + byte_count_ += * size = (int)GRPC_SLICE_LENGTH(*slice_); return true; } @@ -100,7 +99,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { /// bytes that have already been returned by the last call of Next. /// So do the backup and have that ready for a later Next. void BackUp(int count) override { - GPR_CODEGEN_ASSERT(count <= static_cast(GRPC_SLICE_LENGTH(slice_))); + GPR_CODEGEN_ASSERT(count <= static_cast(GRPC_SLICE_LENGTH(*slice_))); backup_count_ = count; } @@ -135,14 +134,15 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream { int64_t backup_count() { return backup_count_; } void set_backup_count(int64_t backup_count) { backup_count_ = backup_count; } grpc_byte_buffer_reader* reader() { return &reader_; } - grpc_slice* slice() { return &slice_; } + grpc_slice* slice() { return slice_; } + grpc_slice** mutable_slice_ptr() { return &slice_; } private: int64_t byte_count_; ///< total bytes read since object creation int64_t backup_count_; ///< how far backed up in the stream we are grpc_byte_buffer_reader reader_; ///< internal object to read \a grpc_slice ///< from the \a grpc_byte_buffer - grpc_slice slice_; ///< current slice passed back to the caller + grpc_slice* slice_; ///< current slice passed back to the caller Status status_; ///< status of the entire object }; diff --git a/src/core/lib/surface/byte_buffer_reader.cc b/src/core/lib/surface/byte_buffer_reader.cc index 1debc98ea0c..ed8ecc49590 100644 --- a/src/core/lib/surface/byte_buffer_reader.cc +++ b/src/core/lib/surface/byte_buffer_reader.cc @@ -91,6 +91,23 @@ void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader* reader) { } } +int grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) { + switch (reader->buffer_in->type) { + case GRPC_BB_RAW: { + grpc_slice_buffer* slice_buffer; + slice_buffer = &reader->buffer_out->data.raw.slice_buffer; + if (reader->current.index < slice_buffer->count) { + *slice = &slice_buffer->slices[reader->current.index]; + reader->current.index += 1; + return 1; + } + break; + } + } + return 0; +} + int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, grpc_slice* slice) { switch (reader->buffer_in->type) { diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc index ab5f601fdd4..665305ca0a5 100644 --- a/src/cpp/common/core_codegen.cc +++ b/src/cpp/common/core_codegen.cc @@ -139,6 +139,11 @@ int CoreCodegen::grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader, return ::grpc_byte_buffer_reader_next(reader, slice); } +int CoreCodegen::grpc_byte_buffer_reader_peek(grpc_byte_buffer_reader* reader, + grpc_slice** slice) { + return ::grpc_byte_buffer_reader_peek(reader, slice); +} + grpc_byte_buffer* CoreCodegen::grpc_raw_byte_buffer_create(grpc_slice* slice, size_t nslices) { return ::grpc_raw_byte_buffer_create(slice, nslices); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index fdbe0df4e52..f8a31286115 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -172,6 +172,7 @@ grpc_byte_buffer_destroy_type grpc_byte_buffer_destroy_import; grpc_byte_buffer_reader_init_type grpc_byte_buffer_reader_init_import; grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_import; grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import; +grpc_byte_buffer_reader_peek_type grpc_byte_buffer_reader_peek_import; grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import; grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import; gpr_log_severity_string_type gpr_log_severity_string_import; @@ -440,6 +441,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_byte_buffer_reader_init_import = (grpc_byte_buffer_reader_init_type) GetProcAddress(library, "grpc_byte_buffer_reader_init"); grpc_byte_buffer_reader_destroy_import = (grpc_byte_buffer_reader_destroy_type) GetProcAddress(library, "grpc_byte_buffer_reader_destroy"); grpc_byte_buffer_reader_next_import = (grpc_byte_buffer_reader_next_type) GetProcAddress(library, "grpc_byte_buffer_reader_next"); + grpc_byte_buffer_reader_peek_import = (grpc_byte_buffer_reader_peek_type) GetProcAddress(library, "grpc_byte_buffer_reader_peek"); grpc_byte_buffer_reader_readall_import = (grpc_byte_buffer_reader_readall_type) GetProcAddress(library, "grpc_byte_buffer_reader_readall"); grpc_raw_byte_buffer_from_reader_import = (grpc_raw_byte_buffer_from_reader_type) GetProcAddress(library, "grpc_raw_byte_buffer_from_reader"); gpr_log_severity_string_import = (gpr_log_severity_string_type) GetProcAddress(library, "gpr_log_severity_string"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index cf16f0ca33b..275ca6e9cbf 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -491,6 +491,9 @@ extern grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_impo typedef int(*grpc_byte_buffer_reader_next_type)(grpc_byte_buffer_reader* reader, grpc_slice* slice); extern grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import; #define grpc_byte_buffer_reader_next grpc_byte_buffer_reader_next_import +typedef int(*grpc_byte_buffer_reader_peek_type)(grpc_byte_buffer_reader* reader, grpc_slice** slice); +extern grpc_byte_buffer_reader_peek_type grpc_byte_buffer_reader_peek_import; +#define grpc_byte_buffer_reader_peek grpc_byte_buffer_reader_peek_import typedef grpc_slice(*grpc_byte_buffer_reader_readall_type)(grpc_byte_buffer_reader* reader); extern grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import; #define grpc_byte_buffer_reader_readall grpc_byte_buffer_reader_readall_import diff --git a/test/core/surface/byte_buffer_reader_test.cc b/test/core/surface/byte_buffer_reader_test.cc index 301a1e283ba..bc368c49657 100644 --- a/test/core/surface/byte_buffer_reader_test.cc +++ b/test/core/surface/byte_buffer_reader_test.cc @@ -101,6 +101,73 @@ static void test_read_none_compressed_slice(void) { grpc_byte_buffer_destroy(buffer); } +static void test_peek_one_slice(void) { + grpc_slice slice; + grpc_byte_buffer* buffer; + grpc_byte_buffer_reader reader; + grpc_slice* first_slice; + grpc_slice* second_slice; + int first_code, second_code; + + LOG_TEST("test_peek_one_slice"); + slice = grpc_slice_from_copied_string("test"); + buffer = grpc_raw_byte_buffer_create(&slice, 1); + grpc_slice_unref(slice); + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && + "Couldn't init byte buffer reader"); + first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); + GPR_ASSERT(first_code != 0); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); + second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); + GPR_ASSERT(second_code == 0); + grpc_byte_buffer_destroy(buffer); +} + +static void test_peek_one_slice_malloc(void) { + grpc_slice slice; + grpc_byte_buffer* buffer; + grpc_byte_buffer_reader reader; + grpc_slice* first_slice; + grpc_slice* second_slice; + int first_code, second_code; + + LOG_TEST("test_peek_one_slice_malloc"); + slice = grpc_slice_malloc(4); + memcpy(GRPC_SLICE_START_PTR(slice), "test", 4); + buffer = grpc_raw_byte_buffer_create(&slice, 1); + grpc_slice_unref(slice); + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && + "Couldn't init byte buffer reader"); + first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); + GPR_ASSERT(first_code != 0); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); + second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); + GPR_ASSERT(second_code == 0); + grpc_byte_buffer_destroy(buffer); +} + +static void test_peek_none_compressed_slice(void) { + grpc_slice slice; + grpc_byte_buffer* buffer; + grpc_byte_buffer_reader reader; + grpc_slice* first_slice; + grpc_slice* second_slice; + int first_code, second_code; + + LOG_TEST("test_peek_none_compressed_slice"); + slice = grpc_slice_from_copied_string("test"); + buffer = grpc_raw_byte_buffer_create(&slice, 1); + grpc_slice_unref(slice); + GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, buffer) && + "Couldn't init byte buffer reader"); + first_code = grpc_byte_buffer_reader_peek(&reader, &first_slice); + GPR_ASSERT(first_code != 0); + GPR_ASSERT(memcmp(GRPC_SLICE_START_PTR(*first_slice), "test", 4) == 0); + second_code = grpc_byte_buffer_reader_peek(&reader, &second_slice); + GPR_ASSERT(second_code == 0); + grpc_byte_buffer_destroy(buffer); +} + static void test_read_corrupted_slice(void) { grpc_slice slice; grpc_byte_buffer* buffer; @@ -271,6 +338,9 @@ int main(int argc, char** argv) { test_read_one_slice(); test_read_one_slice_malloc(); test_read_none_compressed_slice(); + test_peek_one_slice(); + test_peek_one_slice_malloc(); + test_peek_none_compressed_slice(); test_read_gzip_compressed_slice(); test_read_deflate_compressed_slice(); test_read_corrupted_slice(); diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 04d0506b3c2..fa02e76ec92 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -209,6 +209,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_byte_buffer_reader_init); printf("%lx", (unsigned long) grpc_byte_buffer_reader_destroy); printf("%lx", (unsigned long) grpc_byte_buffer_reader_next); + printf("%lx", (unsigned long) grpc_byte_buffer_reader_peek); printf("%lx", (unsigned long) grpc_byte_buffer_reader_readall); printf("%lx", (unsigned long) grpc_raw_byte_buffer_from_reader); printf("%lx", (unsigned long) gpr_log_severity_string); diff --git a/test/cpp/microbenchmarks/bm_byte_buffer.cc b/test/cpp/microbenchmarks/bm_byte_buffer.cc index a359e6f6212..644c27c4873 100644 --- a/test/cpp/microbenchmarks/bm_byte_buffer.cc +++ b/test/cpp/microbenchmarks/bm_byte_buffer.cc @@ -29,9 +29,8 @@ namespace grpc { namespace testing { -auto& force_library_initialization = Library::get(); - static void BM_ByteBuffer_Copy(benchmark::State& state) { + Library::get(); int num_slices = state.range(0); size_t slice_size = state.range(1); std::vector slices; @@ -48,6 +47,74 @@ static void BM_ByteBuffer_Copy(benchmark::State& state) { } BENCHMARK(BM_ByteBuffer_Copy)->Ranges({{1, 64}, {1, 1024 * 1024}}); +static void BM_ByteBufferReader_Next(benchmark::State& state) { + Library::get(); + const int num_slices = state.range(0); + constexpr size_t kSliceSize = 16; + std::vector slices; + for (int i = 0; i < num_slices; ++i) { + std::unique_ptr buf(new char[kSliceSize]); + slices.emplace_back(g_core_codegen_interface->grpc_slice_from_copied_buffer( + buf.get(), kSliceSize)); + } + grpc_byte_buffer* bb = g_core_codegen_interface->grpc_raw_byte_buffer_create( + slices.data(), num_slices); + grpc_byte_buffer_reader reader; + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + while (state.KeepRunning()) { + grpc_slice* slice; + if (GPR_UNLIKELY(!g_core_codegen_interface->grpc_byte_buffer_reader_peek( + &reader, &slice))) { + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + continue; + } + } + + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + g_core_codegen_interface->grpc_byte_buffer_destroy(bb); + for (auto& slice : slices) { + g_core_codegen_interface->grpc_slice_unref(slice); + } +} +BENCHMARK(BM_ByteBufferReader_Next)->Ranges({{64 * 1024, 1024 * 1024}}); + +static void BM_ByteBufferReader_Peek(benchmark::State& state) { + Library::get(); + const int num_slices = state.range(0); + constexpr size_t kSliceSize = 16; + std::vector slices; + for (int i = 0; i < num_slices; ++i) { + std::unique_ptr buf(new char[kSliceSize]); + slices.emplace_back(g_core_codegen_interface->grpc_slice_from_copied_buffer( + buf.get(), kSliceSize)); + } + grpc_byte_buffer* bb = g_core_codegen_interface->grpc_raw_byte_buffer_create( + slices.data(), num_slices); + grpc_byte_buffer_reader reader; + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + while (state.KeepRunning()) { + grpc_slice* slice; + if (GPR_UNLIKELY(!g_core_codegen_interface->grpc_byte_buffer_reader_peek( + &reader, &slice))) { + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + GPR_ASSERT( + g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader, bb)); + continue; + } + } + + g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader); + g_core_codegen_interface->grpc_byte_buffer_destroy(bb); + for (auto& slice : slices) { + g_core_codegen_interface->grpc_slice_unref(slice); + } +} +BENCHMARK(BM_ByteBufferReader_Peek)->Ranges({{64 * 1024, 1024 * 1024}}); + } // namespace testing } // namespace grpc From fa33d47da504040195c7f2a9537eae01467b8341 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 21 Mar 2019 04:46:40 -0700 Subject: [PATCH 759/814] address interview feedback --- .../Internal/NativeCallbackDispatcher.cs | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs index 97d3fb81c9c..d5146e816e2 100644 --- a/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs +++ b/src/csharp/Grpc.Core/Internal/NativeCallbackDispatcher.cs @@ -24,6 +24,7 @@ using System.Runtime.InteropServices; using System.Threading; using System.Collections.Generic; using Grpc.Core.Logging; +using Grpc.Core.Utils; namespace Grpc.Core.Internal { @@ -34,20 +35,14 @@ namespace Grpc.Core.Internal internal class NativeCallbackDispatcher { static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); - static readonly object staticLock = new object(); static NativeCallbackDispatcherCallback dispatcherCallback; public static void Init(NativeMethods native) { - lock (staticLock) - { - if (dispatcherCallback == null) - { - dispatcherCallback = new NativeCallbackDispatcherCallback(HandleDispatcherCallback); - native.grpcsharp_native_callback_dispatcher_init(dispatcherCallback); - } - } + GrpcPreconditions.CheckState(dispatcherCallback == null); + dispatcherCallback = new NativeCallbackDispatcherCallback(HandleDispatcherCallback); + native.grpcsharp_native_callback_dispatcher_init(dispatcherCallback); } public static NativeCallbackRegistration RegisterCallback(UniversalNativeCallback callback) @@ -56,18 +51,13 @@ namespace Grpc.Core.Internal return new NativeCallbackRegistration(gcHandle); } - private static UniversalNativeCallback GetCallback(IntPtr tag) - { - var gcHandle = GCHandle.FromIntPtr(tag); - return (UniversalNativeCallback) gcHandle.Target; - } - [MonoPInvokeCallback(typeof(NativeCallbackDispatcherCallback))] private static int HandleDispatcherCallback(IntPtr tag, IntPtr arg0, IntPtr arg1, IntPtr arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5) { try { - var callback = GetCallback(tag); + var gcHandle = GCHandle.FromIntPtr(tag); + var callback = (UniversalNativeCallback) gcHandle.Target; return callback(arg0, arg1, arg2, arg3, arg4, arg5); } catch (Exception e) From 6dac288e957333e6c684bfc0fc730d221333aed2 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 21 Mar 2019 08:01:52 -0400 Subject: [PATCH 760/814] clang format code --- src/csharp/ext/grpc_csharp_ext.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 26a92708e8c..dc690a6a608 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -1013,11 +1013,14 @@ grpcsharp_composite_call_credentials_create(grpc_call_credentials* creds1, /* Native callback dispatcher */ typedef int(GPR_CALLTYPE* grpcsharp_native_callback_dispatcher_func)( - void* tag, void* arg0, void* arg1, void* arg2, void* arg3, void* arg4, void *arg5); + void* tag, void* arg0, void* arg1, void* arg2, void* arg3, void* arg4, + void* arg5); -static grpcsharp_native_callback_dispatcher_func native_callback_dispatcher = NULL; +static grpcsharp_native_callback_dispatcher_func native_callback_dispatcher = + NULL; -GPR_EXPORT void GPR_CALLTYPE grpcsharp_native_callback_dispatcher_init(grpcsharp_native_callback_dispatcher_func func) { +GPR_EXPORT void GPR_CALLTYPE grpcsharp_native_callback_dispatcher_init( + grpcsharp_native_callback_dispatcher_func func) { GPR_ASSERT(func); native_callback_dispatcher = func; } @@ -1041,8 +1044,9 @@ static int grpcsharp_get_metadata_handler( grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], size_t* num_creds_md, grpc_status_code* status, const char** error_details) { - native_callback_dispatcher(state, (void*)context.service_url, (void*)context.method_name, cb, user_data, - (void*)0, NULL); + native_callback_dispatcher(state, (void*)context.service_url, + (void*)context.method_name, cb, user_data, + (void*)0, NULL); return 0; /* Asynchronous return. */ } @@ -1051,7 +1055,7 @@ static void grpcsharp_metadata_credentials_destroy_handler(void* state) { } GPR_EXPORT grpc_call_credentials* GPR_CALLTYPE -grpcsharp_metadata_credentials_create_from_plugin(void *callback_tag) { +grpcsharp_metadata_credentials_create_from_plugin(void* callback_tag) { grpc_metadata_credentials_plugin plugin; plugin.get_metadata = grpcsharp_get_metadata_handler; plugin.destroy = grpcsharp_metadata_credentials_destroy_handler; From ddae4333fa1aba2ed53eb4d0bb3ca2bf58b795ee Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 21 Mar 2019 10:29:32 -0700 Subject: [PATCH 761/814] addressed comments --- cmake/benchmark.cmake | 3 +-- templates/CMakeLists.txt.template | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cmake/benchmark.cmake b/cmake/benchmark.cmake index ff95ed86a25..99148b52adf 100644 --- a/cmake/benchmark.cmake +++ b/cmake/benchmark.cmake @@ -12,9 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -set(BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE BOOL "Turn off gTest in gBenchmark") - if("${gRPC_BENCHMARK_PROVIDER}" STREQUAL "module") + set(BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE BOOL "Turn off gTest in gBenchmark") if(NOT BENCHMARK_ROOT_DIR) set(BENCHMARK_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/benchmark) endif() diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 59410f7bdf3..4057da40c16 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -53,7 +53,7 @@ deps.append("${_gRPC_BENCHMARK_LIBRARIES}") else: deps.append(d) - if target_dict.build == 'test' or target_dict.build == 'private' and target_dict.language == 'c++': + if (target_dict.build == 'test' or target_dict.build == 'private') and target_dict.language == 'c++': deps.append("${_gRPC_GFLAGS_LIBRARIES}") return deps From 746bfeac5e588c1eadc434220e629854cb623341 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 21 Mar 2019 11:03:36 -0700 Subject: [PATCH 762/814] regenerated CMakeLists --- CMakeLists.txt | 193 ------------------------------------------------- 1 file changed, 193 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 762917821b8..d39c1941a74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5932,7 +5932,6 @@ target_link_libraries(algorithm_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -5967,7 +5966,6 @@ target_link_libraries(alloc_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6002,7 +6000,6 @@ target_link_libraries(alpn_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6037,7 +6034,6 @@ target_link_libraries(arena_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6072,7 +6068,6 @@ target_link_libraries(avl_test gpr grpc_test_util grpc - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6108,7 +6103,6 @@ target_link_libraries(bad_server_response_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6142,7 +6136,6 @@ target_link_libraries(bin_decoder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6176,7 +6169,6 @@ target_link_libraries(bin_encoder_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6212,7 +6204,6 @@ target_link_libraries(buffer_list_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6248,7 +6239,6 @@ target_link_libraries(channel_create_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6314,7 +6304,6 @@ target_link_libraries(chttp2_hpack_encoder_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6349,7 +6338,6 @@ target_link_libraries(chttp2_stream_map_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6384,7 +6372,6 @@ target_link_libraries(chttp2_varint_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6420,7 +6407,6 @@ target_link_libraries(close_fd_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6456,7 +6442,6 @@ target_link_libraries(cmdline_test gpr grpc_test_util grpc - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6491,7 +6476,6 @@ target_link_libraries(combiner_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6526,7 +6510,6 @@ target_link_libraries(compression_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6561,7 +6544,6 @@ target_link_libraries(concurrent_connectivity_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6596,7 +6578,6 @@ target_link_libraries(connection_refused_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6631,7 +6612,6 @@ target_link_libraries(dns_resolver_connectivity_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6666,7 +6646,6 @@ target_link_libraries(dns_resolver_cooldown_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6701,7 +6680,6 @@ target_link_libraries(dns_resolver_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6737,7 +6715,6 @@ target_link_libraries(dualstack_socket_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6773,7 +6750,6 @@ target_link_libraries(endpoint_pair_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6808,7 +6784,6 @@ target_link_libraries(error_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6844,7 +6819,6 @@ target_link_libraries(ev_epollex_linux_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6880,7 +6854,6 @@ target_link_libraries(fake_resolver_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6917,7 +6890,6 @@ target_link_libraries(fake_transport_security_test gpr grpc_test_util grpc - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6954,7 +6926,6 @@ target_link_libraries(fd_conservation_posix_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -6991,7 +6962,6 @@ target_link_libraries(fd_posix_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7027,7 +6997,6 @@ target_link_libraries(fling_client grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7062,7 +7031,6 @@ target_link_libraries(fling_server grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7098,7 +7066,6 @@ target_link_libraries(fling_stream_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7135,7 +7102,6 @@ target_link_libraries(fling_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7172,7 +7138,6 @@ target_link_libraries(fork_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7209,7 +7174,6 @@ target_link_libraries(goaway_server_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7245,7 +7209,6 @@ target_link_libraries(gpr_cpu_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7280,7 +7243,6 @@ target_link_libraries(gpr_env_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7315,7 +7277,6 @@ target_link_libraries(gpr_host_port_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7350,7 +7311,6 @@ target_link_libraries(gpr_log_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7385,7 +7345,6 @@ target_link_libraries(gpr_manual_constructor_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7420,7 +7379,6 @@ target_link_libraries(gpr_mpscq_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7455,7 +7413,6 @@ target_link_libraries(gpr_spinlock_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7490,7 +7447,6 @@ target_link_libraries(gpr_string_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7525,7 +7481,6 @@ target_link_libraries(gpr_sync_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7560,7 +7515,6 @@ target_link_libraries(gpr_thd_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7595,7 +7549,6 @@ target_link_libraries(gpr_time_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7630,7 +7583,6 @@ target_link_libraries(gpr_tls_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7665,7 +7617,6 @@ target_link_libraries(gpr_useful_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7700,7 +7651,6 @@ target_link_libraries(grpc_auth_context_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7735,7 +7685,6 @@ target_link_libraries(grpc_b64_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7770,7 +7719,6 @@ target_link_libraries(grpc_byte_buffer_reader_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7805,7 +7753,6 @@ target_link_libraries(grpc_channel_args_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7840,7 +7787,6 @@ target_link_libraries(grpc_channel_stack_builder_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7875,7 +7821,6 @@ target_link_libraries(grpc_channel_stack_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7910,7 +7855,6 @@ target_link_libraries(grpc_completion_queue_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -7945,7 +7889,6 @@ target_link_libraries(grpc_completion_queue_threading_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8013,7 +7956,6 @@ target_link_libraries(grpc_credentials_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8048,7 +7990,6 @@ target_link_libraries(grpc_fetch_oauth2 grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8083,7 +8024,6 @@ target_link_libraries(grpc_ipv6_loopback_available_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8119,7 +8059,6 @@ target_link_libraries(grpc_json_token_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8155,7 +8094,6 @@ target_link_libraries(grpc_jwt_verifier_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8222,7 +8160,6 @@ target_link_libraries(grpc_security_connector_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8257,7 +8194,6 @@ target_link_libraries(grpc_ssl_credentials_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8326,7 +8262,6 @@ target_link_libraries(handshake_client_ssl grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8365,7 +8300,6 @@ target_link_libraries(handshake_server_ssl grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8404,7 +8338,6 @@ target_link_libraries(handshake_server_with_readahead_handshaker grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8442,7 +8375,6 @@ target_link_libraries(handshake_verify_peer_options grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8477,7 +8409,6 @@ target_link_libraries(histogram_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8512,7 +8443,6 @@ target_link_libraries(hpack_parser_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8547,7 +8477,6 @@ target_link_libraries(hpack_table_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8582,7 +8511,6 @@ target_link_libraries(http_parser_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8617,7 +8545,6 @@ target_link_libraries(httpcli_format_request_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8653,7 +8580,6 @@ target_link_libraries(httpcli_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8690,7 +8616,6 @@ target_link_libraries(httpscli_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8726,7 +8651,6 @@ target_link_libraries(init_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8761,7 +8685,6 @@ target_link_libraries(inproc_callback_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8796,7 +8719,6 @@ target_link_libraries(invalid_call_argument_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8831,7 +8753,6 @@ target_link_libraries(json_rewrite grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8866,7 +8787,6 @@ target_link_libraries(json_rewrite_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8901,7 +8821,6 @@ target_link_libraries(json_stream_error_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8936,7 +8855,6 @@ target_link_libraries(json_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -8971,7 +8889,6 @@ target_link_libraries(lame_client_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9006,7 +8923,6 @@ target_link_libraries(load_file_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9041,7 +8957,6 @@ target_link_libraries(memory_usage_client grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9076,7 +8991,6 @@ target_link_libraries(memory_usage_server grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9112,7 +9026,6 @@ target_link_libraries(memory_usage_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9148,7 +9061,6 @@ target_link_libraries(message_compress_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9183,7 +9095,6 @@ target_link_libraries(minimal_stack_is_minimal_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9218,7 +9129,6 @@ target_link_libraries(multiple_server_queues_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9253,7 +9163,6 @@ target_link_libraries(murmur_hash_test gpr grpc_test_util_unsecure grpc_unsecure - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9288,7 +9197,6 @@ target_link_libraries(no_server_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9323,7 +9231,6 @@ target_link_libraries(num_external_connectivity_watchers_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9358,7 +9265,6 @@ target_link_libraries(parse_address_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9394,7 +9300,6 @@ target_link_libraries(parse_address_with_named_scope_id_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9430,7 +9335,6 @@ target_link_libraries(percent_encoding_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9466,7 +9370,6 @@ target_link_libraries(resolve_address_using_ares_resolver_posix_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9502,7 +9405,6 @@ target_link_libraries(resolve_address_using_ares_resolver_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9538,7 +9440,6 @@ target_link_libraries(resolve_address_using_native_resolver_posix_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9574,7 +9475,6 @@ target_link_libraries(resolve_address_using_native_resolver_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9609,7 +9509,6 @@ target_link_libraries(resource_quota_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9644,7 +9543,6 @@ target_link_libraries(secure_channel_create_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9679,7 +9577,6 @@ target_link_libraries(secure_endpoint_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9714,7 +9611,6 @@ target_link_libraries(sequential_connectivity_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9749,7 +9645,6 @@ target_link_libraries(server_chttp2_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9784,7 +9679,6 @@ target_link_libraries(server_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9819,7 +9713,6 @@ target_link_libraries(slice_buffer_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9854,7 +9747,6 @@ target_link_libraries(slice_string_helpers_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9889,7 +9781,6 @@ target_link_libraries(slice_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9924,7 +9815,6 @@ target_link_libraries(sockaddr_resolver_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9959,7 +9849,6 @@ target_link_libraries(sockaddr_utils_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -9995,7 +9884,6 @@ target_link_libraries(socket_utils_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10033,7 +9921,6 @@ target_link_libraries(ssl_transport_security_test gpr grpc_test_util grpc - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10069,7 +9956,6 @@ target_link_libraries(status_conversion_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10104,7 +9990,6 @@ target_link_libraries(stream_compression_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10139,7 +10024,6 @@ target_link_libraries(stream_owned_slice_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10175,7 +10059,6 @@ target_link_libraries(tcp_client_posix_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10211,7 +10094,6 @@ target_link_libraries(tcp_client_uv_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10247,7 +10129,6 @@ target_link_libraries(tcp_posix_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10284,7 +10165,6 @@ target_link_libraries(tcp_server_posix_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10320,7 +10200,6 @@ target_link_libraries(tcp_server_uv_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10355,7 +10234,6 @@ target_link_libraries(time_averaged_stats_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10390,7 +10268,6 @@ target_link_libraries(timeout_encoding_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10425,7 +10302,6 @@ target_link_libraries(timer_heap_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10460,7 +10336,6 @@ target_link_libraries(timer_list_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10495,7 +10370,6 @@ target_link_libraries(transport_connectivity_state_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10530,7 +10404,6 @@ target_link_libraries(transport_metadata_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10566,7 +10439,6 @@ target_link_libraries(transport_security_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10603,7 +10475,6 @@ target_link_libraries(udp_server_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -10639,7 +10510,6 @@ target_link_libraries(uri_parser_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16463,7 +16333,6 @@ target_link_libraries(public_headers_must_be_c89 ${_gRPC_ALLTARGETS_LIBRARIES} grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) @@ -16569,7 +16438,6 @@ target_link_libraries(badreq_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16606,7 +16474,6 @@ target_link_libraries(connection_prefix_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16643,7 +16510,6 @@ target_link_libraries(duplicate_header_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16680,7 +16546,6 @@ target_link_libraries(head_of_line_blocking_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16717,7 +16582,6 @@ target_link_libraries(headers_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16754,7 +16618,6 @@ target_link_libraries(initial_settings_frame_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16791,7 +16654,6 @@ target_link_libraries(large_metadata_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16828,7 +16690,6 @@ target_link_libraries(server_registered_method_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16865,7 +16726,6 @@ target_link_libraries(simple_request_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16902,7 +16762,6 @@ target_link_libraries(unknown_frame_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16939,7 +16798,6 @@ target_link_libraries(window_overflow_bad_client_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -16976,7 +16834,6 @@ target_link_libraries(bad_ssl_cert_server grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17013,7 +16870,6 @@ target_link_libraries(bad_ssl_cert_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17050,7 +16906,6 @@ target_link_libraries(h2_census_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17086,7 +16941,6 @@ target_link_libraries(h2_compress_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17122,7 +16976,6 @@ target_link_libraries(h2_fakesec_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17159,7 +17012,6 @@ target_link_libraries(h2_fd_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17196,7 +17048,6 @@ target_link_libraries(h2_full_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17233,7 +17084,6 @@ target_link_libraries(h2_full+pipe_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17270,7 +17120,6 @@ target_link_libraries(h2_full+trace_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17306,7 +17155,6 @@ target_link_libraries(h2_full+workarounds_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17342,7 +17190,6 @@ target_link_libraries(h2_http_proxy_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17379,7 +17226,6 @@ target_link_libraries(h2_local_ipv4_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17417,7 +17263,6 @@ target_link_libraries(h2_local_ipv6_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17455,7 +17300,6 @@ target_link_libraries(h2_local_uds_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17492,7 +17336,6 @@ target_link_libraries(h2_oauth2_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17528,7 +17371,6 @@ target_link_libraries(h2_proxy_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17564,7 +17406,6 @@ target_link_libraries(h2_sockpair_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17600,7 +17441,6 @@ target_link_libraries(h2_sockpair+trace_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17636,7 +17476,6 @@ target_link_libraries(h2_sockpair_1byte_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17672,7 +17511,6 @@ target_link_libraries(h2_spiffe_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17708,7 +17546,6 @@ target_link_libraries(h2_ssl_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17744,7 +17581,6 @@ target_link_libraries(h2_ssl_proxy_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17781,7 +17617,6 @@ target_link_libraries(h2_uds_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17818,7 +17653,6 @@ target_link_libraries(inproc_test grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17854,7 +17688,6 @@ target_link_libraries(h2_census_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17890,7 +17723,6 @@ target_link_libraries(h2_compress_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17927,7 +17759,6 @@ target_link_libraries(h2_fd_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -17964,7 +17795,6 @@ target_link_libraries(h2_full_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18001,7 +17831,6 @@ target_link_libraries(h2_full+pipe_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18038,7 +17867,6 @@ target_link_libraries(h2_full+trace_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18074,7 +17902,6 @@ target_link_libraries(h2_full+workarounds_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18110,7 +17937,6 @@ target_link_libraries(h2_http_proxy_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18146,7 +17972,6 @@ target_link_libraries(h2_proxy_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18182,7 +18007,6 @@ target_link_libraries(h2_sockpair_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18218,7 +18042,6 @@ target_link_libraries(h2_sockpair+trace_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18254,7 +18077,6 @@ target_link_libraries(h2_sockpair_1byte_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18291,7 +18113,6 @@ target_link_libraries(h2_uds_nosec_test grpc_test_util_unsecure grpc_unsecure gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18619,7 +18440,6 @@ target_link_libraries(alts_credentials_fuzzer_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18655,7 +18475,6 @@ target_link_libraries(api_fuzzer_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18691,7 +18510,6 @@ target_link_libraries(client_fuzzer_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18727,7 +18545,6 @@ target_link_libraries(hpack_parser_fuzzer_test_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18763,7 +18580,6 @@ target_link_libraries(http_request_fuzzer_test_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18799,7 +18615,6 @@ target_link_libraries(http_response_fuzzer_test_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18835,7 +18650,6 @@ target_link_libraries(json_fuzzer_test_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18871,7 +18685,6 @@ target_link_libraries(nanopb_fuzzer_response_test_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18907,7 +18720,6 @@ target_link_libraries(nanopb_fuzzer_serverlist_test_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18943,7 +18755,6 @@ target_link_libraries(percent_decode_fuzzer_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -18979,7 +18790,6 @@ target_link_libraries(percent_encode_fuzzer_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -19015,7 +18825,6 @@ target_link_libraries(server_fuzzer_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -19051,7 +18860,6 @@ target_link_libraries(ssl_server_fuzzer_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ @@ -19087,7 +18895,6 @@ target_link_libraries(uri_fuzzer_test_one_entry grpc_test_util grpc gpr - ${_gRPC_GFLAGS_LIBRARIES} ) # avoid dependency on libstdc++ From 2fe0d21736fbd49dbda1824f63327b4940500dff Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 14 Mar 2019 13:41:14 -0700 Subject: [PATCH 763/814] Add a new compute engine channel creds interop test case --- doc/interop-test-descriptions.md | 37 ++++++++ tools/run_tests/run_interop_tests.py | 132 +++++++++++++++++++++------ 2 files changed, 141 insertions(+), 28 deletions(-) diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md index 208af424298..f210da0b0b3 100755 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -718,6 +718,43 @@ Client asserts: * received SimpleResponse.username matches the value of `--default_service_account` +### compute_engine_channel_credentials + +Similar to the other auth tests, this test should only be run against prod +servers. Note that this test may only be ran on GCP. + +This test verifies unary calls succeed when the client uses +ComputeEngineChannelCredentials. All that is needed by the test environment +is for the client to be running on GCP. + +The test uses `--default_service_account` with GCE service account email. This +email must identify the default service account of the GCP VM that the test +is running on. + +Server features: +* [UnaryCall][] +* [Echo Authenticated Username][] + +Procedure: + 1. Client configures the channel to use ComputeEngineChannelCredentials + * Note: the term `ComputeEngineChannelCredentials` within the context + of this test description refers to an API which encapsulates + both "transport credentials" and "call credentials" and which + is capable of transport creds auto-selection (including ALTS). + The exact name of the API may vary per language. + 2. Client calls UnaryCall with: + + ``` + { + fill_username: true + } + ``` + +Client asserts: +* call was successful +* received SimpleResponse.username matches the value of + `--default_service_account` + ### custom_metadata This test verifies that custom metadata in either binary or ascii format can be diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 3fb9eda5673..6a025505910 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -71,6 +71,12 @@ _SKIP_GOOGLE_DEFAULT_CREDS = [ _GOOGLE_DEFAULT_CREDS_TEST_CASE, ] +_COMPUTE_ENGINE_CHANNEL_CREDS_TEST_CASE = 'compute_engine_channel_credentials' + +_SKIP_COMPUTE_ENGINE_CHANNEL_CREDS = [ + _COMPUTE_ENGINE_CHANNEL_CREDS_TEST_CASE, +] + _TEST_TIMEOUT = 3 * 60 # disable this test on core-based languages, @@ -106,7 +112,9 @@ class CXXLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + return _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return [] @@ -135,7 +143,11 @@ class CSharpLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS + return _SKIP_SERVER_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -164,7 +176,11 @@ class CSharpCoreCLRLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS + return _SKIP_SERVER_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -225,7 +241,10 @@ class DartLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS + return _SKIP_COMPRESSION + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION + _SKIP_SPECIAL_STATUS_MESSAGE @@ -316,7 +335,7 @@ class GoLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + return _SKIP_COMPRESSION + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -346,7 +365,11 @@ class Http2Server: return {} def unimplemented_test_cases(self): - return _TEST_CASES + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS + return _TEST_CASES + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _TEST_CASES @@ -376,7 +399,10 @@ class Http2Client: return {} def unimplemented_test_cases(self): - return _TEST_CASES + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS + return _TEST_CASES + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _TEST_CASES @@ -413,7 +439,10 @@ class NodeLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_GOOGLE_DEFAULT_CREDS + return _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -443,7 +472,10 @@ class NodePureJSLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_GOOGLE_DEFAULT_CREDS + return _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return [] @@ -468,7 +500,11 @@ class PHPLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS + return _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return [] @@ -493,7 +529,11 @@ class PHP7Language: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS + return _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return [] @@ -528,7 +568,12 @@ class ObjcLanguage: # cmdline argument. Here we return all but one test cases as unimplemented, # and depend upon ObjC test's behavior that it runs all cases even when # we tell it to run just one. - return _TEST_CASES[1:] + _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS + return _TEST_CASES[1:] + \ + _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -563,7 +608,11 @@ class RubyLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_SPECIAL_STATUS_MESSAGE + _SKIP_GOOGLE_DEFAULT_CREDS + return _SKIP_SERVER_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_SPECIAL_STATUS_MESSAGE + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -608,7 +657,10 @@ class PythonLanguage: } def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING + _SKIP_GOOGLE_DEFAULT_CREDS + return _SKIP_COMPRESSION + \ + _SKIP_DATA_FRAME_PADDING + \ + _SKIP_GOOGLE_DEFAULT_CREDS + \ + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -657,6 +709,7 @@ _AUTH_TEST_CASES = [ 'oauth2_auth_token', 'per_rpc_creds', _GOOGLE_DEFAULT_CREDS_TEST_CASE, + _COMPUTE_ENGINE_CHANNEL_CREDS_TEST_CASE, ] _HTTP2_TEST_CASES = ['tls', 'framing'] @@ -682,9 +735,7 @@ _LANGUAGES_FOR_ALTS_TEST_CASES = ['java', 'go', 'c++'] _SERVERS_FOR_ALTS_TEST_CASES = ['java', 'go', 'c++'] -_TRANSPORT_SECURITY_OPTIONS = [ - 'tls', 'alts', 'google_default_credentials', 'insecure' -] +_TRANSPORT_SECURITY_OPTIONS = ['tls', 'alts', 'insecure'] DOCKER_WORKDIR_ROOT = '/var/local/git/grpc' @@ -796,6 +847,9 @@ def auth_options(language, env['GOOGLE_APPLICATION_CREDENTIALS'] = service_account_key_file cmdargs += [default_account_arg] + if test_case == _COMPUTE_ENGINE_CHANNEL_CREDS_TEST_CASE: + cmdargs += [default_account_arg] + return (cmdargs, env) @@ -832,9 +886,15 @@ def cloud_to_prod_jobspec(language, transport_security_options = [ '--custom_credentials_type=google_default_credentials' ] + elif transport_security == 'compute_engine_channel_creds' and str( + language) in ['java', 'javaokhttp']: + transport_security_options = [ + '--custom_credentials_type=compute_engine_channel_creds' + ] else: - print('Invalid transport security option %s in cloud_to_prod_jobspec.' % - transport_security) + print( + 'Invalid transport security option %s in cloud_to_prod_jobspec. Lang: %s' + % (str(language), transport_security)) sys.exit(1) cmdargs = cmdargs + transport_security_options environ = dict(language.cloud_to_prod_env(), **language.global_env()) @@ -1367,10 +1427,8 @@ try: jobs = [] if args.cloud_to_prod: - if args.transport_security not in ['tls', 'google_default_credentials']: - print( - 'TLS or google default credential is always enabled for cloud_to_prod scenarios.' - ) + if args.transport_security not in ['tls']: + print('TLS is always enabled for cloud_to_prod scenarios.') for server_host_nickname in args.prod_servers: for language in languages: for test_case in _TEST_CASES: @@ -1407,6 +1465,23 @@ try: transport_security= 'google_default_credentials') jobs.append(google_default_creds_test_job) + if str(language) in ['java', 'javaokhttp']: + compute_engine_channel_creds_test_job = cloud_to_prod_jobspec( + language, + test_case, + server_host_nickname, + prod_servers[server_host_nickname], + google_default_creds_use_key_file=args. + google_default_creds_use_key_file, + docker_image=docker_images.get( + str(language)), + manual_cmd_log=client_manual_cmd_log, + service_account_key_file=args. + service_account_key_file, + transport_security= + 'compute_engine_channel_creds') + jobs.append( + compute_engine_channel_creds_test_job) if args.http2_interop: for test_case in _HTTP2_TEST_CASES: @@ -1424,10 +1499,8 @@ try: jobs.append(test_job) if args.cloud_to_prod_auth: - if args.transport_security not in ['tls', 'google_default_credentials']: - print( - 'TLS or google default credential is always enabled for cloud_to_prod scenarios.' - ) + if args.transport_security not in ['tls']: + print('TLS is always enabled for cloud_to_prod scenarios.') for server_host_nickname in args.prod_servers: for language in languages: for test_case in _AUTH_TEST_CASES: @@ -1435,9 +1508,12 @@ try: not compute_engine_creds_required( language, test_case)): if not test_case in language.unimplemented_test_cases(): - transport_security = 'tls' if test_case == _GOOGLE_DEFAULT_CREDS_TEST_CASE: transport_security = 'google_default_credentials' + elif test_case == _COMPUTE_ENGINE_CHANNEL_CREDS_TEST_CASE: + transport_security = 'compute_engine_channel_creds' + else: + transport_security = 'tls' test_job = cloud_to_prod_jobspec( language, test_case, From 0a5113093689d0d4101a876566f9a1381846cdba Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 21 Mar 2019 15:35:29 -0700 Subject: [PATCH 764/814] revert the changes in ssl_security_connector --- .../ssl/ssl_security_connector.cc | 258 ++++++++++++------ 1 file changed, 175 insertions(+), 83 deletions(-) diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index fbf59d23b9d..7158290b6b4 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -1,21 +1,3 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - #include #include "src/core/lib/security/security_connector/ssl/ssl_security_connector.h" @@ -41,6 +23,33 @@ #include "src/core/tsi/transport_security.h" namespace { +grpc_error* ssl_check_peer( + const char* peer_name, const tsi_peer* peer, + grpc_core::RefCountedPtr* auth_context) { +#if TSI_OPENSSL_ALPN_SUPPORT + /* Check the ALPN if ALPN is supported. */ + const tsi_peer_property* p = + tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); + if (p == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing selected ALPN property."); + } + if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: invalid ALPN value."); + } +#endif /* TSI_OPENSSL_ALPN_SUPPORT */ + /* Check the peer name if specified. */ + if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { + char* msg; + gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name); + grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + return error; + } + *auth_context = grpc_ssl_peer_to_auth_context(peer); + return GRPC_ERROR_NONE; +} class grpc_ssl_channel_security_connector final : public grpc_channel_security_connector { @@ -69,10 +78,34 @@ class grpc_ssl_channel_security_connector final } grpc_security_status InitializeHandshakerFactory( - const grpc_ssl_config* config, tsi_ssl_session_cache* ssl_session_cache) { - return grpc_ssl_tsi_client_handshaker_factory_init( - config->pem_key_cert_pair, config->pem_root_certs, ssl_session_cache, - &client_handshaker_factory_); + const grpc_ssl_config* config, const char* pem_root_certs, + const tsi_ssl_root_certs_store* root_store, + tsi_ssl_session_cache* ssl_session_cache) { + bool has_key_cert_pair = + config->pem_key_cert_pair != nullptr && + config->pem_key_cert_pair->private_key != nullptr && + config->pem_key_cert_pair->cert_chain != nullptr; + tsi_ssl_client_handshaker_options options; + GPR_DEBUG_ASSERT(pem_root_certs != nullptr); + options.pem_root_certs = pem_root_certs; + options.root_store = root_store; + options.alpn_protocols = + grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); + if (has_key_cert_pair) { + options.pem_key_cert_pair = config->pem_key_cert_pair; + } + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.session_cache = ssl_session_cache; + const tsi_result result = + tsi_create_ssl_client_handshaker_factory_with_options( + &options, &client_handshaker_factory_); + gpr_free((void*)options.alpn_protocols); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return GRPC_SECURITY_ERROR; + } + return GRPC_SECURITY_OK; } void add_handshakers(grpc_pollset_set* interested_parties, @@ -99,35 +132,29 @@ class grpc_ssl_channel_security_connector final const char* target_name = overridden_target_name_ != nullptr ? overridden_target_name_ : target_name_; - grpc_error* error = grpc_ssl_check_alpn(&peer); - if (error == GRPC_ERROR_NONE) { - error = grpc_ssl_check_peer_name(target_name, &peer); - if (error == GRPC_ERROR_NONE) { - if (verify_options_->verify_peer_callback != nullptr) { - const tsi_peer_property* p = - tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); - if (p == nullptr) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: missing pem cert property."); - } else { - char* peer_pem = - static_cast(gpr_malloc(p->value.length + 1)); - memcpy(peer_pem, p->value.data, p->value.length); - peer_pem[p->value.length] = '\0'; - int callback_status = verify_options_->verify_peer_callback( - target_name, peer_pem, - verify_options_->verify_peer_callback_userdata); - gpr_free(peer_pem); - if (callback_status) { - char* msg; - gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", - callback_status); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); - } - } + grpc_error* error = ssl_check_peer(target_name, &peer, auth_context); + if (error == GRPC_ERROR_NONE && + verify_options_->verify_peer_callback != nullptr) { + const tsi_peer_property* p = + tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); + if (p == nullptr) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing pem cert property."); + } else { + char* peer_pem = static_cast(gpr_malloc(p->value.length + 1)); + memcpy(peer_pem, p->value.data, p->value.length); + peer_pem[p->value.length] = '\0'; + int callback_status = verify_options_->verify_peer_callback( + target_name, peer_pem, + verify_options_->verify_peer_callback_userdata); + gpr_free(peer_pem); + if (callback_status) { + char* msg; + gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", + callback_status); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); } - *auth_context = grpc_ssl_peer_to_auth_context(&peer); } } GRPC_CLOSURE_SCHED(on_peer_checked, error); @@ -139,16 +166,34 @@ class grpc_ssl_channel_security_connector final reinterpret_cast(other_sc); int c = channel_security_connector_cmp(other); if (c != 0) return c; - return grpc_ssl_cmp_target_name(target_name_, other->target_name_, - overridden_target_name_, - other->overridden_target_name_); + c = strcmp(target_name_, other->target_name_); + if (c != 0) return c; + return (overridden_target_name_ == nullptr || + other->overridden_target_name_ == nullptr) + ? GPR_ICMP(overridden_target_name_, + other->overridden_target_name_) + : strcmp(overridden_target_name_, + other->overridden_target_name_); } bool check_call_host(const char* host, grpc_auth_context* auth_context, grpc_closure* on_call_host_checked, grpc_error** error) override { - return grpc_ssl_check_call_host(host, target_name_, overridden_target_name_, - auth_context, on_call_host_checked, error); + grpc_security_status status = GRPC_SECURITY_ERROR; + tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); + if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; + /* If the target name was overridden, then the original target_name was + 'checked' transitively during the previous peer check at the end of the + handshake. */ + if (overridden_target_name_ != nullptr && strcmp(host, target_name_) == 0) { + status = GRPC_SECURITY_OK; + } + if (status != GRPC_SECURITY_OK) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "call host does not match SSL server name"); + } + grpc_shallow_peer_destruct(&peer); + return true; } void cancel_check_call_host(grpc_closure* on_call_host_checked, @@ -185,25 +230,43 @@ class grpc_ssl_server_security_connector } grpc_security_status InitializeHandshakerFactory() { - grpc_security_status retval = GRPC_SECURITY_OK; if (has_cert_config_fetcher()) { // Load initial credentials from certificate_config_fetcher: if (!try_fetch_ssl_server_credentials()) { gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher."); - retval = GRPC_SECURITY_ERROR; + return GRPC_SECURITY_ERROR; } } else { auto* server_credentials = static_cast(server_creds()); - retval = grpc_ssl_tsi_server_handshaker_factory_init( - server_credentials->config().pem_key_cert_pairs, - server_credentials->config().num_key_cert_pairs, - server_credentials->config().pem_root_certs, - server_credentials->config().client_certificate_request, - &server_handshaker_factory_); + size_t num_alpn_protocols = 0; + const char** alpn_protocol_strings = + grpc_fill_alpn_protocol_strings(&num_alpn_protocols); + tsi_ssl_server_handshaker_options options; + options.pem_key_cert_pairs = + server_credentials->config().pem_key_cert_pairs; + options.num_key_cert_pairs = + server_credentials->config().num_key_cert_pairs; + options.pem_client_root_certs = + server_credentials->config().pem_root_certs; + options.client_certificate_request = + grpc_get_tsi_client_certificate_request_type( + server_credentials->config().client_certificate_request); + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.alpn_protocols = alpn_protocol_strings; + options.num_alpn_protocols = static_cast(num_alpn_protocols); + const tsi_result result = + tsi_create_ssl_server_handshaker_factory_with_options( + &options, &server_handshaker_factory_); + gpr_free((void*)alpn_protocol_strings); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return GRPC_SECURITY_ERROR; + } } - return retval; + return GRPC_SECURITY_OK; } void add_handshakers(grpc_pollset_set* interested_parties, @@ -225,8 +288,7 @@ class grpc_ssl_server_security_connector void check_peer(tsi_peer peer, grpc_endpoint* ep, grpc_core::RefCountedPtr* auth_context, grpc_closure* on_peer_checked) override { - grpc_error* error = grpc_ssl_check_alpn(&peer); - *auth_context = grpc_ssl_peer_to_auth_context(&peer); + grpc_error* error = ssl_check_peer(nullptr, &peer, auth_context); tsi_peer_destruct(&peer); GRPC_CLOSURE_SCHED(on_peer_checked, error); } @@ -243,7 +305,9 @@ class grpc_ssl_server_security_connector bool try_fetch_ssl_server_credentials() { grpc_ssl_server_certificate_config* certificate_config = nullptr; bool status; + if (!has_cert_config_fetcher()) return false; + grpc_ssl_server_credentials* server_creds = static_cast(this->mutable_server_creds()); grpc_ssl_certificate_config_reload_status cb_result = @@ -260,6 +324,7 @@ class grpc_ssl_server_security_connector "use previously-loaded credentials."); status = false; } + if (certificate_config != nullptr) { grpc_ssl_server_certificate_config_destroy(certificate_config); } @@ -278,18 +343,34 @@ class grpc_ssl_server_security_connector "config."); return false; } - tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = - grpc_convert_grpc_to_tsi_cert_pairs(config->pem_key_cert_pairs, - config->num_key_cert_pairs); - const grpc_ssl_server_credentials* server_credentials = - static_cast(this->server_creds()); + gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config); + + size_t num_alpn_protocols = 0; + const char** alpn_protocol_strings = + grpc_fill_alpn_protocol_strings(&num_alpn_protocols); tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; - grpc_security_status retval = grpc_ssl_tsi_server_handshaker_factory_init( - pem_key_cert_pairs, config->num_key_cert_pairs, config->pem_root_certs, - server_credentials->config().client_certificate_request, - &new_handshaker_factory); - gpr_free(pem_key_cert_pairs); - if (retval != GRPC_SECURITY_OK) { + const grpc_ssl_server_credentials* server_creds = + static_cast(this->server_creds()); + GPR_DEBUG_ASSERT(config->pem_root_certs != nullptr); + tsi_ssl_server_handshaker_options options; + options.pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( + config->pem_key_cert_pairs, config->num_key_cert_pairs); + options.num_key_cert_pairs = config->num_key_cert_pairs; + options.pem_client_root_certs = config->pem_root_certs; + options.client_certificate_request = + grpc_get_tsi_client_certificate_request_type( + server_creds->config().client_certificate_request); + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.alpn_protocols = alpn_protocol_strings; + options.num_alpn_protocols = static_cast(num_alpn_protocols); + tsi_result result = tsi_create_ssl_server_handshaker_factory_with_options( + &options, &new_handshaker_factory); + gpr_free((void*)options.pem_key_cert_pairs); + gpr_free((void*)alpn_protocol_strings); + + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); return false; } set_server_handshaker_factory(new_handshaker_factory); @@ -319,17 +400,28 @@ grpc_ssl_channel_security_connector_create( gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); return nullptr; } - if (config->pem_root_certs == nullptr && - grpc_core::DefaultSslRootStore::GetPemRootCerts() == nullptr) { - gpr_log(GPR_ERROR, "Could not get pem root certs."); - return nullptr; + + const char* pem_root_certs; + const tsi_ssl_root_certs_store* root_store; + if (config->pem_root_certs == nullptr) { + // Use default root certificates. + pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); + if (pem_root_certs == nullptr) { + gpr_log(GPR_ERROR, "Could not get default pem root certs."); + return nullptr; + } + root_store = grpc_core::DefaultSslRootStore::GetRootStore(); + } else { + pem_root_certs = config->pem_root_certs; + root_store = nullptr; } + grpc_core::RefCountedPtr c = grpc_core::MakeRefCounted( std::move(channel_creds), std::move(request_metadata_creds), config, target_name, overridden_target_name); - const grpc_security_status result = - c->InitializeHandshakerFactory(config, ssl_session_cache); + const grpc_security_status result = c->InitializeHandshakerFactory( + config, pem_root_certs, root_store, ssl_session_cache); if (result != GRPC_SECURITY_OK) { return nullptr; } From f022233c4dec5bcbec0cc0c5b29af5ed74550779 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 21 Mar 2019 16:01:57 -0700 Subject: [PATCH 765/814] fix sanity check --- .../ssl/ssl_security_connector.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index 7158290b6b4..8a00bbb82ed 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -1,3 +1,21 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + #include #include "src/core/lib/security/security_connector/ssl/ssl_security_connector.h" From a176a07c02e0f606993fa871ebd2b79a894a97cc Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Thu, 21 Mar 2019 16:38:16 -0700 Subject: [PATCH 766/814] revert the SSL TSI changes --- src/core/tsi/ssl_transport_security.cc | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 0d7c7443b08..cbdb4227b31 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -344,24 +344,18 @@ static tsi_result add_subject_alt_names_properties_to_peer( size_t subject_alt_name_count) { size_t i; tsi_result result = TSI_OK; + /* Reset for DNS entries filtering. */ peer->property_count -= subject_alt_name_count; + for (i = 0; i < subject_alt_name_count; i++) { GENERAL_NAME* subject_alt_name = sk_GENERAL_NAME_value(subject_alt_names, TSI_SIZE_AS_SIZE(i)); - if (subject_alt_name->type == GEN_DNS || - subject_alt_name->type == GEN_EMAIL || - subject_alt_name->type == GEN_URI) { + /* Filter out the non-dns entries names. */ + if (subject_alt_name->type == GEN_DNS) { unsigned char* name = nullptr; int name_size; - if (subject_alt_name->type == GEN_DNS) { - name_size = ASN1_STRING_to_UTF8(&name, subject_alt_name->d.dNSName); - } else if (subject_alt_name->type == GEN_EMAIL) { - name_size = ASN1_STRING_to_UTF8(&name, subject_alt_name->d.rfc822Name); - } else { - name_size = ASN1_STRING_to_UTF8( - &name, subject_alt_name->d.uniformResourceIdentifier); - } + name_size = ASN1_STRING_to_UTF8(&name, subject_alt_name->d.dNSName); if (name_size < 0) { gpr_log(GPR_ERROR, "Could not get utf8 from asn1 string."); result = TSI_INTERNAL_ERROR; @@ -375,6 +369,7 @@ static tsi_result add_subject_alt_names_properties_to_peer( } else if (subject_alt_name->type == GEN_IPADD) { char ntop_buf[INET6_ADDRSTRLEN]; int af; + if (subject_alt_name->d.iPAddress->length == 4) { af = AF_INET; } else if (subject_alt_name->d.iPAddress->length == 16) { @@ -391,6 +386,7 @@ static tsi_result add_subject_alt_names_properties_to_peer( result = TSI_INTERNAL_ERROR; break; } + result = tsi_construct_string_peer_property_from_cstring( TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, name, &peer->properties[peer->property_count++]); From fb15daf8b9896fd62f6d3444d3e14e90ffe0b9e0 Mon Sep 17 00:00:00 2001 From: Vishal Powar Date: Mon, 18 Mar 2019 16:56:07 -0700 Subject: [PATCH 767/814] Add generated upb code for endpoints information. Also, - Update upb submodule for new code generator and update generated files. --- BUILD | 6 + .../envoy/api/v2/core/address.upb.h | 15 +- .../envoy/api/v2/core/base.upb.h | 19 +- .../envoy/api/v2/core/health_check.upb.h | 13 +- .../envoy/api/v2/discovery.upb.h | 5 +- .../ext/upb-generated/envoy/api/v2/eds.upb.c | 71 ++++++ .../ext/upb-generated/envoy/api/v2/eds.upb.h | 171 +++++++++++++ .../envoy/api/v2/endpoint/endpoint.upb.c | 86 +++++++ .../envoy/api/v2/endpoint/endpoint.upb.h | 234 ++++++++++++++++++ .../envoy/service/discovery/v2/ads.upb.c | 23 ++ .../envoy/service/discovery/v2/ads.upb.h | 52 ++++ .../upb-generated/envoy/type/percent.upb.h | 7 +- .../ext/upb-generated/envoy/type/range.upb.h | 1 + .../ext/upb-generated/gogoproto/gogo.upb.h | 1 + .../google/api/annotations.upb.h | 1 + .../ext/upb-generated/google/api/http.upb.h | 1 + .../upb-generated/google/protobuf/any.upb.h | 1 + .../google/protobuf/descriptor.upb.h | 37 +-- .../google/protobuf/duration.upb.h | 1 + .../google/protobuf/struct.upb.h | 7 +- .../google/protobuf/timestamp.upb.h | 1 + .../google/protobuf/wrappers.upb.h | 1 + .../ext/upb-generated/google/rpc/status.upb.h | 1 + .../ext/upb-generated/validate/validate.upb.h | 1 + third_party/upb | 2 +- tools/codegen/core/gen_upb_api.sh | 3 +- tools/run_tests/sanity/check_submodules.sh | 2 +- 27 files changed, 712 insertions(+), 51 deletions(-) create mode 100644 src/core/ext/upb-generated/envoy/api/v2/eds.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/eds.upb.h create mode 100644 src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h create mode 100644 src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c create mode 100644 src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h diff --git a/BUILD b/BUILD index 9e052dcf0c2..a92a9270675 100644 --- a/BUILD +++ b/BUILD @@ -2319,12 +2319,18 @@ grpc_cc_library( "src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c", "src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c", "src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/eds.upb.c", + "src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c", ], hdrs = [ "src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h", "src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h", "src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h", "src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/eds.upb.h", + "src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h", ], language = "c++", external_deps = [ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h index be9e8312b70..8e0f8a28656 100644 --- a/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h +++ b/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h @@ -38,12 +38,12 @@ extern const upb_msglayout envoy_api_v2_core_TcpKeepalive_msginit; extern const upb_msglayout envoy_api_v2_core_BindConfig_msginit; extern const upb_msglayout envoy_api_v2_core_Address_msginit; extern const upb_msglayout envoy_api_v2_core_CidrRange_msginit; -struct google_protobuf_UInt32Value; -struct google_protobuf_BoolValue; struct envoy_api_v2_core_SocketOption; -extern const upb_msglayout google_protobuf_UInt32Value_msginit; -extern const upb_msglayout google_protobuf_BoolValue_msginit; +struct google_protobuf_BoolValue; +struct google_protobuf_UInt32Value; extern const upb_msglayout envoy_api_v2_core_SocketOption_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; /* Enums */ @@ -52,6 +52,7 @@ typedef enum { envoy_api_v2_core_SocketAddress_UDP = 1 } envoy_api_v2_core_SocketAddress_Protocol; + /* envoy.api.v2.core.Pipe */ UPB_INLINE envoy_api_v2_core_Pipe *envoy_api_v2_core_Pipe_new(upb_arena *arena) { @@ -92,7 +93,7 @@ typedef enum { } envoy_api_v2_core_SocketAddress_port_specifier_oneofcases; UPB_INLINE envoy_api_v2_core_SocketAddress_port_specifier_oneofcases envoy_api_v2_core_SocketAddress_port_specifier_case(const envoy_api_v2_core_SocketAddress* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(36, 64)); } -UPB_INLINE envoy_api_v2_core_SocketAddress_Protocol envoy_api_v2_core_SocketAddress_protocol(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, envoy_api_v2_core_SocketAddress_Protocol, UPB_SIZE(0, 0)); } +UPB_INLINE int32_t envoy_api_v2_core_SocketAddress_protocol(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } UPB_INLINE upb_strview envoy_api_v2_core_SocketAddress_address(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)); } UPB_INLINE bool envoy_api_v2_core_SocketAddress_has_port_value(const envoy_api_v2_core_SocketAddress *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(36, 64), 3); } UPB_INLINE uint32_t envoy_api_v2_core_SocketAddress_port_value(const envoy_api_v2_core_SocketAddress *msg) { return UPB_READ_ONEOF(msg, uint32_t, UPB_SIZE(28, 48), UPB_SIZE(36, 64), 3, 0); } @@ -101,8 +102,8 @@ UPB_INLINE upb_strview envoy_api_v2_core_SocketAddress_named_port(const envoy_ap UPB_INLINE upb_strview envoy_api_v2_core_SocketAddress_resolver_name(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 32)); } UPB_INLINE bool envoy_api_v2_core_SocketAddress_ipv4_compat(const envoy_api_v2_core_SocketAddress *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)); } -UPB_INLINE void envoy_api_v2_core_SocketAddress_set_protocol(envoy_api_v2_core_SocketAddress *msg, envoy_api_v2_core_SocketAddress_Protocol value) { - UPB_FIELD_AT(msg, envoy_api_v2_core_SocketAddress_Protocol, UPB_SIZE(0, 0)) = value; +UPB_INLINE void envoy_api_v2_core_SocketAddress_set_protocol(envoy_api_v2_core_SocketAddress *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; } UPB_INLINE void envoy_api_v2_core_SocketAddress_set_address(envoy_api_v2_core_SocketAddress *msg, upb_strview value) { UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)) = value; diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h index e630d1d53ca..41d0dd096ac 100644 --- a/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h +++ b/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h @@ -53,14 +53,14 @@ extern const upb_msglayout envoy_api_v2_core_DataSource_msginit; extern const upb_msglayout envoy_api_v2_core_TransportSocket_msginit; extern const upb_msglayout envoy_api_v2_core_SocketOption_msginit; extern const upb_msglayout envoy_api_v2_core_RuntimeFractionalPercent_msginit; -struct google_protobuf_Any; -struct google_protobuf_Struct; -struct google_protobuf_BoolValue; struct envoy_type_FractionalPercent; -extern const upb_msglayout google_protobuf_Any_msginit; -extern const upb_msglayout google_protobuf_Struct_msginit; -extern const upb_msglayout google_protobuf_BoolValue_msginit; +struct google_protobuf_Any; +struct google_protobuf_BoolValue; +struct google_protobuf_Struct; extern const upb_msglayout envoy_type_FractionalPercent_msginit; +extern const upb_msglayout google_protobuf_Any_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_Struct_msginit; /* Enums */ @@ -87,6 +87,7 @@ typedef enum { envoy_api_v2_core_SocketOption_STATE_LISTENING = 2 } envoy_api_v2_core_SocketOption_SocketState; + /* envoy.api.v2.core.Locality */ UPB_INLINE envoy_api_v2_core_Locality *envoy_api_v2_core_Locality_new(upb_arena *arena) { @@ -443,7 +444,7 @@ UPB_INLINE bool envoy_api_v2_core_SocketOption_has_int_value(const envoy_api_v2_ UPB_INLINE int64_t envoy_api_v2_core_SocketOption_int_value(const envoy_api_v2_core_SocketOption *msg) { return UPB_READ_ONEOF(msg, int64_t, UPB_SIZE(32, 40), UPB_SIZE(40, 56), 4, 0); } UPB_INLINE bool envoy_api_v2_core_SocketOption_has_buf_value(const envoy_api_v2_core_SocketOption *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(40, 56), 5); } UPB_INLINE upb_strview envoy_api_v2_core_SocketOption_buf_value(const envoy_api_v2_core_SocketOption *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(32, 40), UPB_SIZE(40, 56), 5, upb_strview_make("", strlen(""))); } -UPB_INLINE envoy_api_v2_core_SocketOption_SocketState envoy_api_v2_core_SocketOption_state(const envoy_api_v2_core_SocketOption *msg) { return UPB_FIELD_AT(msg, envoy_api_v2_core_SocketOption_SocketState, UPB_SIZE(16, 16)); } +UPB_INLINE int32_t envoy_api_v2_core_SocketOption_state(const envoy_api_v2_core_SocketOption *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } UPB_INLINE void envoy_api_v2_core_SocketOption_set_description(envoy_api_v2_core_SocketOption *msg, upb_strview value) { UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(24, 24)) = value; @@ -460,8 +461,8 @@ UPB_INLINE void envoy_api_v2_core_SocketOption_set_int_value(envoy_api_v2_core_S UPB_INLINE void envoy_api_v2_core_SocketOption_set_buf_value(envoy_api_v2_core_SocketOption *msg, upb_strview value) { UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(32, 40), value, UPB_SIZE(40, 56), 5); } -UPB_INLINE void envoy_api_v2_core_SocketOption_set_state(envoy_api_v2_core_SocketOption *msg, envoy_api_v2_core_SocketOption_SocketState value) { - UPB_FIELD_AT(msg, envoy_api_v2_core_SocketOption_SocketState, UPB_SIZE(16, 16)) = value; +UPB_INLINE void envoy_api_v2_core_SocketOption_set_state(envoy_api_v2_core_SocketOption *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; } diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h index d788fea61c6..7db04bf3e73 100644 --- a/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h +++ b/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h @@ -41,18 +41,18 @@ extern const upb_msglayout envoy_api_v2_core_HealthCheck_TcpHealthCheck_msginit; extern const upb_msglayout envoy_api_v2_core_HealthCheck_RedisHealthCheck_msginit; extern const upb_msglayout envoy_api_v2_core_HealthCheck_GrpcHealthCheck_msginit; extern const upb_msglayout envoy_api_v2_core_HealthCheck_CustomHealthCheck_msginit; +struct envoy_api_v2_core_HeaderValueOption; struct google_protobuf_Any; -struct google_protobuf_Struct; -struct google_protobuf_UInt32Value; struct google_protobuf_BoolValue; struct google_protobuf_Duration; -struct envoy_api_v2_core_HeaderValueOption; +struct google_protobuf_Struct; +struct google_protobuf_UInt32Value; +extern const upb_msglayout envoy_api_v2_core_HeaderValueOption_msginit; extern const upb_msglayout google_protobuf_Any_msginit; -extern const upb_msglayout google_protobuf_Struct_msginit; -extern const upb_msglayout google_protobuf_UInt32Value_msginit; extern const upb_msglayout google_protobuf_BoolValue_msginit; extern const upb_msglayout google_protobuf_Duration_msginit; -extern const upb_msglayout envoy_api_v2_core_HeaderValueOption_msginit; +extern const upb_msglayout google_protobuf_Struct_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; /* Enums */ @@ -64,6 +64,7 @@ typedef enum { envoy_api_v2_core_TIMEOUT = 4 } envoy_api_v2_core_HealthStatus; + /* envoy.api.v2.core.HealthCheck */ UPB_INLINE envoy_api_v2_core_HealthCheck *envoy_api_v2_core_HealthCheck_new(upb_arena *arena) { diff --git a/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h b/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h index a437ebaad5c..7044ea956bf 100644 --- a/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h +++ b/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h @@ -38,15 +38,16 @@ extern const upb_msglayout envoy_api_v2_IncrementalDiscoveryRequest_msginit; extern const upb_msglayout envoy_api_v2_IncrementalDiscoveryRequest_InitialResourceVersionsEntry_msginit; extern const upb_msglayout envoy_api_v2_IncrementalDiscoveryResponse_msginit; extern const upb_msglayout envoy_api_v2_Resource_msginit; -struct google_protobuf_Any; struct envoy_api_v2_core_Node; +struct google_protobuf_Any; struct google_rpc_Status; -extern const upb_msglayout google_protobuf_Any_msginit; extern const upb_msglayout envoy_api_v2_core_Node_msginit; +extern const upb_msglayout google_protobuf_Any_msginit; extern const upb_msglayout google_rpc_Status_msginit; /* Enums */ + /* envoy.api.v2.DiscoveryRequest */ UPB_INLINE envoy_api_v2_DiscoveryRequest *envoy_api_v2_DiscoveryRequest_new(upb_arena *arena) { diff --git a/src/core/ext/upb-generated/envoy/api/v2/eds.upb.c b/src/core/ext/upb-generated/envoy/api/v2/eds.upb.c new file mode 100644 index 00000000000..d6f074b0879 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/eds.upb.c @@ -0,0 +1,71 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/eds.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/eds.upb.h" +#include "envoy/api/v2/discovery.upb.h" +#include "envoy/api/v2/endpoint/endpoint.upb.h" +#include "envoy/type/percent.upb.h" +#include "google/api/annotations.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" +#include "google/protobuf/wrappers.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_ClusterLoadAssignment_submsgs[2] = { + &envoy_api_v2_ClusterLoadAssignment_Policy_msginit, + &envoy_api_v2_endpoint_LocalityLbEndpoints_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_ClusterLoadAssignment__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(12, 24), 0, 1, 11, 3}, + {4, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_ClusterLoadAssignment_msginit = { + &envoy_api_v2_ClusterLoadAssignment_submsgs[0], + &envoy_api_v2_ClusterLoadAssignment__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_ClusterLoadAssignment_Policy_submsgs[2] = { + &envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_ClusterLoadAssignment_Policy__fields[2] = { + {2, UPB_SIZE(4, 8), 0, 0, 11, 3}, + {3, UPB_SIZE(0, 0), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_ClusterLoadAssignment_Policy_msginit = { + &envoy_api_v2_ClusterLoadAssignment_Policy_submsgs[0], + &envoy_api_v2_ClusterLoadAssignment_Policy__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_submsgs[1] = { + &envoy_type_FractionalPercent_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit = { + &envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_submsgs[0], + &envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/eds.upb.h b/src/core/ext/upb-generated/envoy/api/v2/eds.upb.h new file mode 100644 index 00000000000..a9b6f5f9c3d --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/eds.upb.h @@ -0,0 +1,171 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/eds.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_EDS_PROTO_UPB_H_ +#define ENVOY_API_V2_EDS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_ClusterLoadAssignment; +struct envoy_api_v2_ClusterLoadAssignment_Policy; +struct envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload; +typedef struct envoy_api_v2_ClusterLoadAssignment envoy_api_v2_ClusterLoadAssignment; +typedef struct envoy_api_v2_ClusterLoadAssignment_Policy envoy_api_v2_ClusterLoadAssignment_Policy; +typedef struct envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload; +extern const upb_msglayout envoy_api_v2_ClusterLoadAssignment_msginit; +extern const upb_msglayout envoy_api_v2_ClusterLoadAssignment_Policy_msginit; +extern const upb_msglayout envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit; +struct envoy_api_v2_endpoint_LocalityLbEndpoints; +struct envoy_type_FractionalPercent; +struct google_protobuf_UInt32Value; +extern const upb_msglayout envoy_api_v2_endpoint_LocalityLbEndpoints_msginit; +extern const upb_msglayout envoy_type_FractionalPercent_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + + +/* envoy.api.v2.ClusterLoadAssignment */ + +UPB_INLINE envoy_api_v2_ClusterLoadAssignment *envoy_api_v2_ClusterLoadAssignment_new(upb_arena *arena) { + return (envoy_api_v2_ClusterLoadAssignment *)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_msginit, arena); +} +UPB_INLINE envoy_api_v2_ClusterLoadAssignment *envoy_api_v2_ClusterLoadAssignment_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_ClusterLoadAssignment *ret = envoy_api_v2_ClusterLoadAssignment_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_ClusterLoadAssignment_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_ClusterLoadAssignment_serialize(const envoy_api_v2_ClusterLoadAssignment *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_ClusterLoadAssignment_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_ClusterLoadAssignment_cluster_name(const envoy_api_v2_ClusterLoadAssignment *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_endpoint_LocalityLbEndpoints* const* envoy_api_v2_ClusterLoadAssignment_endpoints(const envoy_api_v2_ClusterLoadAssignment *msg, size_t *len) { return (const struct envoy_api_v2_endpoint_LocalityLbEndpoints* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); } +UPB_INLINE const envoy_api_v2_ClusterLoadAssignment_Policy* envoy_api_v2_ClusterLoadAssignment_policy(const envoy_api_v2_ClusterLoadAssignment *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_ClusterLoadAssignment_Policy*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_ClusterLoadAssignment_set_cluster_name(envoy_api_v2_ClusterLoadAssignment *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_endpoint_LocalityLbEndpoints** envoy_api_v2_ClusterLoadAssignment_mutable_endpoints(envoy_api_v2_ClusterLoadAssignment *msg, size_t *len) { + return (struct envoy_api_v2_endpoint_LocalityLbEndpoints**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len); +} +UPB_INLINE struct envoy_api_v2_endpoint_LocalityLbEndpoints** envoy_api_v2_ClusterLoadAssignment_resize_endpoints(envoy_api_v2_ClusterLoadAssignment *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_endpoint_LocalityLbEndpoints**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_endpoint_LocalityLbEndpoints* envoy_api_v2_ClusterLoadAssignment_add_endpoints(envoy_api_v2_ClusterLoadAssignment *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_LocalityLbEndpoints* sub = (struct envoy_api_v2_endpoint_LocalityLbEndpoints*)upb_msg_new(&envoy_api_v2_endpoint_LocalityLbEndpoints_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_ClusterLoadAssignment_set_policy(envoy_api_v2_ClusterLoadAssignment *msg, envoy_api_v2_ClusterLoadAssignment_Policy* value) { + UPB_FIELD_AT(msg, envoy_api_v2_ClusterLoadAssignment_Policy*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_ClusterLoadAssignment_Policy* envoy_api_v2_ClusterLoadAssignment_mutable_policy(envoy_api_v2_ClusterLoadAssignment *msg, upb_arena *arena) { + struct envoy_api_v2_ClusterLoadAssignment_Policy* sub = (struct envoy_api_v2_ClusterLoadAssignment_Policy*)envoy_api_v2_ClusterLoadAssignment_policy(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_ClusterLoadAssignment_Policy*)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_Policy_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_ClusterLoadAssignment_set_policy(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.ClusterLoadAssignment.Policy */ + +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy *envoy_api_v2_ClusterLoadAssignment_Policy_new(upb_arena *arena) { + return (envoy_api_v2_ClusterLoadAssignment_Policy *)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_Policy_msginit, arena); +} +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy *envoy_api_v2_ClusterLoadAssignment_Policy_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_ClusterLoadAssignment_Policy *ret = envoy_api_v2_ClusterLoadAssignment_Policy_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_ClusterLoadAssignment_Policy_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_ClusterLoadAssignment_Policy_serialize(const envoy_api_v2_ClusterLoadAssignment_Policy *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_ClusterLoadAssignment_Policy_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* const* envoy_api_v2_ClusterLoadAssignment_Policy_drop_overloads(const envoy_api_v2_ClusterLoadAssignment_Policy *msg, size_t *len) { return (const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_ClusterLoadAssignment_Policy_overprovisioning_factor(const envoy_api_v2_ClusterLoadAssignment_Policy *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)); } + +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload** envoy_api_v2_ClusterLoadAssignment_Policy_mutable_drop_overloads(envoy_api_v2_ClusterLoadAssignment_Policy *msg, size_t *len) { + return (envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload** envoy_api_v2_ClusterLoadAssignment_Policy_resize_drop_overloads(envoy_api_v2_ClusterLoadAssignment_Policy *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* envoy_api_v2_ClusterLoadAssignment_Policy_add_drop_overloads(envoy_api_v2_ClusterLoadAssignment_Policy *msg, upb_arena *arena) { + struct envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* sub = (struct envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload*)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_ClusterLoadAssignment_Policy_set_overprovisioning_factor(envoy_api_v2_ClusterLoadAssignment_Policy *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_ClusterLoadAssignment_Policy_mutable_overprovisioning_factor(envoy_api_v2_ClusterLoadAssignment_Policy *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_ClusterLoadAssignment_Policy_overprovisioning_factor(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_ClusterLoadAssignment_Policy_set_overprovisioning_factor(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.ClusterLoadAssignment.Policy.DropOverload */ + +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_new(upb_arena *arena) { + return (envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit, arena); +} +UPB_INLINE envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *ret = envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_serialize(const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_category(const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_type_FractionalPercent* envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_drop_percentage(const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg) { return UPB_FIELD_AT(msg, const struct envoy_type_FractionalPercent*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_set_category(envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_set_drop_percentage(envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg, struct envoy_type_FractionalPercent* value) { + UPB_FIELD_AT(msg, struct envoy_type_FractionalPercent*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_type_FractionalPercent* envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_mutable_drop_percentage(envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload *msg, upb_arena *arena) { + struct envoy_type_FractionalPercent* sub = (struct envoy_type_FractionalPercent*)envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_drop_percentage(msg); + if (sub == NULL) { + sub = (struct envoy_type_FractionalPercent*)upb_msg_new(&envoy_type_FractionalPercent_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_set_drop_percentage(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_EDS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c b/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c new file mode 100644 index 00000000000..4cc9d7dd445 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c @@ -0,0 +1,86 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/endpoint/endpoint.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/endpoint/endpoint.upb.h" +#include "envoy/api/v2/core/address.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "envoy/api/v2/core/health_check.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_endpoint_Endpoint_submsgs[2] = { + &envoy_api_v2_core_Address_msginit, + &envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_Endpoint__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_endpoint_Endpoint_msginit = { + &envoy_api_v2_endpoint_Endpoint_submsgs[0], + &envoy_api_v2_endpoint_Endpoint__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_Endpoint_HealthCheckConfig__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 13, 1}, +}; + +const upb_msglayout envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit = { + NULL, + &envoy_api_v2_endpoint_Endpoint_HealthCheckConfig__fields[0], + UPB_SIZE(4, 4), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_endpoint_LbEndpoint_submsgs[3] = { + &envoy_api_v2_core_Metadata_msginit, + &envoy_api_v2_endpoint_Endpoint_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_LbEndpoint__fields[4] = { + {1, UPB_SIZE(8, 8), 0, 1, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {3, UPB_SIZE(12, 16), 0, 0, 11, 1}, + {4, UPB_SIZE(16, 24), 0, 2, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_endpoint_LbEndpoint_msginit = { + &envoy_api_v2_endpoint_LbEndpoint_submsgs[0], + &envoy_api_v2_endpoint_LbEndpoint__fields[0], + UPB_SIZE(24, 32), 4, false, +}; + +static const upb_msglayout *const envoy_api_v2_endpoint_LocalityLbEndpoints_submsgs[3] = { + &envoy_api_v2_core_Locality_msginit, + &envoy_api_v2_endpoint_LbEndpoint_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_endpoint_LocalityLbEndpoints__fields[4] = { + {1, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {2, UPB_SIZE(12, 24), 0, 1, 11, 3}, + {3, UPB_SIZE(8, 16), 0, 2, 11, 1}, + {5, UPB_SIZE(0, 0), 0, 0, 13, 1}, +}; + +const upb_msglayout envoy_api_v2_endpoint_LocalityLbEndpoints_msginit = { + &envoy_api_v2_endpoint_LocalityLbEndpoints_submsgs[0], + &envoy_api_v2_endpoint_LocalityLbEndpoints__fields[0], + UPB_SIZE(16, 32), 4, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h b/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h new file mode 100644 index 00000000000..4fd6341d3c4 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h @@ -0,0 +1,234 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/endpoint/endpoint.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_ENDPOINT_ENDPOINT_PROTO_UPB_H_ +#define ENVOY_API_V2_ENDPOINT_ENDPOINT_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_endpoint_Endpoint; +struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig; +struct envoy_api_v2_endpoint_LbEndpoint; +struct envoy_api_v2_endpoint_LocalityLbEndpoints; +typedef struct envoy_api_v2_endpoint_Endpoint envoy_api_v2_endpoint_Endpoint; +typedef struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig envoy_api_v2_endpoint_Endpoint_HealthCheckConfig; +typedef struct envoy_api_v2_endpoint_LbEndpoint envoy_api_v2_endpoint_LbEndpoint; +typedef struct envoy_api_v2_endpoint_LocalityLbEndpoints envoy_api_v2_endpoint_LocalityLbEndpoints; +extern const upb_msglayout envoy_api_v2_endpoint_Endpoint_msginit; +extern const upb_msglayout envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit; +extern const upb_msglayout envoy_api_v2_endpoint_LbEndpoint_msginit; +extern const upb_msglayout envoy_api_v2_endpoint_LocalityLbEndpoints_msginit; +struct envoy_api_v2_core_Address; +struct envoy_api_v2_core_Locality; +struct envoy_api_v2_core_Metadata; +struct google_protobuf_UInt32Value; +extern const upb_msglayout envoy_api_v2_core_Address_msginit; +extern const upb_msglayout envoy_api_v2_core_Locality_msginit; +extern const upb_msglayout envoy_api_v2_core_Metadata_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + + +/* envoy.api.v2.endpoint.Endpoint */ + +UPB_INLINE envoy_api_v2_endpoint_Endpoint *envoy_api_v2_endpoint_Endpoint_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_Endpoint *)upb_msg_new(&envoy_api_v2_endpoint_Endpoint_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_Endpoint *envoy_api_v2_endpoint_Endpoint_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_Endpoint *ret = envoy_api_v2_endpoint_Endpoint_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_Endpoint_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_Endpoint_serialize(const envoy_api_v2_endpoint_Endpoint *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_Endpoint_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_Address* envoy_api_v2_endpoint_Endpoint_address(const envoy_api_v2_endpoint_Endpoint *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Address*, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_endpoint_Endpoint_HealthCheckConfig* envoy_api_v2_endpoint_Endpoint_health_check_config(const envoy_api_v2_endpoint_Endpoint *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_endpoint_Endpoint_HealthCheckConfig*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_endpoint_Endpoint_set_address(envoy_api_v2_endpoint_Endpoint *msg, struct envoy_api_v2_core_Address* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Address*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Address* envoy_api_v2_endpoint_Endpoint_mutable_address(envoy_api_v2_endpoint_Endpoint *msg, upb_arena *arena) { + struct envoy_api_v2_core_Address* sub = (struct envoy_api_v2_core_Address*)envoy_api_v2_endpoint_Endpoint_address(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Address*)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_Endpoint_set_address(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_Endpoint_set_health_check_config(envoy_api_v2_endpoint_Endpoint *msg, envoy_api_v2_endpoint_Endpoint_HealthCheckConfig* value) { + UPB_FIELD_AT(msg, envoy_api_v2_endpoint_Endpoint_HealthCheckConfig*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig* envoy_api_v2_endpoint_Endpoint_mutable_health_check_config(envoy_api_v2_endpoint_Endpoint *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig* sub = (struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig*)envoy_api_v2_endpoint_Endpoint_health_check_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_endpoint_Endpoint_HealthCheckConfig*)upb_msg_new(&envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_Endpoint_set_health_check_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.endpoint.Endpoint.HealthCheckConfig */ + +UPB_INLINE envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *)upb_msg_new(&envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *ret = envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_serialize(const envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_msginit, arena, len); +} + +UPB_INLINE uint32_t envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_port_value(const envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_endpoint_Endpoint_HealthCheckConfig_set_port_value(envoy_api_v2_endpoint_Endpoint_HealthCheckConfig *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.endpoint.LbEndpoint */ + +UPB_INLINE envoy_api_v2_endpoint_LbEndpoint *envoy_api_v2_endpoint_LbEndpoint_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_LbEndpoint *)upb_msg_new(&envoy_api_v2_endpoint_LbEndpoint_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_LbEndpoint *envoy_api_v2_endpoint_LbEndpoint_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_LbEndpoint *ret = envoy_api_v2_endpoint_LbEndpoint_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_LbEndpoint_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_LbEndpoint_serialize(const envoy_api_v2_endpoint_LbEndpoint *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_LbEndpoint_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_endpoint_Endpoint* envoy_api_v2_endpoint_LbEndpoint_endpoint(const envoy_api_v2_endpoint_LbEndpoint *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_endpoint_Endpoint*, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t envoy_api_v2_endpoint_LbEndpoint_health_status(const envoy_api_v2_endpoint_LbEndpoint *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_Metadata* envoy_api_v2_endpoint_LbEndpoint_metadata(const envoy_api_v2_endpoint_LbEndpoint *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Metadata*, UPB_SIZE(12, 16)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_endpoint_LbEndpoint_load_balancing_weight(const envoy_api_v2_endpoint_LbEndpoint *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(16, 24)); } + +UPB_INLINE void envoy_api_v2_endpoint_LbEndpoint_set_endpoint(envoy_api_v2_endpoint_LbEndpoint *msg, envoy_api_v2_endpoint_Endpoint* value) { + UPB_FIELD_AT(msg, envoy_api_v2_endpoint_Endpoint*, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_endpoint_Endpoint* envoy_api_v2_endpoint_LbEndpoint_mutable_endpoint(envoy_api_v2_endpoint_LbEndpoint *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_Endpoint* sub = (struct envoy_api_v2_endpoint_Endpoint*)envoy_api_v2_endpoint_LbEndpoint_endpoint(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_endpoint_Endpoint*)upb_msg_new(&envoy_api_v2_endpoint_Endpoint_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_LbEndpoint_set_endpoint(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_LbEndpoint_set_health_status(envoy_api_v2_endpoint_LbEndpoint *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_endpoint_LbEndpoint_set_metadata(envoy_api_v2_endpoint_LbEndpoint *msg, struct envoy_api_v2_core_Metadata* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Metadata*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Metadata* envoy_api_v2_endpoint_LbEndpoint_mutable_metadata(envoy_api_v2_endpoint_LbEndpoint *msg, upb_arena *arena) { + struct envoy_api_v2_core_Metadata* sub = (struct envoy_api_v2_core_Metadata*)envoy_api_v2_endpoint_LbEndpoint_metadata(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Metadata*)upb_msg_new(&envoy_api_v2_core_Metadata_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_LbEndpoint_set_metadata(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_LbEndpoint_set_load_balancing_weight(envoy_api_v2_endpoint_LbEndpoint *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(16, 24)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_endpoint_LbEndpoint_mutable_load_balancing_weight(envoy_api_v2_endpoint_LbEndpoint *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_endpoint_LbEndpoint_load_balancing_weight(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_LbEndpoint_set_load_balancing_weight(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.endpoint.LocalityLbEndpoints */ + +UPB_INLINE envoy_api_v2_endpoint_LocalityLbEndpoints *envoy_api_v2_endpoint_LocalityLbEndpoints_new(upb_arena *arena) { + return (envoy_api_v2_endpoint_LocalityLbEndpoints *)upb_msg_new(&envoy_api_v2_endpoint_LocalityLbEndpoints_msginit, arena); +} +UPB_INLINE envoy_api_v2_endpoint_LocalityLbEndpoints *envoy_api_v2_endpoint_LocalityLbEndpoints_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_endpoint_LocalityLbEndpoints *ret = envoy_api_v2_endpoint_LocalityLbEndpoints_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_endpoint_LocalityLbEndpoints_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_endpoint_LocalityLbEndpoints_serialize(const envoy_api_v2_endpoint_LocalityLbEndpoints *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_endpoint_LocalityLbEndpoints_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_Locality* envoy_api_v2_endpoint_LocalityLbEndpoints_locality(const envoy_api_v2_endpoint_LocalityLbEndpoints *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Locality*, UPB_SIZE(4, 8)); } +UPB_INLINE const envoy_api_v2_endpoint_LbEndpoint* const* envoy_api_v2_endpoint_LocalityLbEndpoints_lb_endpoints(const envoy_api_v2_endpoint_LocalityLbEndpoints *msg, size_t *len) { return (const envoy_api_v2_endpoint_LbEndpoint* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_endpoint_LocalityLbEndpoints_load_balancing_weight(const envoy_api_v2_endpoint_LocalityLbEndpoints *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)); } +UPB_INLINE uint32_t envoy_api_v2_endpoint_LocalityLbEndpoints_priority(const envoy_api_v2_endpoint_LocalityLbEndpoints *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_endpoint_LocalityLbEndpoints_set_locality(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, struct envoy_api_v2_core_Locality* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Locality*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Locality* envoy_api_v2_endpoint_LocalityLbEndpoints_mutable_locality(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, upb_arena *arena) { + struct envoy_api_v2_core_Locality* sub = (struct envoy_api_v2_core_Locality*)envoy_api_v2_endpoint_LocalityLbEndpoints_locality(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Locality*)upb_msg_new(&envoy_api_v2_core_Locality_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_LocalityLbEndpoints_set_locality(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_endpoint_LbEndpoint** envoy_api_v2_endpoint_LocalityLbEndpoints_mutable_lb_endpoints(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, size_t *len) { + return (envoy_api_v2_endpoint_LbEndpoint**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len); +} +UPB_INLINE envoy_api_v2_endpoint_LbEndpoint** envoy_api_v2_endpoint_LocalityLbEndpoints_resize_lb_endpoints(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_endpoint_LbEndpoint**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_endpoint_LbEndpoint* envoy_api_v2_endpoint_LocalityLbEndpoints_add_lb_endpoints(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, upb_arena *arena) { + struct envoy_api_v2_endpoint_LbEndpoint* sub = (struct envoy_api_v2_endpoint_LbEndpoint*)upb_msg_new(&envoy_api_v2_endpoint_LbEndpoint_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_LocalityLbEndpoints_set_load_balancing_weight(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_endpoint_LocalityLbEndpoints_mutable_load_balancing_weight(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_endpoint_LocalityLbEndpoints_load_balancing_weight(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_endpoint_LocalityLbEndpoints_set_load_balancing_weight(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_endpoint_LocalityLbEndpoints_set_priority(envoy_api_v2_endpoint_LocalityLbEndpoints *msg, uint32_t value) { + UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_ENDPOINT_ENDPOINT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c b/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c new file mode 100644 index 00000000000..5611346c3fd --- /dev/null +++ b/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c @@ -0,0 +1,23 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/service/discovery/v2/ads.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/service/discovery/v2/ads.upb.h" +#include "envoy/api/v2/discovery.upb.h" + +#include "upb/port_def.inc" + +const upb_msglayout envoy_service_discovery_v2_AdsDummy_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h b/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h new file mode 100644 index 00000000000..d5f1b90a032 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h @@ -0,0 +1,52 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/service/discovery/v2/ads.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_SERVICE_DISCOVERY_V2_ADS_PROTO_UPB_H_ +#define ENVOY_SERVICE_DISCOVERY_V2_ADS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_service_discovery_v2_AdsDummy; +typedef struct envoy_service_discovery_v2_AdsDummy envoy_service_discovery_v2_AdsDummy; +extern const upb_msglayout envoy_service_discovery_v2_AdsDummy_msginit; + +/* Enums */ + + +/* envoy.service.discovery.v2.AdsDummy */ + +UPB_INLINE envoy_service_discovery_v2_AdsDummy *envoy_service_discovery_v2_AdsDummy_new(upb_arena *arena) { + return (envoy_service_discovery_v2_AdsDummy *)upb_msg_new(&envoy_service_discovery_v2_AdsDummy_msginit, arena); +} +UPB_INLINE envoy_service_discovery_v2_AdsDummy *envoy_service_discovery_v2_AdsDummy_parsenew(upb_strview buf, upb_arena *arena) { + envoy_service_discovery_v2_AdsDummy *ret = envoy_service_discovery_v2_AdsDummy_new(arena); + return (ret && upb_decode(buf, ret, &envoy_service_discovery_v2_AdsDummy_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_service_discovery_v2_AdsDummy_serialize(const envoy_service_discovery_v2_AdsDummy *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_service_discovery_v2_AdsDummy_msginit, arena, len); +} + + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_SERVICE_DISCOVERY_V2_ADS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/type/percent.upb.h b/src/core/ext/upb-generated/envoy/type/percent.upb.h index 6fa665a2de9..13df96a610c 100644 --- a/src/core/ext/upb-generated/envoy/type/percent.upb.h +++ b/src/core/ext/upb-generated/envoy/type/percent.upb.h @@ -35,6 +35,7 @@ typedef enum { envoy_type_FractionalPercent_MILLION = 2 } envoy_type_FractionalPercent_DenominatorType; + /* envoy.type.Percent */ UPB_INLINE envoy_type_Percent *envoy_type_Percent_new(upb_arena *arena) { @@ -69,13 +70,13 @@ UPB_INLINE char *envoy_type_FractionalPercent_serialize(const envoy_type_Fractio } UPB_INLINE uint32_t envoy_type_FractionalPercent_numerator(const envoy_type_FractionalPercent *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)); } -UPB_INLINE envoy_type_FractionalPercent_DenominatorType envoy_type_FractionalPercent_denominator(const envoy_type_FractionalPercent *msg) { return UPB_FIELD_AT(msg, envoy_type_FractionalPercent_DenominatorType, UPB_SIZE(0, 0)); } +UPB_INLINE int32_t envoy_type_FractionalPercent_denominator(const envoy_type_FractionalPercent *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } UPB_INLINE void envoy_type_FractionalPercent_set_numerator(envoy_type_FractionalPercent *msg, uint32_t value) { UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(8, 8)) = value; } -UPB_INLINE void envoy_type_FractionalPercent_set_denominator(envoy_type_FractionalPercent *msg, envoy_type_FractionalPercent_DenominatorType value) { - UPB_FIELD_AT(msg, envoy_type_FractionalPercent_DenominatorType, UPB_SIZE(0, 0)) = value; +UPB_INLINE void envoy_type_FractionalPercent_set_denominator(envoy_type_FractionalPercent *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; } diff --git a/src/core/ext/upb-generated/envoy/type/range.upb.h b/src/core/ext/upb-generated/envoy/type/range.upb.h index c036ee66a95..de1846a1300 100644 --- a/src/core/ext/upb-generated/envoy/type/range.upb.h +++ b/src/core/ext/upb-generated/envoy/type/range.upb.h @@ -29,6 +29,7 @@ extern const upb_msglayout envoy_type_DoubleRange_msginit; /* Enums */ + /* envoy.type.Int64Range */ UPB_INLINE envoy_type_Int64Range *envoy_type_Int64Range_new(upb_arena *arena) { diff --git a/src/core/ext/upb-generated/gogoproto/gogo.upb.h b/src/core/ext/upb-generated/gogoproto/gogo.upb.h index 313d6fa644e..6b3dda647ee 100644 --- a/src/core/ext/upb-generated/gogoproto/gogo.upb.h +++ b/src/core/ext/upb-generated/gogoproto/gogo.upb.h @@ -23,6 +23,7 @@ extern "C" { /* Enums */ + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/core/ext/upb-generated/google/api/annotations.upb.h b/src/core/ext/upb-generated/google/api/annotations.upb.h index 93d7868ff34..5a49fffdd22 100644 --- a/src/core/ext/upb-generated/google/api/annotations.upb.h +++ b/src/core/ext/upb-generated/google/api/annotations.upb.h @@ -23,6 +23,7 @@ extern "C" { /* Enums */ + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/core/ext/upb-generated/google/api/http.upb.h b/src/core/ext/upb-generated/google/api/http.upb.h index 6fec36802d3..d8bda895b86 100644 --- a/src/core/ext/upb-generated/google/api/http.upb.h +++ b/src/core/ext/upb-generated/google/api/http.upb.h @@ -32,6 +32,7 @@ extern const upb_msglayout google_api_CustomHttpPattern_msginit; /* Enums */ + /* google.api.Http */ UPB_INLINE google_api_Http *google_api_Http_new(upb_arena *arena) { diff --git a/src/core/ext/upb-generated/google/protobuf/any.upb.h b/src/core/ext/upb-generated/google/protobuf/any.upb.h index 386916c7ca8..877e5bd606d 100644 --- a/src/core/ext/upb-generated/google/protobuf/any.upb.h +++ b/src/core/ext/upb-generated/google/protobuf/any.upb.h @@ -26,6 +26,7 @@ extern const upb_msglayout google_protobuf_Any_msginit; /* Enums */ + /* google.protobuf.Any */ UPB_INLINE google_protobuf_Any *google_protobuf_Any_new(upb_arena *arena) { diff --git a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h index 89e24a6c976..11868b28f1f 100644 --- a/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h +++ b/src/core/ext/upb-generated/google/protobuf/descriptor.upb.h @@ -155,6 +155,7 @@ typedef enum { google_protobuf_MethodOptions_IDEMPOTENT = 2 } google_protobuf_MethodOptions_IdempotencyLevel; + /* google.protobuf.FileDescriptorSet */ UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_new(upb_arena *arena) { @@ -605,9 +606,9 @@ UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const googl UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 3); } UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE google_protobuf_FieldDescriptorProto_Label google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Label, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE google_protobuf_FieldDescriptorProto_Type google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Type, UPB_SIZE(16, 16)); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 7); } UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 8); } @@ -631,13 +632,13 @@ UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_ _upb_sethas(msg, 3); UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)) = value; } -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldDescriptorProto_Label value) { +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Label, UPB_SIZE(8, 8)) = value; + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; } -UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldDescriptorProto_Type value) { +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, int32_t value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, google_protobuf_FieldDescriptorProto_Type, UPB_SIZE(16, 16)) = value; + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; } UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { _upb_sethas(msg, 7); @@ -984,7 +985,7 @@ UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_pro UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 12); } UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 48)); } UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE google_protobuf_FileOptions_OptimizeMode google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FileOptions_OptimizeMode, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 2); } UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); } UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 13); } @@ -1029,9 +1030,9 @@ UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_prot _upb_sethas(msg, 12); UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 48)) = value; } -UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, google_protobuf_FileOptions_OptimizeMode value) { +UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, google_protobuf_FileOptions_OptimizeMode, UPB_SIZE(8, 8)) = value; + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; } UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) { _upb_sethas(msg, 2); @@ -1184,7 +1185,7 @@ UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_Fi } UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE google_protobuf_FieldOptions_CType google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_CType, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 3); } UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); } UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 4); } @@ -1192,14 +1193,14 @@ UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_Fi UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 5); } UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)); } UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 2); } -UPB_INLINE google_protobuf_FieldOptions_JSType google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_FieldOptions_JSType, UPB_SIZE(16, 16)); } +UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 6); } UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); } -UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, google_protobuf_FieldOptions_CType value) { +UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, google_protobuf_FieldOptions_CType, UPB_SIZE(8, 8)) = value; + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) { _upb_sethas(msg, 3); @@ -1213,9 +1214,9 @@ UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptio _upb_sethas(msg, 5); UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)) = value; } -UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, google_protobuf_FieldOptions_JSType value) { +UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, int32_t value) { _upb_sethas(msg, 2); - UPB_FIELD_AT(msg, google_protobuf_FieldOptions_JSType, UPB_SIZE(16, 16)) = value; + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; } UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) { _upb_sethas(msg, 6); @@ -1396,16 +1397,16 @@ UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_M UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 2); } UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); } UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 1); } -UPB_INLINE google_protobuf_MethodOptions_IdempotencyLevel google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, UPB_SIZE(8, 8)); } +UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); } UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) { _upb_sethas(msg, 2); UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value; } -UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, google_protobuf_MethodOptions_IdempotencyLevel value) { +UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, int32_t value) { _upb_sethas(msg, 1); - UPB_FIELD_AT(msg, google_protobuf_MethodOptions_IdempotencyLevel, UPB_SIZE(8, 8)) = value; + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; } UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t *len) { return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len); diff --git a/src/core/ext/upb-generated/google/protobuf/duration.upb.h b/src/core/ext/upb-generated/google/protobuf/duration.upb.h index 871d67dcbb5..bb116dcc89a 100644 --- a/src/core/ext/upb-generated/google/protobuf/duration.upb.h +++ b/src/core/ext/upb-generated/google/protobuf/duration.upb.h @@ -26,6 +26,7 @@ extern const upb_msglayout google_protobuf_Duration_msginit; /* Enums */ + /* google.protobuf.Duration */ UPB_INLINE google_protobuf_Duration *google_protobuf_Duration_new(upb_arena *arena) { diff --git a/src/core/ext/upb-generated/google/protobuf/struct.upb.h b/src/core/ext/upb-generated/google/protobuf/struct.upb.h index 2e28858fc7b..da5da203457 100644 --- a/src/core/ext/upb-generated/google/protobuf/struct.upb.h +++ b/src/core/ext/upb-generated/google/protobuf/struct.upb.h @@ -39,6 +39,7 @@ typedef enum { google_protobuf_NULL_VALUE = 0 } google_protobuf_NullValue; + /* google.protobuf.Struct */ UPB_INLINE google_protobuf_Struct *google_protobuf_Struct_new(upb_arena *arena) { @@ -127,7 +128,7 @@ typedef enum { UPB_INLINE google_protobuf_Value_kind_oneofcases google_protobuf_Value_kind_case(const google_protobuf_Value* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } UPB_INLINE bool google_protobuf_Value_has_null_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } -UPB_INLINE google_protobuf_NullValue google_protobuf_Value_null_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, google_protobuf_NullValue, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, google_protobuf_NULL_VALUE); } +UPB_INLINE int32_t google_protobuf_Value_null_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, int32_t, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, google_protobuf_NULL_VALUE); } UPB_INLINE bool google_protobuf_Value_has_number_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } UPB_INLINE double google_protobuf_Value_number_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, double, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, 0); } UPB_INLINE bool google_protobuf_Value_has_string_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 3); } @@ -139,8 +140,8 @@ UPB_INLINE const google_protobuf_Struct* google_protobuf_Value_struct_value(cons UPB_INLINE bool google_protobuf_Value_has_list_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 6); } UPB_INLINE const google_protobuf_ListValue* google_protobuf_Value_list_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, const google_protobuf_ListValue*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 6, NULL); } -UPB_INLINE void google_protobuf_Value_set_null_value(google_protobuf_Value *msg, google_protobuf_NullValue value) { - UPB_WRITE_ONEOF(msg, google_protobuf_NullValue, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); +UPB_INLINE void google_protobuf_Value_set_null_value(google_protobuf_Value *msg, int32_t value) { + UPB_WRITE_ONEOF(msg, int32_t, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); } UPB_INLINE void google_protobuf_Value_set_number_value(google_protobuf_Value *msg, double value) { UPB_WRITE_ONEOF(msg, double, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); diff --git a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h index 42413a43014..23d39e55f9d 100644 --- a/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h +++ b/src/core/ext/upb-generated/google/protobuf/timestamp.upb.h @@ -26,6 +26,7 @@ extern const upb_msglayout google_protobuf_Timestamp_msginit; /* Enums */ + /* google.protobuf.Timestamp */ UPB_INLINE google_protobuf_Timestamp *google_protobuf_Timestamp_new(upb_arena *arena) { diff --git a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h index d08ee51780a..b9897ecceb2 100644 --- a/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h +++ b/src/core/ext/upb-generated/google/protobuf/wrappers.upb.h @@ -50,6 +50,7 @@ extern const upb_msglayout google_protobuf_BytesValue_msginit; /* Enums */ + /* google.protobuf.DoubleValue */ UPB_INLINE google_protobuf_DoubleValue *google_protobuf_DoubleValue_new(upb_arena *arena) { diff --git a/src/core/ext/upb-generated/google/rpc/status.upb.h b/src/core/ext/upb-generated/google/rpc/status.upb.h index 23f72447e4d..ccdac652130 100644 --- a/src/core/ext/upb-generated/google/rpc/status.upb.h +++ b/src/core/ext/upb-generated/google/rpc/status.upb.h @@ -28,6 +28,7 @@ extern const upb_msglayout google_protobuf_Any_msginit; /* Enums */ + /* google.rpc.Status */ UPB_INLINE google_rpc_Status *google_rpc_Status_new(upb_arena *arena) { diff --git a/src/core/ext/upb-generated/validate/validate.upb.h b/src/core/ext/upb-generated/validate/validate.upb.h index 04b6cd431f5..c28ac41881d 100644 --- a/src/core/ext/upb-generated/validate/validate.upb.h +++ b/src/core/ext/upb-generated/validate/validate.upb.h @@ -96,6 +96,7 @@ extern const upb_msglayout google_protobuf_Timestamp_msginit; /* Enums */ + /* validate.FieldRules */ UPB_INLINE validate_FieldRules *validate_FieldRules_new(upb_arena *arena) { diff --git a/third_party/upb b/third_party/upb index ed9faae0993..fa88c6017dd 160000 --- a/third_party/upb +++ b/third_party/upb @@ -1 +1 @@ -Subproject commit ed9faae0993704b033c594b072d65e1bf19207fa +Subproject commit fa88c6017ddb490aa78c57bea682193f533ed69a diff --git a/tools/codegen/core/gen_upb_api.sh b/tools/codegen/core/gen_upb_api.sh index b3466c70566..5a89147c311 100755 --- a/tools/codegen/core/gen_upb_api.sh +++ b/tools/codegen/core/gen_upb_api.sh @@ -43,7 +43,8 @@ proto_files=( \ "envoy/api/v2/core/health_check.proto" \ "envoy/api/v2/discovery.proto" \ "envoy/api/v2/eds.proto" \ - "envoy/api/v2/endpoint/endpoint.proto") + "envoy/api/v2/endpoint/endpoint.proto" \ + "envoy/service/discovery/v2/ads.proto") for i in "${proto_files[@]}" do diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index 12e4c157193..5991e443006 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -40,7 +40,7 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules" 9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60) 582743bf40c5d3639a70f98f183914a2c0cd0680 third_party/protobuf (v3.7.0-rc.2-20-g582743bf) e143189bf6f37b3957fb31743df6a1bcf4a8c685 third_party/protoc-gen-validate (v0.0.10) - ed9faae0993704b033c594b072d65e1bf19207fa third_party/upb (heads/master) + fa88c6017ddb490aa78c57bea682193f533ed69a third_party/upb (heads/master) cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11) EOF From cbb70f534b417d6826e3c501be8fdb8ad5b4ae4a Mon Sep 17 00:00:00 2001 From: kkm Date: Fri, 22 Mar 2019 00:46:52 -0700 Subject: [PATCH 768/814] C# tools: support generated filename corner cases protoc and gRPC codegens differently treat non-ASCII letter characters and symbols other than underscores when constructing their respective output filenames for generated .cs files. This change reproduces their respective behaviors exactly. Fixes #17661 --- .../Grpc.Tools.Tests/CSharpGeneratorTest.cs | 14 +++--- src/csharp/Grpc.Tools/GeneratorServices.cs | 45 +++++++++++++------ 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs index e4c9b2fa843..782c63b7107 100644 --- a/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs @@ -33,12 +33,14 @@ namespace Grpc.Tools.Tests [TestCase("foo.proto", "Foo.cs", "FooGrpc.cs")] [TestCase("sub/foo.proto", "Foo.cs", "FooGrpc.cs")] [TestCase("one_two.proto", "OneTwo.cs", "OneTwoGrpc.cs")] - [TestCase("__one_two!.proto", "OneTwo!.cs", "OneTwo!Grpc.cs")] - [TestCase("one(two).proto", "One(two).cs", "One(two)Grpc.cs")] - [TestCase("one_(two).proto", "One(two).cs", "One(two)Grpc.cs")] - [TestCase("one two.proto", "One two.cs", "One twoGrpc.cs")] - [TestCase("one_ two.proto", "One two.cs", "One twoGrpc.cs")] - [TestCase("one .proto", "One .cs", "One Grpc.cs")] + [TestCase("ONE_TWO.proto", "ONETWO.cs", "ONETWOGrpc.cs")] + [TestCase("one.two.proto", "OneTwo.cs", "One.twoGrpc.cs")] + [TestCase("__one_two!.proto", "OneTwo.cs", "OneTwo!Grpc.cs")] + [TestCase("one(two).proto", "OneTwo.cs", "One(two)Grpc.cs")] + [TestCase("one_(two).proto", "OneTwo.cs", "One(two)Grpc.cs")] + [TestCase("one two.proto", "OneTwo.cs", "One twoGrpc.cs")] + [TestCase("one_ two.proto", "OneTwo.cs", "One twoGrpc.cs")] + [TestCase("one .proto", "One.cs", "One Grpc.cs")] public void NameMangling(string proto, string expectCs, string expectGrpcCs) { var poss = _generator.GetPossibleOutputs(Utils.MakeItem(proto, "grpcservices", "both")); diff --git a/src/csharp/Grpc.Tools/GeneratorServices.cs b/src/csharp/Grpc.Tools/GeneratorServices.cs index 536ec43c836..c956c89d6d8 100644 --- a/src/csharp/Grpc.Tools/GeneratorServices.cs +++ b/src/csharp/Grpc.Tools/GeneratorServices.cs @@ -66,29 +66,28 @@ namespace Grpc.Tools public override string[] GetPossibleOutputs(ITaskItem protoItem) { bool doGrpc = GrpcOutputPossible(protoItem); - string filename = LowerUnderscoreToUpperCamel( - Path.GetFileNameWithoutExtension(protoItem.ItemSpec)); - var outputs = new string[doGrpc ? 2 : 1]; + string basename = Path.GetFileNameWithoutExtension(protoItem.ItemSpec); + string outdir = protoItem.GetMetadata(Metadata.OutputDir); - string fileStem = Path.Combine(outdir, filename); - outputs[0] = fileStem + ".cs"; + string filename = LowerUnderscoreToUpperCamelProtocWay(basename); + outputs[0] = Path.Combine(outdir, filename) + ".cs"; + if (doGrpc) { // Override outdir if kGrpcOutputDir present, default to proto output. - outdir = protoItem.GetMetadata(Metadata.GrpcOutputDir); - if (outdir != "") - { - fileStem = Path.Combine(outdir, filename); - } - outputs[1] = fileStem + "Grpc.cs"; + string grpcdir = protoItem.GetMetadata(Metadata.GrpcOutputDir); + filename = LowerUnderscoreToUpperCamelGrpcWay(basename); + outputs[1] = Path.Combine( + grpcdir != "" ? grpcdir : outdir, filename) + "Grpc.cs"; } return outputs; } - string LowerUnderscoreToUpperCamel(string str) + // This is how the gRPC codegen currently construct its output filename. + // See src/compiler/generator_helpers.h:118. + string LowerUnderscoreToUpperCamelGrpcWay(string str) { - // See src/compiler/generator_helpers.h:118 var result = new StringBuilder(str.Length, str.Length); bool cap = true; foreach (char c in str) @@ -109,6 +108,26 @@ namespace Grpc.Tools } return result.ToString(); } + + // This is how the protoc codegen constructs its output filename. + // See protobuf/compiler/csharp/csharp_helpers.cc:356. + // Note that protoc explicitly discards non-ASCII letters. + string LowerUnderscoreToUpperCamelProtocWay(string str) + { + var result = new StringBuilder(str.Length, str.Length); + bool cap = true; + foreach (char c in str) + { + char upperC = char.ToUpperInvariant(c); + bool isAsciiLetter = 'A' <= upperC && upperC <= 'Z'; + if (isAsciiLetter || ('0' <= c && c <= '9')) + { + result.Append(cap ? upperC : c); + } + cap = !isAsciiLetter; + } + return result.ToString(); + } }; // C++ generator services. From c07a74d0e5072b1c988d84e09a36ce3a77f19366 Mon Sep 17 00:00:00 2001 From: kkm Date: Fri, 22 Mar 2019 01:10:13 -0700 Subject: [PATCH 769/814] C# Tooling: change the case to 'Protobuf' consistently Users will not be affected, as MSBuild is not case-sensitive. The changes in C# code are also entirely for consistency; they do not affect the tooling dll at runtime. Closes #17884 --- .../Grpc.Tools.Tests/ProtoCompileBasicTest.cs | 2 +- .../ProtoCompileCommandLineGeneratorTest.cs | 4 +- .../ProtoCompileCommandLinePrinterTest.cs | 2 +- src/csharp/Grpc.Tools/Common.cs | 2 +- src/csharp/Grpc.Tools/GeneratorServices.cs | 2 +- src/csharp/Grpc.Tools/ProtoCompile.cs | 8 ++-- src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs | 4 +- .../Grpc.Tools/ProtoReadDependencies.cs | 4 +- .../Grpc.Tools/build/_grpc/Grpc.CSharp.xml | 6 +-- .../build/_grpc/_Grpc.Tools.targets | 6 +-- .../_protobuf/Google.Protobuf.Tools.props | 6 +-- .../_protobuf/Google.Protobuf.Tools.targets | 38 +++++++++---------- .../build/_protobuf/Protobuf.CSharp.xml | 18 ++++----- 13 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs index ea763f4e408..6fbab47b3c3 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs @@ -62,7 +62,7 @@ namespace Grpc.Tools.Tests }; } - [TestCase("ProtoBuf")] + [TestCase("Protobuf")] [TestCase("Generator")] [TestCase("OutputDir")] [Description("We trust MSBuild to initialize these properties.")] diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs index 1ed7ca67b42..ab16c70a65e 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs @@ -30,7 +30,7 @@ namespace Grpc.Tools.Tests { _task.Generator = "csharp"; _task.OutputDir = "outdir"; - _task.ProtoBuf = Utils.MakeSimpleItems("a.proto"); + _task.Protobuf = Utils.MakeSimpleItems("a.proto"); } void ExecuteExpectSuccess() @@ -55,7 +55,7 @@ namespace Grpc.Tools.Tests [Test] public void CompileTwoFiles() { - _task.ProtoBuf = Utils.MakeSimpleItems("a.proto", "foo/b.proto"); + _task.Protobuf = Utils.MakeSimpleItems("a.proto", "foo/b.proto"); ExecuteExpectSuccess(); Assert.That(_task.LastResponseFile, Is.EqualTo(new[] { "--csharp_out=outdir", "--error_format=msvs", "a.proto", "foo/b.proto" })); diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs index 1773dcb8750..a11e3462fa0 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLinePrinterTest.cs @@ -29,7 +29,7 @@ namespace Grpc.Tools.Tests { _task.Generator = "csharp"; _task.OutputDir = "outdir"; - _task.ProtoBuf = Utils.MakeSimpleItems("a.proto"); + _task.Protobuf = Utils.MakeSimpleItems("a.proto"); _mockEngine .Setup(me => me.LogMessageEvent(It.IsAny())) diff --git a/src/csharp/Grpc.Tools/Common.cs b/src/csharp/Grpc.Tools/Common.cs index e6acdd63939..a4fcfc2c53c 100644 --- a/src/csharp/Grpc.Tools/Common.cs +++ b/src/csharp/Grpc.Tools/Common.cs @@ -31,7 +31,7 @@ namespace Grpc.Tools { // On output dependency lists. public static string Source = "Source"; - // On ProtoBuf items. + // On Protobuf items. public static string ProtoRoot = "ProtoRoot"; public static string OutputDir = "OutputDir"; public static string GrpcServices = "GrpcServices"; diff --git a/src/csharp/Grpc.Tools/GeneratorServices.cs b/src/csharp/Grpc.Tools/GeneratorServices.cs index 536ec43c836..4a9ea0d9f18 100644 --- a/src/csharp/Grpc.Tools/GeneratorServices.cs +++ b/src/csharp/Grpc.Tools/GeneratorServices.cs @@ -164,7 +164,7 @@ namespace Grpc.Tools protoDir = EndWithSlash(protoDir); if (!protoDir.StartsWith(rootDir)) { - Log.LogWarning("ProtoBuf item '{0}' has the ProtoRoot metadata '{1}' " + + Log.LogWarning("Protobuf item '{0}' has the ProtoRoot metadata '{1}' " + "which is not prefix to its path. Cannot compute relative path.", proto, root); return ""; diff --git a/src/csharp/Grpc.Tools/ProtoCompile.cs b/src/csharp/Grpc.Tools/ProtoCompile.cs index abff1ea016a..fee2af0f44d 100644 --- a/src/csharp/Grpc.Tools/ProtoCompile.cs +++ b/src/csharp/Grpc.Tools/ProtoCompile.cs @@ -133,7 +133,7 @@ namespace Grpc.Tools /// Protobuf files to compile. /// [Required] - public ITaskItem[] ProtoBuf { get; set; } + public ITaskItem[] Protobuf { get; set; } /// /// Directory where protoc dependency files are cached. If provided, dependency @@ -237,7 +237,7 @@ namespace Grpc.Tools Log.LogError("Properties ProtoDepDir and DependencyOut may not be both specified"); } - if (ProtoBuf.Length > 1 && (ProtoDepDir != null || DependencyOut != null)) + if (Protobuf.Length > 1 && (ProtoDepDir != null || DependencyOut != null)) { Log.LogError("Proto compiler currently allows only one input when " + "--dependency_out is specified (via ProtoDepDir or DependencyOut). " + @@ -247,7 +247,7 @@ namespace Grpc.Tools // Use ProtoDepDir to autogenerate DependencyOut if (ProtoDepDir != null) { - DependencyOut = DepFileUtil.GetDepFilenameForProto(ProtoDepDir, ProtoBuf[0].ItemSpec); + DependencyOut = DepFileUtil.GetDepFilenameForProto(ProtoDepDir, Protobuf[0].ItemSpec); } if (GrpcPluginExe == null) @@ -319,7 +319,7 @@ namespace Grpc.Tools } cmd.AddSwitchMaybe("dependency_out", DependencyOut); cmd.AddSwitchMaybe("error_format", "msvs"); - foreach (var proto in ProtoBuf) + foreach (var proto in Protobuf) { cmd.AddArg(proto.ItemSpec); } diff --git a/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs b/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs index 915be3421e8..24c0dd8482d 100644 --- a/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs +++ b/src/csharp/Grpc.Tools/ProtoCompilerOutputs.cs @@ -38,7 +38,7 @@ namespace Grpc.Tools /// files actually produced by the compiler. /// [Required] - public ITaskItem[] ProtoBuf { get; set; } + public ITaskItem[] Protobuf { get; set; } /// /// Output items per each potential output. We do not look at existing @@ -68,7 +68,7 @@ namespace Grpc.Tools // Get language-specific possible output. The generator expects certain // metadata be set on the proto item. var possible = new List(); - foreach (var proto in ProtoBuf) + foreach (var proto in Protobuf) { var outputs = generator.GetPossibleOutputs(proto); foreach (string output in outputs) diff --git a/src/csharp/Grpc.Tools/ProtoReadDependencies.cs b/src/csharp/Grpc.Tools/ProtoReadDependencies.cs index 963837e8b74..34e1379f679 100644 --- a/src/csharp/Grpc.Tools/ProtoReadDependencies.cs +++ b/src/csharp/Grpc.Tools/ProtoReadDependencies.cs @@ -29,7 +29,7 @@ namespace Grpc.Tools /// of proto files cached under ProtoDepDir. /// [Required] - public ITaskItem[] ProtoBuf { get; set; } + public ITaskItem[] Protobuf { get; set; } /// /// Directory where protoc dependency files are cached. @@ -55,7 +55,7 @@ namespace Grpc.Tools if (ProtoDepDir != null) { var dependencies = new List(); - foreach (var proto in ProtoBuf) + foreach (var proto in Protobuf) { string[] deps = DepFileUtil.ReadDependencyInputs(ProtoDepDir, proto.ItemSpec, Log); foreach (string dep in deps) diff --git a/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml b/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml index 54468eb5eff..66862582dad 100644 --- a/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml +++ b/src/csharp/Grpc.Tools/build/_grpc/Grpc.CSharp.xml @@ -1,11 +1,11 @@ - - @@ -21,7 +21,7 @@ - diff --git a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets index 3fe1ccc9181..dd01b8183db 100644 --- a/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_grpc/_Grpc.Tools.targets @@ -13,9 +13,9 @@ - - Both - + + Both + diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.props b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.props index 9f2d8bb4b5c..22bfef7f66a 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.props +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.props @@ -15,10 +15,10 @@ - + diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets index dc9a1522f17..05582767953 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -22,27 +22,27 @@ - - Public - True - - True - $(Protobuf_OutputPath) - + + Public + True + + True + $(Protobuf_OutputPath) + File;BrowseObject - + - false + false @@ -96,7 +96,7 @@ + Files="@(Protobuf->WithMetadataValue('ProtoRoot',''))"> - + . @@ -154,13 +154,13 @@ @@ -263,7 +263,7 @@ @@ -376,9 +376,9 @@ * The Pack target includes .proto files into the source package. --> + Condition=" '@(Protobuf)' != '' " > - + diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Protobuf.CSharp.xml b/src/csharp/Grpc.Tools/build/_protobuf/Protobuf.CSharp.xml index 2c41fbcbd06..66b9f4bd5da 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Protobuf.CSharp.xml +++ b/src/csharp/Grpc.Tools/build/_protobuf/Protobuf.CSharp.xml @@ -4,18 +4,18 @@ + ItemType="Protobuf" /> - - - @@ -31,7 +31,7 @@ - @@ -42,7 +42,7 @@ Category="Misc" Description="Location of the file."> - @@ -53,7 +53,7 @@ Category="Misc" Description="Name of the file or folder."> - @@ -81,7 +81,7 @@ - @@ -90,7 +90,7 @@ Category="Protobuf" Default="true" Description="Specifies if this file is compiled or only imported by other files."> - From 88fe29c63df9a0936c0f58598e65175819f921cd Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 22 Mar 2019 06:27:33 -0400 Subject: [PATCH 770/814] Preallocate for incoming metadatas. There is usually 9 metadata in incoming headers. We are calling arena_alloc for all of them and that accounts for 75% of the calls to arena_alloc. Simply preallocate 10 of them in the structure so that we can avoid the atomic op, per header. --- .../chttp2/transport/incoming_metadata.cc | 14 +++++++++----- .../transport/chttp2/transport/incoming_metadata.h | 7 ++++++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.cc b/src/core/ext/transport/chttp2/transport/incoming_metadata.cc index dca15e76803..1e04be79f7b 100644 --- a/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.cc @@ -30,11 +30,15 @@ grpc_error* grpc_chttp2_incoming_metadata_buffer_add( grpc_chttp2_incoming_metadata_buffer* buffer, grpc_mdelem elem) { buffer->size += GRPC_MDELEM_LENGTH(elem); - return grpc_metadata_batch_add_tail( - &buffer->batch, - static_cast( - gpr_arena_alloc(buffer->arena, sizeof(grpc_linked_mdelem))), - elem); + grpc_linked_mdelem* storage; + if (buffer->count < buffer->kPreallocatedMDElem) { + storage = &buffer->preallocated_mdelems[buffer->count]; + buffer->count++; + } else { + storage = static_cast( + gpr_arena_alloc(buffer->arena, sizeof(grpc_linked_mdelem))); + } + return grpc_metadata_batch_add_tail(&buffer->batch, storage, elem); } grpc_error* grpc_chttp2_incoming_metadata_buffer_replace_or_add( diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.h b/src/core/ext/transport/chttp2/transport/incoming_metadata.h index c551b3cc8be..4a9a59288f4 100644 --- a/src/core/ext/transport/chttp2/transport/incoming_metadata.h +++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.h @@ -32,9 +32,14 @@ struct grpc_chttp2_incoming_metadata_buffer { grpc_metadata_batch_destroy(&batch); } + static constexpr size_t kPreallocatedMDElem = 10; + gpr_arena* arena; + size_t size = 0; // total size of metadata. + size_t count = 0; // minimum of count of metadata and kPreallocatedMDElem. + // These preallocated mdelems are used while count < kPreallocatedMDElem. + grpc_linked_mdelem preallocated_mdelems[kPreallocatedMDElem]; grpc_metadata_batch batch; - size_t size = 0; // total size of metadata }; void grpc_chttp2_incoming_metadata_buffer_publish( From 1014fe507fa98c65bc276d5d1658168b758b83de Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 22 Mar 2019 06:15:11 -0400 Subject: [PATCH 771/814] Use const ref for grpc_slice. We are copying the slice on every call creation, which is hurting ping/pong traffic. --- src/core/lib/channel/channel_stack.h | 2 +- test/cpp/microbenchmarks/bm_call_create.cc | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 0de8c670790..580e1e55100 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -66,7 +66,7 @@ typedef struct { grpc_call_stack* call_stack; const void* server_transport_data; grpc_call_context_element* context; - grpc_slice path; + const grpc_slice& path; gpr_timespec start_time; grpc_millis deadline; gpr_arena* arena; diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index c1c8651ba43..e84999b213f 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -533,15 +533,15 @@ static void BM_IsolatedFilter(benchmark::State& state) { grpc_slice method = grpc_slice_from_static_string("/foo/bar"); grpc_call_final_info final_info; TestOp test_op_data; - grpc_call_element_args call_args; - call_args.call_stack = call_stack; - call_args.server_transport_data = nullptr; - call_args.context = nullptr; - call_args.path = method; - call_args.start_time = start_time; - call_args.deadline = deadline; const int kArenaSize = 4096; - call_args.arena = gpr_arena_create(kArenaSize); + grpc_call_element_args call_args{call_stack, + nullptr, + nullptr, + method, + start_time, + deadline, + gpr_arena_create(kArenaSize), + nullptr}; while (state.KeepRunning()) { GPR_TIMER_SCOPE("BenchmarkCycle", 0); GRPC_ERROR_UNREF( From 5534fb2e23f6a2656827c7654701e69b5680199b Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 22 Mar 2019 06:54:18 -0400 Subject: [PATCH 772/814] Fix compilation error in JWT using const_cast. I got this error on an unrelated patch, and I believe the Distribution Test is broken: /var/local/git/grpc/src/core/lib/security/credentials/jwt/jwt_verifier.cc:628:57: error: invalid conversion from 'const uint8_t* {aka const unsigned char*}' to 'unsigned char*' [-fpermissive] GRPC_SLICE_LENGTH(signature)) != 1) { ^ In file included from /usr/include/openssl/pem.h:69:0, from /var/local/git/grpc/src/core/lib/security/credentials/jwt/jwt_verifier.cc:35: /usr/include/openssl/evp.h:642:5: note: initializing argument 2 of 'int EVP_DigestVerifyFinal(EVP_MD_CTX*, unsigned char*, size_t)' int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen); --- src/core/lib/security/credentials/jwt/jwt_verifier.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc index 5b120eddb43..d573c30787d 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc @@ -624,8 +624,9 @@ static int verify_jwt_signature(EVP_PKEY* key, const char* alg, gpr_log(GPR_ERROR, "EVP_DigestVerifyUpdate failed."); goto end; } - if (EVP_DigestVerifyFinal(md_ctx, GRPC_SLICE_START_PTR(signature), - GRPC_SLICE_LENGTH(signature)) != 1) { + if (EVP_DigestVerifyFinal( + md_ctx, const_cast(GRPC_SLICE_START_PTR(signature)), + GRPC_SLICE_LENGTH(signature)) != 1) { gpr_log(GPR_ERROR, "JWT signature verification failed."); goto end; } From 50aed8d23835aa9593ff467e0a25aff62a34175a Mon Sep 17 00:00:00 2001 From: kkm Date: Fri, 22 Mar 2019 07:37:39 -0700 Subject: [PATCH 773/814] fixup! C# tools: support generated filename corner cases --- src/csharp/Grpc.Tools/GeneratorServices.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Tools/GeneratorServices.cs b/src/csharp/Grpc.Tools/GeneratorServices.cs index c956c89d6d8..655c92891ae 100644 --- a/src/csharp/Grpc.Tools/GeneratorServices.cs +++ b/src/csharp/Grpc.Tools/GeneratorServices.cs @@ -110,7 +110,7 @@ namespace Grpc.Tools } // This is how the protoc codegen constructs its output filename. - // See protobuf/compiler/csharp/csharp_helpers.cc:356. + // See protobuf/compiler/csharp/csharp_helpers.cc:137. // Note that protoc explicitly discards non-ASCII letters. string LowerUnderscoreToUpperCamelProtocWay(string str) { From aa40424bb26f76a1ecb10048ad168e25d2e674af Mon Sep 17 00:00:00 2001 From: kkm Date: Fri, 22 Mar 2019 08:03:15 -0700 Subject: [PATCH 774/814] fixup! C# tools: support generated filename corner cases --- src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs index 782c63b7107..320bb6dc9fc 100644 --- a/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs @@ -35,6 +35,7 @@ namespace Grpc.Tools.Tests [TestCase("one_two.proto", "OneTwo.cs", "OneTwoGrpc.cs")] [TestCase("ONE_TWO.proto", "ONETWO.cs", "ONETWOGrpc.cs")] [TestCase("one.two.proto", "OneTwo.cs", "One.twoGrpc.cs")] + [TestCase("one123two.proto", "One123Two.cs", "One123twoGrpc.cs")] [TestCase("__one_two!.proto", "OneTwo.cs", "OneTwo!Grpc.cs")] [TestCase("one(two).proto", "OneTwo.cs", "One(two)Grpc.cs")] [TestCase("one_(two).proto", "OneTwo.cs", "One(two)Grpc.cs")] From c9e1a71c8e104a575135a8a4b1a4dc7d4aee1234 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 22 Mar 2019 16:05:04 -0700 Subject: [PATCH 775/814] Remove unnecessary hack which causes data races --- .../chttp2/transport/chttp2_transport.cc | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 49ec869d707..0d25645c07e 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1409,21 +1409,13 @@ static void perform_stream_op_locked(void* stream_op, } grpc_closure* on_complete = op->on_complete; - // TODO(roth): This is a hack needed because we use data inside of the - // closure itself to do the barrier calculation (i.e., to ensure that - // we don't schedule the closure until all ops in the batch have been - // completed). This can go away once we move to a new C++ closure API - // that provides the ability to create a barrier closure. - if (on_complete == nullptr) { - on_complete = GRPC_CLOSURE_INIT(&op->handler_private.closure, do_nothing, - nullptr, grpc_schedule_on_exec_ctx); + if(on_complete != nullptr) { + /* This batch has send ops. Use final_data as a barrier until enqueue time; + * the inital counter is dropped at the end of this function */ + on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT; + on_complete->error_data.error = GRPC_ERROR_NONE; } - /* use final_data as a barrier until enqueue time; the inital counter is - dropped at the end of this function */ - on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT; - on_complete->error_data.error = GRPC_ERROR_NONE; - if (op->cancel_stream) { GRPC_STATS_INC_HTTP2_OP_CANCEL(); grpc_chttp2_cancel_stream(t, s, op_payload->cancel_stream.cancel_error); @@ -1672,8 +1664,10 @@ static void perform_stream_op_locked(void* stream_op, grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); } - grpc_chttp2_complete_closure_step(t, s, &on_complete, GRPC_ERROR_NONE, - "op->on_complete"); + if(on_complete != nullptr) { + grpc_chttp2_complete_closure_step(t, s, &on_complete, GRPC_ERROR_NONE, + "op->on_complete"); + } GRPC_CHTTP2_STREAM_UNREF(s, "perform_stream_op"); } From eab66cb6cc1afd4586a40e16667a59234a133490 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 22 Mar 2019 16:08:11 -0700 Subject: [PATCH 776/814] Remove unused function --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 0d25645c07e..d334b470bf7 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1363,8 +1363,6 @@ static void complete_fetch_locked(void* gs, grpc_error* error) { } } -static void do_nothing(void* arg, grpc_error* error) {} - static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id, bool is_client, bool is_initial) { for (grpc_linked_mdelem* md = md_batch->list.head; md != nullptr; @@ -1409,7 +1407,7 @@ static void perform_stream_op_locked(void* stream_op, } grpc_closure* on_complete = op->on_complete; - if(on_complete != nullptr) { + if (on_complete != nullptr) { /* This batch has send ops. Use final_data as a barrier until enqueue time; * the inital counter is dropped at the end of this function */ on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT; @@ -1664,7 +1662,7 @@ static void perform_stream_op_locked(void* stream_op, grpc_chttp2_maybe_complete_recv_trailing_metadata(t, s); } - if(on_complete != nullptr) { + if (on_complete != nullptr) { grpc_chttp2_complete_closure_step(t, s, &on_complete, GRPC_ERROR_NONE, "op->on_complete"); } From 65e266b47f9c505d0d8cdc82795b82bb457f995f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 22 Mar 2019 16:35:34 -0700 Subject: [PATCH 777/814] Locked function needs to be run inside a combiner --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 49ec869d707..1cbfbac17f2 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -678,7 +678,7 @@ grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t, grpc_slice_buffer_init(&decompressed_data_buffer); GRPC_CLOSURE_INIT(&complete_fetch_locked, ::complete_fetch_locked, this, - grpc_schedule_on_exec_ctx); + grpc_combiner_scheduler(t->combiner)); GRPC_CLOSURE_INIT(&reset_byte_stream, ::reset_byte_stream, this, grpc_combiner_scheduler(t->combiner)); } From 072749b38c7008943b66eb4cd9bfa420636f0df9 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 22 Mar 2019 16:58:14 -0700 Subject: [PATCH 778/814] Reviewer comments --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index d334b470bf7..6e2d323fe6c 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1407,9 +1407,10 @@ static void perform_stream_op_locked(void* stream_op, } grpc_closure* on_complete = op->on_complete; + // on_complete will be null if and only if there are no send ops in the batch. if (on_complete != nullptr) { - /* This batch has send ops. Use final_data as a barrier until enqueue time; - * the inital counter is dropped at the end of this function */ + // This batch has send ops. Use final_data as a barrier until enqueue time; + // the inital counter is dropped at the end of this function. on_complete->next_data.scratch = CLOSURE_BARRIER_FIRST_REF_BIT; on_complete->error_data.error = GRPC_ERROR_NONE; } From a7b2ed3b98657b079f989a0a009e7300ac514579 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 22 Mar 2019 17:25:54 -0700 Subject: [PATCH 779/814] Add documentation for 'grpcio-status' package --- doc/python/sphinx/conf.py | 1 + doc/python/sphinx/grpc_status.rst | 7 +++++++ doc/python/sphinx/index.rst | 1 + 3 files changed, 9 insertions(+) create mode 100644 doc/python/sphinx/grpc_status.rst diff --git a/doc/python/sphinx/conf.py b/doc/python/sphinx/conf.py index 307c3bdaf60..7cb5ee4d66e 100644 --- a/doc/python/sphinx/conf.py +++ b/doc/python/sphinx/conf.py @@ -22,6 +22,7 @@ sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio')) sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_channelz')) sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_health_checking')) sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_reflection')) +sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_status')) sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_testing')) # -- Project information ----------------------------------------------------- diff --git a/doc/python/sphinx/grpc_status.rst b/doc/python/sphinx/grpc_status.rst new file mode 100644 index 00000000000..2b9a324e3a4 --- /dev/null +++ b/doc/python/sphinx/grpc_status.rst @@ -0,0 +1,7 @@ +gRPC Status +==================== + +Module Contents +--------------- + +.. automodule:: grpc_status.rpc_status diff --git a/doc/python/sphinx/index.rst b/doc/python/sphinx/index.rst index 2f8a47a0747..bb671e75603 100644 --- a/doc/python/sphinx/index.rst +++ b/doc/python/sphinx/index.rst @@ -13,6 +13,7 @@ API Reference grpc_channelz grpc_health_checking grpc_reflection + grpc_status grpc_testing glossary From e95937374237a42faffbae530694265ffd1478d0 Mon Sep 17 00:00:00 2001 From: Vishal Powar Date: Fri, 22 Mar 2019 09:59:25 -0700 Subject: [PATCH 780/814] Generate upb code for cds protos and BUILD rule changes --- BUILD | 46 +- .../envoy/api/v2/auth/cert.upb.c | 199 ++++ .../envoy/api/v2/auth/cert.upb.h | 730 ++++++++++++ .../ext/upb-generated/envoy/api/v2/cds.upb.c | 285 +++++ .../ext/upb-generated/envoy/api/v2/cds.upb.h | 1012 +++++++++++++++++ .../api/v2/cluster/circuit_breaker.upb.c | 51 + .../api/v2/cluster/circuit_breaker.upb.h | 143 +++ .../api/v2/cluster/outlier_detection.upb.c | 45 + .../api/v2/cluster/outlier_detection.upb.h | 199 ++++ .../envoy/api/v2/core/config_source.upb.c | 81 ++ .../envoy/api/v2/core/config_source.upb.h | 258 +++++ .../envoy/api/v2/core/grpc_service.upb.c | 175 +++ .../envoy/api/v2/core/grpc_service.upb.h | 574 ++++++++++ .../envoy/api/v2/core/protocol.upb.c | 88 ++ .../envoy/api/v2/core/protocol.upb.h | 237 ++++ .../upb-generated/google/protobuf/empty.upb.c | 22 + .../upb-generated/google/protobuf/empty.upb.h | 52 + tools/codegen/core/gen_upb_api.sh | 12 +- 18 files changed, 4201 insertions(+), 8 deletions(-) create mode 100644 src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h create mode 100644 src/core/ext/upb-generated/envoy/api/v2/cds.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/cds.upb.h create mode 100644 src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h create mode 100644 src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c create mode 100644 src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h create mode 100644 src/core/ext/upb-generated/google/protobuf/empty.upb.c create mode 100644 src/core/ext/upb-generated/google/protobuf/empty.upb.h diff --git a/BUILD b/BUILD index a92a9270675..12687c799ef 100644 --- a/BUILD +++ b/BUILD @@ -2315,20 +2315,22 @@ grpc_cc_library( grpc_cc_library( name = "envoy_ads_upb", srcs = [ - "src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c", - "src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c", - "src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c", "src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c", "src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/cds.upb.c", "src/core/ext/upb-generated/envoy/api/v2/eds.upb.c", "src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.c", ], hdrs = [ - "src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h", - "src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h", - "src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h", "src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h", "src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/cds.upb.h", "src/core/ext/upb-generated/envoy/api/v2/eds.upb.h", "src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h", ], @@ -2337,9 +2339,39 @@ grpc_cc_library( "upb_lib", ], deps = [ + ":envoy_core_upb", + ":envoy_type_upb", ":google_api_upb", ":proto_gen_validate_upb", + ] +) + +grpc_cc_library( + name = "envoy_core_upb", + srcs = [ + "src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c", + "src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h", + "src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h", + ], + language = "c++", + external_deps = [ + "upb_lib", + ], + deps = [ ":envoy_type_upb", + ":google_api_upb", + ":proto_gen_validate_upb" ] ) @@ -2390,6 +2422,7 @@ grpc_cc_library( "src/core/ext/upb-generated/google/protobuf/any.upb.c", "src/core/ext/upb-generated/google/protobuf/descriptor.upb.c", "src/core/ext/upb-generated/google/protobuf/duration.upb.c", + "src/core/ext/upb-generated/google/protobuf/empty.upb.c", "src/core/ext/upb-generated/google/protobuf/struct.upb.c", "src/core/ext/upb-generated/google/protobuf/timestamp.upb.c", "src/core/ext/upb-generated/google/protobuf/wrappers.upb.c", @@ -2401,6 +2434,7 @@ grpc_cc_library( "src/core/ext/upb-generated/google/protobuf/any.upb.h", "src/core/ext/upb-generated/google/protobuf/descriptor.upb.h", "src/core/ext/upb-generated/google/protobuf/duration.upb.h", + "src/core/ext/upb-generated/google/protobuf/empty.upb.h", "src/core/ext/upb-generated/google/protobuf/struct.upb.h", "src/core/ext/upb-generated/google/protobuf/timestamp.upb.h", "src/core/ext/upb-generated/google/protobuf/wrappers.upb.h", diff --git a/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c b/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c new file mode 100644 index 00000000000..e8a2fb32bab --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c @@ -0,0 +1,199 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/auth/cert.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/auth/cert.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "envoy/api/v2/core/config_source.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout_field envoy_api_v2_auth_TlsParameters__fields[4] = { + {1, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 14, 1}, + {3, UPB_SIZE(16, 16), 0, 0, 9, 3}, + {4, UPB_SIZE(20, 24), 0, 0, 9, 3}, +}; + +const upb_msglayout envoy_api_v2_auth_TlsParameters_msginit = { + NULL, + &envoy_api_v2_auth_TlsParameters__fields[0], + UPB_SIZE(24, 32), 4, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_TlsCertificate_submsgs[5] = { + &envoy_api_v2_core_DataSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_TlsCertificate__fields[5] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 0, 11, 1}, + {4, UPB_SIZE(12, 24), 0, 0, 11, 1}, + {5, UPB_SIZE(16, 32), 0, 0, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_auth_TlsCertificate_msginit = { + &envoy_api_v2_auth_TlsCertificate_submsgs[0], + &envoy_api_v2_auth_TlsCertificate__fields[0], + UPB_SIZE(20, 40), 5, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_TlsSessionTicketKeys_submsgs[1] = { + &envoy_api_v2_core_DataSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_TlsSessionTicketKeys__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_auth_TlsSessionTicketKeys_msginit = { + &envoy_api_v2_auth_TlsSessionTicketKeys_submsgs[0], + &envoy_api_v2_auth_TlsSessionTicketKeys__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_CertificateValidationContext_submsgs[4] = { + &envoy_api_v2_core_DataSource_msginit, + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_CertificateValidationContext__fields[8] = { + {1, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {2, UPB_SIZE(20, 40), 0, 0, 9, 3}, + {3, UPB_SIZE(24, 48), 0, 0, 9, 3}, + {4, UPB_SIZE(28, 56), 0, 0, 9, 3}, + {5, UPB_SIZE(8, 16), 0, 1, 11, 1}, + {6, UPB_SIZE(12, 24), 0, 1, 11, 1}, + {7, UPB_SIZE(16, 32), 0, 0, 11, 1}, + {8, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_CertificateValidationContext_msginit = { + &envoy_api_v2_auth_CertificateValidationContext_submsgs[0], + &envoy_api_v2_auth_CertificateValidationContext__fields[0], + UPB_SIZE(32, 64), 8, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_CommonTlsContext_submsgs[6] = { + &envoy_api_v2_auth_CertificateValidationContext_msginit, + &envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit, + &envoy_api_v2_auth_SdsSecretConfig_msginit, + &envoy_api_v2_auth_TlsCertificate_msginit, + &envoy_api_v2_auth_TlsParameters_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_CommonTlsContext__fields[7] = { + {1, UPB_SIZE(0, 0), 0, 4, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 3, 11, 3}, + {3, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 0, 11, 1}, + {4, UPB_SIZE(8, 16), 0, 0, 9, 3}, + {6, UPB_SIZE(12, 24), 0, 2, 11, 3}, + {7, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 2, 11, 1}, + {8, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_CommonTlsContext_msginit = { + &envoy_api_v2_auth_CommonTlsContext_submsgs[0], + &envoy_api_v2_auth_CommonTlsContext__fields[0], + UPB_SIZE(24, 48), 7, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_submsgs[2] = { + &envoy_api_v2_auth_CertificateValidationContext_msginit, + &envoy_api_v2_auth_SdsSecretConfig_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit = { + &envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_submsgs[0], + &envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_UpstreamTlsContext_submsgs[1] = { + &envoy_api_v2_auth_CommonTlsContext_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_UpstreamTlsContext__fields[3] = { + {1, UPB_SIZE(12, 24), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 9, 1}, + {3, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_UpstreamTlsContext_msginit = { + &envoy_api_v2_auth_UpstreamTlsContext_submsgs[0], + &envoy_api_v2_auth_UpstreamTlsContext__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_DownstreamTlsContext_submsgs[5] = { + &envoy_api_v2_auth_CommonTlsContext_msginit, + &envoy_api_v2_auth_SdsSecretConfig_msginit, + &envoy_api_v2_auth_TlsSessionTicketKeys_msginit, + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_DownstreamTlsContext__fields[5] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 3, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 3, 11, 1}, + {4, UPB_SIZE(12, 24), UPB_SIZE(-17, -33), 2, 11, 1}, + {5, UPB_SIZE(12, 24), UPB_SIZE(-17, -33), 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_DownstreamTlsContext_msginit = { + &envoy_api_v2_auth_DownstreamTlsContext_submsgs[0], + &envoy_api_v2_auth_DownstreamTlsContext__fields[0], + UPB_SIZE(20, 40), 5, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_SdsSecretConfig_submsgs[1] = { + &envoy_api_v2_core_ConfigSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_SdsSecretConfig__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_SdsSecretConfig_msginit = { + &envoy_api_v2_auth_SdsSecretConfig_submsgs[0], + &envoy_api_v2_auth_SdsSecretConfig__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_auth_Secret_submsgs[3] = { + &envoy_api_v2_auth_CertificateValidationContext_msginit, + &envoy_api_v2_auth_TlsCertificate_msginit, + &envoy_api_v2_auth_TlsSessionTicketKeys_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_auth_Secret__fields[4] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 2, 11, 1}, + {4, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_auth_Secret_msginit = { + &envoy_api_v2_auth_Secret_submsgs[0], + &envoy_api_v2_auth_Secret__fields[0], + UPB_SIZE(16, 32), 4, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h b/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h new file mode 100644 index 00000000000..22379341331 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h @@ -0,0 +1,730 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/auth/cert.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_AUTH_CERT_PROTO_UPB_H_ +#define ENVOY_API_V2_AUTH_CERT_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_auth_TlsParameters; +struct envoy_api_v2_auth_TlsCertificate; +struct envoy_api_v2_auth_TlsSessionTicketKeys; +struct envoy_api_v2_auth_CertificateValidationContext; +struct envoy_api_v2_auth_CommonTlsContext; +struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext; +struct envoy_api_v2_auth_UpstreamTlsContext; +struct envoy_api_v2_auth_DownstreamTlsContext; +struct envoy_api_v2_auth_SdsSecretConfig; +struct envoy_api_v2_auth_Secret; +typedef struct envoy_api_v2_auth_TlsParameters envoy_api_v2_auth_TlsParameters; +typedef struct envoy_api_v2_auth_TlsCertificate envoy_api_v2_auth_TlsCertificate; +typedef struct envoy_api_v2_auth_TlsSessionTicketKeys envoy_api_v2_auth_TlsSessionTicketKeys; +typedef struct envoy_api_v2_auth_CertificateValidationContext envoy_api_v2_auth_CertificateValidationContext; +typedef struct envoy_api_v2_auth_CommonTlsContext envoy_api_v2_auth_CommonTlsContext; +typedef struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext; +typedef struct envoy_api_v2_auth_UpstreamTlsContext envoy_api_v2_auth_UpstreamTlsContext; +typedef struct envoy_api_v2_auth_DownstreamTlsContext envoy_api_v2_auth_DownstreamTlsContext; +typedef struct envoy_api_v2_auth_SdsSecretConfig envoy_api_v2_auth_SdsSecretConfig; +typedef struct envoy_api_v2_auth_Secret envoy_api_v2_auth_Secret; +extern const upb_msglayout envoy_api_v2_auth_TlsParameters_msginit; +extern const upb_msglayout envoy_api_v2_auth_TlsCertificate_msginit; +extern const upb_msglayout envoy_api_v2_auth_TlsSessionTicketKeys_msginit; +extern const upb_msglayout envoy_api_v2_auth_CertificateValidationContext_msginit; +extern const upb_msglayout envoy_api_v2_auth_CommonTlsContext_msginit; +extern const upb_msglayout envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit; +extern const upb_msglayout envoy_api_v2_auth_UpstreamTlsContext_msginit; +extern const upb_msglayout envoy_api_v2_auth_DownstreamTlsContext_msginit; +extern const upb_msglayout envoy_api_v2_auth_SdsSecretConfig_msginit; +extern const upb_msglayout envoy_api_v2_auth_Secret_msginit; +struct envoy_api_v2_core_ConfigSource; +struct envoy_api_v2_core_DataSource; +struct google_protobuf_BoolValue; +extern const upb_msglayout envoy_api_v2_core_ConfigSource_msginit; +extern const upb_msglayout envoy_api_v2_core_DataSource_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_auth_TlsParameters_TLS_AUTO = 0, + envoy_api_v2_auth_TlsParameters_TLSv1_0 = 1, + envoy_api_v2_auth_TlsParameters_TLSv1_1 = 2, + envoy_api_v2_auth_TlsParameters_TLSv1_2 = 3, + envoy_api_v2_auth_TlsParameters_TLSv1_3 = 4 +} envoy_api_v2_auth_TlsParameters_TlsProtocol; + + +/* envoy.api.v2.auth.TlsParameters */ + +UPB_INLINE envoy_api_v2_auth_TlsParameters *envoy_api_v2_auth_TlsParameters_new(upb_arena *arena) { + return (envoy_api_v2_auth_TlsParameters *)upb_msg_new(&envoy_api_v2_auth_TlsParameters_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_TlsParameters *envoy_api_v2_auth_TlsParameters_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_TlsParameters *ret = envoy_api_v2_auth_TlsParameters_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_TlsParameters_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_TlsParameters_serialize(const envoy_api_v2_auth_TlsParameters *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_TlsParameters_msginit, arena, len); +} + +UPB_INLINE int32_t envoy_api_v2_auth_TlsParameters_tls_minimum_protocol_version(const envoy_api_v2_auth_TlsParameters *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE int32_t envoy_api_v2_auth_TlsParameters_tls_maximum_protocol_version(const envoy_api_v2_auth_TlsParameters *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_TlsParameters_cipher_suites(const envoy_api_v2_auth_TlsParameters *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(16, 16), len); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_TlsParameters_ecdh_curves(const envoy_api_v2_auth_TlsParameters *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); } + +UPB_INLINE void envoy_api_v2_auth_TlsParameters_set_tls_minimum_protocol_version(envoy_api_v2_auth_TlsParameters *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_auth_TlsParameters_set_tls_maximum_protocol_version(envoy_api_v2_auth_TlsParameters *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE upb_strview* envoy_api_v2_auth_TlsParameters_mutable_cipher_suites(envoy_api_v2_auth_TlsParameters *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 16), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_TlsParameters_resize_cipher_suites(envoy_api_v2_auth_TlsParameters *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(16, 16), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_TlsParameters_add_cipher_suites(envoy_api_v2_auth_TlsParameters *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(16, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_TlsParameters_mutable_ecdh_curves(envoy_api_v2_auth_TlsParameters *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_TlsParameters_resize_ecdh_curves(envoy_api_v2_auth_TlsParameters *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_TlsParameters_add_ecdh_curves(envoy_api_v2_auth_TlsParameters *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 24), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* envoy.api.v2.auth.TlsCertificate */ + +UPB_INLINE envoy_api_v2_auth_TlsCertificate *envoy_api_v2_auth_TlsCertificate_new(upb_arena *arena) { + return (envoy_api_v2_auth_TlsCertificate *)upb_msg_new(&envoy_api_v2_auth_TlsCertificate_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_TlsCertificate *envoy_api_v2_auth_TlsCertificate_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_TlsCertificate *ret = envoy_api_v2_auth_TlsCertificate_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_TlsCertificate_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_TlsCertificate_serialize(const envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_TlsCertificate_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_certificate_chain(const envoy_api_v2_auth_TlsCertificate *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_private_key(const envoy_api_v2_auth_TlsCertificate *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_password(const envoy_api_v2_auth_TlsCertificate *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(8, 16)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_ocsp_staple(const envoy_api_v2_auth_TlsCertificate *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(12, 24)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* const* envoy_api_v2_auth_TlsCertificate_signed_certificate_timestamp(const envoy_api_v2_auth_TlsCertificate *msg, size_t *len) { return (const struct envoy_api_v2_core_DataSource* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); } + +UPB_INLINE void envoy_api_v2_auth_TlsCertificate_set_certificate_chain(envoy_api_v2_auth_TlsCertificate *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_mutable_certificate_chain(envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_TlsCertificate_certificate_chain(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_TlsCertificate_set_certificate_chain(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_TlsCertificate_set_private_key(envoy_api_v2_auth_TlsCertificate *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_mutable_private_key(envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_TlsCertificate_private_key(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_TlsCertificate_set_private_key(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_TlsCertificate_set_password(envoy_api_v2_auth_TlsCertificate *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_mutable_password(envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_TlsCertificate_password(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_TlsCertificate_set_password(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_TlsCertificate_set_ocsp_staple(envoy_api_v2_auth_TlsCertificate *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_mutable_ocsp_staple(envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_TlsCertificate_ocsp_staple(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_TlsCertificate_set_ocsp_staple(msg, sub); + } + return sub; +} +UPB_INLINE struct envoy_api_v2_core_DataSource** envoy_api_v2_auth_TlsCertificate_mutable_signed_certificate_timestamp(envoy_api_v2_auth_TlsCertificate *msg, size_t *len) { + return (struct envoy_api_v2_core_DataSource**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len); +} +UPB_INLINE struct envoy_api_v2_core_DataSource** envoy_api_v2_auth_TlsCertificate_resize_signed_certificate_timestamp(envoy_api_v2_auth_TlsCertificate *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_DataSource**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsCertificate_add_signed_certificate_timestamp(envoy_api_v2_auth_TlsCertificate *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.auth.TlsSessionTicketKeys */ + +UPB_INLINE envoy_api_v2_auth_TlsSessionTicketKeys *envoy_api_v2_auth_TlsSessionTicketKeys_new(upb_arena *arena) { + return (envoy_api_v2_auth_TlsSessionTicketKeys *)upb_msg_new(&envoy_api_v2_auth_TlsSessionTicketKeys_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_TlsSessionTicketKeys *envoy_api_v2_auth_TlsSessionTicketKeys_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_TlsSessionTicketKeys *ret = envoy_api_v2_auth_TlsSessionTicketKeys_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_TlsSessionTicketKeys_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_TlsSessionTicketKeys_serialize(const envoy_api_v2_auth_TlsSessionTicketKeys *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_TlsSessionTicketKeys_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_DataSource* const* envoy_api_v2_auth_TlsSessionTicketKeys_keys(const envoy_api_v2_auth_TlsSessionTicketKeys *msg, size_t *len) { return (const struct envoy_api_v2_core_DataSource* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE struct envoy_api_v2_core_DataSource** envoy_api_v2_auth_TlsSessionTicketKeys_mutable_keys(envoy_api_v2_auth_TlsSessionTicketKeys *msg, size_t *len) { + return (struct envoy_api_v2_core_DataSource**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE struct envoy_api_v2_core_DataSource** envoy_api_v2_auth_TlsSessionTicketKeys_resize_keys(envoy_api_v2_auth_TlsSessionTicketKeys *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_DataSource**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_TlsSessionTicketKeys_add_keys(envoy_api_v2_auth_TlsSessionTicketKeys *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.auth.CertificateValidationContext */ + +UPB_INLINE envoy_api_v2_auth_CertificateValidationContext *envoy_api_v2_auth_CertificateValidationContext_new(upb_arena *arena) { + return (envoy_api_v2_auth_CertificateValidationContext *)upb_msg_new(&envoy_api_v2_auth_CertificateValidationContext_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_CertificateValidationContext *envoy_api_v2_auth_CertificateValidationContext_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_CertificateValidationContext *ret = envoy_api_v2_auth_CertificateValidationContext_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_CertificateValidationContext_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_CertificateValidationContext_serialize(const envoy_api_v2_auth_CertificateValidationContext *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_CertificateValidationContext_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_CertificateValidationContext_trusted_ca(const envoy_api_v2_auth_CertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_CertificateValidationContext_verify_certificate_hash(const envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_CertificateValidationContext_verify_certificate_spki(const envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_CertificateValidationContext_verify_subject_alt_name(const envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_auth_CertificateValidationContext_require_ocsp_staple(const envoy_api_v2_auth_CertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(8, 16)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_auth_CertificateValidationContext_require_signed_certificate_timestamp(const envoy_api_v2_auth_CertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(12, 24)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_CertificateValidationContext_crl(const envoy_api_v2_auth_CertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(16, 32)); } +UPB_INLINE bool envoy_api_v2_auth_CertificateValidationContext_allow_expired_certificate(const envoy_api_v2_auth_CertificateValidationContext *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_auth_CertificateValidationContext_set_trusted_ca(envoy_api_v2_auth_CertificateValidationContext *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_CertificateValidationContext_mutable_trusted_ca(envoy_api_v2_auth_CertificateValidationContext *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_CertificateValidationContext_trusted_ca(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CertificateValidationContext_set_trusted_ca(msg, sub); + } + return sub; +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_mutable_verify_certificate_hash(envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_resize_verify_certificate_hash(envoy_api_v2_auth_CertificateValidationContext *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_CertificateValidationContext_add_verify_certificate_hash(envoy_api_v2_auth_CertificateValidationContext *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 40), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_mutable_verify_certificate_spki(envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_resize_verify_certificate_spki(envoy_api_v2_auth_CertificateValidationContext *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_CertificateValidationContext_add_verify_certificate_spki(envoy_api_v2_auth_CertificateValidationContext *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_mutable_verify_subject_alt_name(envoy_api_v2_auth_CertificateValidationContext *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CertificateValidationContext_resize_verify_subject_alt_name(envoy_api_v2_auth_CertificateValidationContext *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_CertificateValidationContext_add_verify_subject_alt_name(envoy_api_v2_auth_CertificateValidationContext *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE void envoy_api_v2_auth_CertificateValidationContext_set_require_ocsp_staple(envoy_api_v2_auth_CertificateValidationContext *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_auth_CertificateValidationContext_mutable_require_ocsp_staple(envoy_api_v2_auth_CertificateValidationContext *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_auth_CertificateValidationContext_require_ocsp_staple(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CertificateValidationContext_set_require_ocsp_staple(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CertificateValidationContext_set_require_signed_certificate_timestamp(envoy_api_v2_auth_CertificateValidationContext *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_auth_CertificateValidationContext_mutable_require_signed_certificate_timestamp(envoy_api_v2_auth_CertificateValidationContext *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_auth_CertificateValidationContext_require_signed_certificate_timestamp(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CertificateValidationContext_set_require_signed_certificate_timestamp(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CertificateValidationContext_set_crl(envoy_api_v2_auth_CertificateValidationContext *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_auth_CertificateValidationContext_mutable_crl(envoy_api_v2_auth_CertificateValidationContext *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_auth_CertificateValidationContext_crl(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CertificateValidationContext_set_crl(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CertificateValidationContext_set_allow_expired_certificate(envoy_api_v2_auth_CertificateValidationContext *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.auth.CommonTlsContext */ + +UPB_INLINE envoy_api_v2_auth_CommonTlsContext *envoy_api_v2_auth_CommonTlsContext_new(upb_arena *arena) { + return (envoy_api_v2_auth_CommonTlsContext *)upb_msg_new(&envoy_api_v2_auth_CommonTlsContext_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_CommonTlsContext *envoy_api_v2_auth_CommonTlsContext_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_CommonTlsContext *ret = envoy_api_v2_auth_CommonTlsContext_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_CommonTlsContext_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_CommonTlsContext_serialize(const envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_CommonTlsContext_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_auth_CommonTlsContext_validation_context_type_validation_context = 3, + envoy_api_v2_auth_CommonTlsContext_validation_context_type_validation_context_sds_secret_config = 7, + envoy_api_v2_auth_CommonTlsContext_validation_context_type_combined_validation_context = 8, + envoy_api_v2_auth_CommonTlsContext_validation_context_type_NOT_SET = 0, +} envoy_api_v2_auth_CommonTlsContext_validation_context_type_oneofcases; +UPB_INLINE envoy_api_v2_auth_CommonTlsContext_validation_context_type_oneofcases envoy_api_v2_auth_CommonTlsContext_validation_context_type_case(const envoy_api_v2_auth_CommonTlsContext* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(20, 40)); } + +UPB_INLINE const envoy_api_v2_auth_TlsParameters* envoy_api_v2_auth_CommonTlsContext_tls_params(const envoy_api_v2_auth_CommonTlsContext *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_auth_TlsParameters*, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_auth_TlsCertificate* const* envoy_api_v2_auth_CommonTlsContext_tls_certificates(const envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { return (const envoy_api_v2_auth_TlsCertificate* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } +UPB_INLINE bool envoy_api_v2_auth_CommonTlsContext_has_validation_context(const envoy_api_v2_auth_CommonTlsContext *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(20, 40), 3); } +UPB_INLINE const envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_validation_context(const envoy_api_v2_auth_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 3, NULL); } +UPB_INLINE upb_strview const* envoy_api_v2_auth_CommonTlsContext_alpn_protocols(const envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); } +UPB_INLINE const envoy_api_v2_auth_SdsSecretConfig* const* envoy_api_v2_auth_CommonTlsContext_tls_certificate_sds_secret_configs(const envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { return (const envoy_api_v2_auth_SdsSecretConfig* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); } +UPB_INLINE bool envoy_api_v2_auth_CommonTlsContext_has_validation_context_sds_secret_config(const envoy_api_v2_auth_CommonTlsContext *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(20, 40), 7); } +UPB_INLINE const envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_CommonTlsContext_validation_context_sds_secret_config(const envoy_api_v2_auth_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 7, NULL); } +UPB_INLINE bool envoy_api_v2_auth_CommonTlsContext_has_combined_validation_context(const envoy_api_v2_auth_CommonTlsContext *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(20, 40), 8); } +UPB_INLINE const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_combined_validation_context(const envoy_api_v2_auth_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 8, NULL); } + +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_set_tls_params(envoy_api_v2_auth_CommonTlsContext *msg, envoy_api_v2_auth_TlsParameters* value) { + UPB_FIELD_AT(msg, envoy_api_v2_auth_TlsParameters*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_TlsParameters* envoy_api_v2_auth_CommonTlsContext_mutable_tls_params(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_TlsParameters* sub = (struct envoy_api_v2_auth_TlsParameters*)envoy_api_v2_auth_CommonTlsContext_tls_params(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_TlsParameters*)upb_msg_new(&envoy_api_v2_auth_TlsParameters_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_set_tls_params(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_auth_TlsCertificate** envoy_api_v2_auth_CommonTlsContext_mutable_tls_certificates(envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { + return (envoy_api_v2_auth_TlsCertificate**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE envoy_api_v2_auth_TlsCertificate** envoy_api_v2_auth_CommonTlsContext_resize_tls_certificates(envoy_api_v2_auth_CommonTlsContext *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_auth_TlsCertificate**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_auth_TlsCertificate* envoy_api_v2_auth_CommonTlsContext_add_tls_certificates(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_TlsCertificate* sub = (struct envoy_api_v2_auth_TlsCertificate*)upb_msg_new(&envoy_api_v2_auth_TlsCertificate_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_set_validation_context(envoy_api_v2_auth_CommonTlsContext *msg, envoy_api_v2_auth_CertificateValidationContext* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(16, 32), value, UPB_SIZE(20, 40), 3); +} +UPB_INLINE struct envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_mutable_validation_context(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CertificateValidationContext* sub = (struct envoy_api_v2_auth_CertificateValidationContext*)envoy_api_v2_auth_CommonTlsContext_validation_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CertificateValidationContext*)upb_msg_new(&envoy_api_v2_auth_CertificateValidationContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_set_validation_context(msg, sub); + } + return sub; +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CommonTlsContext_mutable_alpn_protocols(envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len); +} +UPB_INLINE upb_strview* envoy_api_v2_auth_CommonTlsContext_resize_alpn_protocols(envoy_api_v2_auth_CommonTlsContext *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_auth_CommonTlsContext_add_alpn_protocols(envoy_api_v2_auth_CommonTlsContext *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(8, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE envoy_api_v2_auth_SdsSecretConfig** envoy_api_v2_auth_CommonTlsContext_mutable_tls_certificate_sds_secret_configs(envoy_api_v2_auth_CommonTlsContext *msg, size_t *len) { + return (envoy_api_v2_auth_SdsSecretConfig**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len); +} +UPB_INLINE envoy_api_v2_auth_SdsSecretConfig** envoy_api_v2_auth_CommonTlsContext_resize_tls_certificate_sds_secret_configs(envoy_api_v2_auth_CommonTlsContext *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_auth_SdsSecretConfig**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_CommonTlsContext_add_tls_certificate_sds_secret_configs(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_SdsSecretConfig* sub = (struct envoy_api_v2_auth_SdsSecretConfig*)upb_msg_new(&envoy_api_v2_auth_SdsSecretConfig_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_set_validation_context_sds_secret_config(envoy_api_v2_auth_CommonTlsContext *msg, envoy_api_v2_auth_SdsSecretConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(16, 32), value, UPB_SIZE(20, 40), 7); +} +UPB_INLINE struct envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_CommonTlsContext_mutable_validation_context_sds_secret_config(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_SdsSecretConfig* sub = (struct envoy_api_v2_auth_SdsSecretConfig*)envoy_api_v2_auth_CommonTlsContext_validation_context_sds_secret_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_SdsSecretConfig*)upb_msg_new(&envoy_api_v2_auth_SdsSecretConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_set_validation_context_sds_secret_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_set_combined_validation_context(envoy_api_v2_auth_CommonTlsContext *msg, envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext*, UPB_SIZE(16, 32), value, UPB_SIZE(20, 40), 8); +} +UPB_INLINE struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_mutable_combined_validation_context(envoy_api_v2_auth_CommonTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext* sub = (struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext*)envoy_api_v2_auth_CommonTlsContext_combined_validation_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext*)upb_msg_new(&envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_set_combined_validation_context(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.auth.CommonTlsContext.CombinedCertificateValidationContext */ + +UPB_INLINE envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_new(upb_arena *arena) { + return (envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *)upb_msg_new(&envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *ret = envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_serialize(const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_default_validation_context(const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_validation_context_sds_secret_config(const envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_set_default_validation_context(envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg, envoy_api_v2_auth_CertificateValidationContext* value) { + UPB_FIELD_AT(msg, envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_mutable_default_validation_context(envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CertificateValidationContext* sub = (struct envoy_api_v2_auth_CertificateValidationContext*)envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_default_validation_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CertificateValidationContext*)upb_msg_new(&envoy_api_v2_auth_CertificateValidationContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_set_default_validation_context(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_set_validation_context_sds_secret_config(envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg, envoy_api_v2_auth_SdsSecretConfig* value) { + UPB_FIELD_AT(msg, envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_mutable_validation_context_sds_secret_config(envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_SdsSecretConfig* sub = (struct envoy_api_v2_auth_SdsSecretConfig*)envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_validation_context_sds_secret_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_SdsSecretConfig*)upb_msg_new(&envoy_api_v2_auth_SdsSecretConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext_set_validation_context_sds_secret_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.auth.UpstreamTlsContext */ + +UPB_INLINE envoy_api_v2_auth_UpstreamTlsContext *envoy_api_v2_auth_UpstreamTlsContext_new(upb_arena *arena) { + return (envoy_api_v2_auth_UpstreamTlsContext *)upb_msg_new(&envoy_api_v2_auth_UpstreamTlsContext_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_UpstreamTlsContext *envoy_api_v2_auth_UpstreamTlsContext_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_UpstreamTlsContext *ret = envoy_api_v2_auth_UpstreamTlsContext_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_UpstreamTlsContext_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_UpstreamTlsContext_serialize(const envoy_api_v2_auth_UpstreamTlsContext *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_UpstreamTlsContext_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_auth_CommonTlsContext* envoy_api_v2_auth_UpstreamTlsContext_common_tls_context(const envoy_api_v2_auth_UpstreamTlsContext *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_auth_CommonTlsContext*, UPB_SIZE(12, 24)); } +UPB_INLINE upb_strview envoy_api_v2_auth_UpstreamTlsContext_sni(const envoy_api_v2_auth_UpstreamTlsContext *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } +UPB_INLINE bool envoy_api_v2_auth_UpstreamTlsContext_allow_renegotiation(const envoy_api_v2_auth_UpstreamTlsContext *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_auth_UpstreamTlsContext_set_common_tls_context(envoy_api_v2_auth_UpstreamTlsContext *msg, envoy_api_v2_auth_CommonTlsContext* value) { + UPB_FIELD_AT(msg, envoy_api_v2_auth_CommonTlsContext*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_CommonTlsContext* envoy_api_v2_auth_UpstreamTlsContext_mutable_common_tls_context(envoy_api_v2_auth_UpstreamTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CommonTlsContext* sub = (struct envoy_api_v2_auth_CommonTlsContext*)envoy_api_v2_auth_UpstreamTlsContext_common_tls_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CommonTlsContext*)upb_msg_new(&envoy_api_v2_auth_CommonTlsContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_UpstreamTlsContext_set_common_tls_context(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_UpstreamTlsContext_set_sni(envoy_api_v2_auth_UpstreamTlsContext *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE void envoy_api_v2_auth_UpstreamTlsContext_set_allow_renegotiation(envoy_api_v2_auth_UpstreamTlsContext *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.auth.DownstreamTlsContext */ + +UPB_INLINE envoy_api_v2_auth_DownstreamTlsContext *envoy_api_v2_auth_DownstreamTlsContext_new(upb_arena *arena) { + return (envoy_api_v2_auth_DownstreamTlsContext *)upb_msg_new(&envoy_api_v2_auth_DownstreamTlsContext_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_DownstreamTlsContext *envoy_api_v2_auth_DownstreamTlsContext_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_DownstreamTlsContext *ret = envoy_api_v2_auth_DownstreamTlsContext_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_DownstreamTlsContext_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_DownstreamTlsContext_serialize(const envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_DownstreamTlsContext_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_session_ticket_keys = 4, + envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_session_ticket_keys_sds_secret_config = 5, + envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_NOT_SET = 0, +} envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_oneofcases; +UPB_INLINE envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_oneofcases envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_type_case(const envoy_api_v2_auth_DownstreamTlsContext* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(16, 32)); } + +UPB_INLINE const envoy_api_v2_auth_CommonTlsContext* envoy_api_v2_auth_DownstreamTlsContext_common_tls_context(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_auth_CommonTlsContext*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_auth_DownstreamTlsContext_require_client_certificate(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_auth_DownstreamTlsContext_require_sni(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(8, 16)); } +UPB_INLINE bool envoy_api_v2_auth_DownstreamTlsContext_has_session_ticket_keys(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(16, 32), 4); } +UPB_INLINE const envoy_api_v2_auth_TlsSessionTicketKeys* envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_TlsSessionTicketKeys*, UPB_SIZE(12, 24), UPB_SIZE(16, 32), 4, NULL); } +UPB_INLINE bool envoy_api_v2_auth_DownstreamTlsContext_has_session_ticket_keys_sds_secret_config(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(16, 32), 5); } +UPB_INLINE const envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_sds_secret_config(const envoy_api_v2_auth_DownstreamTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(12, 24), UPB_SIZE(16, 32), 5, NULL); } + +UPB_INLINE void envoy_api_v2_auth_DownstreamTlsContext_set_common_tls_context(envoy_api_v2_auth_DownstreamTlsContext *msg, envoy_api_v2_auth_CommonTlsContext* value) { + UPB_FIELD_AT(msg, envoy_api_v2_auth_CommonTlsContext*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_CommonTlsContext* envoy_api_v2_auth_DownstreamTlsContext_mutable_common_tls_context(envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CommonTlsContext* sub = (struct envoy_api_v2_auth_CommonTlsContext*)envoy_api_v2_auth_DownstreamTlsContext_common_tls_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CommonTlsContext*)upb_msg_new(&envoy_api_v2_auth_CommonTlsContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_DownstreamTlsContext_set_common_tls_context(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_DownstreamTlsContext_set_require_client_certificate(envoy_api_v2_auth_DownstreamTlsContext *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_auth_DownstreamTlsContext_mutable_require_client_certificate(envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_auth_DownstreamTlsContext_require_client_certificate(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_DownstreamTlsContext_set_require_client_certificate(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_DownstreamTlsContext_set_require_sni(envoy_api_v2_auth_DownstreamTlsContext *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_auth_DownstreamTlsContext_mutable_require_sni(envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_auth_DownstreamTlsContext_require_sni(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_DownstreamTlsContext_set_require_sni(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_DownstreamTlsContext_set_session_ticket_keys(envoy_api_v2_auth_DownstreamTlsContext *msg, envoy_api_v2_auth_TlsSessionTicketKeys* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_TlsSessionTicketKeys*, UPB_SIZE(12, 24), value, UPB_SIZE(16, 32), 4); +} +UPB_INLINE struct envoy_api_v2_auth_TlsSessionTicketKeys* envoy_api_v2_auth_DownstreamTlsContext_mutable_session_ticket_keys(envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_TlsSessionTicketKeys* sub = (struct envoy_api_v2_auth_TlsSessionTicketKeys*)envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_TlsSessionTicketKeys*)upb_msg_new(&envoy_api_v2_auth_TlsSessionTicketKeys_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_DownstreamTlsContext_set_session_ticket_keys(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_DownstreamTlsContext_set_session_ticket_keys_sds_secret_config(envoy_api_v2_auth_DownstreamTlsContext *msg, envoy_api_v2_auth_SdsSecretConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_SdsSecretConfig*, UPB_SIZE(12, 24), value, UPB_SIZE(16, 32), 5); +} +UPB_INLINE struct envoy_api_v2_auth_SdsSecretConfig* envoy_api_v2_auth_DownstreamTlsContext_mutable_session_ticket_keys_sds_secret_config(envoy_api_v2_auth_DownstreamTlsContext *msg, upb_arena *arena) { + struct envoy_api_v2_auth_SdsSecretConfig* sub = (struct envoy_api_v2_auth_SdsSecretConfig*)envoy_api_v2_auth_DownstreamTlsContext_session_ticket_keys_sds_secret_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_SdsSecretConfig*)upb_msg_new(&envoy_api_v2_auth_SdsSecretConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_DownstreamTlsContext_set_session_ticket_keys_sds_secret_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.auth.SdsSecretConfig */ + +UPB_INLINE envoy_api_v2_auth_SdsSecretConfig *envoy_api_v2_auth_SdsSecretConfig_new(upb_arena *arena) { + return (envoy_api_v2_auth_SdsSecretConfig *)upb_msg_new(&envoy_api_v2_auth_SdsSecretConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_SdsSecretConfig *envoy_api_v2_auth_SdsSecretConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_SdsSecretConfig *ret = envoy_api_v2_auth_SdsSecretConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_SdsSecretConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_SdsSecretConfig_serialize(const envoy_api_v2_auth_SdsSecretConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_SdsSecretConfig_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_auth_SdsSecretConfig_name(const envoy_api_v2_auth_SdsSecretConfig *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_ConfigSource* envoy_api_v2_auth_SdsSecretConfig_sds_config(const envoy_api_v2_auth_SdsSecretConfig *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_ConfigSource*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_auth_SdsSecretConfig_set_name(envoy_api_v2_auth_SdsSecretConfig *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_auth_SdsSecretConfig_set_sds_config(envoy_api_v2_auth_SdsSecretConfig *msg, struct envoy_api_v2_core_ConfigSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_ConfigSource*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_ConfigSource* envoy_api_v2_auth_SdsSecretConfig_mutable_sds_config(envoy_api_v2_auth_SdsSecretConfig *msg, upb_arena *arena) { + struct envoy_api_v2_core_ConfigSource* sub = (struct envoy_api_v2_core_ConfigSource*)envoy_api_v2_auth_SdsSecretConfig_sds_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_ConfigSource*)upb_msg_new(&envoy_api_v2_core_ConfigSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_SdsSecretConfig_set_sds_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.auth.Secret */ + +UPB_INLINE envoy_api_v2_auth_Secret *envoy_api_v2_auth_Secret_new(upb_arena *arena) { + return (envoy_api_v2_auth_Secret *)upb_msg_new(&envoy_api_v2_auth_Secret_msginit, arena); +} +UPB_INLINE envoy_api_v2_auth_Secret *envoy_api_v2_auth_Secret_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_auth_Secret *ret = envoy_api_v2_auth_Secret_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_auth_Secret_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_auth_Secret_serialize(const envoy_api_v2_auth_Secret *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_auth_Secret_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_auth_Secret_type_tls_certificate = 2, + envoy_api_v2_auth_Secret_type_session_ticket_keys = 3, + envoy_api_v2_auth_Secret_type_validation_context = 4, + envoy_api_v2_auth_Secret_type_NOT_SET = 0, +} envoy_api_v2_auth_Secret_type_oneofcases; +UPB_INLINE envoy_api_v2_auth_Secret_type_oneofcases envoy_api_v2_auth_Secret_type_case(const envoy_api_v2_auth_Secret* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE upb_strview envoy_api_v2_auth_Secret_name(const envoy_api_v2_auth_Secret *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE bool envoy_api_v2_auth_Secret_has_tls_certificate(const envoy_api_v2_auth_Secret *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const envoy_api_v2_auth_TlsCertificate* envoy_api_v2_auth_Secret_tls_certificate(const envoy_api_v2_auth_Secret *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_TlsCertificate*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE bool envoy_api_v2_auth_Secret_has_session_ticket_keys(const envoy_api_v2_auth_Secret *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 3); } +UPB_INLINE const envoy_api_v2_auth_TlsSessionTicketKeys* envoy_api_v2_auth_Secret_session_ticket_keys(const envoy_api_v2_auth_Secret *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_TlsSessionTicketKeys*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 3, NULL); } +UPB_INLINE bool envoy_api_v2_auth_Secret_has_validation_context(const envoy_api_v2_auth_Secret *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 4); } +UPB_INLINE const envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_Secret_validation_context(const envoy_api_v2_auth_Secret *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 4, NULL); } + +UPB_INLINE void envoy_api_v2_auth_Secret_set_name(envoy_api_v2_auth_Secret *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_auth_Secret_set_tls_certificate(envoy_api_v2_auth_Secret *msg, envoy_api_v2_auth_TlsCertificate* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_TlsCertificate*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct envoy_api_v2_auth_TlsCertificate* envoy_api_v2_auth_Secret_mutable_tls_certificate(envoy_api_v2_auth_Secret *msg, upb_arena *arena) { + struct envoy_api_v2_auth_TlsCertificate* sub = (struct envoy_api_v2_auth_TlsCertificate*)envoy_api_v2_auth_Secret_tls_certificate(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_TlsCertificate*)upb_msg_new(&envoy_api_v2_auth_TlsCertificate_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_Secret_set_tls_certificate(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_Secret_set_session_ticket_keys(envoy_api_v2_auth_Secret *msg, envoy_api_v2_auth_TlsSessionTicketKeys* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_TlsSessionTicketKeys*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 3); +} +UPB_INLINE struct envoy_api_v2_auth_TlsSessionTicketKeys* envoy_api_v2_auth_Secret_mutable_session_ticket_keys(envoy_api_v2_auth_Secret *msg, upb_arena *arena) { + struct envoy_api_v2_auth_TlsSessionTicketKeys* sub = (struct envoy_api_v2_auth_TlsSessionTicketKeys*)envoy_api_v2_auth_Secret_session_ticket_keys(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_TlsSessionTicketKeys*)upb_msg_new(&envoy_api_v2_auth_TlsSessionTicketKeys_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_Secret_set_session_ticket_keys(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_auth_Secret_set_validation_context(envoy_api_v2_auth_Secret *msg, envoy_api_v2_auth_CertificateValidationContext* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_auth_CertificateValidationContext*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 4); +} +UPB_INLINE struct envoy_api_v2_auth_CertificateValidationContext* envoy_api_v2_auth_Secret_mutable_validation_context(envoy_api_v2_auth_Secret *msg, upb_arena *arena) { + struct envoy_api_v2_auth_CertificateValidationContext* sub = (struct envoy_api_v2_auth_CertificateValidationContext*)envoy_api_v2_auth_Secret_validation_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_CertificateValidationContext*)upb_msg_new(&envoy_api_v2_auth_CertificateValidationContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_auth_Secret_set_validation_context(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_AUTH_CERT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/cds.upb.c b/src/core/ext/upb-generated/envoy/api/v2/cds.upb.c new file mode 100644 index 00000000000..91a25cd220b --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cds.upb.c @@ -0,0 +1,285 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cds.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/cds.upb.h" +#include "envoy/api/v2/core/address.upb.h" +#include "envoy/api/v2/auth/cert.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "envoy/api/v2/core/config_source.upb.h" +#include "envoy/api/v2/discovery.upb.h" +#include "envoy/api/v2/core/health_check.upb.h" +#include "envoy/api/v2/core/protocol.upb.h" +#include "envoy/api/v2/cluster/circuit_breaker.upb.h" +#include "envoy/api/v2/cluster/outlier_detection.upb.h" +#include "envoy/api/v2/eds.upb.h" +#include "envoy/type/percent.upb.h" +#include "google/api/annotations.upb.h" +#include "google/protobuf/any.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/struct.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_Cluster_submsgs[26] = { + &envoy_api_v2_Cluster_CommonLbConfig_msginit, + &envoy_api_v2_Cluster_EdsClusterConfig_msginit, + &envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit, + &envoy_api_v2_Cluster_LbSubsetConfig_msginit, + &envoy_api_v2_Cluster_OriginalDstLbConfig_msginit, + &envoy_api_v2_Cluster_RingHashLbConfig_msginit, + &envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit, + &envoy_api_v2_ClusterLoadAssignment_msginit, + &envoy_api_v2_UpstreamConnectionOptions_msginit, + &envoy_api_v2_auth_UpstreamTlsContext_msginit, + &envoy_api_v2_cluster_CircuitBreakers_msginit, + &envoy_api_v2_cluster_OutlierDetection_msginit, + &envoy_api_v2_core_Address_msginit, + &envoy_api_v2_core_BindConfig_msginit, + &envoy_api_v2_core_HealthCheck_msginit, + &envoy_api_v2_core_Http1ProtocolOptions_msginit, + &envoy_api_v2_core_Http2ProtocolOptions_msginit, + &envoy_api_v2_core_HttpProtocolOptions_msginit, + &envoy_api_v2_core_Metadata_msginit, + &envoy_api_v2_core_TransportSocket_msginit, + &google_protobuf_Duration_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster__fields[34] = { + {1, UPB_SIZE(36, 40), 0, 0, 9, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {3, UPB_SIZE(52, 72), 0, 1, 11, 1}, + {4, UPB_SIZE(56, 80), 0, 20, 11, 1}, + {5, UPB_SIZE(60, 88), 0, 21, 11, 1}, + {6, UPB_SIZE(8, 8), 0, 0, 14, 1}, + {7, UPB_SIZE(128, 224), 0, 12, 11, 3}, + {8, UPB_SIZE(132, 232), 0, 14, 11, 3}, + {9, UPB_SIZE(64, 96), 0, 21, 11, 1}, + {10, UPB_SIZE(68, 104), 0, 10, 11, 1}, + {11, UPB_SIZE(72, 112), 0, 9, 11, 1}, + {13, UPB_SIZE(76, 120), 0, 15, 11, 1}, + {14, UPB_SIZE(80, 128), 0, 16, 11, 1}, + {16, UPB_SIZE(84, 136), 0, 20, 11, 1}, + {17, UPB_SIZE(16, 16), 0, 0, 14, 1}, + {18, UPB_SIZE(136, 240), 0, 12, 11, 3}, + {19, UPB_SIZE(88, 144), 0, 11, 11, 1}, + {20, UPB_SIZE(92, 152), 0, 20, 11, 1}, + {21, UPB_SIZE(96, 160), 0, 13, 11, 1}, + {22, UPB_SIZE(100, 168), 0, 3, 11, 1}, + {23, UPB_SIZE(148, 264), UPB_SIZE(-153, -273), 5, 11, 1}, + {24, UPB_SIZE(104, 176), 0, 19, 11, 1}, + {25, UPB_SIZE(108, 184), 0, 18, 11, 1}, + {26, UPB_SIZE(24, 24), 0, 0, 14, 1}, + {27, UPB_SIZE(112, 192), 0, 0, 11, 1}, + {28, UPB_SIZE(44, 56), 0, 0, 9, 1}, + {29, UPB_SIZE(116, 200), 0, 17, 11, 1}, + {30, UPB_SIZE(120, 208), 0, 8, 11, 1}, + {31, UPB_SIZE(32, 32), 0, 0, 8, 1}, + {32, UPB_SIZE(33, 33), 0, 0, 8, 1}, + {33, UPB_SIZE(124, 216), 0, 7, 11, 1}, + {34, UPB_SIZE(148, 264), UPB_SIZE(-153, -273), 4, 11, 1}, + {35, UPB_SIZE(140, 248), 0, 2, 11, 3}, + {36, UPB_SIZE(144, 256), 0, 6, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_Cluster_msginit = { + &envoy_api_v2_Cluster_submsgs[0], + &envoy_api_v2_Cluster__fields[0], + UPB_SIZE(160, 288), 34, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_EdsClusterConfig_submsgs[1] = { + &envoy_api_v2_core_ConfigSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_EdsClusterConfig__fields[2] = { + {1, UPB_SIZE(8, 16), 0, 0, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_EdsClusterConfig_msginit = { + &envoy_api_v2_Cluster_EdsClusterConfig_submsgs[0], + &envoy_api_v2_Cluster_EdsClusterConfig__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_submsgs[1] = { + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit = { + &envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_submsgs[0], + &envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_submsgs[1] = { + &google_protobuf_Any_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit = { + &envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_submsgs[0], + &envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_LbSubsetConfig_submsgs[2] = { + &envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_LbSubsetConfig__fields[4] = { + {1, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {2, UPB_SIZE(12, 16), 0, 1, 11, 1}, + {3, UPB_SIZE(16, 24), 0, 0, 11, 3}, + {4, UPB_SIZE(8, 8), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_LbSubsetConfig_msginit = { + &envoy_api_v2_Cluster_LbSubsetConfig_submsgs[0], + &envoy_api_v2_Cluster_LbSubsetConfig__fields[0], + UPB_SIZE(24, 32), 4, false, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 3}, +}; + +const upb_msglayout envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit = { + NULL, + &envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_RingHashLbConfig_submsgs[2] = { + &envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit, + &google_protobuf_UInt64Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_RingHashLbConfig__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 1, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_RingHashLbConfig_msginit = { + &envoy_api_v2_Cluster_RingHashLbConfig_submsgs[0], + &envoy_api_v2_Cluster_RingHashLbConfig__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_submsgs[1] = { + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit = { + &envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_submsgs[0], + &envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_OriginalDstLbConfig__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_OriginalDstLbConfig_msginit = { + NULL, + &envoy_api_v2_Cluster_OriginalDstLbConfig__fields[0], + UPB_SIZE(1, 1), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_CommonLbConfig_submsgs[4] = { + &envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit, + &envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit, + &envoy_type_Percent_msginit, + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_CommonLbConfig__fields[4] = { + {1, UPB_SIZE(0, 0), 0, 2, 11, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, + {4, UPB_SIZE(4, 8), 0, 3, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_msginit = { + &envoy_api_v2_Cluster_CommonLbConfig_submsgs[0], + &envoy_api_v2_Cluster_CommonLbConfig__fields[0], + UPB_SIZE(16, 32), 4, false, +}; + +static const upb_msglayout *const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_submsgs[2] = { + &envoy_type_Percent_msginit, + &google_protobuf_UInt64Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit = { + &envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_submsgs[0], + &envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +static const upb_msglayout *const envoy_api_v2_UpstreamBindConfig_submsgs[1] = { + &envoy_api_v2_core_Address_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_UpstreamBindConfig__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_UpstreamBindConfig_msginit = { + &envoy_api_v2_UpstreamBindConfig_submsgs[0], + &envoy_api_v2_UpstreamBindConfig__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_UpstreamConnectionOptions_submsgs[1] = { + &envoy_api_v2_core_TcpKeepalive_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_UpstreamConnectionOptions__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_UpstreamConnectionOptions_msginit = { + &envoy_api_v2_UpstreamConnectionOptions_submsgs[0], + &envoy_api_v2_UpstreamConnectionOptions__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/cds.upb.h b/src/core/ext/upb-generated/envoy/api/v2/cds.upb.h new file mode 100644 index 00000000000..e960b82506e --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cds.upb.h @@ -0,0 +1,1012 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cds.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CDS_PROTO_UPB_H_ +#define ENVOY_API_V2_CDS_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_Cluster; +struct envoy_api_v2_Cluster_EdsClusterConfig; +struct envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry; +struct envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry; +struct envoy_api_v2_Cluster_LbSubsetConfig; +struct envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector; +struct envoy_api_v2_Cluster_RingHashLbConfig; +struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1; +struct envoy_api_v2_Cluster_OriginalDstLbConfig; +struct envoy_api_v2_Cluster_CommonLbConfig; +struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig; +struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig; +struct envoy_api_v2_UpstreamBindConfig; +struct envoy_api_v2_UpstreamConnectionOptions; +typedef struct envoy_api_v2_Cluster envoy_api_v2_Cluster; +typedef struct envoy_api_v2_Cluster_EdsClusterConfig envoy_api_v2_Cluster_EdsClusterConfig; +typedef struct envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry; +typedef struct envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry; +typedef struct envoy_api_v2_Cluster_LbSubsetConfig envoy_api_v2_Cluster_LbSubsetConfig; +typedef struct envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector; +typedef struct envoy_api_v2_Cluster_RingHashLbConfig envoy_api_v2_Cluster_RingHashLbConfig; +typedef struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1; +typedef struct envoy_api_v2_Cluster_OriginalDstLbConfig envoy_api_v2_Cluster_OriginalDstLbConfig; +typedef struct envoy_api_v2_Cluster_CommonLbConfig envoy_api_v2_Cluster_CommonLbConfig; +typedef struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig; +typedef struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig; +typedef struct envoy_api_v2_UpstreamBindConfig envoy_api_v2_UpstreamBindConfig; +typedef struct envoy_api_v2_UpstreamConnectionOptions envoy_api_v2_UpstreamConnectionOptions; +extern const upb_msglayout envoy_api_v2_Cluster_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_EdsClusterConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_LbSubsetConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_RingHashLbConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_OriginalDstLbConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit; +extern const upb_msglayout envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit; +extern const upb_msglayout envoy_api_v2_UpstreamBindConfig_msginit; +extern const upb_msglayout envoy_api_v2_UpstreamConnectionOptions_msginit; +struct envoy_api_v2_ClusterLoadAssignment; +struct envoy_api_v2_auth_UpstreamTlsContext; +struct envoy_api_v2_cluster_CircuitBreakers; +struct envoy_api_v2_cluster_OutlierDetection; +struct envoy_api_v2_core_Address; +struct envoy_api_v2_core_BindConfig; +struct envoy_api_v2_core_ConfigSource; +struct envoy_api_v2_core_HealthCheck; +struct envoy_api_v2_core_Http1ProtocolOptions; +struct envoy_api_v2_core_Http2ProtocolOptions; +struct envoy_api_v2_core_HttpProtocolOptions; +struct envoy_api_v2_core_Metadata; +struct envoy_api_v2_core_TcpKeepalive; +struct envoy_api_v2_core_TransportSocket; +struct envoy_type_Percent; +struct google_protobuf_Any; +struct google_protobuf_BoolValue; +struct google_protobuf_Duration; +struct google_protobuf_Struct; +struct google_protobuf_UInt32Value; +struct google_protobuf_UInt64Value; +extern const upb_msglayout envoy_api_v2_ClusterLoadAssignment_msginit; +extern const upb_msglayout envoy_api_v2_auth_UpstreamTlsContext_msginit; +extern const upb_msglayout envoy_api_v2_cluster_CircuitBreakers_msginit; +extern const upb_msglayout envoy_api_v2_cluster_OutlierDetection_msginit; +extern const upb_msglayout envoy_api_v2_core_Address_msginit; +extern const upb_msglayout envoy_api_v2_core_BindConfig_msginit; +extern const upb_msglayout envoy_api_v2_core_ConfigSource_msginit; +extern const upb_msglayout envoy_api_v2_core_HealthCheck_msginit; +extern const upb_msglayout envoy_api_v2_core_Http1ProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_Http2ProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_HttpProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_Metadata_msginit; +extern const upb_msglayout envoy_api_v2_core_TcpKeepalive_msginit; +extern const upb_msglayout envoy_api_v2_core_TransportSocket_msginit; +extern const upb_msglayout envoy_type_Percent_msginit; +extern const upb_msglayout google_protobuf_Any_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_Struct_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; +extern const upb_msglayout google_protobuf_UInt64Value_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_Cluster_USE_CONFIGURED_PROTOCOL = 0, + envoy_api_v2_Cluster_USE_DOWNSTREAM_PROTOCOL = 1 +} envoy_api_v2_Cluster_ClusterProtocolSelection; + +typedef enum { + envoy_api_v2_Cluster_STATIC = 0, + envoy_api_v2_Cluster_STRICT_DNS = 1, + envoy_api_v2_Cluster_LOGICAL_DNS = 2, + envoy_api_v2_Cluster_EDS = 3, + envoy_api_v2_Cluster_ORIGINAL_DST = 4 +} envoy_api_v2_Cluster_DiscoveryType; + +typedef enum { + envoy_api_v2_Cluster_AUTO = 0, + envoy_api_v2_Cluster_V4_ONLY = 1, + envoy_api_v2_Cluster_V6_ONLY = 2 +} envoy_api_v2_Cluster_DnsLookupFamily; + +typedef enum { + envoy_api_v2_Cluster_ROUND_ROBIN = 0, + envoy_api_v2_Cluster_LEAST_REQUEST = 1, + envoy_api_v2_Cluster_RING_HASH = 2, + envoy_api_v2_Cluster_RANDOM = 3, + envoy_api_v2_Cluster_ORIGINAL_DST_LB = 4, + envoy_api_v2_Cluster_MAGLEV = 5 +} envoy_api_v2_Cluster_LbPolicy; + +typedef enum { + envoy_api_v2_Cluster_LbSubsetConfig_NO_FALLBACK = 0, + envoy_api_v2_Cluster_LbSubsetConfig_ANY_ENDPOINT = 1, + envoy_api_v2_Cluster_LbSubsetConfig_DEFAULT_SUBSET = 2 +} envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy; + + +/* envoy.api.v2.Cluster */ + +UPB_INLINE envoy_api_v2_Cluster *envoy_api_v2_Cluster_new(upb_arena *arena) { + return (envoy_api_v2_Cluster *)upb_msg_new(&envoy_api_v2_Cluster_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster *envoy_api_v2_Cluster_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster *ret = envoy_api_v2_Cluster_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_serialize(const envoy_api_v2_Cluster *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_Cluster_lb_config_ring_hash_lb_config = 23, + envoy_api_v2_Cluster_lb_config_original_dst_lb_config = 34, + envoy_api_v2_Cluster_lb_config_NOT_SET = 0, +} envoy_api_v2_Cluster_lb_config_oneofcases; +UPB_INLINE envoy_api_v2_Cluster_lb_config_oneofcases envoy_api_v2_Cluster_lb_config_case(const envoy_api_v2_Cluster* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(152, 272)); } + +UPB_INLINE upb_strview envoy_api_v2_Cluster_name(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 40)); } +UPB_INLINE int32_t envoy_api_v2_Cluster_type(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_Cluster_EdsClusterConfig* envoy_api_v2_Cluster_eds_cluster_config(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_Cluster_EdsClusterConfig*, UPB_SIZE(52, 72)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_Cluster_connect_timeout(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(56, 80)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_Cluster_per_connection_buffer_limit_bytes(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(60, 88)); } +UPB_INLINE int32_t envoy_api_v2_Cluster_lb_policy(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } +UPB_INLINE const struct envoy_api_v2_core_Address* const* envoy_api_v2_Cluster_hosts(const envoy_api_v2_Cluster *msg, size_t *len) { return (const struct envoy_api_v2_core_Address* const*)_upb_array_accessor(msg, UPB_SIZE(128, 224), len); } +UPB_INLINE const struct envoy_api_v2_core_HealthCheck* const* envoy_api_v2_Cluster_health_checks(const envoy_api_v2_Cluster *msg, size_t *len) { return (const struct envoy_api_v2_core_HealthCheck* const*)_upb_array_accessor(msg, UPB_SIZE(132, 232), len); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_Cluster_max_requests_per_connection(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(64, 96)); } +UPB_INLINE const struct envoy_api_v2_cluster_CircuitBreakers* envoy_api_v2_Cluster_circuit_breakers(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_cluster_CircuitBreakers*, UPB_SIZE(68, 104)); } +UPB_INLINE const struct envoy_api_v2_auth_UpstreamTlsContext* envoy_api_v2_Cluster_tls_context(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_auth_UpstreamTlsContext*, UPB_SIZE(72, 112)); } +UPB_INLINE const struct envoy_api_v2_core_Http1ProtocolOptions* envoy_api_v2_Cluster_http_protocol_options(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Http1ProtocolOptions*, UPB_SIZE(76, 120)); } +UPB_INLINE const struct envoy_api_v2_core_Http2ProtocolOptions* envoy_api_v2_Cluster_http2_protocol_options(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Http2ProtocolOptions*, UPB_SIZE(80, 128)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_Cluster_dns_refresh_rate(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(84, 136)); } +UPB_INLINE int32_t envoy_api_v2_Cluster_dns_lookup_family(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); } +UPB_INLINE const struct envoy_api_v2_core_Address* const* envoy_api_v2_Cluster_dns_resolvers(const envoy_api_v2_Cluster *msg, size_t *len) { return (const struct envoy_api_v2_core_Address* const*)_upb_array_accessor(msg, UPB_SIZE(136, 240), len); } +UPB_INLINE const struct envoy_api_v2_cluster_OutlierDetection* envoy_api_v2_Cluster_outlier_detection(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_cluster_OutlierDetection*, UPB_SIZE(88, 144)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_Cluster_cleanup_interval(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(92, 152)); } +UPB_INLINE const struct envoy_api_v2_core_BindConfig* envoy_api_v2_Cluster_upstream_bind_config(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_BindConfig*, UPB_SIZE(96, 160)); } +UPB_INLINE const envoy_api_v2_Cluster_LbSubsetConfig* envoy_api_v2_Cluster_lb_subset_config(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_Cluster_LbSubsetConfig*, UPB_SIZE(100, 168)); } +UPB_INLINE bool envoy_api_v2_Cluster_has_ring_hash_lb_config(const envoy_api_v2_Cluster *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(152, 272), 23); } +UPB_INLINE const envoy_api_v2_Cluster_RingHashLbConfig* envoy_api_v2_Cluster_ring_hash_lb_config(const envoy_api_v2_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_Cluster_RingHashLbConfig*, UPB_SIZE(148, 264), UPB_SIZE(152, 272), 23, NULL); } +UPB_INLINE const struct envoy_api_v2_core_TransportSocket* envoy_api_v2_Cluster_transport_socket(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_TransportSocket*, UPB_SIZE(104, 176)); } +UPB_INLINE const struct envoy_api_v2_core_Metadata* envoy_api_v2_Cluster_metadata(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Metadata*, UPB_SIZE(108, 184)); } +UPB_INLINE int32_t envoy_api_v2_Cluster_protocol_selection(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)); } +UPB_INLINE const envoy_api_v2_Cluster_CommonLbConfig* envoy_api_v2_Cluster_common_lb_config(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_Cluster_CommonLbConfig*, UPB_SIZE(112, 192)); } +UPB_INLINE upb_strview envoy_api_v2_Cluster_alt_stat_name(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 56)); } +UPB_INLINE const struct envoy_api_v2_core_HttpProtocolOptions* envoy_api_v2_Cluster_common_http_protocol_options(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_HttpProtocolOptions*, UPB_SIZE(116, 200)); } +UPB_INLINE const envoy_api_v2_UpstreamConnectionOptions* envoy_api_v2_Cluster_upstream_connection_options(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_UpstreamConnectionOptions*, UPB_SIZE(120, 208)); } +UPB_INLINE bool envoy_api_v2_Cluster_close_connections_on_host_health_failure(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(32, 32)); } +UPB_INLINE bool envoy_api_v2_Cluster_drain_connections_on_host_removal(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(33, 33)); } +UPB_INLINE const struct envoy_api_v2_ClusterLoadAssignment* envoy_api_v2_Cluster_load_assignment(const envoy_api_v2_Cluster *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_ClusterLoadAssignment*, UPB_SIZE(124, 216)); } +UPB_INLINE bool envoy_api_v2_Cluster_has_original_dst_lb_config(const envoy_api_v2_Cluster *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(152, 272), 34); } +UPB_INLINE const envoy_api_v2_Cluster_OriginalDstLbConfig* envoy_api_v2_Cluster_original_dst_lb_config(const envoy_api_v2_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_Cluster_OriginalDstLbConfig*, UPB_SIZE(148, 264), UPB_SIZE(152, 272), 34, NULL); } +UPB_INLINE const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry* const* envoy_api_v2_Cluster_extension_protocol_options(const envoy_api_v2_Cluster *msg, size_t *len) { return (const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry* const*)_upb_array_accessor(msg, UPB_SIZE(140, 248), len); } +UPB_INLINE const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry* const* envoy_api_v2_Cluster_typed_extension_protocol_options(const envoy_api_v2_Cluster *msg, size_t *len) { return (const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry* const*)_upb_array_accessor(msg, UPB_SIZE(144, 256), len); } + +UPB_INLINE void envoy_api_v2_Cluster_set_name(envoy_api_v2_Cluster *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 40)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_type(envoy_api_v2_Cluster *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_eds_cluster_config(envoy_api_v2_Cluster *msg, envoy_api_v2_Cluster_EdsClusterConfig* value) { + UPB_FIELD_AT(msg, envoy_api_v2_Cluster_EdsClusterConfig*, UPB_SIZE(52, 72)) = value; +} +UPB_INLINE struct envoy_api_v2_Cluster_EdsClusterConfig* envoy_api_v2_Cluster_mutable_eds_cluster_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_EdsClusterConfig* sub = (struct envoy_api_v2_Cluster_EdsClusterConfig*)envoy_api_v2_Cluster_eds_cluster_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_EdsClusterConfig*)upb_msg_new(&envoy_api_v2_Cluster_EdsClusterConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_eds_cluster_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_connect_timeout(envoy_api_v2_Cluster *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(56, 80)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_Cluster_mutable_connect_timeout(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_Cluster_connect_timeout(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_connect_timeout(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_per_connection_buffer_limit_bytes(envoy_api_v2_Cluster *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(60, 88)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_Cluster_mutable_per_connection_buffer_limit_bytes(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_Cluster_per_connection_buffer_limit_bytes(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_per_connection_buffer_limit_bytes(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_lb_policy(envoy_api_v2_Cluster *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Address** envoy_api_v2_Cluster_mutable_hosts(envoy_api_v2_Cluster *msg, size_t *len) { + return (struct envoy_api_v2_core_Address**)_upb_array_mutable_accessor(msg, UPB_SIZE(128, 224), len); +} +UPB_INLINE struct envoy_api_v2_core_Address** envoy_api_v2_Cluster_resize_hosts(envoy_api_v2_Cluster *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_Address**)_upb_array_resize_accessor(msg, UPB_SIZE(128, 224), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_Address* envoy_api_v2_Cluster_add_hosts(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_Address* sub = (struct envoy_api_v2_core_Address*)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(128, 224), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck** envoy_api_v2_Cluster_mutable_health_checks(envoy_api_v2_Cluster *msg, size_t *len) { + return (struct envoy_api_v2_core_HealthCheck**)_upb_array_mutable_accessor(msg, UPB_SIZE(132, 232), len); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck** envoy_api_v2_Cluster_resize_health_checks(envoy_api_v2_Cluster *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_HealthCheck**)_upb_array_resize_accessor(msg, UPB_SIZE(132, 232), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_HealthCheck* envoy_api_v2_Cluster_add_health_checks(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_HealthCheck* sub = (struct envoy_api_v2_core_HealthCheck*)upb_msg_new(&envoy_api_v2_core_HealthCheck_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(132, 232), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_max_requests_per_connection(envoy_api_v2_Cluster *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(64, 96)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_Cluster_mutable_max_requests_per_connection(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_Cluster_max_requests_per_connection(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_max_requests_per_connection(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_circuit_breakers(envoy_api_v2_Cluster *msg, struct envoy_api_v2_cluster_CircuitBreakers* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_cluster_CircuitBreakers*, UPB_SIZE(68, 104)) = value; +} +UPB_INLINE struct envoy_api_v2_cluster_CircuitBreakers* envoy_api_v2_Cluster_mutable_circuit_breakers(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_cluster_CircuitBreakers* sub = (struct envoy_api_v2_cluster_CircuitBreakers*)envoy_api_v2_Cluster_circuit_breakers(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_cluster_CircuitBreakers*)upb_msg_new(&envoy_api_v2_cluster_CircuitBreakers_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_circuit_breakers(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_tls_context(envoy_api_v2_Cluster *msg, struct envoy_api_v2_auth_UpstreamTlsContext* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_auth_UpstreamTlsContext*, UPB_SIZE(72, 112)) = value; +} +UPB_INLINE struct envoy_api_v2_auth_UpstreamTlsContext* envoy_api_v2_Cluster_mutable_tls_context(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_auth_UpstreamTlsContext* sub = (struct envoy_api_v2_auth_UpstreamTlsContext*)envoy_api_v2_Cluster_tls_context(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_auth_UpstreamTlsContext*)upb_msg_new(&envoy_api_v2_auth_UpstreamTlsContext_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_tls_context(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_http_protocol_options(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_Http1ProtocolOptions* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Http1ProtocolOptions*, UPB_SIZE(76, 120)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Http1ProtocolOptions* envoy_api_v2_Cluster_mutable_http_protocol_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_Http1ProtocolOptions* sub = (struct envoy_api_v2_core_Http1ProtocolOptions*)envoy_api_v2_Cluster_http_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Http1ProtocolOptions*)upb_msg_new(&envoy_api_v2_core_Http1ProtocolOptions_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_http_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_http2_protocol_options(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_Http2ProtocolOptions* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Http2ProtocolOptions*, UPB_SIZE(80, 128)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Http2ProtocolOptions* envoy_api_v2_Cluster_mutable_http2_protocol_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_Http2ProtocolOptions* sub = (struct envoy_api_v2_core_Http2ProtocolOptions*)envoy_api_v2_Cluster_http2_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Http2ProtocolOptions*)upb_msg_new(&envoy_api_v2_core_Http2ProtocolOptions_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_http2_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_dns_refresh_rate(envoy_api_v2_Cluster *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(84, 136)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_Cluster_mutable_dns_refresh_rate(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_Cluster_dns_refresh_rate(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_dns_refresh_rate(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_dns_lookup_family(envoy_api_v2_Cluster *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Address** envoy_api_v2_Cluster_mutable_dns_resolvers(envoy_api_v2_Cluster *msg, size_t *len) { + return (struct envoy_api_v2_core_Address**)_upb_array_mutable_accessor(msg, UPB_SIZE(136, 240), len); +} +UPB_INLINE struct envoy_api_v2_core_Address** envoy_api_v2_Cluster_resize_dns_resolvers(envoy_api_v2_Cluster *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_Address**)_upb_array_resize_accessor(msg, UPB_SIZE(136, 240), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_Address* envoy_api_v2_Cluster_add_dns_resolvers(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_Address* sub = (struct envoy_api_v2_core_Address*)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(136, 240), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_outlier_detection(envoy_api_v2_Cluster *msg, struct envoy_api_v2_cluster_OutlierDetection* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_cluster_OutlierDetection*, UPB_SIZE(88, 144)) = value; +} +UPB_INLINE struct envoy_api_v2_cluster_OutlierDetection* envoy_api_v2_Cluster_mutable_outlier_detection(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_cluster_OutlierDetection* sub = (struct envoy_api_v2_cluster_OutlierDetection*)envoy_api_v2_Cluster_outlier_detection(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_cluster_OutlierDetection*)upb_msg_new(&envoy_api_v2_cluster_OutlierDetection_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_outlier_detection(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_cleanup_interval(envoy_api_v2_Cluster *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(92, 152)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_Cluster_mutable_cleanup_interval(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_Cluster_cleanup_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_cleanup_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_upstream_bind_config(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_BindConfig* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_BindConfig*, UPB_SIZE(96, 160)) = value; +} +UPB_INLINE struct envoy_api_v2_core_BindConfig* envoy_api_v2_Cluster_mutable_upstream_bind_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_BindConfig* sub = (struct envoy_api_v2_core_BindConfig*)envoy_api_v2_Cluster_upstream_bind_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_BindConfig*)upb_msg_new(&envoy_api_v2_core_BindConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_upstream_bind_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_lb_subset_config(envoy_api_v2_Cluster *msg, envoy_api_v2_Cluster_LbSubsetConfig* value) { + UPB_FIELD_AT(msg, envoy_api_v2_Cluster_LbSubsetConfig*, UPB_SIZE(100, 168)) = value; +} +UPB_INLINE struct envoy_api_v2_Cluster_LbSubsetConfig* envoy_api_v2_Cluster_mutable_lb_subset_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_LbSubsetConfig* sub = (struct envoy_api_v2_Cluster_LbSubsetConfig*)envoy_api_v2_Cluster_lb_subset_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_LbSubsetConfig*)upb_msg_new(&envoy_api_v2_Cluster_LbSubsetConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_lb_subset_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_ring_hash_lb_config(envoy_api_v2_Cluster *msg, envoy_api_v2_Cluster_RingHashLbConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_Cluster_RingHashLbConfig*, UPB_SIZE(148, 264), value, UPB_SIZE(152, 272), 23); +} +UPB_INLINE struct envoy_api_v2_Cluster_RingHashLbConfig* envoy_api_v2_Cluster_mutable_ring_hash_lb_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_RingHashLbConfig* sub = (struct envoy_api_v2_Cluster_RingHashLbConfig*)envoy_api_v2_Cluster_ring_hash_lb_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_RingHashLbConfig*)upb_msg_new(&envoy_api_v2_Cluster_RingHashLbConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_ring_hash_lb_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_transport_socket(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_TransportSocket* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_TransportSocket*, UPB_SIZE(104, 176)) = value; +} +UPB_INLINE struct envoy_api_v2_core_TransportSocket* envoy_api_v2_Cluster_mutable_transport_socket(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_TransportSocket* sub = (struct envoy_api_v2_core_TransportSocket*)envoy_api_v2_Cluster_transport_socket(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_TransportSocket*)upb_msg_new(&envoy_api_v2_core_TransportSocket_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_transport_socket(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_metadata(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_Metadata* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Metadata*, UPB_SIZE(108, 184)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Metadata* envoy_api_v2_Cluster_mutable_metadata(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_Metadata* sub = (struct envoy_api_v2_core_Metadata*)envoy_api_v2_Cluster_metadata(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Metadata*)upb_msg_new(&envoy_api_v2_core_Metadata_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_metadata(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_protocol_selection(envoy_api_v2_Cluster *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_common_lb_config(envoy_api_v2_Cluster *msg, envoy_api_v2_Cluster_CommonLbConfig* value) { + UPB_FIELD_AT(msg, envoy_api_v2_Cluster_CommonLbConfig*, UPB_SIZE(112, 192)) = value; +} +UPB_INLINE struct envoy_api_v2_Cluster_CommonLbConfig* envoy_api_v2_Cluster_mutable_common_lb_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_CommonLbConfig* sub = (struct envoy_api_v2_Cluster_CommonLbConfig*)envoy_api_v2_Cluster_common_lb_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_CommonLbConfig*)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_common_lb_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_alt_stat_name(envoy_api_v2_Cluster *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 56)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_common_http_protocol_options(envoy_api_v2_Cluster *msg, struct envoy_api_v2_core_HttpProtocolOptions* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_HttpProtocolOptions*, UPB_SIZE(116, 200)) = value; +} +UPB_INLINE struct envoy_api_v2_core_HttpProtocolOptions* envoy_api_v2_Cluster_mutable_common_http_protocol_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_core_HttpProtocolOptions* sub = (struct envoy_api_v2_core_HttpProtocolOptions*)envoy_api_v2_Cluster_common_http_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_HttpProtocolOptions*)upb_msg_new(&envoy_api_v2_core_HttpProtocolOptions_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_common_http_protocol_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_upstream_connection_options(envoy_api_v2_Cluster *msg, envoy_api_v2_UpstreamConnectionOptions* value) { + UPB_FIELD_AT(msg, envoy_api_v2_UpstreamConnectionOptions*, UPB_SIZE(120, 208)) = value; +} +UPB_INLINE struct envoy_api_v2_UpstreamConnectionOptions* envoy_api_v2_Cluster_mutable_upstream_connection_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_UpstreamConnectionOptions* sub = (struct envoy_api_v2_UpstreamConnectionOptions*)envoy_api_v2_Cluster_upstream_connection_options(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_UpstreamConnectionOptions*)upb_msg_new(&envoy_api_v2_UpstreamConnectionOptions_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_upstream_connection_options(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_close_connections_on_host_health_failure(envoy_api_v2_Cluster *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(32, 32)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_drain_connections_on_host_removal(envoy_api_v2_Cluster *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(33, 33)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_set_load_assignment(envoy_api_v2_Cluster *msg, struct envoy_api_v2_ClusterLoadAssignment* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_ClusterLoadAssignment*, UPB_SIZE(124, 216)) = value; +} +UPB_INLINE struct envoy_api_v2_ClusterLoadAssignment* envoy_api_v2_Cluster_mutable_load_assignment(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_ClusterLoadAssignment* sub = (struct envoy_api_v2_ClusterLoadAssignment*)envoy_api_v2_Cluster_load_assignment(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_ClusterLoadAssignment*)upb_msg_new(&envoy_api_v2_ClusterLoadAssignment_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_load_assignment(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_set_original_dst_lb_config(envoy_api_v2_Cluster *msg, envoy_api_v2_Cluster_OriginalDstLbConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_Cluster_OriginalDstLbConfig*, UPB_SIZE(148, 264), value, UPB_SIZE(152, 272), 34); +} +UPB_INLINE struct envoy_api_v2_Cluster_OriginalDstLbConfig* envoy_api_v2_Cluster_mutable_original_dst_lb_config(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_OriginalDstLbConfig* sub = (struct envoy_api_v2_Cluster_OriginalDstLbConfig*)envoy_api_v2_Cluster_original_dst_lb_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_OriginalDstLbConfig*)upb_msg_new(&envoy_api_v2_Cluster_OriginalDstLbConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_set_original_dst_lb_config(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry** envoy_api_v2_Cluster_mutable_extension_protocol_options(envoy_api_v2_Cluster *msg, size_t *len) { + return (envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(140, 248), len); +} +UPB_INLINE envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry** envoy_api_v2_Cluster_resize_extension_protocol_options(envoy_api_v2_Cluster *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(140, 248), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry* envoy_api_v2_Cluster_add_extension_protocol_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry* sub = (struct envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry*)upb_msg_new(&envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(140, 248), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry** envoy_api_v2_Cluster_mutable_typed_extension_protocol_options(envoy_api_v2_Cluster *msg, size_t *len) { + return (envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(144, 256), len); +} +UPB_INLINE envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry** envoy_api_v2_Cluster_resize_typed_extension_protocol_options(envoy_api_v2_Cluster *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(144, 256), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry* envoy_api_v2_Cluster_add_typed_extension_protocol_options(envoy_api_v2_Cluster *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry* sub = (struct envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry*)upb_msg_new(&envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(144, 256), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.Cluster.EdsClusterConfig */ + +UPB_INLINE envoy_api_v2_Cluster_EdsClusterConfig *envoy_api_v2_Cluster_EdsClusterConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_EdsClusterConfig *)upb_msg_new(&envoy_api_v2_Cluster_EdsClusterConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_EdsClusterConfig *envoy_api_v2_Cluster_EdsClusterConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_EdsClusterConfig *ret = envoy_api_v2_Cluster_EdsClusterConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_EdsClusterConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_EdsClusterConfig_serialize(const envoy_api_v2_Cluster_EdsClusterConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_EdsClusterConfig_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_ConfigSource* envoy_api_v2_Cluster_EdsClusterConfig_eds_config(const envoy_api_v2_Cluster_EdsClusterConfig *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_ConfigSource*, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview envoy_api_v2_Cluster_EdsClusterConfig_service_name(const envoy_api_v2_Cluster_EdsClusterConfig *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_Cluster_EdsClusterConfig_set_eds_config(envoy_api_v2_Cluster_EdsClusterConfig *msg, struct envoy_api_v2_core_ConfigSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_ConfigSource*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_ConfigSource* envoy_api_v2_Cluster_EdsClusterConfig_mutable_eds_config(envoy_api_v2_Cluster_EdsClusterConfig *msg, upb_arena *arena) { + struct envoy_api_v2_core_ConfigSource* sub = (struct envoy_api_v2_core_ConfigSource*)envoy_api_v2_Cluster_EdsClusterConfig_eds_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_ConfigSource*)upb_msg_new(&envoy_api_v2_core_ConfigSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_EdsClusterConfig_set_eds_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_EdsClusterConfig_set_service_name(envoy_api_v2_Cluster_EdsClusterConfig *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.Cluster.ExtensionProtocolOptionsEntry */ + +UPB_INLINE envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *)upb_msg_new(&envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *ret = envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_serialize(const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_key(const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_value(const envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Struct*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_set_key(envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_set_value(envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg, struct google_protobuf_Struct* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Struct*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_mutable_value(envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_ExtensionProtocolOptionsEntry_set_value(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.TypedExtensionProtocolOptionsEntry */ + +UPB_INLINE envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *)upb_msg_new(&envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *ret = envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_serialize(const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_key(const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Any* envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_value(const envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Any*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_set_key(envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_set_value(envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg, struct google_protobuf_Any* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Any*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_mutable_value(envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_TypedExtensionProtocolOptionsEntry_set_value(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.LbSubsetConfig */ + +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig *envoy_api_v2_Cluster_LbSubsetConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_LbSubsetConfig *)upb_msg_new(&envoy_api_v2_Cluster_LbSubsetConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig *envoy_api_v2_Cluster_LbSubsetConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_LbSubsetConfig *ret = envoy_api_v2_Cluster_LbSubsetConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_LbSubsetConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_LbSubsetConfig_serialize(const envoy_api_v2_Cluster_LbSubsetConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_LbSubsetConfig_msginit, arena, len); +} + +UPB_INLINE int32_t envoy_api_v2_Cluster_LbSubsetConfig_fallback_policy(const envoy_api_v2_Cluster_LbSubsetConfig *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_Cluster_LbSubsetConfig_default_subset(const envoy_api_v2_Cluster_LbSubsetConfig *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Struct*, UPB_SIZE(12, 16)); } +UPB_INLINE const envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector* const* envoy_api_v2_Cluster_LbSubsetConfig_subset_selectors(const envoy_api_v2_Cluster_LbSubsetConfig *msg, size_t *len) { return (const envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector* const*)_upb_array_accessor(msg, UPB_SIZE(16, 24), len); } +UPB_INLINE bool envoy_api_v2_Cluster_LbSubsetConfig_locality_weight_aware(const envoy_api_v2_Cluster_LbSubsetConfig *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)); } + +UPB_INLINE void envoy_api_v2_Cluster_LbSubsetConfig_set_fallback_policy(envoy_api_v2_Cluster_LbSubsetConfig *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_Cluster_LbSubsetConfig_set_default_subset(envoy_api_v2_Cluster_LbSubsetConfig *msg, struct google_protobuf_Struct* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Struct*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_Cluster_LbSubsetConfig_mutable_default_subset(envoy_api_v2_Cluster_LbSubsetConfig *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_Cluster_LbSubsetConfig_default_subset(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_LbSubsetConfig_set_default_subset(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector** envoy_api_v2_Cluster_LbSubsetConfig_mutable_subset_selectors(envoy_api_v2_Cluster_LbSubsetConfig *msg, size_t *len) { + return (envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 24), len); +} +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector** envoy_api_v2_Cluster_LbSubsetConfig_resize_subset_selectors(envoy_api_v2_Cluster_LbSubsetConfig *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector* envoy_api_v2_Cluster_LbSubsetConfig_add_subset_selectors(envoy_api_v2_Cluster_LbSubsetConfig *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector* sub = (struct envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector*)upb_msg_new(&envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(16, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_LbSubsetConfig_set_locality_weight_aware(envoy_api_v2_Cluster_LbSubsetConfig *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(8, 8)) = value; +} + + +/* envoy.api.v2.Cluster.LbSubsetConfig.LbSubsetSelector */ + +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *)upb_msg_new(&envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *ret = envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_serialize(const envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, arena, len); +} + +UPB_INLINE upb_strview const* envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_keys(const envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE upb_strview* envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_mutable_keys(envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE upb_strview* envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_resize_keys(envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_add_keys(envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} + + +/* envoy.api.v2.Cluster.RingHashLbConfig */ + +UPB_INLINE envoy_api_v2_Cluster_RingHashLbConfig *envoy_api_v2_Cluster_RingHashLbConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_RingHashLbConfig *)upb_msg_new(&envoy_api_v2_Cluster_RingHashLbConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_RingHashLbConfig *envoy_api_v2_Cluster_RingHashLbConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_RingHashLbConfig *ret = envoy_api_v2_Cluster_RingHashLbConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_RingHashLbConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_RingHashLbConfig_serialize(const envoy_api_v2_Cluster_RingHashLbConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_RingHashLbConfig_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_UInt64Value* envoy_api_v2_Cluster_RingHashLbConfig_minimum_ring_size(const envoy_api_v2_Cluster_RingHashLbConfig *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt64Value*, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1* envoy_api_v2_Cluster_RingHashLbConfig_deprecated_v1(const envoy_api_v2_Cluster_RingHashLbConfig *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_Cluster_RingHashLbConfig_set_minimum_ring_size(envoy_api_v2_Cluster_RingHashLbConfig *msg, struct google_protobuf_UInt64Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt64Value*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_UInt64Value* envoy_api_v2_Cluster_RingHashLbConfig_mutable_minimum_ring_size(envoy_api_v2_Cluster_RingHashLbConfig *msg, upb_arena *arena) { + struct google_protobuf_UInt64Value* sub = (struct google_protobuf_UInt64Value*)envoy_api_v2_Cluster_RingHashLbConfig_minimum_ring_size(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt64Value*)upb_msg_new(&google_protobuf_UInt64Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_RingHashLbConfig_set_minimum_ring_size(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_RingHashLbConfig_set_deprecated_v1(envoy_api_v2_Cluster_RingHashLbConfig *msg, envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1* value) { + UPB_FIELD_AT(msg, envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1* envoy_api_v2_Cluster_RingHashLbConfig_mutable_deprecated_v1(envoy_api_v2_Cluster_RingHashLbConfig *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1* sub = (struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1*)envoy_api_v2_Cluster_RingHashLbConfig_deprecated_v1(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1*)upb_msg_new(&envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_RingHashLbConfig_set_deprecated_v1(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.RingHashLbConfig.DeprecatedV1 */ + +UPB_INLINE envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *)upb_msg_new(&envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *ret = envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_serialize(const envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_use_std_hash(const envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_set_use_std_hash(envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_mutable_use_std_hash(envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1 *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_use_std_hash(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_RingHashLbConfig_DeprecatedV1_set_use_std_hash(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.OriginalDstLbConfig */ + +UPB_INLINE envoy_api_v2_Cluster_OriginalDstLbConfig *envoy_api_v2_Cluster_OriginalDstLbConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_OriginalDstLbConfig *)upb_msg_new(&envoy_api_v2_Cluster_OriginalDstLbConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_OriginalDstLbConfig *envoy_api_v2_Cluster_OriginalDstLbConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_OriginalDstLbConfig *ret = envoy_api_v2_Cluster_OriginalDstLbConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_OriginalDstLbConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_OriginalDstLbConfig_serialize(const envoy_api_v2_Cluster_OriginalDstLbConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_OriginalDstLbConfig_msginit, arena, len); +} + +UPB_INLINE bool envoy_api_v2_Cluster_OriginalDstLbConfig_use_http_header(const envoy_api_v2_Cluster_OriginalDstLbConfig *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_Cluster_OriginalDstLbConfig_set_use_http_header(envoy_api_v2_Cluster_OriginalDstLbConfig *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.Cluster.CommonLbConfig */ + +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig *envoy_api_v2_Cluster_CommonLbConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_CommonLbConfig *)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig *envoy_api_v2_Cluster_CommonLbConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_CommonLbConfig *ret = envoy_api_v2_Cluster_CommonLbConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_CommonLbConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_CommonLbConfig_serialize(const envoy_api_v2_Cluster_CommonLbConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_CommonLbConfig_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_zone_aware_lb_config = 2, + envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_locality_weighted_lb_config = 3, + envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_NOT_SET = 0, +} envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_oneofcases; +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_oneofcases envoy_api_v2_Cluster_CommonLbConfig_locality_config_specifier_case(const envoy_api_v2_Cluster_CommonLbConfig* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE const struct envoy_type_Percent* envoy_api_v2_Cluster_CommonLbConfig_healthy_panic_threshold(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return UPB_FIELD_AT(msg, const struct envoy_type_Percent*, UPB_SIZE(0, 0)); } +UPB_INLINE bool envoy_api_v2_Cluster_CommonLbConfig_has_zone_aware_lb_config(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig* envoy_api_v2_Cluster_CommonLbConfig_zone_aware_lb_config(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE bool envoy_api_v2_Cluster_CommonLbConfig_has_locality_weighted_lb_config(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 3); } +UPB_INLINE const envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig* envoy_api_v2_Cluster_CommonLbConfig_locality_weighted_lb_config(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 3, NULL); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_Cluster_CommonLbConfig_update_merge_window(const envoy_api_v2_Cluster_CommonLbConfig *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_set_healthy_panic_threshold(envoy_api_v2_Cluster_CommonLbConfig *msg, struct envoy_type_Percent* value) { + UPB_FIELD_AT(msg, struct envoy_type_Percent*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_type_Percent* envoy_api_v2_Cluster_CommonLbConfig_mutable_healthy_panic_threshold(envoy_api_v2_Cluster_CommonLbConfig *msg, upb_arena *arena) { + struct envoy_type_Percent* sub = (struct envoy_type_Percent*)envoy_api_v2_Cluster_CommonLbConfig_healthy_panic_threshold(msg); + if (sub == NULL) { + sub = (struct envoy_type_Percent*)upb_msg_new(&envoy_type_Percent_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_set_healthy_panic_threshold(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_set_zone_aware_lb_config(envoy_api_v2_Cluster_CommonLbConfig *msg, envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig* envoy_api_v2_Cluster_CommonLbConfig_mutable_zone_aware_lb_config(envoy_api_v2_Cluster_CommonLbConfig *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig* sub = (struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig*)envoy_api_v2_Cluster_CommonLbConfig_zone_aware_lb_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig*)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_set_zone_aware_lb_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_set_locality_weighted_lb_config(envoy_api_v2_Cluster_CommonLbConfig *msg, envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 3); +} +UPB_INLINE struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig* envoy_api_v2_Cluster_CommonLbConfig_mutable_locality_weighted_lb_config(envoy_api_v2_Cluster_CommonLbConfig *msg, upb_arena *arena) { + struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig* sub = (struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig*)envoy_api_v2_Cluster_CommonLbConfig_locality_weighted_lb_config(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig*)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_set_locality_weighted_lb_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_set_update_merge_window(envoy_api_v2_Cluster_CommonLbConfig *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_Cluster_CommonLbConfig_mutable_update_merge_window(envoy_api_v2_Cluster_CommonLbConfig *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_Cluster_CommonLbConfig_update_merge_window(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_set_update_merge_window(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.CommonLbConfig.ZoneAwareLbConfig */ + +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *ret = envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_serialize(const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit, arena, len); +} + +UPB_INLINE const struct envoy_type_Percent* envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_routing_enabled(const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return UPB_FIELD_AT(msg, const struct envoy_type_Percent*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_UInt64Value* envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_min_cluster_size(const envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt64Value*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_set_routing_enabled(envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, struct envoy_type_Percent* value) { + UPB_FIELD_AT(msg, struct envoy_type_Percent*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_type_Percent* envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_mutable_routing_enabled(envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, upb_arena *arena) { + struct envoy_type_Percent* sub = (struct envoy_type_Percent*)envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_routing_enabled(msg); + if (sub == NULL) { + sub = (struct envoy_type_Percent*)upb_msg_new(&envoy_type_Percent_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_set_routing_enabled(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_set_min_cluster_size(envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, struct google_protobuf_UInt64Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt64Value*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_UInt64Value* envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_mutable_min_cluster_size(envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, upb_arena *arena) { + struct google_protobuf_UInt64Value* sub = (struct google_protobuf_UInt64Value*)envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_min_cluster_size(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt64Value*)upb_msg_new(&google_protobuf_UInt64Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig_set_min_cluster_size(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.Cluster.CommonLbConfig.LocalityWeightedLbConfig */ + +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig *envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_new(upb_arena *arena) { + return (envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig *)upb_msg_new(&envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig *envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig *ret = envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_serialize(const envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit, arena, len); +} + + + + +/* envoy.api.v2.UpstreamBindConfig */ + +UPB_INLINE envoy_api_v2_UpstreamBindConfig *envoy_api_v2_UpstreamBindConfig_new(upb_arena *arena) { + return (envoy_api_v2_UpstreamBindConfig *)upb_msg_new(&envoy_api_v2_UpstreamBindConfig_msginit, arena); +} +UPB_INLINE envoy_api_v2_UpstreamBindConfig *envoy_api_v2_UpstreamBindConfig_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_UpstreamBindConfig *ret = envoy_api_v2_UpstreamBindConfig_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_UpstreamBindConfig_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_UpstreamBindConfig_serialize(const envoy_api_v2_UpstreamBindConfig *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_UpstreamBindConfig_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_Address* envoy_api_v2_UpstreamBindConfig_source_address(const envoy_api_v2_UpstreamBindConfig *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_Address*, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_UpstreamBindConfig_set_source_address(envoy_api_v2_UpstreamBindConfig *msg, struct envoy_api_v2_core_Address* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_Address*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Address* envoy_api_v2_UpstreamBindConfig_mutable_source_address(envoy_api_v2_UpstreamBindConfig *msg, upb_arena *arena) { + struct envoy_api_v2_core_Address* sub = (struct envoy_api_v2_core_Address*)envoy_api_v2_UpstreamBindConfig_source_address(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Address*)upb_msg_new(&envoy_api_v2_core_Address_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_UpstreamBindConfig_set_source_address(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.UpstreamConnectionOptions */ + +UPB_INLINE envoy_api_v2_UpstreamConnectionOptions *envoy_api_v2_UpstreamConnectionOptions_new(upb_arena *arena) { + return (envoy_api_v2_UpstreamConnectionOptions *)upb_msg_new(&envoy_api_v2_UpstreamConnectionOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_UpstreamConnectionOptions *envoy_api_v2_UpstreamConnectionOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_UpstreamConnectionOptions *ret = envoy_api_v2_UpstreamConnectionOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_UpstreamConnectionOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_UpstreamConnectionOptions_serialize(const envoy_api_v2_UpstreamConnectionOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_UpstreamConnectionOptions_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_TcpKeepalive* envoy_api_v2_UpstreamConnectionOptions_tcp_keepalive(const envoy_api_v2_UpstreamConnectionOptions *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_TcpKeepalive*, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_UpstreamConnectionOptions_set_tcp_keepalive(envoy_api_v2_UpstreamConnectionOptions *msg, struct envoy_api_v2_core_TcpKeepalive* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_TcpKeepalive*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_TcpKeepalive* envoy_api_v2_UpstreamConnectionOptions_mutable_tcp_keepalive(envoy_api_v2_UpstreamConnectionOptions *msg, upb_arena *arena) { + struct envoy_api_v2_core_TcpKeepalive* sub = (struct envoy_api_v2_core_TcpKeepalive*)envoy_api_v2_UpstreamConnectionOptions_tcp_keepalive(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_TcpKeepalive*)upb_msg_new(&envoy_api_v2_core_TcpKeepalive_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_UpstreamConnectionOptions_set_tcp_keepalive(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CDS_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c b/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c new file mode 100644 index 00000000000..d16f2ce2afb --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c @@ -0,0 +1,51 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cluster/circuit_breaker.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/cluster/circuit_breaker.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_cluster_CircuitBreakers_submsgs[1] = { + &envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_cluster_CircuitBreakers__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_cluster_CircuitBreakers_msginit = { + &envoy_api_v2_cluster_CircuitBreakers_submsgs[0], + &envoy_api_v2_cluster_CircuitBreakers__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_cluster_CircuitBreakers_Thresholds_submsgs[4] = { + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_cluster_CircuitBreakers_Thresholds__fields[5] = { + {1, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {2, UPB_SIZE(8, 8), 0, 0, 11, 1}, + {3, UPB_SIZE(12, 16), 0, 0, 11, 1}, + {4, UPB_SIZE(16, 24), 0, 0, 11, 1}, + {5, UPB_SIZE(20, 32), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit = { + &envoy_api_v2_cluster_CircuitBreakers_Thresholds_submsgs[0], + &envoy_api_v2_cluster_CircuitBreakers_Thresholds__fields[0], + UPB_SIZE(24, 40), 5, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h b/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h new file mode 100644 index 00000000000..45fd07230b0 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h @@ -0,0 +1,143 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cluster/circuit_breaker.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CLUSTER_CIRCUIT_BREAKER_PROTO_UPB_H_ +#define ENVOY_API_V2_CLUSTER_CIRCUIT_BREAKER_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_cluster_CircuitBreakers; +struct envoy_api_v2_cluster_CircuitBreakers_Thresholds; +typedef struct envoy_api_v2_cluster_CircuitBreakers envoy_api_v2_cluster_CircuitBreakers; +typedef struct envoy_api_v2_cluster_CircuitBreakers_Thresholds envoy_api_v2_cluster_CircuitBreakers_Thresholds; +extern const upb_msglayout envoy_api_v2_cluster_CircuitBreakers_msginit; +extern const upb_msglayout envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit; +struct google_protobuf_UInt32Value; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + + +/* envoy.api.v2.cluster.CircuitBreakers */ + +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers *envoy_api_v2_cluster_CircuitBreakers_new(upb_arena *arena) { + return (envoy_api_v2_cluster_CircuitBreakers *)upb_msg_new(&envoy_api_v2_cluster_CircuitBreakers_msginit, arena); +} +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers *envoy_api_v2_cluster_CircuitBreakers_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_cluster_CircuitBreakers *ret = envoy_api_v2_cluster_CircuitBreakers_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_cluster_CircuitBreakers_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_cluster_CircuitBreakers_serialize(const envoy_api_v2_cluster_CircuitBreakers *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_cluster_CircuitBreakers_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_cluster_CircuitBreakers_Thresholds* const* envoy_api_v2_cluster_CircuitBreakers_thresholds(const envoy_api_v2_cluster_CircuitBreakers *msg, size_t *len) { return (const envoy_api_v2_cluster_CircuitBreakers_Thresholds* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } + +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers_Thresholds** envoy_api_v2_cluster_CircuitBreakers_mutable_thresholds(envoy_api_v2_cluster_CircuitBreakers *msg, size_t *len) { + return (envoy_api_v2_cluster_CircuitBreakers_Thresholds**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); +} +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers_Thresholds** envoy_api_v2_cluster_CircuitBreakers_resize_thresholds(envoy_api_v2_cluster_CircuitBreakers *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_cluster_CircuitBreakers_Thresholds**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_cluster_CircuitBreakers_Thresholds* envoy_api_v2_cluster_CircuitBreakers_add_thresholds(envoy_api_v2_cluster_CircuitBreakers *msg, upb_arena *arena) { + struct envoy_api_v2_cluster_CircuitBreakers_Thresholds* sub = (struct envoy_api_v2_cluster_CircuitBreakers_Thresholds*)upb_msg_new(&envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.cluster.CircuitBreakers.Thresholds */ + +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers_Thresholds *envoy_api_v2_cluster_CircuitBreakers_Thresholds_new(upb_arena *arena) { + return (envoy_api_v2_cluster_CircuitBreakers_Thresholds *)upb_msg_new(&envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit, arena); +} +UPB_INLINE envoy_api_v2_cluster_CircuitBreakers_Thresholds *envoy_api_v2_cluster_CircuitBreakers_Thresholds_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_cluster_CircuitBreakers_Thresholds *ret = envoy_api_v2_cluster_CircuitBreakers_Thresholds_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_cluster_CircuitBreakers_Thresholds_serialize(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_cluster_CircuitBreakers_Thresholds_msginit, arena, len); +} + +UPB_INLINE int32_t envoy_api_v2_cluster_CircuitBreakers_Thresholds_priority(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_connections(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(8, 8)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_pending_requests(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(12, 16)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_requests(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(16, 24)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_retries(const envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(20, 32)); } + +UPB_INLINE void envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_priority(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_connections(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_mutable_max_connections(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_connections(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_connections(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_pending_requests(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_mutable_max_pending_requests(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_pending_requests(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_pending_requests(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_requests(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(16, 24)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_mutable_max_requests(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_requests(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_requests(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_retries(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(20, 32)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_CircuitBreakers_Thresholds_mutable_max_retries(envoy_api_v2_cluster_CircuitBreakers_Thresholds *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_CircuitBreakers_Thresholds_max_retries(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_CircuitBreakers_Thresholds_set_max_retries(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CLUSTER_CIRCUIT_BREAKER_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c b/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c new file mode 100644 index 00000000000..7158a8b8809 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.c @@ -0,0 +1,45 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cluster/outlier_detection.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/cluster/outlier_detection.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_cluster_OutlierDetection_submsgs[11] = { + &google_protobuf_Duration_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_cluster_OutlierDetection__fields[11] = { + {1, UPB_SIZE(0, 0), 0, 1, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 0, 11, 1}, + {4, UPB_SIZE(12, 24), 0, 1, 11, 1}, + {5, UPB_SIZE(16, 32), 0, 1, 11, 1}, + {6, UPB_SIZE(20, 40), 0, 1, 11, 1}, + {7, UPB_SIZE(24, 48), 0, 1, 11, 1}, + {8, UPB_SIZE(28, 56), 0, 1, 11, 1}, + {9, UPB_SIZE(32, 64), 0, 1, 11, 1}, + {10, UPB_SIZE(36, 72), 0, 1, 11, 1}, + {11, UPB_SIZE(40, 80), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_cluster_OutlierDetection_msginit = { + &envoy_api_v2_cluster_OutlierDetection_submsgs[0], + &envoy_api_v2_cluster_OutlierDetection__fields[0], + UPB_SIZE(44, 88), 11, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h b/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h new file mode 100644 index 00000000000..06fa49f6fd7 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h @@ -0,0 +1,199 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/cluster/outlier_detection.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CLUSTER_OUTLIER_DETECTION_PROTO_UPB_H_ +#define ENVOY_API_V2_CLUSTER_OUTLIER_DETECTION_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_cluster_OutlierDetection; +typedef struct envoy_api_v2_cluster_OutlierDetection envoy_api_v2_cluster_OutlierDetection; +extern const upb_msglayout envoy_api_v2_cluster_OutlierDetection_msginit; +struct google_protobuf_Duration; +struct google_protobuf_UInt32Value; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + + +/* envoy.api.v2.cluster.OutlierDetection */ + +UPB_INLINE envoy_api_v2_cluster_OutlierDetection *envoy_api_v2_cluster_OutlierDetection_new(upb_arena *arena) { + return (envoy_api_v2_cluster_OutlierDetection *)upb_msg_new(&envoy_api_v2_cluster_OutlierDetection_msginit, arena); +} +UPB_INLINE envoy_api_v2_cluster_OutlierDetection *envoy_api_v2_cluster_OutlierDetection_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_cluster_OutlierDetection *ret = envoy_api_v2_cluster_OutlierDetection_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_cluster_OutlierDetection_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_cluster_OutlierDetection_serialize(const envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_cluster_OutlierDetection_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_consecutive_5xx(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_cluster_OutlierDetection_interval(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_cluster_OutlierDetection_base_ejection_time(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(8, 16)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_max_ejection_percent(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(12, 24)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_enforcing_consecutive_5xx(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(16, 32)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_enforcing_success_rate(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(20, 40)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_success_rate_minimum_hosts(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(24, 48)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_success_rate_request_volume(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(28, 56)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_success_rate_stdev_factor(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(32, 64)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_consecutive_gateway_failure(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(36, 72)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_enforcing_consecutive_gateway_failure(const envoy_api_v2_cluster_OutlierDetection *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(40, 80)); } + +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_consecutive_5xx(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_consecutive_5xx(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_consecutive_5xx(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_consecutive_5xx(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_interval(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_cluster_OutlierDetection_mutable_interval(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_cluster_OutlierDetection_interval(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_interval(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_base_ejection_time(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_cluster_OutlierDetection_mutable_base_ejection_time(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_cluster_OutlierDetection_base_ejection_time(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_base_ejection_time(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_max_ejection_percent(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_max_ejection_percent(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_max_ejection_percent(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_max_ejection_percent(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_enforcing_consecutive_5xx(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_enforcing_consecutive_5xx(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_enforcing_consecutive_5xx(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_enforcing_consecutive_5xx(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_enforcing_success_rate(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(20, 40)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_enforcing_success_rate(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_enforcing_success_rate(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_enforcing_success_rate(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_success_rate_minimum_hosts(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_success_rate_minimum_hosts(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_success_rate_minimum_hosts(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_success_rate_minimum_hosts(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_success_rate_request_volume(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_success_rate_request_volume(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_success_rate_request_volume(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_success_rate_request_volume(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_success_rate_stdev_factor(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(32, 64)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_success_rate_stdev_factor(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_success_rate_stdev_factor(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_success_rate_stdev_factor(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_consecutive_gateway_failure(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(36, 72)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_consecutive_gateway_failure(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_consecutive_gateway_failure(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_consecutive_gateway_failure(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_cluster_OutlierDetection_set_enforcing_consecutive_gateway_failure(envoy_api_v2_cluster_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(40, 80)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_cluster_OutlierDetection_mutable_enforcing_consecutive_gateway_failure(envoy_api_v2_cluster_OutlierDetection *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_cluster_OutlierDetection_enforcing_consecutive_gateway_failure(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_cluster_OutlierDetection_set_enforcing_consecutive_gateway_failure(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CLUSTER_OUTLIER_DETECTION_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c new file mode 100644 index 00000000000..b36d02aeb81 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c @@ -0,0 +1,81 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/config_source.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/config_source.upb.h" +#include "envoy/api/v2/core/grpc_service.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_core_ApiConfigSource_submsgs[4] = { + &envoy_api_v2_core_GrpcService_msginit, + &envoy_api_v2_core_RateLimitSettings_msginit, + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_ApiConfigSource__fields[6] = { + {1, UPB_SIZE(0, 0), 0, 0, 14, 1}, + {2, UPB_SIZE(20, 32), 0, 0, 9, 3}, + {3, UPB_SIZE(8, 8), 0, 2, 11, 1}, + {4, UPB_SIZE(24, 40), 0, 0, 11, 3}, + {5, UPB_SIZE(12, 16), 0, 2, 11, 1}, + {6, UPB_SIZE(16, 24), 0, 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_ApiConfigSource_msginit = { + &envoy_api_v2_core_ApiConfigSource_submsgs[0], + &envoy_api_v2_core_ApiConfigSource__fields[0], + UPB_SIZE(32, 48), 6, false, +}; + +const upb_msglayout envoy_api_v2_core_AggregatedConfigSource_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_RateLimitSettings_submsgs[2] = { + &google_protobuf_DoubleValue_msginit, + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_RateLimitSettings__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 1, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_RateLimitSettings_msginit = { + &envoy_api_v2_core_RateLimitSettings_submsgs[0], + &envoy_api_v2_core_RateLimitSettings__fields[0], + UPB_SIZE(8, 16), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_ConfigSource_submsgs[2] = { + &envoy_api_v2_core_AggregatedConfigSource_msginit, + &envoy_api_v2_core_ApiConfigSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_ConfigSource__fields[3] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 1, 11, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_ConfigSource_msginit = { + &envoy_api_v2_core_ConfigSource_submsgs[0], + &envoy_api_v2_core_ConfigSource__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h new file mode 100644 index 00000000000..2b03b134c8e --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h @@ -0,0 +1,258 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/config_source.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_CONFIG_SOURCE_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_CONFIG_SOURCE_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_ApiConfigSource; +struct envoy_api_v2_core_AggregatedConfigSource; +struct envoy_api_v2_core_RateLimitSettings; +struct envoy_api_v2_core_ConfigSource; +typedef struct envoy_api_v2_core_ApiConfigSource envoy_api_v2_core_ApiConfigSource; +typedef struct envoy_api_v2_core_AggregatedConfigSource envoy_api_v2_core_AggregatedConfigSource; +typedef struct envoy_api_v2_core_RateLimitSettings envoy_api_v2_core_RateLimitSettings; +typedef struct envoy_api_v2_core_ConfigSource envoy_api_v2_core_ConfigSource; +extern const upb_msglayout envoy_api_v2_core_ApiConfigSource_msginit; +extern const upb_msglayout envoy_api_v2_core_AggregatedConfigSource_msginit; +extern const upb_msglayout envoy_api_v2_core_RateLimitSettings_msginit; +extern const upb_msglayout envoy_api_v2_core_ConfigSource_msginit; +struct envoy_api_v2_core_GrpcService; +struct google_protobuf_DoubleValue; +struct google_protobuf_Duration; +struct google_protobuf_UInt32Value; +extern const upb_msglayout envoy_api_v2_core_GrpcService_msginit; +extern const upb_msglayout google_protobuf_DoubleValue_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + +typedef enum { + envoy_api_v2_core_ApiConfigSource_REST_LEGACY = 0, + envoy_api_v2_core_ApiConfigSource_REST = 1, + envoy_api_v2_core_ApiConfigSource_GRPC = 2 +} envoy_api_v2_core_ApiConfigSource_ApiType; + + +/* envoy.api.v2.core.ApiConfigSource */ + +UPB_INLINE envoy_api_v2_core_ApiConfigSource *envoy_api_v2_core_ApiConfigSource_new(upb_arena *arena) { + return (envoy_api_v2_core_ApiConfigSource *)upb_msg_new(&envoy_api_v2_core_ApiConfigSource_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_ApiConfigSource *envoy_api_v2_core_ApiConfigSource_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_ApiConfigSource *ret = envoy_api_v2_core_ApiConfigSource_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_ApiConfigSource_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_ApiConfigSource_serialize(const envoy_api_v2_core_ApiConfigSource *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_ApiConfigSource_msginit, arena, len); +} + +UPB_INLINE int32_t envoy_api_v2_core_ApiConfigSource_api_type(const envoy_api_v2_core_ApiConfigSource *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview const* envoy_api_v2_core_ApiConfigSource_cluster_names(const envoy_api_v2_core_ApiConfigSource *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_ApiConfigSource_refresh_delay(const envoy_api_v2_core_ApiConfigSource *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(8, 8)); } +UPB_INLINE const struct envoy_api_v2_core_GrpcService* const* envoy_api_v2_core_ApiConfigSource_grpc_services(const envoy_api_v2_core_ApiConfigSource *msg, size_t *len) { return (const struct envoy_api_v2_core_GrpcService* const*)_upb_array_accessor(msg, UPB_SIZE(24, 40), len); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_ApiConfigSource_request_timeout(const envoy_api_v2_core_ApiConfigSource *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(12, 16)); } +UPB_INLINE const envoy_api_v2_core_RateLimitSettings* envoy_api_v2_core_ApiConfigSource_rate_limit_settings(const envoy_api_v2_core_ApiConfigSource *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_RateLimitSettings*, UPB_SIZE(16, 24)); } + +UPB_INLINE void envoy_api_v2_core_ApiConfigSource_set_api_type(envoy_api_v2_core_ApiConfigSource *msg, int32_t value) { + UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE upb_strview* envoy_api_v2_core_ApiConfigSource_mutable_cluster_names(envoy_api_v2_core_ApiConfigSource *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len); +} +UPB_INLINE upb_strview* envoy_api_v2_core_ApiConfigSource_resize_cluster_names(envoy_api_v2_core_ApiConfigSource *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena); +} +UPB_INLINE bool envoy_api_v2_core_ApiConfigSource_add_cluster_names(envoy_api_v2_core_ApiConfigSource *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor( + msg, UPB_SIZE(20, 32), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena); +} +UPB_INLINE void envoy_api_v2_core_ApiConfigSource_set_refresh_delay(envoy_api_v2_core_ApiConfigSource *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_ApiConfigSource_mutable_refresh_delay(envoy_api_v2_core_ApiConfigSource *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_ApiConfigSource_refresh_delay(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_ApiConfigSource_set_refresh_delay(msg, sub); + } + return sub; +} +UPB_INLINE struct envoy_api_v2_core_GrpcService** envoy_api_v2_core_ApiConfigSource_mutable_grpc_services(envoy_api_v2_core_ApiConfigSource *msg, size_t *len) { + return (struct envoy_api_v2_core_GrpcService**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 40), len); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService** envoy_api_v2_core_ApiConfigSource_resize_grpc_services(envoy_api_v2_core_ApiConfigSource *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_GrpcService**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService* envoy_api_v2_core_ApiConfigSource_add_grpc_services(envoy_api_v2_core_ApiConfigSource *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService* sub = (struct envoy_api_v2_core_GrpcService*)upb_msg_new(&envoy_api_v2_core_GrpcService_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(24, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_core_ApiConfigSource_set_request_timeout(envoy_api_v2_core_ApiConfigSource *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(12, 16)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_ApiConfigSource_mutable_request_timeout(envoy_api_v2_core_ApiConfigSource *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_ApiConfigSource_request_timeout(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_ApiConfigSource_set_request_timeout(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_ApiConfigSource_set_rate_limit_settings(envoy_api_v2_core_ApiConfigSource *msg, envoy_api_v2_core_RateLimitSettings* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_RateLimitSettings*, UPB_SIZE(16, 24)) = value; +} +UPB_INLINE struct envoy_api_v2_core_RateLimitSettings* envoy_api_v2_core_ApiConfigSource_mutable_rate_limit_settings(envoy_api_v2_core_ApiConfigSource *msg, upb_arena *arena) { + struct envoy_api_v2_core_RateLimitSettings* sub = (struct envoy_api_v2_core_RateLimitSettings*)envoy_api_v2_core_ApiConfigSource_rate_limit_settings(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_RateLimitSettings*)upb_msg_new(&envoy_api_v2_core_RateLimitSettings_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_ApiConfigSource_set_rate_limit_settings(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.AggregatedConfigSource */ + +UPB_INLINE envoy_api_v2_core_AggregatedConfigSource *envoy_api_v2_core_AggregatedConfigSource_new(upb_arena *arena) { + return (envoy_api_v2_core_AggregatedConfigSource *)upb_msg_new(&envoy_api_v2_core_AggregatedConfigSource_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_AggregatedConfigSource *envoy_api_v2_core_AggregatedConfigSource_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_AggregatedConfigSource *ret = envoy_api_v2_core_AggregatedConfigSource_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_AggregatedConfigSource_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_AggregatedConfigSource_serialize(const envoy_api_v2_core_AggregatedConfigSource *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_AggregatedConfigSource_msginit, arena, len); +} + + + + +/* envoy.api.v2.core.RateLimitSettings */ + +UPB_INLINE envoy_api_v2_core_RateLimitSettings *envoy_api_v2_core_RateLimitSettings_new(upb_arena *arena) { + return (envoy_api_v2_core_RateLimitSettings *)upb_msg_new(&envoy_api_v2_core_RateLimitSettings_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_RateLimitSettings *envoy_api_v2_core_RateLimitSettings_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_RateLimitSettings *ret = envoy_api_v2_core_RateLimitSettings_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_RateLimitSettings_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_RateLimitSettings_serialize(const envoy_api_v2_core_RateLimitSettings *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_RateLimitSettings_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_RateLimitSettings_max_tokens(const envoy_api_v2_core_RateLimitSettings *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct google_protobuf_DoubleValue* envoy_api_v2_core_RateLimitSettings_fill_rate(const envoy_api_v2_core_RateLimitSettings *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_DoubleValue*, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_core_RateLimitSettings_set_max_tokens(envoy_api_v2_core_RateLimitSettings *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_RateLimitSettings_mutable_max_tokens(envoy_api_v2_core_RateLimitSettings *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_RateLimitSettings_max_tokens(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_RateLimitSettings_set_max_tokens(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_RateLimitSettings_set_fill_rate(envoy_api_v2_core_RateLimitSettings *msg, struct google_protobuf_DoubleValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_DoubleValue*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_DoubleValue* envoy_api_v2_core_RateLimitSettings_mutable_fill_rate(envoy_api_v2_core_RateLimitSettings *msg, upb_arena *arena) { + struct google_protobuf_DoubleValue* sub = (struct google_protobuf_DoubleValue*)envoy_api_v2_core_RateLimitSettings_fill_rate(msg); + if (sub == NULL) { + sub = (struct google_protobuf_DoubleValue*)upb_msg_new(&google_protobuf_DoubleValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_RateLimitSettings_set_fill_rate(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.ConfigSource */ + +UPB_INLINE envoy_api_v2_core_ConfigSource *envoy_api_v2_core_ConfigSource_new(upb_arena *arena) { + return (envoy_api_v2_core_ConfigSource *)upb_msg_new(&envoy_api_v2_core_ConfigSource_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_ConfigSource *envoy_api_v2_core_ConfigSource_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_ConfigSource *ret = envoy_api_v2_core_ConfigSource_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_ConfigSource_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_ConfigSource_serialize(const envoy_api_v2_core_ConfigSource *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_ConfigSource_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_ConfigSource_config_source_specifier_path = 1, + envoy_api_v2_core_ConfigSource_config_source_specifier_api_config_source = 2, + envoy_api_v2_core_ConfigSource_config_source_specifier_ads = 3, + envoy_api_v2_core_ConfigSource_config_source_specifier_NOT_SET = 0, +} envoy_api_v2_core_ConfigSource_config_source_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_ConfigSource_config_source_specifier_oneofcases envoy_api_v2_core_ConfigSource_config_source_specifier_case(const envoy_api_v2_core_ConfigSource* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } + +UPB_INLINE bool envoy_api_v2_core_ConfigSource_has_path(const envoy_api_v2_core_ConfigSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } +UPB_INLINE upb_strview envoy_api_v2_core_ConfigSource_path(const envoy_api_v2_core_ConfigSource *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_ConfigSource_has_api_config_source(const envoy_api_v2_core_ConfigSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } +UPB_INLINE const envoy_api_v2_core_ApiConfigSource* envoy_api_v2_core_ConfigSource_api_config_source(const envoy_api_v2_core_ConfigSource *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_ApiConfigSource*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_ConfigSource_has_ads(const envoy_api_v2_core_ConfigSource *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 3); } +UPB_INLINE const envoy_api_v2_core_AggregatedConfigSource* envoy_api_v2_core_ConfigSource_ads(const envoy_api_v2_core_ConfigSource *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_AggregatedConfigSource*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, NULL); } + +UPB_INLINE void envoy_api_v2_core_ConfigSource_set_path(envoy_api_v2_core_ConfigSource *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); +} +UPB_INLINE void envoy_api_v2_core_ConfigSource_set_api_config_source(envoy_api_v2_core_ConfigSource *msg, envoy_api_v2_core_ApiConfigSource* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_ApiConfigSource*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); +} +UPB_INLINE struct envoy_api_v2_core_ApiConfigSource* envoy_api_v2_core_ConfigSource_mutable_api_config_source(envoy_api_v2_core_ConfigSource *msg, upb_arena *arena) { + struct envoy_api_v2_core_ApiConfigSource* sub = (struct envoy_api_v2_core_ApiConfigSource*)envoy_api_v2_core_ConfigSource_api_config_source(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_ApiConfigSource*)upb_msg_new(&envoy_api_v2_core_ApiConfigSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_ConfigSource_set_api_config_source(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_ConfigSource_set_ads(envoy_api_v2_core_ConfigSource *msg, envoy_api_v2_core_AggregatedConfigSource* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_AggregatedConfigSource*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 3); +} +UPB_INLINE struct envoy_api_v2_core_AggregatedConfigSource* envoy_api_v2_core_ConfigSource_mutable_ads(envoy_api_v2_core_ConfigSource *msg, upb_arena *arena) { + struct envoy_api_v2_core_AggregatedConfigSource* sub = (struct envoy_api_v2_core_AggregatedConfigSource*)envoy_api_v2_core_ConfigSource_ads(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_AggregatedConfigSource*)upb_msg_new(&envoy_api_v2_core_AggregatedConfigSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_ConfigSource_set_ads(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_CONFIG_SOURCE_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c new file mode 100644 index 00000000000..e0c32f7eaf6 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c @@ -0,0 +1,175 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/grpc_service.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/grpc_service.upb.h" +#include "envoy/api/v2/core/base.upb.h" +#include "google/protobuf/any.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/struct.upb.h" +#include "google/protobuf/empty.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_submsgs[4] = { + &envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit, + &envoy_api_v2_core_GrpcService_GoogleGrpc_msginit, + &envoy_api_v2_core_HeaderValue_msginit, + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService__fields[4] = { + {1, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(0, 0), 0, 3, 11, 1}, + {5, UPB_SIZE(4, 8), 0, 2, 11, 3}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_msginit = { + &envoy_api_v2_core_GrpcService_submsgs[0], + &envoy_api_v2_core_GrpcService__fields[0], + UPB_SIZE(16, 32), 4, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_EnvoyGrpc__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit = { + NULL, + &envoy_api_v2_core_GrpcService_EnvoyGrpc__fields[0], + UPB_SIZE(8, 16), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_GoogleGrpc_submsgs[3] = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit, + &envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc__fields[6] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(24, 48), 0, 1, 11, 1}, + {3, UPB_SIZE(32, 64), 0, 0, 11, 3}, + {4, UPB_SIZE(8, 16), 0, 0, 9, 1}, + {5, UPB_SIZE(16, 32), 0, 0, 9, 1}, + {6, UPB_SIZE(28, 56), 0, 2, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_msginit = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_submsgs[0], + &envoy_api_v2_core_GrpcService_GoogleGrpc__fields[0], + UPB_SIZE(40, 80), 6, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_submsgs[3] = { + &envoy_api_v2_core_DataSource_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, + {2, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {3, UPB_SIZE(8, 16), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_submsgs[0], + &envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials__fields[0], + UPB_SIZE(12, 24), 3, false, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_submsgs[3] = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit, + &envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit, + &google_protobuf_Empty_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials__fields[3] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 1, 11, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 2, 11, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-5, -9), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_submsgs[0], + &envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials__fields[0], + UPB_SIZE(8, 16), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_submsgs[4] = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit, + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit, + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit, + &google_protobuf_Empty_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials__fields[6] = { + {1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 3, 11, 1}, + {3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, + {4, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 2, 11, 1}, + {5, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 11, 1}, + {6, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 1, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_submsgs[0], + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials__fields[0], + UPB_SIZE(16, 32), 6, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__fields[2] = { + {1, UPB_SIZE(8, 8), 0, 0, 9, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 4, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit = { + NULL, + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__fields[2] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit = { + NULL, + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__fields[0], + UPB_SIZE(16, 32), 2, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_submsgs[2] = { + &google_protobuf_Any_msginit, + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__fields[3] = { + {1, UPB_SIZE(0, 0), 0, 0, 9, 1}, + {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1}, + {3, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit = { + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_submsgs[0], + &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h new file mode 100644 index 00000000000..8369c026dc7 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h @@ -0,0 +1,574 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/grpc_service.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_GRPC_SERVICE_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_GRPC_SERVICE_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_GrpcService; +struct envoy_api_v2_core_GrpcService_EnvoyGrpc; +struct envoy_api_v2_core_GrpcService_GoogleGrpc; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials; +struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin; +typedef struct envoy_api_v2_core_GrpcService envoy_api_v2_core_GrpcService; +typedef struct envoy_api_v2_core_GrpcService_EnvoyGrpc envoy_api_v2_core_GrpcService_EnvoyGrpc; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc envoy_api_v2_core_GrpcService_GoogleGrpc; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials; +typedef struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin; +extern const upb_msglayout envoy_api_v2_core_GrpcService_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit; +struct envoy_api_v2_core_DataSource; +struct envoy_api_v2_core_HeaderValue; +struct google_protobuf_Any; +struct google_protobuf_Duration; +struct google_protobuf_Empty; +struct google_protobuf_Struct; +extern const upb_msglayout envoy_api_v2_core_DataSource_msginit; +extern const upb_msglayout envoy_api_v2_core_HeaderValue_msginit; +extern const upb_msglayout google_protobuf_Any_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_Empty_msginit; +extern const upb_msglayout google_protobuf_Struct_msginit; + +/* Enums */ + + +/* envoy.api.v2.core.GrpcService */ + +UPB_INLINE envoy_api_v2_core_GrpcService *envoy_api_v2_core_GrpcService_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService *)upb_msg_new(&envoy_api_v2_core_GrpcService_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService *envoy_api_v2_core_GrpcService_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService *ret = envoy_api_v2_core_GrpcService_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_serialize(const envoy_api_v2_core_GrpcService *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_GrpcService_target_specifier_envoy_grpc = 1, + envoy_api_v2_core_GrpcService_target_specifier_google_grpc = 2, + envoy_api_v2_core_GrpcService_target_specifier_NOT_SET = 0, +} envoy_api_v2_core_GrpcService_target_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_GrpcService_target_specifier_oneofcases envoy_api_v2_core_GrpcService_target_specifier_case(const envoy_api_v2_core_GrpcService* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE bool envoy_api_v2_core_GrpcService_has_envoy_grpc(const envoy_api_v2_core_GrpcService *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 1); } +UPB_INLINE const envoy_api_v2_core_GrpcService_EnvoyGrpc* envoy_api_v2_core_GrpcService_envoy_grpc(const envoy_api_v2_core_GrpcService *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_EnvoyGrpc*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 1, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_has_google_grpc(const envoy_api_v2_core_GrpcService *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc* envoy_api_v2_core_GrpcService_google_grpc(const envoy_api_v2_core_GrpcService *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_GrpcService_timeout(const envoy_api_v2_core_GrpcService *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_HeaderValue* const* envoy_api_v2_core_GrpcService_initial_metadata(const envoy_api_v2_core_GrpcService *msg, size_t *len) { return (const struct envoy_api_v2_core_HeaderValue* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_set_envoy_grpc(envoy_api_v2_core_GrpcService *msg, envoy_api_v2_core_GrpcService_EnvoyGrpc* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_EnvoyGrpc*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 1); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_EnvoyGrpc* envoy_api_v2_core_GrpcService_mutable_envoy_grpc(envoy_api_v2_core_GrpcService *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_EnvoyGrpc* sub = (struct envoy_api_v2_core_GrpcService_EnvoyGrpc*)envoy_api_v2_core_GrpcService_envoy_grpc(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_EnvoyGrpc*)upb_msg_new(&envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_set_envoy_grpc(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_set_google_grpc(envoy_api_v2_core_GrpcService *msg, envoy_api_v2_core_GrpcService_GoogleGrpc* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc* envoy_api_v2_core_GrpcService_mutable_google_grpc(envoy_api_v2_core_GrpcService *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc*)envoy_api_v2_core_GrpcService_google_grpc(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_set_google_grpc(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_set_timeout(envoy_api_v2_core_GrpcService *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_GrpcService_mutable_timeout(envoy_api_v2_core_GrpcService *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_GrpcService_timeout(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_set_timeout(msg, sub); + } + return sub; +} +UPB_INLINE struct envoy_api_v2_core_HeaderValue** envoy_api_v2_core_GrpcService_mutable_initial_metadata(envoy_api_v2_core_GrpcService *msg, size_t *len) { + return (struct envoy_api_v2_core_HeaderValue**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len); +} +UPB_INLINE struct envoy_api_v2_core_HeaderValue** envoy_api_v2_core_GrpcService_resize_initial_metadata(envoy_api_v2_core_GrpcService *msg, size_t len, upb_arena *arena) { + return (struct envoy_api_v2_core_HeaderValue**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_HeaderValue* envoy_api_v2_core_GrpcService_add_initial_metadata(envoy_api_v2_core_GrpcService *msg, upb_arena *arena) { + struct envoy_api_v2_core_HeaderValue* sub = (struct envoy_api_v2_core_HeaderValue*)upb_msg_new(&envoy_api_v2_core_HeaderValue_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} + + +/* envoy.api.v2.core.GrpcService.EnvoyGrpc */ + +UPB_INLINE envoy_api_v2_core_GrpcService_EnvoyGrpc *envoy_api_v2_core_GrpcService_EnvoyGrpc_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_EnvoyGrpc *)upb_msg_new(&envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_EnvoyGrpc *envoy_api_v2_core_GrpcService_EnvoyGrpc_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_EnvoyGrpc *ret = envoy_api_v2_core_GrpcService_EnvoyGrpc_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_EnvoyGrpc_serialize(const envoy_api_v2_core_GrpcService_EnvoyGrpc *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_EnvoyGrpc_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_EnvoyGrpc_cluster_name(const envoy_api_v2_core_GrpcService_EnvoyGrpc *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_EnvoyGrpc_set_cluster_name(envoy_api_v2_core_GrpcService_EnvoyGrpc *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc *envoy_api_v2_core_GrpcService_GoogleGrpc_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc *envoy_api_v2_core_GrpcService_GoogleGrpc_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_target_uri(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_channel_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials*, UPB_SIZE(24, 48)); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials* const* envoy_api_v2_core_GrpcService_GoogleGrpc_call_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg, size_t *len) { return (const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); } +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_stat_prefix(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_credentials_factory_name(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_GrpcService_GoogleGrpc_config(const envoy_api_v2_core_GrpcService_GoogleGrpc *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Struct*, UPB_SIZE(28, 56)); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_set_target_uri(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_set_channel_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials*, UPB_SIZE(24, 48)) = value; +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_mutable_channel_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials*)envoy_api_v2_core_GrpcService_GoogleGrpc_channel_credentials(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_set_channel_credentials(msg, sub); + } + return sub; +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials** envoy_api_v2_core_GrpcService_GoogleGrpc_mutable_call_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, size_t *len) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials** envoy_api_v2_core_GrpcService_GoogleGrpc_resize_call_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, size_t len, upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_add_call_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit, arena); + bool ok = _upb_array_append_accessor( + msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_set_stat_prefix(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_set_credentials_factory_name(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_set_config(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, struct google_protobuf_Struct* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Struct*, UPB_SIZE(28, 56)) = value; +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_GrpcService_GoogleGrpc_mutable_config(envoy_api_v2_core_GrpcService_GoogleGrpc *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_GrpcService_GoogleGrpc_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_set_config(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.SslCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit, arena, len); +} + +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_root_certs(const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(0, 0)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_private_key(const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_cert_chain(const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg) { return UPB_FIELD_AT(msg, const struct envoy_api_v2_core_DataSource*, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_root_certs(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_mutable_root_certs(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_root_certs(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_root_certs(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_private_key(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_mutable_private_key(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_private_key(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_private_key(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_cert_chain(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, struct envoy_api_v2_core_DataSource* value) { + UPB_FIELD_AT(msg, struct envoy_api_v2_core_DataSource*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct envoy_api_v2_core_DataSource* envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_mutable_cert_chain(envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_DataSource* sub = (struct envoy_api_v2_core_DataSource*)envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_cert_chain(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_DataSource*)upb_msg_new(&envoy_api_v2_core_DataSource_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_set_cert_chain(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.GoogleLocalCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit, arena, len); +} + + + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.ChannelCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_ssl_credentials = 1, + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_google_default = 2, + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_local_credentials = 3, + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_NOT_SET = 0, +} envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_oneofcases envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_credential_specifier_case(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(4, 8)); } + +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_has_ssl_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 1); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_ssl_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 1, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_has_google_default(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 2); } +UPB_INLINE const struct google_protobuf_Empty* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_google_default(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Empty*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_has_local_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(4, 8), 3); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_local_credentials(const envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials*, UPB_SIZE(0, 0), UPB_SIZE(4, 8), 3, NULL); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_ssl_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 1); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_mutable_ssl_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials*)envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_ssl_credentials(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_ssl_credentials(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_google_default(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, struct google_protobuf_Empty* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Empty*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 2); +} +UPB_INLINE struct google_protobuf_Empty* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_mutable_google_default(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, upb_arena *arena) { + struct google_protobuf_Empty* sub = (struct google_protobuf_Empty*)envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_google_default(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Empty*)upb_msg_new(&google_protobuf_Empty_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_google_default(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_local_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials*, UPB_SIZE(0, 0), value, UPB_SIZE(4, 8), 3); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_mutable_local_credentials(envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials*)envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_local_credentials(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials_set_local_credentials(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.CallCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_access_token = 1, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_google_compute_engine = 2, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_google_refresh_token = 3, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_service_account_jwt_access = 4, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_google_iam = 5, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_from_plugin = 6, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_NOT_SET = 0, +} envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_oneofcases; +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_oneofcases envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_credential_specifier_case(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } + +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_access_token(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_access_token(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_google_compute_engine(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } +UPB_INLINE const struct google_protobuf_Empty* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_google_compute_engine(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Empty*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_google_refresh_token(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 3); } +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_google_refresh_token(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, upb_strview_make("", strlen(""))); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_service_account_jwt_access(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 4); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_service_account_jwt_access(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 4, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_google_iam(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 5); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_google_iam(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 5, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_has_from_plugin(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 6); } +UPB_INLINE const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_from_plugin(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg) { return UPB_READ_ONEOF(msg, const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 6, NULL); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_access_token(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_google_compute_engine(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, struct google_protobuf_Empty* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Empty*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); +} +UPB_INLINE struct google_protobuf_Empty* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_mutable_google_compute_engine(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_arena *arena) { + struct google_protobuf_Empty* sub = (struct google_protobuf_Empty*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_google_compute_engine(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Empty*)upb_msg_new(&google_protobuf_Empty_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_google_compute_engine(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_google_refresh_token(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_strview value) { + UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 3); +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_service_account_jwt_access(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 4); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_mutable_service_account_jwt_access(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_service_account_jwt_access(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_service_account_jwt_access(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_google_iam(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 5); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_mutable_google_iam(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_google_iam(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_google_iam(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_from_plugin(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin* value) { + UPB_WRITE_ONEOF(msg, envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 6); +} +UPB_INLINE struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_mutable_from_plugin(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials *msg, upb_arena *arena) { + struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin* sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_from_plugin(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin*)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_set_from_plugin(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.CallCredentials.ServiceAccountJWTAccessCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_json_key(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)); } +UPB_INLINE uint64_t envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_token_lifetime_seconds(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_set_json_key(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_set_token_lifetime_seconds(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *msg, uint64_t value) { + UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.CallCredentials.GoogleIAMCredentials */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit, arena, len); +} + +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_authorization_token(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_authority_selector(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_set_authorization_token(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_set_authority_selector(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; +} + + +/* envoy.api.v2.core.GrpcService.GoogleGrpc.CallCredentials.MetadataCredentialsFromPlugin */ + +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *)upb_msg_new(&envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *ret = envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_serialize(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit, arena, len); +} + +typedef enum { + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_config = 2, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_typed_config = 3, + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_NOT_SET = 0, +} envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_oneofcases; +UPB_INLINE envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_oneofcases envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config_type_case(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(12, 24)); } + +UPB_INLINE upb_strview envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_name(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_has_config(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 2); } +UPB_INLINE const struct google_protobuf_Struct* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Struct*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); } +UPB_INLINE bool envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_has_typed_config(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(12, 24), 3); } +UPB_INLINE const struct google_protobuf_Any* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_typed_config(const envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Any*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 3, NULL); } + +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_set_name(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_set_config(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, struct google_protobuf_Struct* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Struct*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2); +} +UPB_INLINE struct google_protobuf_Struct* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_mutable_config(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_set_config(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_set_typed_config(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, struct google_protobuf_Any* value) { + UPB_WRITE_ONEOF(msg, struct google_protobuf_Any*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 3); +} +UPB_INLINE struct google_protobuf_Any* envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_mutable_typed_config(envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, upb_arena *arena) { + struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_typed_config(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Any*)upb_msg_new(&google_protobuf_Any_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_set_typed_config(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_GRPC_SERVICE_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c b/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c new file mode 100644 index 00000000000..fa8855d20b9 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c @@ -0,0 +1,88 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/protocol.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/api/v2/core/protocol.upb.h" +#include "google/protobuf/duration.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "validate/validate.upb.h" +#include "gogoproto/gogo.upb.h" + +#include "upb/port_def.inc" + +const upb_msglayout envoy_api_v2_core_TcpProtocolOptions_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_HttpProtocolOptions_submsgs[1] = { + &google_protobuf_Duration_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_HttpProtocolOptions__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_HttpProtocolOptions_msginit = { + &envoy_api_v2_core_HttpProtocolOptions_submsgs[0], + &envoy_api_v2_core_HttpProtocolOptions__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Http1ProtocolOptions_submsgs[1] = { + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Http1ProtocolOptions__fields[3] = { + {1, UPB_SIZE(12, 24), 0, 0, 11, 1}, + {2, UPB_SIZE(0, 0), 0, 0, 8, 1}, + {3, UPB_SIZE(4, 8), 0, 0, 9, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Http1ProtocolOptions_msginit = { + &envoy_api_v2_core_Http1ProtocolOptions_submsgs[0], + &envoy_api_v2_core_Http1ProtocolOptions__fields[0], + UPB_SIZE(16, 32), 3, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_Http2ProtocolOptions_submsgs[4] = { + &google_protobuf_UInt32Value_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_Http2ProtocolOptions__fields[5] = { + {1, UPB_SIZE(4, 8), 0, 0, 11, 1}, + {2, UPB_SIZE(8, 16), 0, 0, 11, 1}, + {3, UPB_SIZE(12, 24), 0, 0, 11, 1}, + {4, UPB_SIZE(16, 32), 0, 0, 11, 1}, + {5, UPB_SIZE(0, 0), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_api_v2_core_Http2ProtocolOptions_msginit = { + &envoy_api_v2_core_Http2ProtocolOptions_submsgs[0], + &envoy_api_v2_core_Http2ProtocolOptions__fields[0], + UPB_SIZE(20, 40), 5, false, +}; + +static const upb_msglayout *const envoy_api_v2_core_GrpcProtocolOptions_submsgs[1] = { + &envoy_api_v2_core_Http2ProtocolOptions_msginit, +}; + +static const upb_msglayout_field envoy_api_v2_core_GrpcProtocolOptions__fields[1] = { + {1, UPB_SIZE(0, 0), 0, 0, 11, 1}, +}; + +const upb_msglayout envoy_api_v2_core_GrpcProtocolOptions_msginit = { + &envoy_api_v2_core_GrpcProtocolOptions_submsgs[0], + &envoy_api_v2_core_GrpcProtocolOptions__fields[0], + UPB_SIZE(4, 8), 1, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h b/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h new file mode 100644 index 00000000000..db352e43d87 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h @@ -0,0 +1,237 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/api/v2/core/protocol.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_API_V2_CORE_PROTOCOL_PROTO_UPB_H_ +#define ENVOY_API_V2_CORE_PROTOCOL_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_api_v2_core_TcpProtocolOptions; +struct envoy_api_v2_core_HttpProtocolOptions; +struct envoy_api_v2_core_Http1ProtocolOptions; +struct envoy_api_v2_core_Http2ProtocolOptions; +struct envoy_api_v2_core_GrpcProtocolOptions; +typedef struct envoy_api_v2_core_TcpProtocolOptions envoy_api_v2_core_TcpProtocolOptions; +typedef struct envoy_api_v2_core_HttpProtocolOptions envoy_api_v2_core_HttpProtocolOptions; +typedef struct envoy_api_v2_core_Http1ProtocolOptions envoy_api_v2_core_Http1ProtocolOptions; +typedef struct envoy_api_v2_core_Http2ProtocolOptions envoy_api_v2_core_Http2ProtocolOptions; +typedef struct envoy_api_v2_core_GrpcProtocolOptions envoy_api_v2_core_GrpcProtocolOptions; +extern const upb_msglayout envoy_api_v2_core_TcpProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_HttpProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_Http1ProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_Http2ProtocolOptions_msginit; +extern const upb_msglayout envoy_api_v2_core_GrpcProtocolOptions_msginit; +struct google_protobuf_BoolValue; +struct google_protobuf_Duration; +struct google_protobuf_UInt32Value; +extern const upb_msglayout google_protobuf_BoolValue_msginit; +extern const upb_msglayout google_protobuf_Duration_msginit; +extern const upb_msglayout google_protobuf_UInt32Value_msginit; + +/* Enums */ + + +/* envoy.api.v2.core.TcpProtocolOptions */ + +UPB_INLINE envoy_api_v2_core_TcpProtocolOptions *envoy_api_v2_core_TcpProtocolOptions_new(upb_arena *arena) { + return (envoy_api_v2_core_TcpProtocolOptions *)upb_msg_new(&envoy_api_v2_core_TcpProtocolOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_TcpProtocolOptions *envoy_api_v2_core_TcpProtocolOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_TcpProtocolOptions *ret = envoy_api_v2_core_TcpProtocolOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_TcpProtocolOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_TcpProtocolOptions_serialize(const envoy_api_v2_core_TcpProtocolOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_TcpProtocolOptions_msginit, arena, len); +} + + + + +/* envoy.api.v2.core.HttpProtocolOptions */ + +UPB_INLINE envoy_api_v2_core_HttpProtocolOptions *envoy_api_v2_core_HttpProtocolOptions_new(upb_arena *arena) { + return (envoy_api_v2_core_HttpProtocolOptions *)upb_msg_new(&envoy_api_v2_core_HttpProtocolOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_HttpProtocolOptions *envoy_api_v2_core_HttpProtocolOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_HttpProtocolOptions *ret = envoy_api_v2_core_HttpProtocolOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_HttpProtocolOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_HttpProtocolOptions_serialize(const envoy_api_v2_core_HttpProtocolOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_HttpProtocolOptions_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_Duration* envoy_api_v2_core_HttpProtocolOptions_idle_timeout(const envoy_api_v2_core_HttpProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_Duration*, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_HttpProtocolOptions_set_idle_timeout(envoy_api_v2_core_HttpProtocolOptions *msg, struct google_protobuf_Duration* value) { + UPB_FIELD_AT(msg, struct google_protobuf_Duration*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct google_protobuf_Duration* envoy_api_v2_core_HttpProtocolOptions_mutable_idle_timeout(envoy_api_v2_core_HttpProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_api_v2_core_HttpProtocolOptions_idle_timeout(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Duration*)upb_msg_new(&google_protobuf_Duration_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_HttpProtocolOptions_set_idle_timeout(msg, sub); + } + return sub; +} + + +/* envoy.api.v2.core.Http1ProtocolOptions */ + +UPB_INLINE envoy_api_v2_core_Http1ProtocolOptions *envoy_api_v2_core_Http1ProtocolOptions_new(upb_arena *arena) { + return (envoy_api_v2_core_Http1ProtocolOptions *)upb_msg_new(&envoy_api_v2_core_Http1ProtocolOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Http1ProtocolOptions *envoy_api_v2_core_Http1ProtocolOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Http1ProtocolOptions *ret = envoy_api_v2_core_Http1ProtocolOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Http1ProtocolOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Http1ProtocolOptions_serialize(const envoy_api_v2_core_Http1ProtocolOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Http1ProtocolOptions_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_BoolValue* envoy_api_v2_core_Http1ProtocolOptions_allow_absolute_url(const envoy_api_v2_core_Http1ProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(12, 24)); } +UPB_INLINE bool envoy_api_v2_core_Http1ProtocolOptions_accept_http_10(const envoy_api_v2_core_Http1ProtocolOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } +UPB_INLINE upb_strview envoy_api_v2_core_Http1ProtocolOptions_default_host_for_http_10(const envoy_api_v2_core_Http1ProtocolOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); } + +UPB_INLINE void envoy_api_v2_core_Http1ProtocolOptions_set_allow_absolute_url(envoy_api_v2_core_Http1ProtocolOptions *msg, struct google_protobuf_BoolValue* value) { + UPB_FIELD_AT(msg, struct google_protobuf_BoolValue*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_api_v2_core_Http1ProtocolOptions_mutable_allow_absolute_url(envoy_api_v2_core_Http1ProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_api_v2_core_Http1ProtocolOptions_allow_absolute_url(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Http1ProtocolOptions_set_allow_absolute_url(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Http1ProtocolOptions_set_accept_http_10(envoy_api_v2_core_Http1ProtocolOptions *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE void envoy_api_v2_core_Http1ProtocolOptions_set_default_host_for_http_10(envoy_api_v2_core_Http1ProtocolOptions *msg, upb_strview value) { + UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value; +} + + +/* envoy.api.v2.core.Http2ProtocolOptions */ + +UPB_INLINE envoy_api_v2_core_Http2ProtocolOptions *envoy_api_v2_core_Http2ProtocolOptions_new(upb_arena *arena) { + return (envoy_api_v2_core_Http2ProtocolOptions *)upb_msg_new(&envoy_api_v2_core_Http2ProtocolOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_Http2ProtocolOptions *envoy_api_v2_core_Http2ProtocolOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_Http2ProtocolOptions *ret = envoy_api_v2_core_Http2ProtocolOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_Http2ProtocolOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_Http2ProtocolOptions_serialize(const envoy_api_v2_core_Http2ProtocolOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_Http2ProtocolOptions_msginit, arena, len); +} + +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_hpack_table_size(const envoy_api_v2_core_Http2ProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(4, 8)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_max_concurrent_streams(const envoy_api_v2_core_Http2ProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_initial_stream_window_size(const envoy_api_v2_core_Http2ProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(12, 24)); } +UPB_INLINE const struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_initial_connection_window_size(const envoy_api_v2_core_Http2ProtocolOptions *msg) { return UPB_FIELD_AT(msg, const struct google_protobuf_UInt32Value*, UPB_SIZE(16, 32)); } +UPB_INLINE bool envoy_api_v2_core_Http2ProtocolOptions_allow_connect(const envoy_api_v2_core_Http2ProtocolOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_Http2ProtocolOptions_set_hpack_table_size(envoy_api_v2_core_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(4, 8)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_mutable_hpack_table_size(envoy_api_v2_core_Http2ProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_Http2ProtocolOptions_hpack_table_size(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Http2ProtocolOptions_set_hpack_table_size(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Http2ProtocolOptions_set_max_concurrent_streams(envoy_api_v2_core_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(8, 16)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_mutable_max_concurrent_streams(envoy_api_v2_core_Http2ProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_Http2ProtocolOptions_max_concurrent_streams(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Http2ProtocolOptions_set_max_concurrent_streams(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Http2ProtocolOptions_set_initial_stream_window_size(envoy_api_v2_core_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(12, 24)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_mutable_initial_stream_window_size(envoy_api_v2_core_Http2ProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_Http2ProtocolOptions_initial_stream_window_size(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Http2ProtocolOptions_set_initial_stream_window_size(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Http2ProtocolOptions_set_initial_connection_window_size(envoy_api_v2_core_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) { + UPB_FIELD_AT(msg, struct google_protobuf_UInt32Value*, UPB_SIZE(16, 32)) = value; +} +UPB_INLINE struct google_protobuf_UInt32Value* envoy_api_v2_core_Http2ProtocolOptions_mutable_initial_connection_window_size(envoy_api_v2_core_Http2ProtocolOptions *msg, upb_arena *arena) { + struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_api_v2_core_Http2ProtocolOptions_initial_connection_window_size(msg); + if (sub == NULL) { + sub = (struct google_protobuf_UInt32Value*)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_Http2ProtocolOptions_set_initial_connection_window_size(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_api_v2_core_Http2ProtocolOptions_set_allow_connect(envoy_api_v2_core_Http2ProtocolOptions *msg, bool value) { + UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; +} + + +/* envoy.api.v2.core.GrpcProtocolOptions */ + +UPB_INLINE envoy_api_v2_core_GrpcProtocolOptions *envoy_api_v2_core_GrpcProtocolOptions_new(upb_arena *arena) { + return (envoy_api_v2_core_GrpcProtocolOptions *)upb_msg_new(&envoy_api_v2_core_GrpcProtocolOptions_msginit, arena); +} +UPB_INLINE envoy_api_v2_core_GrpcProtocolOptions *envoy_api_v2_core_GrpcProtocolOptions_parsenew(upb_strview buf, upb_arena *arena) { + envoy_api_v2_core_GrpcProtocolOptions *ret = envoy_api_v2_core_GrpcProtocolOptions_new(arena); + return (ret && upb_decode(buf, ret, &envoy_api_v2_core_GrpcProtocolOptions_msginit)) ? ret : NULL; +} +UPB_INLINE char *envoy_api_v2_core_GrpcProtocolOptions_serialize(const envoy_api_v2_core_GrpcProtocolOptions *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_api_v2_core_GrpcProtocolOptions_msginit, arena, len); +} + +UPB_INLINE const envoy_api_v2_core_Http2ProtocolOptions* envoy_api_v2_core_GrpcProtocolOptions_http2_protocol_options(const envoy_api_v2_core_GrpcProtocolOptions *msg) { return UPB_FIELD_AT(msg, const envoy_api_v2_core_Http2ProtocolOptions*, UPB_SIZE(0, 0)); } + +UPB_INLINE void envoy_api_v2_core_GrpcProtocolOptions_set_http2_protocol_options(envoy_api_v2_core_GrpcProtocolOptions *msg, envoy_api_v2_core_Http2ProtocolOptions* value) { + UPB_FIELD_AT(msg, envoy_api_v2_core_Http2ProtocolOptions*, UPB_SIZE(0, 0)) = value; +} +UPB_INLINE struct envoy_api_v2_core_Http2ProtocolOptions* envoy_api_v2_core_GrpcProtocolOptions_mutable_http2_protocol_options(envoy_api_v2_core_GrpcProtocolOptions *msg, upb_arena *arena) { + struct envoy_api_v2_core_Http2ProtocolOptions* sub = (struct envoy_api_v2_core_Http2ProtocolOptions*)envoy_api_v2_core_GrpcProtocolOptions_http2_protocol_options(msg); + if (sub == NULL) { + sub = (struct envoy_api_v2_core_Http2ProtocolOptions*)upb_msg_new(&envoy_api_v2_core_Http2ProtocolOptions_msginit, arena); + if (!sub) return NULL; + envoy_api_v2_core_GrpcProtocolOptions_set_http2_protocol_options(msg, sub); + } + return sub; +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_API_V2_CORE_PROTOCOL_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/google/protobuf/empty.upb.c b/src/core/ext/upb-generated/google/protobuf/empty.upb.c new file mode 100644 index 00000000000..51ac7ed26c3 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/empty.upb.c @@ -0,0 +1,22 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/empty.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "google/protobuf/empty.upb.h" + +#include "upb/port_def.inc" + +const upb_msglayout google_protobuf_Empty_msginit = { + NULL, + NULL, + UPB_SIZE(0, 0), 0, false, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/google/protobuf/empty.upb.h b/src/core/ext/upb-generated/google/protobuf/empty.upb.h new file mode 100644 index 00000000000..43b2edd8cc0 --- /dev/null +++ b/src/core/ext/upb-generated/google/protobuf/empty.upb.h @@ -0,0 +1,52 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * google/protobuf/empty.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef GOOGLE_PROTOBUF_EMPTY_PROTO_UPB_H_ +#define GOOGLE_PROTOBUF_EMPTY_PROTO_UPB_H_ + +#include "upb/generated_util.h" + +#include "upb/msg.h" + +#include "upb/decode.h" +#include "upb/encode.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +struct google_protobuf_Empty; +typedef struct google_protobuf_Empty google_protobuf_Empty; +extern const upb_msglayout google_protobuf_Empty_msginit; + +/* Enums */ + + +/* google.protobuf.Empty */ + +UPB_INLINE google_protobuf_Empty *google_protobuf_Empty_new(upb_arena *arena) { + return (google_protobuf_Empty *)upb_msg_new(&google_protobuf_Empty_msginit, arena); +} +UPB_INLINE google_protobuf_Empty *google_protobuf_Empty_parsenew(upb_strview buf, upb_arena *arena) { + google_protobuf_Empty *ret = google_protobuf_Empty_new(arena); + return (ret && upb_decode(buf, ret, &google_protobuf_Empty_msginit)) ? ret : NULL; +} +UPB_INLINE char *google_protobuf_Empty_serialize(const google_protobuf_Empty *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &google_protobuf_Empty_msginit, arena, len); +} + + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* GOOGLE_PROTOBUF_EMPTY_PROTO_UPB_H_ */ diff --git a/tools/codegen/core/gen_upb_api.sh b/tools/codegen/core/gen_upb_api.sh index 5a89147c311..2ca36b70661 100755 --- a/tools/codegen/core/gen_upb_api.sh +++ b/tools/codegen/core/gen_upb_api.sh @@ -28,11 +28,12 @@ proto_files=( \ "google/api/annotations.proto" \ "google/api/http.proto" \ "google/protobuf/any.proto" \ - "google/protobuf/struct.proto" \ - "google/protobuf/wrappers.proto" \ "google/protobuf/descriptor.proto" \ "google/protobuf/duration.proto" \ + "google/protobuf/empty.proto" \ + "google/protobuf/struct.proto" \ "google/protobuf/timestamp.proto" \ + "google/protobuf/wrappers.proto" \ "google/rpc/status.proto" \ "gogoproto/gogo.proto" \ "validate/validate.proto" \ @@ -40,8 +41,15 @@ proto_files=( \ "envoy/type/range.proto" \ "envoy/api/v2/core/address.proto" \ "envoy/api/v2/core/base.proto" \ + "envoy/api/v2/core/config_source.proto" \ + "envoy/api/v2/core/grpc_service.proto" \ "envoy/api/v2/core/health_check.proto" \ + "envoy/api/v2/core/protocol.proto" \ + "envoy/api/v2/auth/cert.proto" \ + "envoy/api/v2/cluster/circuit_breaker.proto" \ + "envoy/api/v2/cluster/outlier_detection.proto" \ "envoy/api/v2/discovery.proto" \ + "envoy/api/v2/cds.proto" \ "envoy/api/v2/eds.proto" \ "envoy/api/v2/endpoint/endpoint.proto" \ "envoy/service/discovery/v2/ads.proto") From 688ad6373b8e17e91bd951f69d676a68f3ee8acc Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Mon, 25 Mar 2019 10:44:31 +1300 Subject: [PATCH 781/814] Fix Grpc.Core.Api assembly version --- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 4 ++++ src/csharp/{Grpc.Core => Grpc.Core.Api}/VersionInfo.cs | 0 src/csharp/Grpc.Core/ForwardedTypes.cs | 1 + 3 files changed, 5 insertions(+) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/VersionInfo.cs (100%) diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index 556f65f4b32..e0a999fe50e 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -22,6 +22,10 @@ + + + + diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core.Api/VersionInfo.cs similarity index 100% rename from src/csharp/Grpc.Core/VersionInfo.cs rename to src/csharp/Grpc.Core.Api/VersionInfo.cs diff --git a/src/csharp/Grpc.Core/ForwardedTypes.cs b/src/csharp/Grpc.Core/ForwardedTypes.cs index dd7f292a248..39221925392 100644 --- a/src/csharp/Grpc.Core/ForwardedTypes.cs +++ b/src/csharp/Grpc.Core/ForwardedTypes.cs @@ -51,5 +51,6 @@ using Grpc.Core.Utils; [assembly:TypeForwardedToAttribute(typeof(ServiceBinderBase))] [assembly:TypeForwardedToAttribute(typeof(Status))] [assembly:TypeForwardedToAttribute(typeof(StatusCode))] +[assembly:TypeForwardedToAttribute(typeof(VersionInfo))] [assembly:TypeForwardedToAttribute(typeof(WriteOptions))] [assembly:TypeForwardedToAttribute(typeof(WriteFlags))] From 297dd0cb6275241b5be892d5fc95d61df0924f38 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Mon, 25 Mar 2019 18:26:14 +1300 Subject: [PATCH 782/814] PR feedback --- src/csharp/Grpc.Auth/Grpc.Auth.csproj | 4 ++-- src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 4 ++-- src/csharp/{Grpc.Core => Grpc.Core.Api}/Version.cs | 0 .../{Grpc.Core => Grpc.Core.Api}/Version.csproj.include | 0 src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj | 4 ++-- src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj | 4 ++-- src/csharp/Grpc.Core/Grpc.Core.csproj | 6 +++++- .../Grpc.Examples.MathClient.csproj | 4 ++-- .../Grpc.Examples.MathServer.csproj | 4 ++-- src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj | 4 ++-- src/csharp/Grpc.Examples/Grpc.Examples.csproj | 4 ++-- .../Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj | 4 ++-- src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj | 4 ++-- .../Grpc.IntegrationTesting.Client.csproj | 4 ++-- .../Grpc.IntegrationTesting.QpsWorker.csproj | 4 ++-- .../Grpc.IntegrationTesting.Server.csproj | 4 ++-- .../Grpc.IntegrationTesting.StressClient.csproj | 4 ++-- .../Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj | 4 ++-- src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj | 4 ++-- .../Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj | 4 ++-- src/csharp/Grpc.Reflection/Grpc.Reflection.csproj | 6 +++--- src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj | 2 +- src/csharp/Grpc.Tools/Grpc.Tools.csproj | 2 +- .../{Grpc.Core => Grpc.Core.Api}/VersionInfo.cs.template | 0 24 files changed, 44 insertions(+), 40 deletions(-) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Version.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Version.csproj.include (100%) mode change 100755 => 100644 rename templates/src/csharp/{Grpc.Core => Grpc.Core.Api}/VersionInfo.cs.template (100%) diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj index e8974f7221f..dbdb2a78bb5 100755 --- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj +++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj @@ -1,6 +1,6 @@  - + @@ -24,7 +24,7 @@ - + diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index e0a999fe50e..2d9746e88b9 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -1,6 +1,6 @@  - + @@ -23,7 +23,7 @@ - + diff --git a/src/csharp/Grpc.Core/Version.cs b/src/csharp/Grpc.Core.Api/Version.cs similarity index 100% rename from src/csharp/Grpc.Core/Version.cs rename to src/csharp/Grpc.Core.Api/Version.cs diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core.Api/Version.csproj.include old mode 100755 new mode 100644 similarity index 100% rename from src/csharp/Grpc.Core/Version.csproj.include rename to src/csharp/Grpc.Core.Api/Version.csproj.include diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj index 3727639f44a..0d38517563c 100755 --- a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj +++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj @@ -1,6 +1,6 @@  - + @@ -23,7 +23,7 @@ - + diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index 8de9b675a7d..656f0c1dbb0 100755 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -1,6 +1,6 @@  - + @@ -27,7 +27,7 @@ - + diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 5a73ac3deb8..9d79358a2c5 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -1,6 +1,6 @@  - + @@ -20,6 +20,10 @@ true + + + + diff --git a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj index 1011ebce0f0..c34af241a15 100755 --- a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj +++ b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj @@ -1,6 +1,6 @@  - + @@ -19,7 +19,7 @@ - + diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj index 1011ebce0f0..c34af241a15 100755 --- a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj +++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj @@ -1,6 +1,6 @@  - + @@ -19,7 +19,7 @@ - + diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index 26ae2776446..9b93ffb30f3 100755 --- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj +++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj @@ -1,6 +1,6 @@  - + @@ -26,7 +26,7 @@ - + diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj index 65ca87ed121..03bc53f13c5 100755 --- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj +++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj @@ -1,6 +1,6 @@  - + @@ -9,7 +9,7 @@ - + diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj index 2c759124689..a2c2ce40364 100755 --- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj +++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj @@ -1,6 +1,6 @@  - + @@ -24,7 +24,7 @@ - + diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index 338c9c2c0d8..9130b1cc99e 100755 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -1,6 +1,6 @@  - + @@ -23,7 +23,7 @@ - + diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj index 30991cd0b57..ee23f4dcaf9 100755 --- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj @@ -1,6 +1,6 @@  - + @@ -19,7 +19,7 @@ - + diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj index 8c682beb396..2e6b1a5b9a0 100755 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj @@ -1,6 +1,6 @@  - + @@ -20,7 +20,7 @@ - + diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj index 30991cd0b57..ee23f4dcaf9 100755 --- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj @@ -1,6 +1,6 @@  - + @@ -19,7 +19,7 @@ - + diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj index 30991cd0b57..ee23f4dcaf9 100755 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj @@ -1,6 +1,6 @@  - + @@ -19,7 +19,7 @@ - + diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index fd90e19c843..3db50b9ed71 100755 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -1,6 +1,6 @@  - + @@ -27,7 +27,7 @@ - + diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index 71f970f09cd..bf51032043c 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -1,6 +1,6 @@  - + @@ -23,7 +23,7 @@ - + diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj index 6436058d4e2..2f31a0439c6 100755 --- a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj +++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj @@ -1,6 +1,6 @@  - + @@ -24,7 +24,7 @@ - + diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj index f080e2085dd..8149880a261 100755 --- a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj +++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj @@ -1,6 +1,6 @@ - + - + @@ -23,7 +23,7 @@ - + diff --git a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj index 402d860e382..36a422f4f07 100644 --- a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj +++ b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj @@ -1,6 +1,6 @@ - + net45;netcoreapp2.1 diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index e1e3633220e..33bfc25e65d 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -1,6 +1,6 @@ - + Protobuf.MSBuild diff --git a/templates/src/csharp/Grpc.Core/VersionInfo.cs.template b/templates/src/csharp/Grpc.Core.Api/VersionInfo.cs.template similarity index 100% rename from templates/src/csharp/Grpc.Core/VersionInfo.cs.template rename to templates/src/csharp/Grpc.Core.Api/VersionInfo.cs.template From 8ef8d912a74e16f17d458c85a33fa54b4c07a4bb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 25 Mar 2019 11:51:14 -0700 Subject: [PATCH 783/814] Use GRPC_CLOSURE_SCHED instead of GRPC_CLOSURE_RUN in complete_closure_step --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 4216a080bc9..404539c9e13 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1268,7 +1268,9 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t, if (closure->next_data.scratch < CLOSURE_BARRIER_FIRST_REF_BIT) { if ((t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE) || !(closure->next_data.scratch & CLOSURE_BARRIER_MAY_COVER_WRITE)) { - GRPC_CLOSURE_RUN(closure, closure->error_data.error); + // Using GRPC_CLOSURE_SCHED instead of GRPC_CLOSURE_RUN to avoid running + // closures earlier than when it is safe to do so. + GRPC_CLOSURE_SCHED(closure, closure->error_data.error); } else { grpc_closure_list_append(&t->run_after_write, closure, closure->error_data.error); From 5d0a5714264cf21063760c9bc8d3f2953dba8673 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 25 Mar 2019 12:41:20 -0700 Subject: [PATCH 784/814] introduce build/dependencies.props --- .../Version.csproj.include => Grpc.Core/build/dependencies.props} | 0 .../dependencies.props.template} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/csharp/{Grpc.Core.Api/Version.csproj.include => Grpc.Core/build/dependencies.props} (100%) rename templates/src/csharp/Grpc.Core/{Version.csproj.include.template => build/dependencies.props.template} (100%) diff --git a/src/csharp/Grpc.Core.Api/Version.csproj.include b/src/csharp/Grpc.Core/build/dependencies.props similarity index 100% rename from src/csharp/Grpc.Core.Api/Version.csproj.include rename to src/csharp/Grpc.Core/build/dependencies.props diff --git a/templates/src/csharp/Grpc.Core/Version.csproj.include.template b/templates/src/csharp/Grpc.Core/build/dependencies.props.template similarity index 100% rename from templates/src/csharp/Grpc.Core/Version.csproj.include.template rename to templates/src/csharp/Grpc.Core/build/dependencies.props.template From f30da05dff1392d8db231619798597d1adfaf359 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 25 Mar 2019 12:41:45 -0700 Subject: [PATCH 785/814] introduce Directory.Build.props --- src/csharp/Directory.Build.props | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/csharp/Directory.Build.props diff --git a/src/csharp/Directory.Build.props b/src/csharp/Directory.Build.props new file mode 100644 index 00000000000..7127cc4d509 --- /dev/null +++ b/src/csharp/Directory.Build.props @@ -0,0 +1,3 @@ + + + \ No newline at end of file From 6fba3c02216bf5d205da6338cffee088d722a900 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 25 Mar 2019 12:47:29 -0700 Subject: [PATCH 786/814] dependency versions are imported through Directory props --- src/csharp/Grpc.Auth/Grpc.Auth.csproj | 1 - src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj | 1 - src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj | 1 - src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj | 1 - src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj | 1 - src/csharp/Grpc.Core/Grpc.Core.csproj | 1 - .../Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj | 1 - .../Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj | 1 - src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj | 1 - src/csharp/Grpc.Examples/Grpc.Examples.csproj | 1 - src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj | 1 - src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj | 1 - .../Grpc.IntegrationTesting.Client.csproj | 1 - .../Grpc.IntegrationTesting.QpsWorker.csproj | 1 - .../Grpc.IntegrationTesting.Server.csproj | 1 - .../Grpc.IntegrationTesting.StressClient.csproj | 1 - .../Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj | 1 - src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj | 1 - src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj | 1 - src/csharp/Grpc.Reflection/Grpc.Reflection.csproj | 1 - src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj | 2 -- src/csharp/Grpc.Tools/Grpc.Tools.csproj | 2 -- src/csharp/Grpc/Grpc.csproj | 1 - 23 files changed, 25 deletions(-) diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj index dbdb2a78bb5..298b721409e 100755 --- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj +++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj index 2d9746e88b9..1d8632a1df7 100755 --- a/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj +++ b/src/csharp/Grpc.Core.Api/Grpc.Core.Api.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj index 3cd5ba4fa6f..a8b13030ee6 100644 --- a/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj +++ b/src/csharp/Grpc.Core.NativeDebug/Grpc.Core.NativeDebug.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj index 0d38517563c..3cd36d45008 100755 --- a/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj +++ b/src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index 656f0c1dbb0..23e5d7f65ef 100755 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 9d79358a2c5..b7c191ea6a9 100755 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj index c34af241a15..03018239525 100755 --- a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj +++ b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj index c34af241a15..03018239525 100755 --- a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj +++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index 9b93ffb30f3..b3fbbfffcca 100755 --- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj +++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj index 03bc53f13c5..66ea71853bf 100755 --- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj +++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj index a2c2ce40364..223c9985ecd 100755 --- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj +++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index 9130b1cc99e..7e8a8a7de87 100755 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj index ee23f4dcaf9..a5baf96357d 100755 --- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj index 2e6b1a5b9a0..8f4833ea749 100755 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj index ee23f4dcaf9..a5baf96357d 100755 --- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj index ee23f4dcaf9..a5baf96357d 100755 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index 3db50b9ed71..9d719896fc1 100755 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index bf51032043c..e0fcdecd9ac 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj index 2f31a0439c6..ef9d2a1c570 100755 --- a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj +++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj @@ -1,6 +1,5 @@  - diff --git a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj index 8149880a261..cf08e58ed65 100755 --- a/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj +++ b/src/csharp/Grpc.Reflection/Grpc.Reflection.csproj @@ -1,6 +1,5 @@ - diff --git a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj index 36a422f4f07..7ad2ce21694 100644 --- a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj +++ b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj @@ -1,7 +1,5 @@ - - net45;netcoreapp2.1 Exe diff --git a/src/csharp/Grpc.Tools/Grpc.Tools.csproj b/src/csharp/Grpc.Tools/Grpc.Tools.csproj index 33bfc25e65d..d09d97d1397 100644 --- a/src/csharp/Grpc.Tools/Grpc.Tools.csproj +++ b/src/csharp/Grpc.Tools/Grpc.Tools.csproj @@ -1,7 +1,5 @@ - - Protobuf.MSBuild $(GrpcCsharpVersion) diff --git a/src/csharp/Grpc/Grpc.csproj b/src/csharp/Grpc/Grpc.csproj index 5174b97086e..b71cd93ff9a 100644 --- a/src/csharp/Grpc/Grpc.csproj +++ b/src/csharp/Grpc/Grpc.csproj @@ -1,6 +1,5 @@  - From 4eedf568a856cdc818542e988629994f56187fce Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 25 Mar 2019 12:48:34 -0700 Subject: [PATCH 787/814] makes generation of dev nuget versions work --- src/csharp/expand_dev_version.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/expand_dev_version.sh b/src/csharp/expand_dev_version.sh index 555f22a619c..714762afac1 100644 --- a/src/csharp/expand_dev_version.sh +++ b/src/csharp/expand_dev_version.sh @@ -22,4 +22,4 @@ cd "$(dirname "$0")" DEV_DATETIME_SUFFIX=$(date -u "+%Y%m%d%H%M") # expand the -dev suffix to contain current timestamp -sed -ibak "s/-dev<\/GrpcCsharpVersion>/-dev${DEV_DATETIME_SUFFIX}<\/GrpcCsharpVersion>/" Grpc.Core/Version.csproj.include +sed -ibak "s/-dev<\/GrpcCsharpVersion>/-dev${DEV_DATETIME_SUFFIX}<\/GrpcCsharpVersion>/" build/dependencies.props From c9b7ca8e242251888935c284d94b05cf8a789de9 Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Mon, 25 Mar 2019 13:44:45 -0700 Subject: [PATCH 788/814] Adding missing language :P --- src/core/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/README.md b/src/core/README.md index 130d2652b39..5dea45a6925 100644 --- a/src/core/README.md +++ b/src/core/README.md @@ -1,4 +1,4 @@ # Overview -This directory contains source code for C library (a.k.a the *gRPC C core*) that provides all gRPC's core functionality through a low level API. Libraries in other languages in this repository (C++, Ruby, +This directory contains source code for C library (a.k.a the *gRPC C core*) that provides all gRPC's core functionality through a low level API. Libraries in other languages in this repository (C++, C#, Ruby, Python, PHP, NodeJS, Objective-C) are layered on top of this library. From 621840900fefd93ab9bab5678db4c798ba1cec32 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 25 Mar 2019 14:24:11 -0700 Subject: [PATCH 789/814] Fully log test scenario --- test/cpp/end2end/client_callback_end2end_test.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 893d009392d..93a5b142576 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -79,7 +79,10 @@ class TestScenario { static std::ostream& operator<<(std::ostream& out, const TestScenario& scenario) { return out << "TestScenario{callback_server=" - << (scenario.callback_server ? "true" : "false") << "}"; + << (scenario.callback_server ? "true" : "false") << ",protocol=" + << (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP") + << ",intercept=" << (scenario.use_interceptors ? "true" : "false") + << ",creds=" << scenario.credentials_type << "}"; } void TestScenario::Log() const { From a48d3efc9eba3d0c6cc3b08b83a4bfdf478da240 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 25 Mar 2019 14:39:14 -0700 Subject: [PATCH 790/814] move dependencies.props to the right directory --- src/csharp/{Grpc.Core => }/build/dependencies.props | 0 .../src/csharp/{Grpc.Core => }/build/dependencies.props.template | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/csharp/{Grpc.Core => }/build/dependencies.props (100%) rename templates/src/csharp/{Grpc.Core => }/build/dependencies.props.template (100%) diff --git a/src/csharp/Grpc.Core/build/dependencies.props b/src/csharp/build/dependencies.props similarity index 100% rename from src/csharp/Grpc.Core/build/dependencies.props rename to src/csharp/build/dependencies.props diff --git a/templates/src/csharp/Grpc.Core/build/dependencies.props.template b/templates/src/csharp/build/dependencies.props.template similarity index 100% rename from templates/src/csharp/Grpc.Core/build/dependencies.props.template rename to templates/src/csharp/build/dependencies.props.template From ecb3dec651b997ed8dcfbecff9856283ceb05920 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Mon, 25 Mar 2019 14:54:29 -0700 Subject: [PATCH 791/814] Enable go compute engine channel creds interop test --- tools/run_tests/run_interop_tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 6a025505910..567c628d8e0 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -335,7 +335,7 @@ class GoLanguage: return {} def unimplemented_test_cases(self): - return _SKIP_COMPRESSION + _SKIP_COMPUTE_ENGINE_CHANNEL_CREDS + return _SKIP_COMPRESSION def unimplemented_test_cases_server(self): return _SKIP_COMPRESSION @@ -887,7 +887,7 @@ def cloud_to_prod_jobspec(language, '--custom_credentials_type=google_default_credentials' ] elif transport_security == 'compute_engine_channel_creds' and str( - language) in ['java', 'javaokhttp']: + language) in ['go', 'java', 'javaokhttp']: transport_security_options = [ '--custom_credentials_type=compute_engine_channel_creds' ] @@ -1465,7 +1465,7 @@ try: transport_security= 'google_default_credentials') jobs.append(google_default_creds_test_job) - if str(language) in ['java', 'javaokhttp']: + if str(language) in ['go', 'java', 'javaokhttp']: compute_engine_channel_creds_test_job = cloud_to_prod_jobspec( language, test_case, From 55e280b7a59e076112f198871cae92475852a25f Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 25 Mar 2019 22:49:20 +0100 Subject: [PATCH 792/814] Breakout of #18445 - part 1 --- src/core/lib/transport/transport.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 5ce568834e9..9d4b5615e57 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -111,10 +111,11 @@ void grpc_transport_move_stats(grpc_transport_stream_stats* from, // currently handling the batch). Once a filter or transport passes control // of the batch to the next handler, it cannot depend on the contents of // this struct anymore, because the next handler may reuse it. -typedef struct { - void* extra_arg; +struct grpc_handler_private_op_data { + void* extra_arg = nullptr; grpc_closure closure; -} grpc_handler_private_op_data; + grpc_handler_private_op_data() { memset(&closure, 0, sizeof(closure)); } +}; typedef struct grpc_transport_stream_op_batch_payload grpc_transport_stream_op_batch_payload; From c40f959de5a619c27be8779734c2d489f3a879c0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 25 Mar 2019 15:46:29 -0700 Subject: [PATCH 793/814] make AuthContext constructor public --- src/csharp/Grpc.Core.Api/AuthContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core.Api/AuthContext.cs b/src/csharp/Grpc.Core.Api/AuthContext.cs index 90887887f2d..fbec5001f6d 100644 --- a/src/csharp/Grpc.Core.Api/AuthContext.cs +++ b/src/csharp/Grpc.Core.Api/AuthContext.cs @@ -39,7 +39,7 @@ namespace Grpc.Core /// /// Peer identity property name. /// Multimap of auth properties by name. - internal AuthContext(string peerIdentityPropertyName, Dictionary> properties) + public AuthContext(string peerIdentityPropertyName, Dictionary> properties) { this.peerIdentityPropertyName = peerIdentityPropertyName; this.properties = GrpcPreconditions.CheckNotNull(properties); From 872d2787a0628f0c88c5726433c8bbaca0e5813c Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 25 Mar 2019 16:19:08 -0700 Subject: [PATCH 794/814] Avoid using grpc_core::Executor when the background poller is available. Instead, run closures in the background poller. This will generally avoid the thread hop in the gRPC runtime. --- src/core/lib/iomgr/ev_epoll1_linux.cc | 6 ++++++ src/core/lib/iomgr/ev_epollex_linux.cc | 6 ++++++ src/core/lib/iomgr/ev_poll_posix.cc | 6 ++++++ src/core/lib/iomgr/ev_posix.cc | 5 +++++ src/core/lib/iomgr/ev_posix.h | 8 ++++++++ src/core/lib/iomgr/executor.cc | 13 +++++++++++++ src/core/lib/iomgr/executor.h | 3 ++- src/core/lib/iomgr/iomgr.cc | 5 +++++ src/core/lib/iomgr/iomgr.h | 7 +++++++ src/core/lib/iomgr/iomgr_custom.cc | 7 ++++++- src/core/lib/iomgr/iomgr_internal.cc | 6 ++++++ src/core/lib/iomgr/iomgr_internal.h | 10 +++++++++- src/core/lib/iomgr/iomgr_posix.cc | 8 +++++++- src/core/lib/iomgr/iomgr_posix_cfstream.cc | 8 +++++++- src/core/lib/iomgr/iomgr_windows.cc | 8 +++++++- test/cpp/microbenchmarks/bm_cq_multiple_threads.cc | 2 ++ 16 files changed, 102 insertions(+), 6 deletions(-) diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index 9eb4c089d86..b6f804cdfca 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -1246,6 +1246,11 @@ static bool is_any_background_poller_thread(void) { return false; } static void shutdown_background_closure(void) {} +static bool add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return false; +} + static void shutdown_engine(void) { fd_global_shutdown(); pollset_global_shutdown(); @@ -1292,6 +1297,7 @@ static const grpc_event_engine_vtable vtable = { is_any_background_poller_thread, shutdown_background_closure, shutdown_engine, + add_closure_to_background_poller, }; /* Called by the child process's post-fork handler to close open fds, including diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 27656063ba5..01be46c9f68 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -1578,6 +1578,11 @@ static bool is_any_background_poller_thread(void) { return false; } static void shutdown_background_closure(void) {} +static bool add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return false; +} + static void shutdown_engine(void) { fd_global_shutdown(); pollset_global_shutdown(); @@ -1619,6 +1624,7 @@ static const grpc_event_engine_vtable vtable = { is_any_background_poller_thread, shutdown_background_closure, shutdown_engine, + add_closure_to_background_poller, }; const grpc_event_engine_vtable* grpc_init_epollex_linux( diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index 29111dd44ed..0c95cb75c6d 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -1320,6 +1320,11 @@ static bool is_any_background_poller_thread(void) { return false; } static void shutdown_background_closure(void) {} +static bool add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return false; +} + static void shutdown_engine(void) { pollset_global_shutdown(); if (track_fds_for_fork) { @@ -1364,6 +1369,7 @@ static const grpc_event_engine_vtable vtable = { is_any_background_poller_thread, shutdown_background_closure, shutdown_engine, + add_closure_to_background_poller, }; /* Called by the child process's post-fork handler to close open fds, including diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index d7aeb81c69e..898686b06c3 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -402,6 +402,11 @@ bool grpc_is_any_background_poller_thread(void) { return g_event_engine->is_any_background_poller_thread(); } +bool grpc_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return g_event_engine->add_closure_to_background_poller(closure, error); +} + void grpc_shutdown_background_closure(void) { g_event_engine->shutdown_background_closure(); } diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index 94ac9fdba6f..699173fe255 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -83,6 +83,8 @@ typedef struct grpc_event_engine_vtable { bool (*is_any_background_poller_thread)(void); void (*shutdown_background_closure)(void); void (*shutdown_engine)(void); + bool (*add_closure_to_background_poller)(grpc_closure* closure, + grpc_error* error); } grpc_event_engine_vtable; /* register a new event engine factory */ @@ -185,6 +187,12 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd); /* Returns true if the caller is a worker thread for any background poller. */ bool grpc_is_any_background_poller_thread(); +/* Returns true if the closure is registered into the background poller. Note + * that the closure may or may not run yet when this function returns, and the + * closure should not be blocking or long-running. */ +bool grpc_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error); + /* Shut down all the closures registered in the background poller. */ void grpc_shutdown_background_closure(); diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index 2ad8972fc79..47836acacc0 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -32,6 +32,7 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/iomgr.h" #define MAX_DEPTH 2 @@ -206,6 +207,14 @@ void Executor::SetThreading(bool threading) { gpr_free(thd_state_); gpr_tls_destroy(&g_this_thread_state); + + // grpc_iomgr_shutdown_background_closure() will close all the registered + // fds in the background poller, and wait for all pending closures to + // finish. Thus, never call Executor::SetThreading(false) in the middle of + // an application. + // TODO(guantaol): create another method to finish all the pending closures + // registered in the background poller by grpc_core::Executor. + grpc_iomgr_shutdown_background_closure(); } EXECUTOR_TRACE("(%s) SetThreading(%d) done", name_, threading); @@ -278,6 +287,10 @@ void Executor::Enqueue(grpc_closure* closure, grpc_error* error, return; } + if (grpc_iomgr_add_closure_to_background_poller(closure, error)) { + return; + } + ThreadState* ts = (ThreadState*)gpr_tls_get(&g_this_thread_state); if (ts == nullptr) { ts = &thd_state_[GPR_HASH_POINTER(grpc_core::ExecCtx::Get(), diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h index 9e472279b7b..a9c609bd7d5 100644 --- a/src/core/lib/iomgr/executor.h +++ b/src/core/lib/iomgr/executor.h @@ -61,7 +61,8 @@ class Executor { /** Is the executor multi-threaded? */ bool IsThreaded() const; - /* Enable/disable threading - must be called after Init and Shutdown() */ + /* Enable/disable threading - must be called after Init and Shutdown(). Never + * call SetThreading(false) in the middle of an application */ void SetThreading(bool threading); /** Shutdown the executor, running all pending work as part of the call */ diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index 33153d9cc3b..0fbfcfce04f 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -162,6 +162,11 @@ bool grpc_iomgr_is_any_background_poller_thread() { return grpc_iomgr_platform_is_any_background_poller_thread(); } +bool grpc_iomgr_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return grpc_iomgr_platform_add_closure_to_background_poller(closure, error); +} + void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name) { obj->name = gpr_strdup(name); gpr_mu_lock(&g_mu); diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h index 74775de8146..e02f15e551c 100644 --- a/src/core/lib/iomgr/iomgr.h +++ b/src/core/lib/iomgr/iomgr.h @@ -21,6 +21,7 @@ #include +#include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/port.h" #include @@ -47,6 +48,12 @@ bool grpc_iomgr_run_in_background(); /** Returns true if the caller is a worker thread for any background poller. */ bool grpc_iomgr_is_any_background_poller_thread(); +/** Returns true if the closure is registered into the background poller. Note + * that the closure may or may not run yet when this function returns, and the + * closure should not be blocking or long-running. */ +bool grpc_iomgr_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error); + /* Exposed only for testing */ size_t grpc_iomgr_count_objects_for_testing(); diff --git a/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc index 3d07f1abe9a..381e00e07a7 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -44,11 +44,16 @@ static void iomgr_platform_shutdown_background_closure(void) {} static bool iomgr_platform_is_any_background_poller_thread(void) { return false; } +static bool iomgr_platform_add_closure_to_background_poller( + grpc_closure* closure, grpc_error* error) { + return false; +} static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, iomgr_platform_shutdown_background_closure, - iomgr_platform_is_any_background_poller_thread}; + iomgr_platform_is_any_background_poller_thread, + iomgr_platform_add_closure_to_background_poller}; void grpc_custom_iomgr_init(grpc_socket_vtable* socket, grpc_custom_resolver_vtable* resolver, diff --git a/src/core/lib/iomgr/iomgr_internal.cc b/src/core/lib/iomgr/iomgr_internal.cc index e68b1cf5812..896d9fce67c 100644 --- a/src/core/lib/iomgr/iomgr_internal.cc +++ b/src/core/lib/iomgr/iomgr_internal.cc @@ -49,3 +49,9 @@ void grpc_iomgr_platform_shutdown_background_closure() { bool grpc_iomgr_platform_is_any_background_poller_thread() { return iomgr_platform_vtable->is_any_background_poller_thread(); } + +bool grpc_iomgr_platform_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error) { + return iomgr_platform_vtable->add_closure_to_background_poller(closure, + error); +} diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h index 2250ad9a18c..17607f98f11 100644 --- a/src/core/lib/iomgr/iomgr_internal.h +++ b/src/core/lib/iomgr/iomgr_internal.h @@ -37,6 +37,8 @@ typedef struct grpc_iomgr_platform_vtable { void (*shutdown)(void); void (*shutdown_background_closure)(void); bool (*is_any_background_poller_thread)(void); + bool (*add_closure_to_background_poller)(grpc_closure* closure, + grpc_error* error); } grpc_iomgr_platform_vtable; void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name); @@ -57,9 +59,15 @@ void grpc_iomgr_platform_shutdown(void); /** shut down all the closures registered in the background poller */ void grpc_iomgr_platform_shutdown_background_closure(void); -/** return true is the caller is a worker thread for any background poller */ +/** return true if the caller is a worker thread for any background poller */ bool grpc_iomgr_platform_is_any_background_poller_thread(void); +/** Return true if the closure is registered into the background poller. Note + * that the closure may or may not run yet when this function returns, and the + * closure should not be blocking or long-running. */ +bool grpc_iomgr_platform_add_closure_to_background_poller(grpc_closure* closure, + grpc_error* error); + bool grpc_iomgr_abort_on_leaks(void); #endif /* GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H */ diff --git a/src/core/lib/iomgr/iomgr_posix.cc b/src/core/lib/iomgr/iomgr_posix.cc index 690e81f3b1d..a4010b8cf9d 100644 --- a/src/core/lib/iomgr/iomgr_posix.cc +++ b/src/core/lib/iomgr/iomgr_posix.cc @@ -59,10 +59,16 @@ static bool iomgr_platform_is_any_background_poller_thread(void) { return grpc_is_any_background_poller_thread(); } +static bool iomgr_platform_add_closure_to_background_poller( + grpc_closure* closure, grpc_error* error) { + return grpc_add_closure_to_background_poller(closure, error); +} + static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, iomgr_platform_shutdown_background_closure, - iomgr_platform_is_any_background_poller_thread}; + iomgr_platform_is_any_background_poller_thread, + iomgr_platform_add_closure_to_background_poller}; void grpc_set_default_iomgr_platform() { grpc_set_tcp_client_impl(&grpc_posix_tcp_client_vtable); diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc index 462ac41fcde..61b8bd100eb 100644 --- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -62,10 +62,16 @@ static bool iomgr_platform_is_any_background_poller_thread(void) { return grpc_is_any_background_poller_thread(); } +static bool iomgr_platform_add_closure_to_background_poller( + grpc_closure* closure, grpc_error* error) { + return grpc_add_closure_to_background_poller(closure, error); +} + static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, iomgr_platform_shutdown_background_closure, - iomgr_platform_is_any_background_poller_thread}; + iomgr_platform_is_any_background_poller_thread, + iomgr_platform_add_closure_to_background_poller}; void grpc_set_default_iomgr_platform() { char* enable_cfstream = getenv(grpc_cfstream_env_var); diff --git a/src/core/lib/iomgr/iomgr_windows.cc b/src/core/lib/iomgr/iomgr_windows.cc index e517a6caee4..0e1a9ba5b7a 100644 --- a/src/core/lib/iomgr/iomgr_windows.cc +++ b/src/core/lib/iomgr/iomgr_windows.cc @@ -77,10 +77,16 @@ static bool iomgr_platform_is_any_background_poller_thread(void) { return false; } +static bool iomgr_platform_add_closure_to_background_poller( + grpc_closure* closure, grpc_error* error) { + return false; +} + static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, iomgr_platform_shutdown_background_closure, - iomgr_platform_is_any_background_poller_thread}; + iomgr_platform_is_any_background_poller_thread, + iomgr_platform_add_closure_to_background_poller}; void grpc_set_default_iomgr_platform() { grpc_set_tcp_client_impl(&grpc_windows_tcp_client_vtable); diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc index 7aa197b5979..54455350c24 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -95,6 +95,8 @@ static const grpc_event_engine_vtable* init_engine_vtable(bool) { g_vtable.pollset_work = pollset_work; g_vtable.pollset_kick = pollset_kick; g_vtable.is_any_background_poller_thread = [] { return false; }; + g_vtable.add_closure_to_background_poller = + [](grpc_closure* closure, grpc_error* error) { return false; }; g_vtable.shutdown_background_closure = [] {}; g_vtable.shutdown_engine = [] {}; From 53065db36686887d6655cd4c83b5a88c3b226a48 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 25 Mar 2019 16:23:19 -0700 Subject: [PATCH 795/814] Clang formatting --- src/core/lib/iomgr/iomgr_custom.cc | 4 +++- src/core/lib/iomgr/iomgr_posix.cc | 4 +++- src/core/lib/iomgr/iomgr_posix_cfstream.cc | 4 +++- src/core/lib/iomgr/iomgr_windows.cc | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc index 381e00e07a7..56363c35fd6 100644 --- a/src/core/lib/iomgr/iomgr_custom.cc +++ b/src/core/lib/iomgr/iomgr_custom.cc @@ -50,7 +50,9 @@ static bool iomgr_platform_add_closure_to_background_poller( } static grpc_iomgr_platform_vtable vtable = { - iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, + iomgr_platform_init, + iomgr_platform_flush, + iomgr_platform_shutdown, iomgr_platform_shutdown_background_closure, iomgr_platform_is_any_background_poller_thread, iomgr_platform_add_closure_to_background_poller}; diff --git a/src/core/lib/iomgr/iomgr_posix.cc b/src/core/lib/iomgr/iomgr_posix.cc index a4010b8cf9d..de22d20a639 100644 --- a/src/core/lib/iomgr/iomgr_posix.cc +++ b/src/core/lib/iomgr/iomgr_posix.cc @@ -65,7 +65,9 @@ static bool iomgr_platform_add_closure_to_background_poller( } static grpc_iomgr_platform_vtable vtable = { - iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, + iomgr_platform_init, + iomgr_platform_flush, + iomgr_platform_shutdown, iomgr_platform_shutdown_background_closure, iomgr_platform_is_any_background_poller_thread, iomgr_platform_add_closure_to_background_poller}; diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc index 61b8bd100eb..cf4d05318ea 100644 --- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -68,7 +68,9 @@ static bool iomgr_platform_add_closure_to_background_poller( } static grpc_iomgr_platform_vtable vtable = { - iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, + iomgr_platform_init, + iomgr_platform_flush, + iomgr_platform_shutdown, iomgr_platform_shutdown_background_closure, iomgr_platform_is_any_background_poller_thread, iomgr_platform_add_closure_to_background_poller}; diff --git a/src/core/lib/iomgr/iomgr_windows.cc b/src/core/lib/iomgr/iomgr_windows.cc index 0e1a9ba5b7a..13b5f87bd18 100644 --- a/src/core/lib/iomgr/iomgr_windows.cc +++ b/src/core/lib/iomgr/iomgr_windows.cc @@ -83,7 +83,9 @@ static bool iomgr_platform_add_closure_to_background_poller( } static grpc_iomgr_platform_vtable vtable = { - iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown, + iomgr_platform_init, + iomgr_platform_flush, + iomgr_platform_shutdown, iomgr_platform_shutdown_background_closure, iomgr_platform_is_any_background_poller_thread, iomgr_platform_add_closure_to_background_poller}; From e4bb7cb8bbd2d306bb8b354a0f98c6ac1efdfe15 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Mon, 25 Mar 2019 19:57:17 -0700 Subject: [PATCH 796/814] Revert "Moving ::grpc::ServerBuilder to ::grpc_impl::ServerBuilder" --- BUILD | 1 - CMakeLists.txt | 3 - Makefile | 3 - build.yaml | 1 - gRPC-C++.podspec | 1 - .../grpcpp/impl/codegen/completion_queue.h | 7 +- include/grpcpp/impl/server_builder_plugin.h | 7 +- include/grpcpp/server.h | 2 +- include/grpcpp/server_builder.h | 315 +++++++++++++++- include/grpcpp/server_builder_impl.h | 346 ------------------ src/cpp/server/server_builder.cc | 47 ++- tools/doxygen/Doxyfile.c++ | 1 - tools/doxygen/Doxyfile.c++.internal | 1 - .../generated/sources_and_headers.json | 2 - 14 files changed, 340 insertions(+), 397 deletions(-) delete mode 100644 include/grpcpp/server_builder_impl.h diff --git a/BUILD b/BUILD index 5bfc88dc186..12687c799ef 100644 --- a/BUILD +++ b/BUILD @@ -247,7 +247,6 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/security/server_credentials.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", - "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", "include/grpcpp/server_posix.h", "include/grpcpp/support/async_stream.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fe76cf11cd..d39c1941a74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3025,7 +3025,6 @@ foreach(_hdr include/grpcpp/security/server_credentials.h include/grpcpp/server.h include/grpcpp/server_builder.h - include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h include/grpcpp/server_posix.h include/grpcpp/support/async_stream.h @@ -3617,7 +3616,6 @@ foreach(_hdr include/grpcpp/security/server_credentials.h include/grpcpp/server.h include/grpcpp/server_builder.h - include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h include/grpcpp/server_posix.h include/grpcpp/support/async_stream.h @@ -4581,7 +4579,6 @@ foreach(_hdr include/grpcpp/security/server_credentials.h include/grpcpp/server.h include/grpcpp/server_builder.h - include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h include/grpcpp/server_posix.h include/grpcpp/support/async_stream.h diff --git a/Makefile b/Makefile index 055300cef00..85e621f87bb 100644 --- a/Makefile +++ b/Makefile @@ -5352,7 +5352,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/server_credentials.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ - include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ include/grpcpp/support/async_stream.h \ @@ -5952,7 +5951,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/server_credentials.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ - include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ include/grpcpp/support/async_stream.h \ @@ -6865,7 +6863,6 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/server_credentials.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ - include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ include/grpcpp/support/async_stream.h \ diff --git a/build.yaml b/build.yaml index 4251ed9ba01..34b271f58de 100644 --- a/build.yaml +++ b/build.yaml @@ -1370,7 +1370,6 @@ filegroups: - include/grpcpp/security/server_credentials.h - include/grpcpp/server.h - include/grpcpp/server_builder.h - - include/grpcpp/server_builder_impl.h - include/grpcpp/server_context.h - include/grpcpp/server_posix.h - include/grpcpp/support/async_stream.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 282a4a1e76c..5a850bc8438 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -111,7 +111,6 @@ Pod::Spec.new do |s| 'include/grpcpp/security/server_credentials.h', 'include/grpcpp/server.h', 'include/grpcpp/server_builder.h', - 'include/grpcpp/server_builder_impl.h', 'include/grpcpp/server_context.h', 'include/grpcpp/server_posix.h', 'include/grpcpp/support/async_stream.h', diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 73556ce9899..4812f0253d4 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -41,10 +41,6 @@ struct grpc_completion_queue; -namespace grpc_impl { - -class ServerBuilder; -} namespace grpc { template @@ -67,6 +63,7 @@ class ChannelInterface; class ClientContext; class CompletionQueue; class Server; +class ServerBuilder; class ServerContext; class ServerInterface; @@ -408,7 +405,7 @@ class ServerCompletionQueue : public CompletionQueue { polling_type_(polling_type) {} grpc_cq_polling_type polling_type_; - friend class ::grpc_impl::ServerBuilder; + friend class ServerBuilder; friend class Server; }; diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 2898f8cfae7..39450b42d56 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -23,12 +23,9 @@ #include -namespace grpc_impl { - -class ServerBuilder; -} namespace grpc { +class ServerBuilder; class ServerInitializer; class ChannelArguments; @@ -43,7 +40,7 @@ class ServerBuilderPlugin { /// UpdateServerBuilder will be called at an early stage in /// ServerBuilder::BuildAndStart(), right after the ServerBuilderOptions have /// done their updates. - virtual void UpdateServerBuilder(grpc_impl::ServerBuilder* builder) {} + virtual void UpdateServerBuilder(ServerBuilder* builder) {} /// InitServer will be called in ServerBuilder::BuildAndStart(), after the /// Server instance is created. diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index f8947a98cab..f5c99f22df2 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -198,7 +198,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { } friend class AsyncGenericService; - friend class ::grpc_impl::ServerBuilder; + friend class ServerBuilder; friend class ServerInitializer; class SyncRequest; diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 5b8fc72eeea..498e5b7bb31 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -1,6 +1,6 @@ /* * - * Copyright 2019 gRPC authors. + * Copyright 2015-2016 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,320 @@ #ifndef GRPCPP_SERVER_BUILDER_H #define GRPCPP_SERVER_BUILDER_H -#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +struct grpc_resource_quota; namespace grpc { -typedef ::grpc_impl::ServerBuilder ServerBuilder; +class AsyncGenericService; +class ResourceQuota; +class CompletionQueue; +class Server; +class ServerCompletionQueue; +class ServerCredentials; +class Service; + +namespace testing { +class ServerBuilderPluginTest; +} // namespace testing + +namespace experimental { +class CallbackGenericService; +} // namespace experimental + +/// A builder class for the creation and startup of \a grpc::Server instances. +class ServerBuilder { + public: + ServerBuilder(); + virtual ~ServerBuilder(); + + ////////////////////////////////////////////////////////////////////////////// + // Primary API's + + /// Return a running server which is ready for processing calls. + /// Before calling, one typically needs to ensure that: + /// 1. a service is registered - so that the server knows what to serve + /// (via RegisterService, or RegisterAsyncGenericService) + /// 2. a listening port has been added - so the server knows where to receive + /// traffic (via AddListeningPort) + /// 3. [for async api only] completion queues have been added via + /// AddCompletionQueue + virtual std::unique_ptr BuildAndStart(); + + /// Register a service. This call does not take ownership of the service. + /// The service must exist for the lifetime of the \a Server instance returned + /// by \a BuildAndStart(). + /// Matches requests with any :authority + ServerBuilder& RegisterService(Service* service); + + /// Enlists an endpoint \a addr (port with an optional IP address) to + /// bind the \a grpc::Server object to be created to. + /// + /// It can be invoked multiple times. + /// + /// \param addr_uri The address to try to bind to the server in URI form. If + /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, + /// please use IPv6 any, i.e., [::]:, which also accepts IPv4 + /// connections. Valid values include dns:///localhost:1234, / + /// 192.168.1.1:31416, dns:///[::1]:27182, etc.). + /// \param creds The credentials associated with the server. + /// \param selected_port[out] If not `nullptr`, gets populated with the port + /// number bound to the \a grpc::Server for the corresponding endpoint after + /// it is successfully bound by BuildAndStart(), 0 otherwise. AddListeningPort + /// does not modify this pointer. + ServerBuilder& AddListeningPort(const grpc::string& addr_uri, + std::shared_ptr creds, + int* selected_port = nullptr); + + /// Add a completion queue for handling asynchronous services. + /// + /// Best performance is typically obtained by using one thread per polling + /// completion queue. + /// + /// Caller is required to shutdown the server prior to shutting down the + /// returned completion queue. Caller is also required to drain the + /// completion queue after shutting it down. A typical usage scenario: + /// + /// // While building the server: + /// ServerBuilder builder; + /// ... + /// cq_ = builder.AddCompletionQueue(); + /// server_ = builder.BuildAndStart(); + /// + /// // While shutting down the server; + /// server_->Shutdown(); + /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()! + /// // Drain the cq_ that was created + /// void* ignored_tag; + /// bool ignored_ok; + /// while (cq_->Next(&ignored_tag, &ignored_ok)) { } + /// + /// \param is_frequently_polled This is an optional parameter to inform gRPC + /// library about whether this completion queue would be frequently polled + /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is + /// 'true' and is the recommended setting. Setting this to 'false' (i.e. + /// not polling the completion queue frequently) will have a significantly + /// negative performance impact and hence should not be used in production + /// use cases. + std::unique_ptr AddCompletionQueue( + bool is_frequently_polled = true); + + ////////////////////////////////////////////////////////////////////////////// + // Less commonly used RegisterService variants + + /// Register a service. This call does not take ownership of the service. + /// The service must exist for the lifetime of the \a Server instance returned + /// by \a BuildAndStart(). + /// Only matches requests with :authority \a host + ServerBuilder& RegisterService(const grpc::string& host, Service* service); + + /// Register a generic service. + /// Matches requests with any :authority + /// This is mostly useful for writing generic gRPC Proxies where the exact + /// serialization format is unknown + ServerBuilder& RegisterAsyncGenericService(AsyncGenericService* service); + + ////////////////////////////////////////////////////////////////////////////// + // Fine control knobs + + /// Set max receive message size in bytes. + /// The default is GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH. + ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) { + max_receive_message_size_ = max_receive_message_size; + return *this; + } + + /// Set max send message size in bytes. + /// The default is GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH. + ServerBuilder& SetMaxSendMessageSize(int max_send_message_size) { + max_send_message_size_ = max_send_message_size; + return *this; + } + + /// \deprecated For backward compatibility. + ServerBuilder& SetMaxMessageSize(int max_message_size) { + return SetMaxReceiveMessageSize(max_message_size); + } + + /// Set the support status for compression algorithms. All algorithms are + /// enabled by default. + /// + /// Incoming calls compressed with an unsupported algorithm will fail with + /// \a GRPC_STATUS_UNIMPLEMENTED. + ServerBuilder& SetCompressionAlgorithmSupportStatus( + grpc_compression_algorithm algorithm, bool enabled); + + /// The default compression level to use for all channel calls in the + /// absence of a call-specific level. + ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level); + + /// The default compression algorithm to use for all channel calls in the + /// absence of a call-specific level. Note that it overrides any compression + /// level set by \a SetDefaultCompressionLevel. + ServerBuilder& SetDefaultCompressionAlgorithm( + grpc_compression_algorithm algorithm); + + /// Set the attached buffer pool for this server + ServerBuilder& SetResourceQuota(const ResourceQuota& resource_quota); + + ServerBuilder& SetOption(std::unique_ptr option); + + /// Options for synchronous servers. + enum SyncServerOption { + NUM_CQS, ///< Number of completion queues. + MIN_POLLERS, ///< Minimum number of polling threads. + MAX_POLLERS, ///< Maximum number of polling threads. + CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds. + }; + + /// Only useful if this is a Synchronous server. + ServerBuilder& SetSyncServerOption(SyncServerOption option, int value); + + /// Add a channel argument (an escape hatch to tuning core library parameters + /// directly) + template + ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) { + return SetOption(MakeChannelArgumentOption(arg, value)); + } + + /// For internal use only: Register a ServerBuilderPlugin factory function. + static void InternalAddPluginFactory( + std::unique_ptr (*CreatePlugin)()); + + /// Enable a server workaround. Do not use unless you know what the workaround + /// does. For explanation and detailed descriptions of workarounds, see + /// doc/workarounds.md. + ServerBuilder& EnableWorkaround(grpc_workaround_list id); + + /// NOTE: class experimental_type is not part of the public API of this class. + /// TODO(yashykt): Integrate into public API when this is no longer + /// experimental. + class experimental_type { + public: + explicit experimental_type(ServerBuilder* builder) : builder_(builder) {} + + void SetInterceptorCreators( + std::vector< + std::unique_ptr> + interceptor_creators) { + builder_->interceptor_creators_ = std::move(interceptor_creators); + } + + ServerBuilder& RegisterCallbackGenericService( + experimental::CallbackGenericService* service); + + private: + ServerBuilder* builder_; + }; + + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + + protected: + /// Experimental, to be deprecated + struct Port { + grpc::string addr; + std::shared_ptr creds; + int* selected_port; + }; + + /// Experimental, to be deprecated + typedef std::unique_ptr HostString; + struct NamedService { + explicit NamedService(Service* s) : service(s) {} + NamedService(const grpc::string& h, Service* s) + : host(new grpc::string(h)), service(s) {} + HostString host; + Service* service; + }; + + /// Experimental, to be deprecated + std::vector ports() { return ports_; } + + /// Experimental, to be deprecated + std::vector services() { + std::vector service_refs; + for (auto& ptr : services_) { + service_refs.push_back(ptr.get()); + } + return service_refs; + } + + /// Experimental, to be deprecated + std::vector options() { + std::vector option_refs; + for (auto& ptr : options_) { + option_refs.push_back(ptr.get()); + } + return option_refs; + } + + private: + friend class ::grpc::testing::ServerBuilderPluginTest; + + struct SyncServerSettings { + SyncServerSettings() + : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} + + /// Number of server completion queues to create to listen to incoming RPCs. + int num_cqs; + + /// Minimum number of threads per completion queue that should be listening + /// to incoming RPCs. + int min_pollers; + + /// Maximum number of threads per completion queue that can be listening to + /// incoming RPCs. + int max_pollers; + + /// The timeout for server completion queue's AsyncNext call. + int cq_timeout_msec; + }; + + int max_receive_message_size_; + int max_send_message_size_; + std::vector> options_; + std::vector> services_; + std::vector ports_; + + SyncServerSettings sync_server_settings_; + + /// List of completion queues added via \a AddCompletionQueue method. + std::vector cqs_; + + std::shared_ptr creds_; + std::vector> plugins_; + grpc_resource_quota* resource_quota_; + AsyncGenericService* generic_service_{nullptr}; + experimental::CallbackGenericService* callback_generic_service_{nullptr}; + struct { + bool is_set; + grpc_compression_level level; + } maybe_default_compression_level_; + struct { + bool is_set; + grpc_compression_algorithm algorithm; + } maybe_default_compression_algorithm_; + uint32_t enabled_compression_algorithms_bitset_; + std::vector> + interceptor_creators_; +}; + } // namespace grpc #endif // GRPCPP_SERVER_BUILDER_H diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h deleted file mode 100644 index a8323c38510..00000000000 --- a/include/grpcpp/server_builder_impl.h +++ /dev/null @@ -1,346 +0,0 @@ -/* - * - * Copyright 2015-2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPCPP_SERVER_BUILDER_IMPL_H -#define GRPCPP_SERVER_BUILDER_IMPL_H - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -struct grpc_resource_quota; - -namespace grpc { - -class AsyncGenericService; -class ResourceQuota; -class CompletionQueue; -class Server; -class ServerCompletionQueue; -class ServerCredentials; -class Service; - -namespace testing { -class ServerBuilderPluginTest; -} // namespace testing - -namespace experimental { -class CallbackGenericService; -} -} // namespace grpc -namespace grpc_impl { - -/// A builder class for the creation and startup of \a grpc::Server instances. -class ServerBuilder { - public: - ServerBuilder(); - virtual ~ServerBuilder(); - - ////////////////////////////////////////////////////////////////////////////// - // Primary API's - - /// Return a running server which is ready for processing calls. - /// Before calling, one typically needs to ensure that: - /// 1. a service is registered - so that the server knows what to serve - /// (via RegisterService, or RegisterAsyncGenericService) - /// 2. a listening port has been added - so the server knows where to receive - /// traffic (via AddListeningPort) - /// 3. [for async api only] completion queues have been added via - /// AddCompletionQueue - virtual std::unique_ptr BuildAndStart(); - - /// Register a service. This call does not take ownership of the service. - /// The service must exist for the lifetime of the \a Server instance returned - /// by \a BuildAndStart(). - /// Matches requests with any :authority - ServerBuilder& RegisterService(grpc::Service* service); - - /// Enlists an endpoint \a addr (port with an optional IP address) to - /// bind the \a grpc::Server object to be created to. - /// - /// It can be invoked multiple times. - /// - /// \param addr_uri The address to try to bind to the server in URI form. If - /// the scheme name is omitted, "dns:///" is assumed. To bind to any address, - /// please use IPv6 any, i.e., [::]:, which also accepts IPv4 - /// connections. Valid values include dns:///localhost:1234, / - /// 192.168.1.1:31416, dns:///[::1]:27182, etc.). - /// \param creds The credentials associated with the server. - /// \param selected_port[out] If not `nullptr`, gets populated with the port - /// number bound to the \a grpc::Server for the corresponding endpoint after - /// it is successfully bound by BuildAndStart(), 0 otherwise. AddListeningPort - /// does not modify this pointer. - ServerBuilder& AddListeningPort( - const grpc::string& addr_uri, - std::shared_ptr creds, - int* selected_port = nullptr); - - /// Add a completion queue for handling asynchronous services. - /// - /// Best performance is typically obtained by using one thread per polling - /// completion queue. - /// - /// Caller is required to shutdown the server prior to shutting down the - /// returned completion queue. Caller is also required to drain the - /// completion queue after shutting it down. A typical usage scenario: - /// - /// // While building the server: - /// ServerBuilder builder; - /// ... - /// cq_ = builder.AddCompletionQueue(); - /// server_ = builder.BuildAndStart(); - /// - /// // While shutting down the server; - /// server_->Shutdown(); - /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()! - /// // Drain the cq_ that was created - /// void* ignored_tag; - /// bool ignored_ok; - /// while (cq_->Next(&ignored_tag, &ignored_ok)) { } - /// - /// \param is_frequently_polled This is an optional parameter to inform gRPC - /// library about whether this completion queue would be frequently polled - /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is - /// 'true' and is the recommended setting. Setting this to 'false' (i.e. - /// not polling the completion queue frequently) will have a significantly - /// negative performance impact and hence should not be used in production - /// use cases. - std::unique_ptr AddCompletionQueue( - bool is_frequently_polled = true); - - ////////////////////////////////////////////////////////////////////////////// - // Less commonly used RegisterService variants - - /// Register a service. This call does not take ownership of the service. - /// The service must exist for the lifetime of the \a Server instance - /// returned by \a BuildAndStart(). Only matches requests with :authority \a - /// host - ServerBuilder& RegisterService(const grpc::string& host, - grpc::Service* service); - - /// Register a generic service. - /// Matches requests with any :authority - /// This is mostly useful for writing generic gRPC Proxies where the exact - /// serialization format is unknown - ServerBuilder& RegisterAsyncGenericService( - grpc::AsyncGenericService* service); - - ////////////////////////////////////////////////////////////////////////////// - // Fine control knobs - - /// Set max receive message size in bytes. - /// The default is GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH. - ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) { - max_receive_message_size_ = max_receive_message_size; - return *this; - } - - /// Set max send message size in bytes. - /// The default is GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH. - ServerBuilder& SetMaxSendMessageSize(int max_send_message_size) { - max_send_message_size_ = max_send_message_size; - return *this; - } - - /// \deprecated For backward compatibility. - ServerBuilder& SetMaxMessageSize(int max_message_size) { - return SetMaxReceiveMessageSize(max_message_size); - } - - /// Set the support status for compression algorithms. All algorithms are - /// enabled by default. - /// - /// Incoming calls compressed with an unsupported algorithm will fail with - /// \a GRPC_STATUS_UNIMPLEMENTED. - ServerBuilder& SetCompressionAlgorithmSupportStatus( - grpc_compression_algorithm algorithm, bool enabled); - - /// The default compression level to use for all channel calls in the - /// absence of a call-specific level. - ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level); - - /// The default compression algorithm to use for all channel calls in the - /// absence of a call-specific level. Note that it overrides any compression - /// level set by \a SetDefaultCompressionLevel. - ServerBuilder& SetDefaultCompressionAlgorithm( - grpc_compression_algorithm algorithm); - - /// Set the attached buffer pool for this server - ServerBuilder& SetResourceQuota(const grpc::ResourceQuota& resource_quota); - - ServerBuilder& SetOption(std::unique_ptr option); - - /// Options for synchronous servers. - enum SyncServerOption { - NUM_CQS, ///< Number of completion queues. - MIN_POLLERS, ///< Minimum number of polling threads. - MAX_POLLERS, ///< Maximum number of polling threads. - CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds. - }; - - /// Only useful if this is a Synchronous server. - ServerBuilder& SetSyncServerOption(SyncServerOption option, int value); - - /// Add a channel argument (an escape hatch to tuning core library parameters - /// directly) - template - ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) { - return SetOption(grpc::MakeChannelArgumentOption(arg, value)); - } - - /// For internal use only: Register a ServerBuilderPlugin factory function. - static void InternalAddPluginFactory( - std::unique_ptr (*CreatePlugin)()); - - /// Enable a server workaround. Do not use unless you know what the workaround - /// does. For explanation and detailed descriptions of workarounds, see - /// doc/workarounds.md. - ServerBuilder& EnableWorkaround(grpc_workaround_list id); - - /// NOTE: class experimental_type is not part of the public API of this class. - /// TODO(yashykt): Integrate into public API when this is no longer - /// experimental. - class experimental_type { - public: - explicit experimental_type(grpc_impl::ServerBuilder* builder) - : builder_(builder) {} - - void SetInterceptorCreators( - std::vector> - interceptor_creators) { - builder_->interceptor_creators_ = std::move(interceptor_creators); - } - - ServerBuilder& RegisterCallbackGenericService( - grpc::experimental::CallbackGenericService* service); - - private: - ServerBuilder* builder_; - }; - - /// NOTE: The function experimental() is not stable public API. It is a view - /// to the experimental components of this class. It may be changed or removed - /// at any time. - experimental_type experimental() { return experimental_type(this); } - - protected: - /// Experimental, to be deprecated - struct Port { - grpc::string addr; - std::shared_ptr creds; - int* selected_port; - }; - - /// Experimental, to be deprecated - typedef std::unique_ptr HostString; - struct NamedService { - explicit NamedService(grpc::Service* s) : service(s) {} - NamedService(const grpc::string& h, grpc::Service* s) - : host(new grpc::string(h)), service(s) {} - HostString host; - grpc::Service* service; - }; - - /// Experimental, to be deprecated - std::vector ports() { return ports_; } - - /// Experimental, to be deprecated - std::vector services() { - std::vector service_refs; - for (auto& ptr : services_) { - service_refs.push_back(ptr.get()); - } - return service_refs; - } - - /// Experimental, to be deprecated - std::vector options() { - std::vector option_refs; - for (auto& ptr : options_) { - option_refs.push_back(ptr.get()); - } - return option_refs; - } - - private: - friend class ::grpc::testing::ServerBuilderPluginTest; - - struct SyncServerSettings { - SyncServerSettings() - : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} - - /// Number of server completion queues to create to listen to incoming RPCs. - int num_cqs; - - /// Minimum number of threads per completion queue that should be listening - /// to incoming RPCs. - int min_pollers; - - /// Maximum number of threads per completion queue that can be listening to - /// incoming RPCs. - int max_pollers; - - /// The timeout for server completion queue's AsyncNext call. - int cq_timeout_msec; - }; - - int max_receive_message_size_; - int max_send_message_size_; - std::vector> options_; - std::vector> services_; - std::vector ports_; - - SyncServerSettings sync_server_settings_; - - /// List of completion queues added via \a AddCompletionQueue method. - std::vector cqs_; - - std::shared_ptr creds_; - std::vector> plugins_; - grpc_resource_quota* resource_quota_; - grpc::AsyncGenericService* generic_service_{nullptr}; - grpc::experimental::CallbackGenericService* callback_generic_service_{ - nullptr}; - struct { - bool is_set; - grpc_compression_level level; - } maybe_default_compression_level_; - struct { - bool is_set; - grpc_compression_algorithm algorithm; - } maybe_default_compression_algorithm_; - uint32_t enabled_compression_algorithms_bitset_; - std::vector< - std::unique_ptr> - interceptor_creators_; -}; - -} // namespace grpc_impl - -#endif // GRPCPP_SERVER_BUILDER_IMPL_H diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index c0cb706a5b1..cd0e516d9a3 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -29,15 +29,15 @@ #include "src/core/lib/gpr/useful.h" #include "src/cpp/server/thread_pool_interface.h" -namespace grpc_impl { +namespace grpc { -static std::vector (*)()>* +static std::vector (*)()>* g_plugin_factory_list; static gpr_once once_init_plugin_list = GPR_ONCE_INIT; static void do_plugin_list_init(void) { g_plugin_factory_list = - new std::vector (*)()>(); + new std::vector (*)()>(); } ServerBuilder::ServerBuilder() @@ -67,29 +67,29 @@ ServerBuilder::~ServerBuilder() { } } -std::unique_ptr ServerBuilder::AddCompletionQueue( +std::unique_ptr ServerBuilder::AddCompletionQueue( bool is_frequently_polled) { - grpc::ServerCompletionQueue* cq = new grpc::ServerCompletionQueue( + ServerCompletionQueue* cq = new ServerCompletionQueue( GRPC_CQ_NEXT, is_frequently_polled ? GRPC_CQ_DEFAULT_POLLING : GRPC_CQ_NON_LISTENING, nullptr); cqs_.push_back(cq); - return std::unique_ptr(cq); + return std::unique_ptr(cq); } -ServerBuilder& ServerBuilder::RegisterService(grpc::Service* service) { +ServerBuilder& ServerBuilder::RegisterService(Service* service) { services_.emplace_back(new NamedService(service)); return *this; } ServerBuilder& ServerBuilder::RegisterService(const grpc::string& addr, - grpc::Service* service) { + Service* service) { services_.emplace_back(new NamedService(addr, service)); return *this; } ServerBuilder& ServerBuilder::RegisterAsyncGenericService( - grpc::AsyncGenericService* service) { + AsyncGenericService* service) { if (generic_service_ || callback_generic_service_) { gpr_log(GPR_ERROR, "Adding multiple generic services is unsupported for now. " @@ -102,7 +102,7 @@ ServerBuilder& ServerBuilder::RegisterAsyncGenericService( } ServerBuilder& ServerBuilder::experimental_type::RegisterCallbackGenericService( - grpc::experimental::CallbackGenericService* service) { + experimental::CallbackGenericService* service) { if (builder_->generic_service_ || builder_->callback_generic_service_) { gpr_log(GPR_ERROR, "Adding multiple generic services is unsupported for now. " @@ -115,7 +115,7 @@ ServerBuilder& ServerBuilder::experimental_type::RegisterCallbackGenericService( } ServerBuilder& ServerBuilder::SetOption( - std::unique_ptr option) { + std::unique_ptr option) { options_.push_back(std::move(option)); return *this; } @@ -174,8 +174,8 @@ ServerBuilder& ServerBuilder::SetResourceQuota( } ServerBuilder& ServerBuilder::AddListeningPort( - const grpc::string& addr_uri, - std::shared_ptr creds, int* selected_port) { + const grpc::string& addr_uri, std::shared_ptr creds, + int* selected_port) { const grpc::string uri_scheme = "dns:"; grpc::string addr = addr_uri; if (addr_uri.compare(0, uri_scheme.size(), uri_scheme) == 0) { @@ -188,8 +188,8 @@ ServerBuilder& ServerBuilder::AddListeningPort( return *this; } -std::unique_ptr ServerBuilder::BuildAndStart() { - grpc::ChannelArguments args; +std::unique_ptr ServerBuilder::BuildAndStart() { + ChannelArguments args; for (auto option = options_.begin(); option != options_.end(); ++option) { (*option)->UpdateArguments(&args); (*option)->UpdatePlugins(&plugins_); @@ -251,10 +251,9 @@ std::unique_ptr ServerBuilder::BuildAndStart() { // This is different from the completion queues added to the server via // ServerBuilder's AddCompletionQueue() method (those completion queues // are in 'cqs_' member variable of ServerBuilder object) - std::shared_ptr>> - sync_server_cqs( - std::make_shared< - std::vector>>()); + std::shared_ptr>> + sync_server_cqs(std::make_shared< + std::vector>>()); bool has_frequently_polled_cqs = false; for (auto it = cqs_.begin(); it != cqs_.end(); ++it) { @@ -283,7 +282,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { // Create completion queues to listen to incoming rpc requests for (int i = 0; i < sync_server_settings_.num_cqs; i++) { sync_server_cqs->emplace_back( - new grpc::ServerCompletionQueue(GRPC_CQ_NEXT, polling_type, nullptr)); + new ServerCompletionQueue(GRPC_CQ_NEXT, polling_type, nullptr)); } } @@ -304,13 +303,13 @@ std::unique_ptr ServerBuilder::BuildAndStart() { gpr_log(GPR_INFO, "Callback server."); } - std::unique_ptr server(new grpc::Server( + std::unique_ptr server(new Server( max_receive_message_size_, &args, sync_server_cqs, sync_server_settings_.min_pollers, sync_server_settings_.max_pollers, sync_server_settings_.cq_timeout_msec, resource_quota_, std::move(interceptor_creators_))); - grpc::ServerInitializer* initializer = server->initializer(); + ServerInitializer* initializer = server->initializer(); // Register all the completion queues with the server. i.e // 1. sync_server_cqs: internal completion queues created IF this is a sync @@ -394,7 +393,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { } void ServerBuilder::InternalAddPluginFactory( - std::unique_ptr (*CreatePlugin)()) { + std::unique_ptr (*CreatePlugin)()) { gpr_once_init(&once_init_plugin_list, do_plugin_list_init); (*g_plugin_factory_list).push_back(CreatePlugin); } @@ -409,4 +408,4 @@ ServerBuilder& ServerBuilder::EnableWorkaround(grpc_workaround_list id) { } } -} // namespace grpc_impl +} // namespace grpc diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 49f0419bacf..9f17a25298a 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1001,7 +1001,6 @@ include/grpcpp/security/credentials.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ -include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ include/grpcpp/support/async_stream.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 937ed0e6749..c0078bf2764 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1003,7 +1003,6 @@ include/grpcpp/security/credentials.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ -include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ include/grpcpp/server_posix.h \ include/grpcpp/support/async_stream.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 5e116090819..501e53560ab 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10089,7 +10089,6 @@ "include/grpcpp/security/server_credentials.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", - "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", "include/grpcpp/server_posix.h", "include/grpcpp/support/async_stream.h", @@ -10199,7 +10198,6 @@ "include/grpcpp/security/server_credentials.h", "include/grpcpp/server.h", "include/grpcpp/server_builder.h", - "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", "include/grpcpp/server_posix.h", "include/grpcpp/support/async_stream.h", From f699bd8604d5e84df5bf2a00948de0b206154201 Mon Sep 17 00:00:00 2001 From: John Luo Date: Tue, 19 Mar 2019 18:13:14 -0700 Subject: [PATCH 797/814] Ensure errors link to correct line numbers through the error list --- .../Grpc.Tools.Tests/ProtoCompileBasicTest.cs | 10 +- .../ProtoCompileCommandLineGeneratorTest.cs | 80 +++++++++++ src/csharp/Grpc.Tools/ProtoCompile.cs | 129 ++++++++++++++++++ .../_protobuf/Google.Protobuf.Tools.targets | 1 - 4 files changed, 218 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs index ea763f4e408..97d044ba671 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileBasicTest.cs @@ -16,6 +16,8 @@ #endregion +using System.Collections.Generic; +using System.Linq; using System.Reflection; // UWYU: Object.GetType() extension. using Microsoft.Build.Framework; using Moq; @@ -30,6 +32,7 @@ namespace Grpc.Tools.Tests { public string LastPathToTool { get; private set; } public string[] LastResponseFile { get; private set; } + public List StdErrMessages { get; } = new List(); protected override int ExecuteTool(string pathToTool, string response, @@ -45,8 +48,13 @@ namespace Grpc.Tools.Tests LastPathToTool = pathToTool; LastResponseFile = response.Remove(response.Length - 1).Split('\n'); + foreach (string message in StdErrMessages) + { + LogEventsFromTextOutput(message, MessageImportance.High); + } + // Do not run the tool, but pretend it ran successfully. - return 0; + return StdErrMessages.Any() ? -1 : 0; } }; diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs index 1ed7ca67b42..e9efa78f96d 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs @@ -175,5 +175,85 @@ namespace Grpc.Tools.Tests Assert.That(_task.LastResponseFile, Does.Contain("--csharp_out=" + expect)); } + + [TestCase( + "../Protos/greet.proto(19) : warning in column=5 : warning : When enum name is stripped and label is PascalCased (Zero) this value label conflicts with Zero.", + "../Protos/greet.proto", + 19, + 5, + "warning : When enum name is stripped and label is PascalCased (Zero) this value label conflicts with Zero.")] + [TestCase( + "../Protos/greet.proto: warning: Import google/protobuf/empty.proto but not used.", + "../Protos/greet.proto", + 0, + 0, + "Import google/protobuf/empty.proto but not used.")] + [TestCase("../Protos/greet.proto(14) : error in column=10: \"name\" is already defined in \"Greet.HelloRequest\".", null, 0, 0, null)] + [TestCase("../Protos/greet.proto: Import \"google / protobuf / empty.proto\" was listed twice.", null, 0, 0, null)] + public void WarningsParsed(string stderr, string file, int line, int col, string message) + { + _task.StdErrMessages.Add(stderr); + + _mockEngine + .Setup(me => me.LogWarningEvent(It.IsAny())) + .Callback((BuildWarningEventArgs e) => { + if (file != null) + { + Assert.AreEqual(file, e.File); + Assert.AreEqual(line, e.LineNumber); + Assert.AreEqual(col, e.ColumnNumber); + Assert.AreEqual(message, e.Message); + } + else + { + Assert.Fail($"Error logged by build engine:\n{e.Message}"); + } + }); + + bool result = _task.Execute(); + Assert.IsFalse(result); + } + + [TestCase( + "../Protos/greet.proto(14) : error in column=10: \"name\" is already defined in \"Greet.HelloRequest\".", + "../Protos/greet.proto", + 14, + 10, + "\"name\" is already defined in \"Greet.HelloRequest\".")] + [TestCase( + "../Protos/greet.proto: Import \"google / protobuf / empty.proto\" was listed twice.", + "../Protos/greet.proto", + 0, + 0, + "Import \"google / protobuf / empty.proto\" was listed twice.")] + [TestCase("../Protos/greet.proto(19) : warning in column=5 : warning : When enum name is stripped and label is PascalCased (Zero) this value label conflicts with Zero.", null, 0, 0, null)] + [TestCase("../Protos/greet.proto: warning: Import google/protobuf/empty.proto but not used.", null, 0, 0, null)] + public void ErrorsParsed(string stderr, string file, int line, int col, string message) + { + _task.StdErrMessages.Add(stderr); + + _mockEngine + .Setup(me => me.LogErrorEvent(It.IsAny())) + .Callback((BuildErrorEventArgs e) => { + if (file != null) + { + Assert.AreEqual(file, e.File); + Assert.AreEqual(line, e.LineNumber); + Assert.AreEqual(col, e.ColumnNumber); + Assert.AreEqual(message, e.Message); + } + else + { + // Ignore expected error + if (e.Message != "\"protoc.exe\" exited with code -1.") + { + Assert.Fail($"Error logged by build engine:\n{e.Message}"); + } + } + }); + + bool result = _task.Execute(); + Assert.IsFalse(result); + } }; } diff --git a/src/csharp/Grpc.Tools/ProtoCompile.cs b/src/csharp/Grpc.Tools/ProtoCompile.cs index abff1ea016a..be8b7ab8961 100644 --- a/src/csharp/Grpc.Tools/ProtoCompile.cs +++ b/src/csharp/Grpc.Tools/ProtoCompile.cs @@ -16,7 +16,10 @@ #endregion +using System; +using System.Collections.Generic; using System.Text; +using System.Text.RegularExpressions; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -123,6 +126,110 @@ namespace Grpc.Tools "javanano", "js", "objc", "php", "python", "ruby" }; + static readonly TimeSpan s_regexTimeout = TimeSpan.FromMilliseconds(100); + + static readonly List s_errorListFilters = new List() + { + // Example warning with location + //../Protos/greet.proto(19) : warning in column=5 : warning : When enum name is stripped and label is PascalCased (Zero), + // this value label conflicts with Zero. This will make the proto fail to compile for some languages, such as C#. + new ErrorListFilter + { + Pattern = new Regex( + pattern: "(?'FILENAME'.+)\\((?'LINE'\\d+)\\) ?: ?warning in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", + options: RegexOptions.Compiled | RegexOptions.IgnoreCase, + matchTimeout: s_regexTimeout), + LogAction = (log, match) => + { + int.TryParse(match.Groups["LINE"].Value, out var line); + int.TryParse(match.Groups["COLUMN"].Value, out var column); + + log.LogWarning( + subcategory: null, + warningCode: null, + helpKeyword: null, + file: match.Groups["FILENAME"].Value, + lineNumber: line, + columnNumber: column, + endLineNumber: 0, + endColumnNumber: 0, + message: match.Groups["TEXT"].Value); + } + }, + + // Example error with location + //../Protos/greet.proto(14) : error in column=10: "name" is already defined in "Greet.HelloRequest". + new ErrorListFilter + { + Pattern = new Regex( + pattern: "(?'FILENAME'.+)\\((?'LINE'\\d+)\\) ?: ?error in column=(?'COLUMN'\\d+) ?: ?(?'TEXT'.*)", + options: RegexOptions.Compiled | RegexOptions.IgnoreCase, + matchTimeout: s_regexTimeout), + LogAction = (log, match) => + { + int.TryParse(match.Groups["LINE"].Value, out var line); + int.TryParse(match.Groups["COLUMN"].Value, out var column); + + log.LogError( + subcategory: null, + errorCode: null, + helpKeyword: null, + file: match.Groups["FILENAME"].Value, + lineNumber: line, + columnNumber: column, + endLineNumber: 0, + endColumnNumber: 0, + message: match.Groups["TEXT"].Value); + } + }, + + // Example warning without location + //../Protos/greet.proto: warning: Import google/protobuf/empty.proto but not used. + new ErrorListFilter + { + Pattern = new Regex( + pattern: "(?'FILENAME'.+): ?warning: ?(?'TEXT'.*)", + options: RegexOptions.Compiled | RegexOptions.IgnoreCase, + matchTimeout: s_regexTimeout), + LogAction = (log, match) => + { + log.LogWarning( + subcategory: null, + warningCode: null, + helpKeyword: null, + file: match.Groups["FILENAME"].Value, + lineNumber: 0, + columnNumber: 0, + endLineNumber: 0, + endColumnNumber: 0, + message: match.Groups["TEXT"].Value); + } + }, + + // Example error without location + //../Protos/greet.proto: Import "google/protobuf/empty.proto" was listed twice. + new ErrorListFilter + { + Pattern = new Regex( + pattern: "(?'FILENAME'.+): ?(?'TEXT'.*)", + options: RegexOptions.Compiled | RegexOptions.IgnoreCase, + matchTimeout: s_regexTimeout), + LogAction = (log, match) => + { + log.LogError( + subcategory: null, + errorCode: null, + helpKeyword: null, + file: match.Groups["FILENAME"].Value, + lineNumber: 0, + columnNumber: 0, + endLineNumber: 0, + endColumnNumber: 0, + message: match.Groups["TEXT"].Value); + } + } + }; + /// /// Code generator. /// @@ -406,6 +513,22 @@ namespace Grpc.Tools base.LogToolCommand(printer.ToString()); } + protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance) + { + foreach (ErrorListFilter filter in s_errorListFilters) + { + Match match = filter.Pattern.Match(singleLine); + + if (match.Success) + { + filter.LogAction(Log, match); + return; + } + } + + base.LogEventsFromTextOutput(singleLine, messageImportance); + } + // Main task entry point. public override bool Execute() { @@ -438,5 +561,11 @@ namespace Grpc.Tools return true; } + + class ErrorListFilter + { + public Regex Pattern { get; set; } + public Action LogAction { get; set; } + } }; } diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets index dc9a1522f17..7896e62c75e 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -271,7 +271,6 @@ GrpcPluginExe="%(_Protobuf_OutOfDateProto.GrpcPluginExe)" GrpcOutputDir="%(_Protobuf_OutOfDateProto.GrpcOutputDir)" GrpcOutputOptions="%(_Protobuf_OutOfDateProto._GrpcOutputOptions)" - LogStandardErrorAsError="true" > From 68c3414cf40bd4d52972abcd1a949110ac8cb1b8 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 26 Mar 2019 02:06:45 -0700 Subject: [PATCH 798/814] fix test --- .../Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs index e9efa78f96d..15b879141e0 100644 --- a/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs +++ b/src/csharp/Grpc.Tools.Tests/ProtoCompileCommandLineGeneratorTest.cs @@ -245,7 +245,8 @@ namespace Grpc.Tools.Tests else { // Ignore expected error - if (e.Message != "\"protoc.exe\" exited with code -1.") + // "protoc/protoc.exe" existed with code -1. + if (!e.Message.EndsWith("exited with code -1.")) { Assert.Fail($"Error logged by build engine:\n{e.Message}"); } From d1dc707908dbb498af6e3da68d3af50fb9f67eff Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 26 Mar 2019 09:33:15 -0700 Subject: [PATCH 799/814] Correct the default DNS resolver to ares --- doc/environment_variables.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index 635c5ee535f..0186cc86764 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -124,9 +124,9 @@ some configuration as environment variables that can be set. Declares which DNS resolver to use. The default is ares if gRPC is built with c-ares support. Otherwise, the value of this environment variable is ignored. Available DNS resolver include: - - native (default)- a DNS resolver based around getaddrinfo(), creates a new thread to + - ares (default)- a DNS resolver based around the c-ares library + - native - a DNS resolver based around getaddrinfo(), creates a new thread to perform name resolution - - ares - a DNS resolver based around the c-ares library * GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS Default: 5000 From c3215ea25b66a339d64f633c13575b3bf2b56f51 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 26 Mar 2019 10:55:56 -0700 Subject: [PATCH 800/814] Add per-platform details for GRPC_DNS_RESOLVER --- doc/environment_variables.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index 0186cc86764..e8d0dbd25f8 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -124,7 +124,8 @@ some configuration as environment variables that can be set. Declares which DNS resolver to use. The default is ares if gRPC is built with c-ares support. Otherwise, the value of this environment variable is ignored. Available DNS resolver include: - - ares (default)- a DNS resolver based around the c-ares library + - ares (default on most platforms except iOS, Android or Node)- a DNS + resolver based around the c-ares library - native - a DNS resolver based around getaddrinfo(), creates a new thread to perform name resolution From 206592ce9c104e95cf699e81d20c3cadbf1f4d1a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 26 Mar 2019 10:52:56 -0700 Subject: [PATCH 801/814] Restructure how addresses and service config are passed from resolver to LB policy. --- BUILD | 5 +- BUILD.gn | 5 +- CMakeLists.txt | 12 +- Makefile | 12 +- build.yaml | 4 +- config.m4 | 2 +- config.w32 | 2 +- gRPC-C++.podspec | 3 +- gRPC-Core.podspec | 6 +- grpc.gemspec | 4 +- grpc.gyp | 8 +- package.xml | 4 +- .../filters/client_channel/client_channel.cc | 6 +- .../ext/filters/client_channel/lb_policy.cc | 43 ++++++- .../ext/filters/client_channel/lb_policy.h | 32 +++-- .../client_channel/lb_policy/grpclb/grpclb.cc | 116 +++++++----------- .../lb_policy/grpclb/grpclb_channel.cc | 2 +- .../lb_policy/grpclb/grpclb_channel.h | 4 +- .../lb_policy/grpclb/grpclb_channel_secure.cc | 8 +- .../lb_policy/pick_first/pick_first.cc | 30 +---- .../lb_policy/round_robin/round_robin.cc | 24 +--- .../lb_policy/subchannel_list.h | 1 - .../client_channel/lb_policy/xds/xds.cc | 72 +++++------ .../ext/filters/client_channel/resolver.cc | 51 ++++++++ .../ext/filters/client_channel/resolver.h | 31 ++++- .../resolver/dns/c_ares/dns_resolver_ares.cc | 25 ++-- .../resolver/dns/native/dns_resolver.cc | 12 +- .../resolver/fake/fake_resolver.cc | 83 ++++++++----- .../resolver/fake/fake_resolver.h | 17 +-- .../resolver/sockaddr/sockaddr_resolver.cc | 26 ++-- .../client_channel/resolver_registry.h | 1 + .../client_channel/resolver_result_parsing.cc | 115 +++++++++-------- .../client_channel/resolver_result_parsing.h | 10 +- .../client_channel/resolving_lb_policy.cc | 49 ++++---- .../client_channel/resolving_lb_policy.h | 14 +-- .../filters/client_channel/server_address.cc | 48 -------- .../filters/client_channel/server_address.h | 10 -- .../filters/client_channel}/service_config.cc | 13 +- .../filters/client_channel}/service_config.h | 16 ++- .../ext/filters/client_channel/subchannel.cc | 2 +- .../message_size/message_size_filter.cc | 2 +- src/core/lib/channel/channel_args.cc | 2 + src/python/grpcio/grpc_core_dependencies.py | 2 +- .../dns_resolver_connectivity_test.cc | 16 +-- .../resolvers/dns_resolver_cooldown_test.cc | 15 +-- .../resolvers/fake_resolver_test.cc | 73 +++++------ .../resolvers/sockaddr_resolver_test.cc | 4 +- test/core/end2end/connection_refused_test.cc | 1 - .../core/end2end/tests/cancel_after_accept.cc | 1 - .../end2end/tests/cancel_after_round_trip.cc | 1 - test/core/end2end/tests/max_message_length.cc | 1 - test/core/util/test_lb_policies.cc | 5 +- test/cpp/client/client_channel_stress_test.cc | 8 +- test/cpp/end2end/client_lb_end2end_test.cc | 21 ++-- test/cpp/end2end/grpclb_end2end_test.cc | 24 ++-- test/cpp/end2end/xds_end2end_test.cc | 46 +++---- test/cpp/naming/cancel_ares_query_test.cc | 2 +- test/cpp/naming/resolver_component_test.cc | 37 +++--- tools/doxygen/Doxyfile.c++.internal | 1 - tools/doxygen/Doxyfile.core.internal | 4 +- .../generated/sources_and_headers.json | 6 +- 61 files changed, 582 insertions(+), 618 deletions(-) rename src/core/{lib/transport => ext/filters/client_channel}/service_config.cc (87%) rename src/core/{lib/transport => ext/filters/client_channel}/service_config.h (94%) diff --git a/BUILD b/BUILD index 12687c799ef..349ade626b4 100644 --- a/BUILD +++ b/BUILD @@ -839,7 +839,6 @@ grpc_cc_library( "src/core/lib/transport/metadata.cc", "src/core/lib/transport/metadata_batch.cc", "src/core/lib/transport/pid_controller.cc", - "src/core/lib/transport/service_config.cc", "src/core/lib/transport/static_metadata.cc", "src/core/lib/transport/status_conversion.cc", "src/core/lib/transport/status_metadata.cc", @@ -974,7 +973,6 @@ grpc_cc_library( "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/pid_controller.h", - "src/core/lib/transport/service_config.h", "src/core/lib/transport/static_metadata.h", "src/core/lib/transport/status_conversion.h", "src/core/lib/transport/status_metadata.h", @@ -1085,6 +1083,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/resolving_lb_policy.cc", "src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/server_address.cc", + "src/core/ext/filters/client_channel/service_config.cc", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", ], @@ -1112,6 +1111,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", + "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.h", ], @@ -1182,6 +1182,7 @@ grpc_cc_library( language = "c++", deps = [ "grpc_base", + "grpc_client_channel", ], ) diff --git a/BUILD.gn b/BUILD.gn index eb831f5b7b6..d15961a4879 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -329,6 +329,8 @@ config("grpc_config") { "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.cc", "src/core/ext/filters/client_channel/server_address.h", + "src/core/ext/filters/client_channel/service_config.cc", + "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", @@ -762,8 +764,6 @@ config("grpc_config") { "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/pid_controller.cc", "src/core/lib/transport/pid_controller.h", - "src/core/lib/transport/service_config.cc", - "src/core/lib/transport/service_config.h", "src/core/lib/transport/static_metadata.cc", "src/core/lib/transport/static_metadata.h", "src/core/lib/transport/status_conversion.cc", @@ -1251,7 +1251,6 @@ config("grpc_config") { "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/pid_controller.h", - "src/core/lib/transport/service_config.h", "src/core/lib/transport/static_metadata.h", "src/core/lib/transport/status_conversion.h", "src/core/lib/transport/status_metadata.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index d39c1941a74..e7857d5d84e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1109,7 +1109,6 @@ add_library(grpc src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc src/core/lib/transport/pid_controller.cc - src/core/lib/transport/service_config.cc src/core/lib/transport/static_metadata.cc src/core/lib/transport/status_conversion.cc src/core/lib/transport/status_metadata.cc @@ -1245,6 +1244,7 @@ add_library(grpc src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc @@ -1535,7 +1535,6 @@ add_library(grpc_cronet src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc src/core/lib/transport/pid_controller.cc - src/core/lib/transport/service_config.cc src/core/lib/transport/static_metadata.cc src/core/lib/transport/status_conversion.cc src/core/lib/transport/status_metadata.cc @@ -1599,6 +1598,7 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc @@ -1946,7 +1946,6 @@ add_library(grpc_test_util src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc src/core/lib/transport/pid_controller.cc - src/core/lib/transport/service_config.cc src/core/lib/transport/static_metadata.cc src/core/lib/transport/status_conversion.cc src/core/lib/transport/status_metadata.cc @@ -1978,6 +1977,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc @@ -2270,7 +2270,6 @@ add_library(grpc_test_util_unsecure src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc src/core/lib/transport/pid_controller.cc - src/core/lib/transport/service_config.cc src/core/lib/transport/static_metadata.cc src/core/lib/transport/status_conversion.cc src/core/lib/transport/status_metadata.cc @@ -2302,6 +2301,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc @@ -2570,7 +2570,6 @@ add_library(grpc_unsecure src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc src/core/lib/transport/pid_controller.cc - src/core/lib/transport/service_config.cc src/core/lib/transport/static_metadata.cc src/core/lib/transport/status_conversion.cc src/core/lib/transport/status_metadata.cc @@ -2637,6 +2636,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc @@ -3457,7 +3457,6 @@ add_library(grpc++_cronet src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc src/core/lib/transport/pid_controller.cc - src/core/lib/transport/service_config.cc src/core/lib/transport/static_metadata.cc src/core/lib/transport/status_conversion.cc src/core/lib/transport/status_metadata.cc @@ -3494,6 +3493,7 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/resolving_lb_policy.cc src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/server_address.cc + src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/deadline/deadline_filter.cc diff --git a/Makefile b/Makefile index 85e621f87bb..d93489e683f 100644 --- a/Makefile +++ b/Makefile @@ -3556,7 +3556,6 @@ LIBGRPC_SRC = \ src/core/lib/transport/metadata.cc \ src/core/lib/transport/metadata_batch.cc \ src/core/lib/transport/pid_controller.cc \ - src/core/lib/transport/service_config.cc \ src/core/lib/transport/static_metadata.cc \ src/core/lib/transport/status_conversion.cc \ src/core/lib/transport/status_metadata.cc \ @@ -3692,6 +3691,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ @@ -3976,7 +3976,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/transport/metadata.cc \ src/core/lib/transport/metadata_batch.cc \ src/core/lib/transport/pid_controller.cc \ - src/core/lib/transport/service_config.cc \ src/core/lib/transport/static_metadata.cc \ src/core/lib/transport/status_conversion.cc \ src/core/lib/transport/status_metadata.cc \ @@ -4040,6 +4039,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ @@ -4380,7 +4380,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/transport/metadata.cc \ src/core/lib/transport/metadata_batch.cc \ src/core/lib/transport/pid_controller.cc \ - src/core/lib/transport/service_config.cc \ src/core/lib/transport/static_metadata.cc \ src/core/lib/transport/status_conversion.cc \ src/core/lib/transport/status_metadata.cc \ @@ -4412,6 +4411,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ @@ -4691,7 +4691,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/transport/metadata.cc \ src/core/lib/transport/metadata_batch.cc \ src/core/lib/transport/pid_controller.cc \ - src/core/lib/transport/service_config.cc \ src/core/lib/transport/static_metadata.cc \ src/core/lib/transport/status_conversion.cc \ src/core/lib/transport/status_metadata.cc \ @@ -4723,6 +4722,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ @@ -4965,7 +4965,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/transport/metadata.cc \ src/core/lib/transport/metadata_batch.cc \ src/core/lib/transport/pid_controller.cc \ - src/core/lib/transport/service_config.cc \ src/core/lib/transport/static_metadata.cc \ src/core/lib/transport/status_conversion.cc \ src/core/lib/transport/status_metadata.cc \ @@ -5032,6 +5031,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ @@ -5828,7 +5828,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/transport/metadata.cc \ src/core/lib/transport/metadata_batch.cc \ src/core/lib/transport/pid_controller.cc \ - src/core/lib/transport/service_config.cc \ src/core/lib/transport/static_metadata.cc \ src/core/lib/transport/status_conversion.cc \ src/core/lib/transport/status_metadata.cc \ @@ -5865,6 +5864,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ diff --git a/build.yaml b/build.yaml index 34b271f58de..c1271be9131 100644 --- a/build.yaml +++ b/build.yaml @@ -372,7 +372,6 @@ filegroups: - src/core/lib/transport/metadata.cc - src/core/lib/transport/metadata_batch.cc - src/core/lib/transport/pid_controller.cc - - src/core/lib/transport/service_config.cc - src/core/lib/transport/static_metadata.cc - src/core/lib/transport/status_conversion.cc - src/core/lib/transport/status_metadata.cc @@ -530,7 +529,6 @@ filegroups: - src/core/lib/transport/metadata.h - src/core/lib/transport/metadata_batch.h - src/core/lib/transport/pid_controller.h - - src/core/lib/transport/service_config.h - src/core/lib/transport/static_metadata.h - src/core/lib/transport/status_conversion.h - src/core/lib/transport/status_metadata.h @@ -590,6 +588,7 @@ filegroups: - src/core/ext/filters/client_channel/resolving_lb_policy.h - src/core/ext/filters/client_channel/retry_throttle.h - src/core/ext/filters/client_channel/server_address.h + - src/core/ext/filters/client_channel/service_config.h - src/core/ext/filters/client_channel/subchannel.h - src/core/ext/filters/client_channel/subchannel_pool_interface.h src: @@ -616,6 +615,7 @@ filegroups: - src/core/ext/filters/client_channel/resolving_lb_policy.cc - src/core/ext/filters/client_channel/retry_throttle.cc - src/core/ext/filters/client_channel/server_address.cc + - src/core/ext/filters/client_channel/service_config.cc - src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_pool_interface.cc plugin: grpc_client_channel diff --git a/config.m4 b/config.m4 index b920799f49b..2c64a3eb168 100644 --- a/config.m4 +++ b/config.m4 @@ -226,7 +226,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/transport/metadata.cc \ src/core/lib/transport/metadata_batch.cc \ src/core/lib/transport/pid_controller.cc \ - src/core/lib/transport/service_config.cc \ src/core/lib/transport/static_metadata.cc \ src/core/lib/transport/status_conversion.cc \ src/core/lib/transport/status_metadata.cc \ @@ -362,6 +361,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/resolving_lb_policy.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/server_address.cc \ + src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ diff --git a/config.w32 b/config.w32 index 49eab2dc109..6897c1041ac 100644 --- a/config.w32 +++ b/config.w32 @@ -201,7 +201,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\transport\\metadata.cc " + "src\\core\\lib\\transport\\metadata_batch.cc " + "src\\core\\lib\\transport\\pid_controller.cc " + - "src\\core\\lib\\transport\\service_config.cc " + "src\\core\\lib\\transport\\static_metadata.cc " + "src\\core\\lib\\transport\\status_conversion.cc " + "src\\core\\lib\\transport\\status_metadata.cc " + @@ -337,6 +336,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\resolving_lb_policy.cc " + "src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " + "src\\core\\ext\\filters\\client_channel\\server_address.cc " + + "src\\core\\ext\\filters\\client_channel\\service_config.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel_pool_interface.cc " + "src\\core\\ext\\filters\\deadline\\deadline_filter.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 5a850bc8438..7afd9ef1a84 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -367,6 +367,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', + 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', @@ -509,7 +510,6 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', 'src/core/lib/transport/pid_controller.h', - 'src/core/lib/transport/service_config.h', 'src/core/lib/transport/static_metadata.h', 'src/core/lib/transport/status_conversion.h', 'src/core/lib/transport/status_metadata.h', @@ -700,7 +700,6 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', 'src/core/lib/transport/pid_controller.h', - 'src/core/lib/transport/service_config.h', 'src/core/lib/transport/static_metadata.h', 'src/core/lib/transport/status_conversion.h', 'src/core/lib/transport/status_metadata.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 42633186ac3..7baaf65bbbf 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -361,6 +361,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', + 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', @@ -503,7 +504,6 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', 'src/core/lib/transport/pid_controller.h', - 'src/core/lib/transport/service_config.h', 'src/core/lib/transport/static_metadata.h', 'src/core/lib/transport/status_conversion.h', 'src/core/lib/transport/status_metadata.h', @@ -674,7 +674,6 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.cc', 'src/core/lib/transport/metadata_batch.cc', 'src/core/lib/transport/pid_controller.cc', - 'src/core/lib/transport/service_config.cc', 'src/core/lib/transport/static_metadata.cc', 'src/core/lib/transport/status_conversion.cc', 'src/core/lib/transport/status_metadata.cc', @@ -807,6 +806,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', @@ -991,6 +991,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolving_lb_policy.h', 'src/core/ext/filters/client_channel/retry_throttle.h', 'src/core/ext/filters/client_channel/server_address.h', + 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', 'src/core/ext/filters/deadline/deadline_filter.h', @@ -1133,7 +1134,6 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', 'src/core/lib/transport/pid_controller.h', - 'src/core/lib/transport/service_config.h', 'src/core/lib/transport/static_metadata.h', 'src/core/lib/transport/status_conversion.h', 'src/core/lib/transport/status_metadata.h', diff --git a/grpc.gemspec b/grpc.gemspec index d9fc6ef0ebc..c5e099585f6 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -295,6 +295,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.h ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h ) s.files += %w( src/core/ext/filters/client_channel/server_address.h ) + s.files += %w( src/core/ext/filters/client_channel/service_config.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.h ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.h ) @@ -437,7 +438,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/metadata.h ) s.files += %w( src/core/lib/transport/metadata_batch.h ) s.files += %w( src/core/lib/transport/pid_controller.h ) - s.files += %w( src/core/lib/transport/service_config.h ) s.files += %w( src/core/lib/transport/static_metadata.h ) s.files += %w( src/core/lib/transport/status_conversion.h ) s.files += %w( src/core/lib/transport/status_metadata.h ) @@ -608,7 +608,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/metadata.cc ) s.files += %w( src/core/lib/transport/metadata_batch.cc ) s.files += %w( src/core/lib/transport/pid_controller.cc ) - s.files += %w( src/core/lib/transport/service_config.cc ) s.files += %w( src/core/lib/transport/static_metadata.cc ) s.files += %w( src/core/lib/transport/status_conversion.cc ) s.files += %w( src/core/lib/transport/status_metadata.cc ) @@ -744,6 +743,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.cc ) s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc ) s.files += %w( src/core/ext/filters/client_channel/server_address.cc ) + s.files += %w( src/core/ext/filters/client_channel/service_config.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.cc ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc ) diff --git a/grpc.gyp b/grpc.gyp index d25e630f867..322259d2ca7 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -408,7 +408,6 @@ 'src/core/lib/transport/metadata.cc', 'src/core/lib/transport/metadata_batch.cc', 'src/core/lib/transport/pid_controller.cc', - 'src/core/lib/transport/service_config.cc', 'src/core/lib/transport/static_metadata.cc', 'src/core/lib/transport/status_conversion.cc', 'src/core/lib/transport/status_metadata.cc', @@ -544,6 +543,7 @@ 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', @@ -775,7 +775,6 @@ 'src/core/lib/transport/metadata.cc', 'src/core/lib/transport/metadata_batch.cc', 'src/core/lib/transport/pid_controller.cc', - 'src/core/lib/transport/service_config.cc', 'src/core/lib/transport/static_metadata.cc', 'src/core/lib/transport/status_conversion.cc', 'src/core/lib/transport/status_metadata.cc', @@ -807,6 +806,7 @@ 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', @@ -1019,7 +1019,6 @@ 'src/core/lib/transport/metadata.cc', 'src/core/lib/transport/metadata_batch.cc', 'src/core/lib/transport/pid_controller.cc', - 'src/core/lib/transport/service_config.cc', 'src/core/lib/transport/static_metadata.cc', 'src/core/lib/transport/status_conversion.cc', 'src/core/lib/transport/status_metadata.cc', @@ -1051,6 +1050,7 @@ 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', @@ -1239,7 +1239,6 @@ 'src/core/lib/transport/metadata.cc', 'src/core/lib/transport/metadata_batch.cc', 'src/core/lib/transport/pid_controller.cc', - 'src/core/lib/transport/service_config.cc', 'src/core/lib/transport/static_metadata.cc', 'src/core/lib/transport/status_conversion.cc', 'src/core/lib/transport/status_metadata.cc', @@ -1306,6 +1305,7 @@ 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', diff --git a/package.xml b/package.xml index 48ccdeff73b..ccdd70bdca3 100644 --- a/package.xml +++ b/package.xml @@ -300,6 +300,7 @@ + @@ -442,7 +443,6 @@ - @@ -613,7 +613,6 @@ - @@ -749,6 +748,7 @@ + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 891df3baf6b..82ce253c83c 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -41,6 +41,7 @@ #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/resolving_lb_policy.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/deadline/deadline_filter.h" #include "src/core/lib/backoff/backoff.h" @@ -61,7 +62,6 @@ #include "src/core/lib/transport/error_utils.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/metadata_batch.h" -#include "src/core/lib/transport/service_config.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" @@ -252,11 +252,11 @@ class ClientChannelControlHelper // Synchronous callback from chand->resolving_lb_policy to process a resolver // result update. static bool process_resolver_result_locked( - void* arg, const grpc_channel_args& args, const char** lb_policy_name, + void* arg, grpc_core::Resolver::Result* result, const char** lb_policy_name, grpc_core::RefCountedPtr* lb_policy_config) { channel_data* chand = static_cast(arg); chand->have_service_config = true; - ProcessedResolverResult resolver_result(args, chand->enable_retries); + ProcessedResolverResult resolver_result(result, chand->enable_retries); grpc_core::UniquePtr service_config_json = resolver_result.service_config_json(); if (grpc_client_channel_routing_trace.enabled()) { diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index f370d745bb1..c8f8e82e5d7 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -23,11 +23,10 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/lib/iomgr/combiner.h" -grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount( - false, "lb_policy_refcount"); - namespace grpc_core { +DebugOnlyTraceFlag grpc_trace_lb_policy_refcount(false, "lb_policy_refcount"); + // // LoadBalancingPolicy // @@ -89,6 +88,44 @@ grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( return nullptr; } +// +// LoadBalancingPolicy::UpdateArgs +// + +LoadBalancingPolicy::UpdateArgs::UpdateArgs(const UpdateArgs& other) { + addresses = other.addresses; + config = other.config; + args = grpc_channel_args_copy(other.args); +} + +LoadBalancingPolicy::UpdateArgs::UpdateArgs(UpdateArgs&& other) { + addresses = std::move(other.addresses); + config = std::move(other.config); + // TODO(roth): Use std::move() once channel args is converted to C++. + args = other.args; + other.args = nullptr; +} + +LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( + const UpdateArgs& other) { + addresses = other.addresses; + config = other.config; + grpc_channel_args_destroy(args); + args = grpc_channel_args_copy(other.args); + return *this; +} + +LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( + UpdateArgs&& other) { + addresses = std::move(other.addresses); + config = std::move(other.config); + // TODO(roth): Use std::move() once channel args is converted to C++. + grpc_channel_args_destroy(args); + args = other.args; + other.args = nullptr; + return *this; +} + // // LoadBalancingPolicy::QueuePicker // diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 30ff9c3fc95..1c17f95423e 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -22,6 +22,8 @@ #include #include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/orphanable.h" @@ -29,7 +31,6 @@ #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/transport/connectivity_state.h" -#include "src/core/lib/transport/service_config.h" extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount; @@ -212,6 +213,23 @@ class LoadBalancingPolicy : public InternallyRefCounted { RefCountedPtr service_config_; }; + /// Data passed to the UpdateLocked() method when new addresses and + /// config are available. + struct UpdateArgs { + ServerAddressList addresses; + RefCountedPtr config; + const grpc_channel_args* args = nullptr; + + // TODO(roth): Remove everything below once channel args is + // converted to a copyable and movable C++ object. + UpdateArgs() = default; + ~UpdateArgs() { grpc_channel_args_destroy(args); } + UpdateArgs(const UpdateArgs& other); + UpdateArgs(UpdateArgs&& other); + UpdateArgs& operator=(const UpdateArgs& other); + UpdateArgs& operator=(UpdateArgs&& other); + }; + /// Args used to instantiate an LB policy. struct Args { /// The combiner under which all LB policy calls will be run. @@ -239,14 +257,10 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Returns the name of the LB policy. virtual const char* name() const GRPC_ABSTRACT; - /// Updates the policy with a new set of \a args and a new \a lb_config from - /// the resolver. Will be invoked immediately after LB policy is constructed, - /// and then again whenever the resolver returns a new result. - /// Note that the LB policy gets the set of addresses from the - /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg. - virtual void UpdateLocked(const grpc_channel_args& args, - RefCountedPtr) // NOLINT - GRPC_ABSTRACT; + /// Updates the policy with new data from the resolver. Will be invoked + /// immediately after LB policy is constructed, and then again whenever + /// the resolver returns a new result. + virtual void UpdateLocked(UpdateArgs) GRPC_ABSTRACT; // NOLINT /// Tries to enter a READY connectivity state. /// This is a no-op by default, since most LB policies never go into diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 7d143dfe1aa..02fe06c4557 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -125,8 +125,7 @@ class GrpcLb : public LoadBalancingPolicy { const char* name() const override { return kGrpclb; } - void UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) override; + void UpdateLocked(UpdateArgs args) override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, @@ -295,7 +294,8 @@ class GrpcLb : public LoadBalancingPolicy { void ShutdownLocked() override; // Helper functions used in UpdateLocked(). - void ProcessChannelArgsLocked(const grpc_channel_args& args); + void ProcessAddressesAndChannelArgsLocked(const ServerAddressList& addresses, + const grpc_channel_args& args); void ParseLbConfig(Config* grpclb_config); static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); @@ -311,7 +311,8 @@ class GrpcLb : public LoadBalancingPolicy { static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error); // Methods for dealing with the child policy. - grpc_channel_args* CreateChildPolicyArgsLocked(); + grpc_channel_args* CreateChildPolicyArgsLocked( + bool is_backend_from_grpclb_load_balancer); OrphanablePtr CreateChildPolicyLocked( const char* name, const grpc_channel_args* args); void CreateOrUpdateChildPolicyLocked(); @@ -1204,7 +1205,6 @@ grpc_channel_args* BuildBalancerChannelArgs( const ServerAddressList& addresses, FakeResolverResponseGenerator* response_generator, const grpc_channel_args* args) { - ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses); // Channel args to remove. static const char* args_to_remove[] = { // LB policy name, since we want to use the default (pick_first) in @@ -1217,15 +1217,6 @@ grpc_channel_args* BuildBalancerChannelArgs( // the LB channel than for the parent channel. The client channel // factory will re-add this arg with the right value. GRPC_ARG_SERVER_URI, - // The resolved addresses, which will be generated by the name resolver - // used in the LB channel. Note that the LB channel will use the fake - // resolver, so this won't actually generate a query to DNS (or some - // other name service). However, the addresses returned by the fake - // resolver will have is_balancer=false, whereas our own addresses have - // is_balancer=true. We need the LB channel to return addresses with - // is_balancer=false so that it does not wind up recursively using the - // grpclb LB policy. - GRPC_ARG_SERVER_ADDRESS_LIST, // The fake resolver response generator, because we are replacing it // with the one from the grpclb policy, used to propagate updates to // the LB channel. @@ -1241,10 +1232,6 @@ grpc_channel_args* BuildBalancerChannelArgs( }; // Channel args to add. const grpc_arg args_to_add[] = { - // New address list. - // Note that we pass these in both when creating the LB channel - // and via the fake resolver. The latter is what actually gets used. - CreateServerAddressListChannelArg(&balancer_addresses), // The fake resolver response generator, which we use to inject // address updates into the LB channel. grpc_core::FakeResolverResponseGenerator::MakeChannelArg( @@ -1262,7 +1249,7 @@ grpc_channel_args* BuildBalancerChannelArgs( args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add, GPR_ARRAY_SIZE(args_to_add)); // Make any necessary modifications for security. - return grpc_lb_policy_grpclb_modify_lb_channel_args(new_args); + return grpc_lb_policy_grpclb_modify_lb_channel_args(addresses, new_args); } // @@ -1388,11 +1375,10 @@ void GrpcLb::FillChildRefsForChannelz( } } -void GrpcLb::UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) { +void GrpcLb::UpdateLocked(UpdateArgs args) { const bool is_initial_update = lb_channel_ == nullptr; - ParseLbConfig(lb_config.get()); - ProcessChannelArgsLocked(args); + ParseLbConfig(args.config.get()); + ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); // Update the existing child policy. if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); // If this is the initial update, start the fallback-at-startup checks @@ -1442,18 +1428,10 @@ ServerAddressList ExtractBackendAddresses(const ServerAddressList& addresses) { return backend_addresses; } -void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); - if (addresses == nullptr) { - // Ignore this update. - gpr_log( - GPR_ERROR, - "[grpclb %p] No valid LB addresses channel arg in update, ignoring.", - this); - return; - } +void GrpcLb::ProcessAddressesAndChannelArgsLocked( + const ServerAddressList& addresses, const grpc_channel_args& args) { // Update fallback address list. - fallback_backend_addresses_ = ExtractBackendAddresses(*addresses); + fallback_backend_addresses_ = ExtractBackendAddresses(addresses); // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args, // since we use this to trigger the client_load_reporting filter. static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME}; @@ -1463,8 +1441,9 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { args_ = grpc_channel_args_copy_and_add_and_remove( &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1); // Construct args for balancer channel. - grpc_channel_args* lb_channel_args = - BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args); + ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses); + grpc_channel_args* lb_channel_args = BuildBalancerChannelArgs( + balancer_addresses, response_generator_.get(), &args); // Create balancer channel if needed. if (lb_channel_ == nullptr) { char* uri_str; @@ -1481,8 +1460,10 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { } // Propagate updates to the LB channel (pick_first) through the fake // resolver. - response_generator_->SetResponse(lb_channel_args); - grpc_channel_args_destroy(lb_channel_args); + Resolver::Result result; + result.addresses = std::move(balancer_addresses); + result.args = lb_channel_args; + response_generator_->SetResponse(std::move(result)); } void GrpcLb::ParseLbConfig(Config* grpclb_config) { @@ -1649,25 +1630,9 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { // code for interacting with the child policy // -grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked() { - ServerAddressList tmp_addresses; - ServerAddressList* addresses = &tmp_addresses; - bool is_backend_from_grpclb_load_balancer = false; - if (fallback_mode_) { - // Note: If fallback backend address list is empty, the child policy - // will go into state TRANSIENT_FAILURE. - addresses = &fallback_backend_addresses_; - } else { - tmp_addresses = serverlist_->GetServerAddressList( - lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats()); - is_backend_from_grpclb_load_balancer = true; - } - GPR_ASSERT(addresses != nullptr); - // Replace the server address list in the channel args that we pass down to - // the subchannel. - static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; - grpc_arg args_to_add[3] = { - CreateServerAddressListChannelArg(addresses), +grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked( + bool is_backend_from_grpclb_load_balancer) { + grpc_arg args_to_add[2] = { // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. grpc_channel_arg_integer_create( @@ -1675,15 +1640,12 @@ grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked() { GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), is_backend_from_grpclb_load_balancer), }; - size_t num_args_to_add = 2; + size_t num_args_to_add = 1; if (is_backend_from_grpclb_load_balancer) { - args_to_add[2] = grpc_channel_arg_integer_create( + args_to_add[num_args_to_add++] = grpc_channel_arg_integer_create( const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); - ++num_args_to_add; } - return grpc_channel_args_copy_and_add_and_remove( - args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, - num_args_to_add); + return grpc_channel_args_copy_and_add(args_, args_to_add, num_args_to_add); } OrphanablePtr GrpcLb::CreateChildPolicyLocked( @@ -1717,8 +1679,25 @@ OrphanablePtr GrpcLb::CreateChildPolicyLocked( void GrpcLb::CreateOrUpdateChildPolicyLocked() { if (shutting_down_) return; - grpc_channel_args* args = CreateChildPolicyArgsLocked(); - GPR_ASSERT(args != nullptr); + // Construct update args. + UpdateArgs update_args; + bool is_backend_from_grpclb_load_balancer = false; + if (fallback_mode_) { + // If CreateOrUpdateChildPolicyLocked() is invoked when we haven't + // received any serverlist from the balancer, we use the fallback backends + // returned by the resolver. Note that the fallback backend list may be + // empty, in which case the new round_robin policy will keep the requested + // picks pending. + update_args.addresses = fallback_backend_addresses_; + } else { + update_args.addresses = serverlist_->GetServerAddressList( + lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats()); + is_backend_from_grpclb_load_balancer = true; + } + update_args.args = + CreateChildPolicyArgsLocked(is_backend_from_grpclb_load_balancer); + GPR_ASSERT(update_args.args != nullptr); + update_args.config = child_policy_config_; // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store // the new child policy in pending_child_policy_. Once the new child @@ -1789,7 +1768,8 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() { gpr_log(GPR_INFO, "[grpclb %p] Creating new %schild policy %s", this, child_policy_ == nullptr ? "" : "pending ", child_policy_name); } - auto new_policy = CreateChildPolicyLocked(child_policy_name, args); + auto new_policy = + CreateChildPolicyLocked(child_policy_name, update_args.args); // Swap the policy into place. auto& lb_policy = child_policy_ == nullptr ? child_policy_ : pending_child_policy_; @@ -1813,9 +1793,7 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() { policy_to_update == pending_child_policy_.get() ? "pending " : "", policy_to_update); } - policy_to_update->UpdateLocked(*args, child_policy_config_); - // Clean up. - grpc_channel_args_destroy(args); + policy_to_update->UpdateLocked(std::move(update_args)); } // diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc index fd873f096d8..b713e26713f 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc @@ -21,6 +21,6 @@ #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( - grpc_channel_args* args) { + const grpc_core::ServerAddressList& addresses, grpc_channel_args* args) { return args; } diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h index 3b2dc370eb3..c78ba36cf1d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h @@ -23,6 +23,8 @@ #include +#include "src/core/ext/filters/client_channel/server_address.h" + /// Makes any necessary modifications to \a args for use in the grpclb /// balancer channel. /// @@ -30,7 +32,7 @@ /// /// Caller takes ownership of the returned args. grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( - grpc_channel_args* args); + const grpc_core::ServerAddressList& addresses, grpc_channel_args* args); #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H \ */ diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc index 657ff693126..892cdeb27b7 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc @@ -68,18 +68,14 @@ RefCountedPtr CreateTargetAuthorityTable( } // namespace grpc_core grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args( - grpc_channel_args* args) { + const grpc_core::ServerAddressList& addresses, grpc_channel_args* args) { const char* args_to_remove[1]; size_t num_args_to_remove = 0; grpc_arg args_to_add[2]; size_t num_args_to_add = 0; // Add arg for targets info table. - grpc_core::ServerAddressList* addresses = - grpc_core::FindServerAddressListChannelArg(args); - GPR_ASSERT(addresses != nullptr); grpc_core::RefCountedPtr - target_authority_table = - grpc_core::CreateTargetAuthorityTable(*addresses); + target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses); args_to_add[num_args_to_add++] = grpc_core::CreateTargetAuthorityTableChannelArg( target_authority_table.get()); diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index c1dd9478044..86c6b25ac63 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -50,8 +50,7 @@ class PickFirst : public LoadBalancingPolicy { const char* name() const override { return kPickFirst; } - void UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) override; + void UpdateLocked(UpdateArgs args) override; void ExitIdleLocked() override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -238,38 +237,19 @@ void PickFirst::UpdateChildRefsLocked() { child_subchannels_ = std::move(cs); } -void PickFirst::UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) { +void PickFirst::UpdateLocked(UpdateArgs args) { AutoChildRefsUpdater guard(this); - const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); - if (addresses == nullptr) { - if (subchannel_list_ == nullptr) { - // If we don't have a current subchannel list, go into TRANSIENT FAILURE. - grpc_error* error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - UniquePtr(New(error))); - } else { - // otherwise, keep using the current subchannel list (ignore this update). - gpr_log(GPR_ERROR, - "No valid LB addresses channel arg for Pick First %p update, " - "ignoring.", - this); - } - return; - } if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p received update with %" PRIuPTR " addresses", this, - addresses->size()); + args.addresses.size()); } grpc_arg new_arg = grpc_channel_arg_integer_create( const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(&args, &new_arg, 1); + grpc_channel_args_copy_and_add(args.args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, *addresses, combiner(), *new_args); + this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args); grpc_channel_args_destroy(new_args); if (subchannel_list->num_subchannels() == 0) { // Empty update or no valid subchannels. Unsubscribe from all current diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 01068c6dc49..d3faaaddc98 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -61,8 +61,7 @@ class RoundRobin : public LoadBalancingPolicy { const char* name() const override { return kRoundRobin; } - void UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) override; + void UpdateLocked(UpdateArgs args) override; void ResetBackoffLocked() override; void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, channelz::ChildRefsList* ignored) override; @@ -476,26 +475,11 @@ void RoundRobin::RoundRobinSubchannelData::ProcessConnectivityChangeLocked( subchannel_list()->UpdateRoundRobinStateFromSubchannelStateCountsLocked(); } -void RoundRobin::UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) { +void RoundRobin::UpdateLocked(UpdateArgs args) { AutoChildRefsUpdater guard(this); - const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); - if (addresses == nullptr) { - gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", this); - // If we don't have a current subchannel list, go into TRANSIENT_FAILURE. - // Otherwise, keep using the current subchannel list (ignore this update). - if (subchannel_list_ == nullptr) { - grpc_error* error = - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"); - channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - UniquePtr(New(error))); - } - return; - } if (grpc_lb_round_robin_trace.enabled()) { gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses", - this, addresses->size()); + this, args.addresses.size()); } // Replace latest_pending_subchannel_list_. if (latest_pending_subchannel_list_ != nullptr) { @@ -506,7 +490,7 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args, } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, *addresses, combiner(), args); + this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args); if (latest_pending_subchannel_list_->num_subchannels() == 0) { // If the new list is empty, immediately promote the new list to the // current list and transition to TRANSIENT_FAILURE. diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index c262dfe60f5..4fde90c2584 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -505,7 +505,6 @@ SubchannelList::SubchannelList( inhibit_health_checking_ = grpc_channel_arg_get_bool( grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false); static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS, - GRPC_ARG_SERVER_ADDRESS_LIST, GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. for (size_t i = 0; i < addresses.size(); i++) { diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 1711c1ab28d..d3b13a60ebf 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -78,6 +78,7 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" @@ -98,7 +99,6 @@ #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/channel_init.h" -#include "src/core/lib/transport/service_config.h" #include "src/core/lib/transport/static_metadata.h" #define GRPC_XDS_INITIAL_CONNECT_BACKOFF_SECONDS 1 @@ -121,8 +121,7 @@ class XdsLb : public LoadBalancingPolicy { const char* name() const override { return kXds; } - void UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) override; + void UpdateLocked(UpdateArgs args) override; void ResetBackoffLocked() override; void FillChildRefsForChannelz( channelz::ChildRefsList* child_subchannels, @@ -293,7 +292,8 @@ class XdsLb : public LoadBalancingPolicy { void ShutdownLocked() override; // Helper function used in UpdateLocked(). - void ProcessChannelArgsLocked(const grpc_channel_args& args); + void ProcessAddressesAndChannelArgsLocked(const ServerAddressList& addresses, + const grpc_channel_args& args); // Parses the xds config given the JSON node of the first child of XdsConfig. // If parsing succeeds, updates \a balancer_name, and updates \a @@ -539,15 +539,14 @@ void ParseServer(const xds_grpclb_server* server, grpc_resolved_address* addr) { } // Returns addresses extracted from \a serverlist. -UniquePtr ProcessServerlist( - const xds_grpclb_serverlist* serverlist) { - auto addresses = MakeUnique(); +ServerAddressList ProcessServerlist(const xds_grpclb_serverlist* serverlist) { + ServerAddressList addresses; for (size_t i = 0; i < serverlist->num_servers; ++i) { const xds_grpclb_server* server = serverlist->servers[i]; if (!IsServerValid(serverlist->servers[i], i, false)) continue; grpc_resolved_address addr; ParseServer(server, &addr); - addresses->emplace_back(addr, nullptr); + addresses.emplace_back(addr, nullptr); } return addresses; } @@ -1082,9 +1081,6 @@ grpc_channel_args* BuildBalancerChannelArgs(const grpc_channel_args* args) { // the LB channel than for the parent channel. The client channel // factory will re-add this arg with the right value. GRPC_ARG_SERVER_URI, - // The resolved addresses, which will be generated by the name resolver - // used in the LB channel. - GRPC_ARG_SERVER_ADDRESS_LIST, // The LB channel should use the authority indicated by the target // authority table (see \a grpc_lb_policy_xds_modify_lb_channel_args), // as opposed to the authority from the parent channel. @@ -1232,17 +1228,10 @@ void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, } } -void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) { - const ServerAddressList* addresses = FindServerAddressListChannelArg(&args); - if (addresses == nullptr) { - // Ignore this update. - gpr_log(GPR_ERROR, - "[xdslb %p] No valid LB addresses channel arg in update, ignoring.", - this); - return; - } +void XdsLb::ProcessAddressesAndChannelArgsLocked( + const ServerAddressList& addresses, const grpc_channel_args& args) { // Update fallback address list. - fallback_backend_addresses_ = ExtractBackendAddresses(*addresses); + fallback_backend_addresses_ = ExtractBackendAddresses(addresses); // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args, // since we use this to trigger the client_load_reporting filter. static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME}; @@ -1310,17 +1299,16 @@ void XdsLb::ParseLbConfig(Config* xds_config) { } } -void XdsLb::UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) { +void XdsLb::UpdateLocked(UpdateArgs args) { const bool is_initial_update = lb_chand_ == nullptr; - ParseLbConfig(lb_config.get()); + ParseLbConfig(args.config.get()); // TODO(juanlishen): Pass fallback policy config update after fallback policy // is added. if (balancer_name_ == nullptr) { gpr_log(GPR_ERROR, "[xdslb %p] LB config parsing fails.", this); return; } - ProcessChannelArgsLocked(args); + ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); // Update the existing child policy. // Note: We have disabled fallback mode in the code, so this child policy must // have been created from a serverlist. @@ -1369,17 +1357,7 @@ void XdsLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { // grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { - // This should never be invoked if we do not have serverlist_, as fallback - // mode is disabled for xDS plugin. - GPR_ASSERT(serverlist_ != nullptr); - GPR_ASSERT(serverlist_->num_servers > 0); - UniquePtr addresses = ProcessServerlist(serverlist_); - GPR_ASSERT(addresses != nullptr); - // Replace the server address list in the channel args that we pass down to - // the subchannel. - static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST}; const grpc_arg args_to_add[] = { - CreateServerAddressListChannelArg(addresses.get()), // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. grpc_channel_arg_integer_create( @@ -1390,9 +1368,8 @@ grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() { grpc_channel_arg_integer_create( const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1), }; - return grpc_channel_args_copy_and_add_and_remove( - args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, - GPR_ARRAY_SIZE(args_to_add)); + return grpc_channel_args_copy_and_add(args_, args_to_add, + GPR_ARRAY_SIZE(args_to_add)); } OrphanablePtr XdsLb::CreateChildPolicyLocked( @@ -1426,8 +1403,16 @@ OrphanablePtr XdsLb::CreateChildPolicyLocked( void XdsLb::CreateOrUpdateChildPolicyLocked() { if (shutting_down_) return; - grpc_channel_args* args = CreateChildPolicyArgsLocked(); - GPR_ASSERT(args != nullptr); + // This should never be invoked if we do not have serverlist_, as fallback + // mode is disabled for xDS plugin. + // TODO(juanlishen): Change this as part of implementing fallback mode. + GPR_ASSERT(serverlist_ != nullptr); + GPR_ASSERT(serverlist_->num_servers > 0); + // Construct update args. + UpdateArgs update_args; + update_args.addresses = ProcessServerlist(serverlist_); + update_args.config = child_policy_config_; + update_args.args = CreateChildPolicyArgsLocked(); // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store // the new child policy in pending_child_policy_. Once the new child @@ -1500,7 +1485,8 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { gpr_log(GPR_INFO, "[xdslb %p] Creating new %schild policy %s", this, child_policy_ == nullptr ? "" : "pending ", child_policy_name); } - auto new_policy = CreateChildPolicyLocked(child_policy_name, args); + auto new_policy = + CreateChildPolicyLocked(child_policy_name, update_args.args); auto& lb_policy = child_policy_ == nullptr ? child_policy_ : pending_child_policy_; { @@ -1523,9 +1509,7 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() { policy_to_update == pending_child_policy_.get() ? "pending " : "", policy_to_update); } - policy_to_update->UpdateLocked(*args, child_policy_config_); - // Clean up. - grpc_channel_args_destroy(args); + policy_to_update->UpdateLocked(std::move(update_args)); } // diff --git a/src/core/ext/filters/client_channel/resolver.cc b/src/core/ext/filters/client_channel/resolver.cc index 5d14d51d011..b50c42f6a1c 100644 --- a/src/core/ext/filters/client_channel/resolver.cc +++ b/src/core/ext/filters/client_channel/resolver.cc @@ -26,6 +26,10 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount(false, namespace grpc_core { +// +// Resolver +// + Resolver::Resolver(grpc_combiner* combiner, UniquePtr result_handler) : InternallyRefCounted(&grpc_trace_resolver_refcount), @@ -34,4 +38,51 @@ Resolver::Resolver(grpc_combiner* combiner, Resolver::~Resolver() { GRPC_COMBINER_UNREF(combiner_, "resolver"); } +// +// Resolver::Result +// + +Resolver::Result::~Result() { + GRPC_ERROR_UNREF(service_config_error); + grpc_channel_args_destroy(args); +} + +Resolver::Result::Result(const Result& other) { + addresses = other.addresses; + service_config = other.service_config; + service_config_error = GRPC_ERROR_REF(other.service_config_error); + args = grpc_channel_args_copy(other.args); +} + +Resolver::Result::Result(Result&& other) { + addresses = std::move(other.addresses); + service_config = std::move(other.service_config); + service_config_error = other.service_config_error; + other.service_config_error = GRPC_ERROR_NONE; + args = other.args; + other.args = nullptr; +} + +Resolver::Result& Resolver::Result::operator=(const Result& other) { + addresses = other.addresses; + service_config = other.service_config; + GRPC_ERROR_UNREF(service_config_error); + service_config_error = GRPC_ERROR_REF(other.service_config_error); + grpc_channel_args_destroy(args); + args = grpc_channel_args_copy(other.args); + return *this; +} + +Resolver::Result& Resolver::Result::operator=(Result&& other) { + addresses = std::move(other.addresses); + service_config = std::move(other.service_config); + GRPC_ERROR_UNREF(service_config_error); + service_config_error = other.service_config_error; + other.service_config_error = GRPC_ERROR_NONE; + grpc_channel_args_destroy(args); + args = other.args; + other.args = nullptr; + return *this; +} + } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h index 790779cfe75..9aa504225ad 100644 --- a/src/core/ext/filters/client_channel/resolver.h +++ b/src/core/ext/filters/client_channel/resolver.h @@ -23,8 +23,11 @@ #include +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/iomgr.h" @@ -46,6 +49,23 @@ namespace grpc_core { /// combiner passed to the constructor. class Resolver : public InternallyRefCounted { public: + /// Results returned by the resolver. + struct Result { + ServerAddressList addresses; + RefCountedPtr service_config; + grpc_error* service_config_error = GRPC_ERROR_NONE; + const grpc_channel_args* args = nullptr; + + // TODO(roth): Remove everything below once grpc_error and + // grpc_channel_args are convert to copyable and movable C++ objects. + Result() = default; + ~Result(); + Result(const Result& other); + Result(Result&& other); + Result& operator=(const Result& other); + Result& operator=(Result&& other); + }; + /// A proxy object used by the resolver to return results to the /// client channel. class ResultHandler { @@ -53,18 +73,17 @@ class Resolver : public InternallyRefCounted { virtual ~ResultHandler() {} /// Returns a result to the channel. - /// The list of addresses will be in GRPC_ARG_SERVER_ADDRESS_LIST. - /// The service config (if any) will be in GRPC_ARG_SERVICE_CONFIG. - /// Takes ownership of \a result. - // TODO(roth): Change this API so that addresses and service config are - // passed explicitly instead of being in channel args. - virtual void ReturnResult(const grpc_channel_args* result) GRPC_ABSTRACT; + /// Takes ownership of \a result.args. + virtual void ReturnResult(Result result) GRPC_ABSTRACT; // NOLINT /// Returns a transient error to the channel. /// If the resolver does not set the GRPC_ERROR_INT_GRPC_STATUS /// attribute on the error, calls will be failed with status UNKNOWN. virtual void ReturnError(grpc_error* error) GRPC_ABSTRACT; + // TODO(yashkt): As part of the service config error handling + // changes, add a method to parse the service config JSON string. + GRPC_ABSTRACT_BASE_CLASS }; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 249b9e3958c..7de1c221a13 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -34,6 +34,7 @@ #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/env.h" @@ -45,7 +46,6 @@ #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/json/json.h" -#include "src/core/lib/transport/service_config.h" #define GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS 1 #define GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER 1.6 @@ -299,28 +299,21 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { return; } if (r->addresses_ != nullptr) { - static const char* args_to_remove[1]; - size_t num_args_to_remove = 0; - grpc_arg args_to_add[2]; - size_t num_args_to_add = 0; - args_to_add[num_args_to_add++] = - CreateServerAddressListChannelArg(r->addresses_.get()); - char* service_config_string = nullptr; + Result result; + result.addresses = std::move(*r->addresses_); if (r->service_config_json_ != nullptr) { - service_config_string = ChooseServiceConfig(r->service_config_json_); + char* service_config_string = + ChooseServiceConfig(r->service_config_json_); gpr_free(r->service_config_json_); if (service_config_string != nullptr) { GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s", r, service_config_string); - args_to_remove[num_args_to_remove++] = GRPC_ARG_SERVICE_CONFIG; - args_to_add[num_args_to_add++] = grpc_channel_arg_string_create( - (char*)GRPC_ARG_SERVICE_CONFIG, service_config_string); + result.service_config = ServiceConfig::Create(service_config_string); } + gpr_free(service_config_string); } - r->result_handler()->ReturnResult(grpc_channel_args_copy_and_add_and_remove( - r->channel_args_, args_to_remove, num_args_to_remove, args_to_add, - num_args_to_add)); - gpr_free(service_config_string); + result.args = grpc_channel_args_copy(r->channel_args_); + r->result_handler()->ReturnResult(std::move(result)); r->addresses_.reset(); // Reset backoff state so that we start from the beginning when the // next request gets triggered. diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index 1c0fe1c6717..164d308c0dd 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -169,15 +169,15 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { return; } if (r->addresses_ != nullptr) { - ServerAddressList addresses; + Result result; for (size_t i = 0; i < r->addresses_->naddrs; ++i) { - addresses.emplace_back(&r->addresses_->addrs[i].addr, - r->addresses_->addrs[i].len, nullptr /* args */); + result.addresses.emplace_back(&r->addresses_->addrs[i].addr, + r->addresses_->addrs[i].len, + nullptr /* args */); } grpc_resolved_addresses_destroy(r->addresses_); - grpc_arg new_arg = CreateServerAddressListChannelArg(&addresses); - r->result_handler()->ReturnResult( - grpc_channel_args_copy_and_add(r->channel_args_, &new_arg, 1)); + result.args = grpc_channel_args_copy(r->channel_args_); + r->result_handler()->ReturnResult(std::move(result)); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc index 153279e323e..85b9bea6f70 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc @@ -69,11 +69,14 @@ class FakeResolver : public Resolver { // passed-in parameters grpc_channel_args* channel_args_ = nullptr; - // If not NULL, the next set of resolution results to be returned. - grpc_channel_args* next_results_ = nullptr; - // Results to use for the pretended re-resolution in + // If has_next_result_ is true, next_result_ is the next resolution result + // to be returned. + bool has_next_result_ = false; + Result next_result_; + // Result to use for the pretended re-resolution in // RequestReresolutionLocked(). - grpc_channel_args* reresolution_results_ = nullptr; + bool has_reresolution_result_ = false; + Result reresolution_result_; // True between the calls to StartLocked() ShutdownLocked(). bool active_ = false; // if true, return failure @@ -92,19 +95,14 @@ FakeResolver::FakeResolver(ResolverArgs args) FakeResolverResponseGenerator::GetFromArgs(args.args); if (response_generator != nullptr) { response_generator->resolver_ = this; - if (response_generator->response_ != nullptr) { - response_generator->SetResponse(response_generator->response_); - grpc_channel_args_destroy(response_generator->response_); - response_generator->response_ = nullptr; + if (response_generator->has_result_) { + response_generator->SetResponse(std::move(response_generator->result_)); + response_generator->has_result_ = false; } } } -FakeResolver::~FakeResolver() { - grpc_channel_args_destroy(next_results_); - grpc_channel_args_destroy(reresolution_results_); - grpc_channel_args_destroy(channel_args_); -} +FakeResolver::~FakeResolver() { grpc_channel_args_destroy(channel_args_); } void FakeResolver::StartLocked() { active_ = true; @@ -112,9 +110,9 @@ void FakeResolver::StartLocked() { } void FakeResolver::RequestReresolutionLocked() { - if (reresolution_results_ != nullptr || return_failure_) { - grpc_channel_args_destroy(next_results_); - next_results_ = grpc_channel_args_copy(reresolution_results_); + if (has_reresolution_result_ || return_failure_) { + next_result_ = reresolution_result_; + has_next_result_ = true; // Return the result in a different closure, so that we don't call // back into the LB policy while it's still processing the previous // update. @@ -135,14 +133,19 @@ void FakeResolver::MaybeSendResultLocked() { GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver transient failure"), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE)); return_failure_ = false; - } else if (next_results_ != nullptr) { + } else if (has_next_result_) { + Result result; + result.addresses = std::move(next_result_.addresses); + result.service_config = std::move(next_result_.service_config); + // TODO(roth): Use std::move() once grpc_error is converted to C++. + result.service_config_error = next_result_.service_config_error; + next_result_.service_config_error = GRPC_ERROR_NONE; // When both next_results_ and channel_args_ contain an arg with the same // name, only the one in next_results_ will be kept since next_results_ is // before channel_args_. - result_handler()->ReturnResult( - grpc_channel_args_union(next_results_, channel_args_)); - grpc_channel_args_destroy(next_results_); - next_results_ = nullptr; + result.args = grpc_channel_args_union(next_result_.args, channel_args_); + result_handler()->ReturnResult(std::move(result)); + has_next_result_ = false; } } @@ -160,7 +163,8 @@ void FakeResolver::ReturnReresolutionResult(void* arg, grpc_error* error) { struct SetResponseClosureArg { grpc_closure set_response_closure; FakeResolverResponseGenerator* generator; - grpc_channel_args* response; + Resolver::Result result; + bool has_result = false; bool immediate = true; }; @@ -168,26 +172,26 @@ void FakeResolverResponseGenerator::SetResponseLocked(void* arg, grpc_error* error) { SetResponseClosureArg* closure_arg = static_cast(arg); FakeResolver* resolver = closure_arg->generator->resolver_; - grpc_channel_args_destroy(resolver->next_results_); - resolver->next_results_ = closure_arg->response; + resolver->next_result_ = std::move(closure_arg->result); + resolver->has_next_result_ = true; resolver->MaybeSendResultLocked(); Delete(closure_arg); } -void FakeResolverResponseGenerator::SetResponse(grpc_channel_args* response) { - GPR_ASSERT(response != nullptr); +void FakeResolverResponseGenerator::SetResponse(Resolver::Result result) { if (resolver_ != nullptr) { SetResponseClosureArg* closure_arg = New(); closure_arg->generator = this; - closure_arg->response = grpc_channel_args_copy(response); + closure_arg->result = std::move(result); GRPC_CLOSURE_SCHED( GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, SetResponseLocked, closure_arg, grpc_combiner_scheduler(resolver_->combiner())), GRPC_ERROR_NONE); } else { - GPR_ASSERT(response_ == nullptr); - response_ = grpc_channel_args_copy(response); + GPR_ASSERT(!has_result_); + has_result_ = true; + result_ = std::move(result); } } @@ -195,18 +199,29 @@ void FakeResolverResponseGenerator::SetReresolutionResponseLocked( void* arg, grpc_error* error) { SetResponseClosureArg* closure_arg = static_cast(arg); FakeResolver* resolver = closure_arg->generator->resolver_; - grpc_channel_args_destroy(resolver->reresolution_results_); - resolver->reresolution_results_ = closure_arg->response; + resolver->reresolution_result_ = std::move(closure_arg->result); + resolver->has_reresolution_result_ = closure_arg->has_result; Delete(closure_arg); } void FakeResolverResponseGenerator::SetReresolutionResponse( - grpc_channel_args* response) { + Resolver::Result result) { + GPR_ASSERT(resolver_ != nullptr); + SetResponseClosureArg* closure_arg = New(); + closure_arg->generator = this; + closure_arg->result = std::move(result); + closure_arg->has_result = true; + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, + SetReresolutionResponseLocked, closure_arg, + grpc_combiner_scheduler(resolver_->combiner())), + GRPC_ERROR_NONE); +} + +void FakeResolverResponseGenerator::UnsetReresolutionResponse() { GPR_ASSERT(resolver_ != nullptr); SetResponseClosureArg* closure_arg = New(); closure_arg->generator = this; - closure_arg->response = - response != nullptr ? grpc_channel_args_copy(response) : nullptr; GRPC_CLOSURE_SCHED( GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, SetReresolutionResponseLocked, closure_arg, diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h index 9e3ec1fb7cb..3b1ea8e8909 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h @@ -19,6 +19,7 @@ #include +#include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/iomgr/error.h" @@ -44,19 +45,20 @@ class FakeResolverResponseGenerator FakeResolverResponseGenerator() {} // Instructs the fake resolver associated with the response generator - // instance to trigger a new resolution with the specified response. If the + // instance to trigger a new resolution with the specified result. If the // resolver is not available yet, delays response setting until it is. This // can be called at most once before the resolver is available. - void SetResponse(grpc_channel_args* next_response); + void SetResponse(Resolver::Result result); // Sets the re-resolution response, which is returned by the fake resolver // when re-resolution is requested (via \a RequestReresolutionLocked()). // The new re-resolution response replaces any previous re-resolution // response that may have been set by a previous call. - // If the re-resolution response is set to NULL, then the fake - // resolver will not return anything when \a RequestReresolutionLocked() - // is called. - void SetReresolutionResponse(grpc_channel_args* response); + void SetReresolutionResponse(Resolver::Result result); + + // Unsets the re-resolution response. After this, the fake resolver will + // not return anything when \a RequestReresolutionLocked() is called. + void UnsetReresolutionResponse(); // Tells the resolver to return a transient failure. void SetFailure(); @@ -80,7 +82,8 @@ class FakeResolverResponseGenerator static void SetFailureLocked(void* arg, grpc_error* error); FakeResolver* resolver_ = nullptr; // Do not own. - grpc_channel_args* response_ = nullptr; + Resolver::Result result_; + bool has_result_ = false; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc index df93c76399d..1465b0c644e 100644 --- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc @@ -44,8 +44,7 @@ namespace { class SockaddrResolver : public Resolver { public: - /// Takes ownership of \a addresses. - explicit SockaddrResolver(ResolverArgs args); + SockaddrResolver(ServerAddressList addresses, ResolverArgs args); ~SockaddrResolver() override; void StartLocked() override; @@ -53,21 +52,27 @@ class SockaddrResolver : public Resolver { void ShutdownLocked() override {} private: - /// channel args + ServerAddressList addresses_; const grpc_channel_args* channel_args_ = nullptr; }; -SockaddrResolver::SockaddrResolver(ResolverArgs args) +SockaddrResolver::SockaddrResolver(ServerAddressList addresses, + ResolverArgs args) : Resolver(args.combiner, std::move(args.result_handler)), - channel_args_(args.args) {} + addresses_(std::move(addresses)), + channel_args_(grpc_channel_args_copy(args.args)) {} SockaddrResolver::~SockaddrResolver() { grpc_channel_args_destroy(channel_args_); } void SockaddrResolver::StartLocked() { - result_handler()->ReturnResult(channel_args_); + Result result; + result.addresses = std::move(addresses_); + // TODO(roth): Use std::move() once channel args is converted to C++. + result.args = channel_args_; channel_args_ = nullptr; + result_handler()->ReturnResult(std::move(result)); } // @@ -82,7 +87,7 @@ OrphanablePtr CreateSockaddrResolver( if (0 != strcmp(args.uri->authority, "")) { gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme", args.uri->scheme); - return OrphanablePtr(nullptr); + return nullptr; } // Construct addresses. grpc_slice path_slice = @@ -108,12 +113,9 @@ OrphanablePtr CreateSockaddrResolver( if (errors_found) { return OrphanablePtr(nullptr); } - // Add addresses to channel args. - // Note: SockaddrResolver takes ownership of channel args. - grpc_arg arg = CreateServerAddressListChannelArg(&addresses); - args.args = grpc_channel_args_copy_and_add(args.args, &arg, 1); // Instantiate resolver. - return OrphanablePtr(New(std::move(args))); + return OrphanablePtr( + New(std::move(addresses), std::move(args))); } class IPv4ResolverFactory : public ResolverFactory { diff --git a/src/core/ext/filters/client_channel/resolver_registry.h b/src/core/ext/filters/client_channel/resolver_registry.h index 1fbe01aabc2..0eec6782609 100644 --- a/src/core/ext/filters/client_channel/resolver_registry.h +++ b/src/core/ext/filters/client_channel/resolver_registry.h @@ -62,6 +62,7 @@ class ResolverRegistry { /// \a args are the channel args to be included in resolver results. /// \a pollset_set is used to drive I/O in the name resolution process. /// \a combiner is the combiner under which all resolver calls will be run. + /// \a result_handler is used to return results from the resolver. static OrphanablePtr CreateResolver( const char* target, const grpc_channel_args* args, grpc_pollset_set* pollset_set, grpc_combiner* combiner, diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index ad23c735b51..daac4f0ff6a 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -31,6 +31,7 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/status_util.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/memory.h" @@ -43,42 +44,64 @@ namespace grpc_core { namespace internal { ProcessedResolverResult::ProcessedResolverResult( - const grpc_channel_args& resolver_result, bool parse_retry) { - ProcessServiceConfig(resolver_result, parse_retry); + Resolver::Result* resolver_result, bool parse_retry) + : service_config_(resolver_result->service_config) { + // If resolver did not return a service config, use the default + // specified via the client API. + if (service_config_ == nullptr) { + const char* service_config_json = grpc_channel_arg_get_string( + grpc_channel_args_find(resolver_result->args, GRPC_ARG_SERVICE_CONFIG)); + if (service_config_json != nullptr) { + service_config_ = ServiceConfig::Create(service_config_json); + } + } else { + // Add the service config JSON to channel args so that it's + // accessible in the subchannel. + // TODO(roth): Consider whether there's a better way to pass the + // service config down into the subchannel stack, such as maybe via + // call context or metadata. This would avoid the problem of having + // to recreate all subchannels whenever the service config changes. + // It would also avoid the need to pass in the resolver result in + // mutable form, both here and in + // ResolvingLoadBalancingPolicy::ProcessResolverResultCallback(). + grpc_arg arg = grpc_channel_arg_string_create( + const_cast(GRPC_ARG_SERVICE_CONFIG), + const_cast(service_config_->service_config_json())); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(resolver_result->args, &arg, 1); + grpc_channel_args_destroy(resolver_result->args); + resolver_result->args = new_args; + } + // Process service config. + ProcessServiceConfig(*resolver_result, parse_retry); // If no LB config was found above, just find the LB policy name then. - if (lb_policy_name_ == nullptr) ProcessLbPolicyName(resolver_result); + if (lb_policy_name_ == nullptr) ProcessLbPolicyName(*resolver_result); } void ProcessedResolverResult::ProcessServiceConfig( - const grpc_channel_args& resolver_result, bool parse_retry) { - const grpc_arg* channel_arg = - grpc_channel_args_find(&resolver_result, GRPC_ARG_SERVICE_CONFIG); - const char* service_config_json = grpc_channel_arg_get_string(channel_arg); - if (service_config_json != nullptr) { - service_config_json_.reset(gpr_strdup(service_config_json)); - service_config_ = grpc_core::ServiceConfig::Create(service_config_json); - if (service_config_ != nullptr) { - if (parse_retry) { - channel_arg = - grpc_channel_args_find(&resolver_result, GRPC_ARG_SERVER_URI); - const char* server_uri = grpc_channel_arg_get_string(channel_arg); - GPR_ASSERT(server_uri != nullptr); - grpc_uri* uri = grpc_uri_parse(server_uri, true); - GPR_ASSERT(uri->path[0] != '\0'); - server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path; - service_config_->ParseGlobalParams(ParseServiceConfig, this); - grpc_uri_destroy(uri); - } else { - service_config_->ParseGlobalParams(ParseServiceConfig, this); - } - method_params_table_ = service_config_->CreateMethodConfigTable( - ClientChannelMethodParams::CreateFromJson); - } + const Resolver::Result& resolver_result, bool parse_retry) { + if (service_config_ == nullptr) return; + service_config_json_ = + UniquePtr(gpr_strdup(service_config_->service_config_json())); + if (parse_retry) { + const grpc_arg* channel_arg = + grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVER_URI); + const char* server_uri = grpc_channel_arg_get_string(channel_arg); + GPR_ASSERT(server_uri != nullptr); + grpc_uri* uri = grpc_uri_parse(server_uri, true); + GPR_ASSERT(uri->path[0] != '\0'); + server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path; + service_config_->ParseGlobalParams(ParseServiceConfig, this); + grpc_uri_destroy(uri); + } else { + service_config_->ParseGlobalParams(ParseServiceConfig, this); } + method_params_table_ = service_config_->CreateMethodConfigTable( + ClientChannelMethodParams::CreateFromJson); } void ProcessedResolverResult::ProcessLbPolicyName( - const grpc_channel_args& resolver_result) { + const Resolver::Result& resolver_result) { // Prefer the LB policy name found in the service config. Note that this is // checking the deprecated loadBalancingPolicy field, rather than the new // loadBalancingConfig field. @@ -96,32 +119,28 @@ void ProcessedResolverResult::ProcessLbPolicyName( // Otherwise, find the LB policy name set by the client API. if (lb_policy_name_ == nullptr) { const grpc_arg* channel_arg = - grpc_channel_args_find(&resolver_result, GRPC_ARG_LB_POLICY_NAME); + grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME); lb_policy_name_.reset(gpr_strdup(grpc_channel_arg_get_string(channel_arg))); } // Special case: If at least one balancer address is present, we use // the grpclb policy, regardless of what the resolver has returned. - const ServerAddressList* addresses = - FindServerAddressListChannelArg(&resolver_result); - if (addresses != nullptr) { - bool found_balancer_address = false; - for (size_t i = 0; i < addresses->size(); ++i) { - const ServerAddress& address = (*addresses)[i]; - if (address.IsBalancer()) { - found_balancer_address = true; - break; - } + bool found_balancer_address = false; + for (size_t i = 0; i < resolver_result.addresses.size(); ++i) { + const ServerAddress& address = resolver_result.addresses[i]; + if (address.IsBalancer()) { + found_balancer_address = true; + break; } - if (found_balancer_address) { - if (lb_policy_name_ != nullptr && - strcmp(lb_policy_name_.get(), "grpclb") != 0) { - gpr_log(GPR_INFO, - "resolver requested LB policy %s but provided at least one " - "balancer address -- forcing use of grpclb LB policy", - lb_policy_name_.get()); - } - lb_policy_name_.reset(gpr_strdup("grpclb")); + } + if (found_balancer_address) { + if (lb_policy_name_ != nullptr && + strcmp(lb_policy_name_.get(), "grpclb") != 0) { + gpr_log(GPR_INFO, + "resolver requested LB policy %s but provided at least one " + "balancer address -- forcing use of grpclb LB policy", + lb_policy_name_.get()); } + lb_policy_name_.reset(gpr_strdup("grpclb")); } // Use pick_first if nothing was specified and we didn't select grpclb // above. diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 3bac45e7664..1a46278f38b 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -22,14 +22,15 @@ #include #include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/status_util.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/exec_ctx.h" // for grpc_millis #include "src/core/lib/json/json.h" #include "src/core/lib/slice/slice_hash_table.h" -#include "src/core/lib/transport/service_config.h" namespace grpc_core { namespace internal { @@ -47,8 +48,7 @@ class ProcessedResolverResult { // Processes the resolver result and populates the relative members // for later consumption. Tries to parse retry parameters only if parse_retry // is true. - ProcessedResolverResult(const grpc_channel_args& resolver_result, - bool parse_retry); + ProcessedResolverResult(Resolver::Result* resolver_result, bool parse_retry); // Getters. Any managed object's ownership is transferred. UniquePtr service_config_json() { @@ -68,11 +68,11 @@ class ProcessedResolverResult { private: // Finds the service config; extracts LB config and (maybe) retry throttle // params from it. - void ProcessServiceConfig(const grpc_channel_args& resolver_result, + void ProcessServiceConfig(const Resolver::Result& resolver_result, bool parse_retry); // Finds the LB policy name (when no LB config was found). - void ProcessLbPolicyName(const grpc_channel_args& resolver_result); + void ProcessLbPolicyName(const Resolver::Result& resolver_result); // Parses the service config. Intended to be used by // ServiceConfig::ParseGlobalParams. diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 63cf56b1a44..d15af908b3f 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -38,6 +38,7 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" #include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/deadline/deadline_filter.h" #include "src/core/lib/backoff/backoff.h" @@ -59,7 +60,6 @@ #include "src/core/lib/transport/error_utils.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/metadata_batch.h" -#include "src/core/lib/transport/service_config.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" @@ -83,8 +83,8 @@ class ResolvingLoadBalancingPolicy::ResolverResultHandler } } - void ReturnResult(const grpc_channel_args* result) override { - parent_->OnResolverResultChangedLocked(result); + void ReturnResult(Resolver::Result result) override { + parent_->OnResolverResultChangedLocked(std::move(result)); } void ReturnError(grpc_error* error) override { @@ -342,7 +342,7 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, RefCountedPtr lb_policy_config, - const grpc_channel_args& args, TraceStringVector* trace_strings) { + Resolver::Result result, TraceStringVector* trace_strings) { // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store // the new child policy in pending_child_policy_. Once the new child @@ -410,7 +410,8 @@ void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( gpr_log(GPR_INFO, "resolving_lb=%p: Creating new %schild policy %s", this, lb_policy_ == nullptr ? "" : "pending ", lb_policy_name); } - auto new_policy = CreateLbPolicyLocked(lb_policy_name, args, trace_strings); + auto new_policy = + CreateLbPolicyLocked(lb_policy_name, *result.args, trace_strings); auto& lb_policy = lb_policy_ == nullptr ? lb_policy_ : pending_lb_policy_; { MutexLock lock(&lb_policy_mu_); @@ -431,7 +432,13 @@ void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( policy_to_update == pending_lb_policy_.get() ? "pending " : "", policy_to_update); } - policy_to_update->UpdateLocked(args, std::move(lb_policy_config)); + UpdateArgs update_args; + update_args.addresses = std::move(result.addresses); + update_args.config = std::move(lb_policy_config); + // TODO(roth): Once channel args is converted to C++, use std::move() here. + update_args.args = result.args; + result.args = nullptr; + policy_to_update->UpdateLocked(std::move(update_args)); } // Creates a new LB policy. @@ -479,12 +486,7 @@ ResolvingLoadBalancingPolicy::CreateLbPolicyLocked( } void ResolvingLoadBalancingPolicy::MaybeAddTraceMessagesForAddressChangesLocked( - const grpc_channel_args& resolver_result, - TraceStringVector* trace_strings) { - const ServerAddressList* addresses = - FindServerAddressListChannelArg(&resolver_result); - const bool resolution_contains_addresses = - addresses != nullptr && addresses->size() > 0; + bool resolution_contains_addresses, TraceStringVector* trace_strings) { if (!resolution_contains_addresses && previous_resolution_contained_addresses_) { trace_strings->push_back(gpr_strdup("Address list became empty")); @@ -517,14 +519,11 @@ void ResolvingLoadBalancingPolicy::ConcatenateAndAddChannelTraceLocked( } void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( - const grpc_channel_args* result) { + Resolver::Result result) { // Handle race conditions. - if (resolver_ == nullptr) { - grpc_channel_args_destroy(result); - return; - } + if (resolver_ == nullptr) return; if (tracer_->enabled()) { - gpr_log(GPR_INFO, "resolving_lb=%p: got resolver result %p", this, result); + gpr_log(GPR_INFO, "resolving_lb=%p: got resolver result", this); } // We only want to trace the address resolution in the follow cases: // (a) Address resolution resulted in service config change. @@ -534,15 +533,16 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( // non-zero to zero. // (d) Address resolution that causes a new LB policy to be created. // - // we track a list of strings to eventually be concatenated and traced. + // We track a list of strings to eventually be concatenated and traced. TraceStringVector trace_strings; - // Parse the resolver result. + const bool resolution_contains_addresses = result.addresses.size() > 0; + // Process the resolver result. const char* lb_policy_name = nullptr; RefCountedPtr lb_policy_config; bool service_config_changed = false; if (process_resolver_result_ != nullptr) { service_config_changed = - process_resolver_result_(process_resolver_result_user_data_, *result, + process_resolver_result_(process_resolver_result_user_data_, &result, &lb_policy_name, &lb_policy_config); } else { lb_policy_name = child_policy_name_.get(); @@ -551,7 +551,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( GPR_ASSERT(lb_policy_name != nullptr); // Create or update LB policy, as needed. CreateOrUpdateLbPolicyLocked(lb_policy_name, std::move(lb_policy_config), - *result, &trace_strings); + std::move(result), &trace_strings); // Add channel trace event. if (channelz_node() != nullptr) { if (service_config_changed) { @@ -559,11 +559,10 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( // config in the trace, at the risk of bloating the trace logs. trace_strings.push_back(gpr_strdup("Service config changed")); } - MaybeAddTraceMessagesForAddressChangesLocked(*result, &trace_strings); + MaybeAddTraceMessagesForAddressChangesLocked(resolution_contains_addresses, + &trace_strings); ConcatenateAndAddChannelTraceLocked(&trace_strings); } - // Clean up. - grpc_channel_args_destroy(result); } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index fa34611c979..c9349769dd2 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -65,8 +65,8 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // lb_policy_name and lb_policy_config to point to the right data. // Returns true if the service config has changed since the last result. typedef bool (*ProcessResolverResultCallback)( - void* user_data, const grpc_channel_args& args, - const char** lb_policy_name, RefCountedPtr* lb_policy_config); + void* user_data, Resolver::Result* result, const char** lb_policy_name, + RefCountedPtr* lb_policy_config); // If error is set when this returns, then construction failed, and // the caller may not use the new object. ResolvingLoadBalancingPolicy( @@ -79,8 +79,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // No-op -- should never get updates from the channel. // TODO(roth): Need to support updating child LB policy's config for xds // use case. - void UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) override {} + void UpdateLocked(UpdateArgs args) override {} void ExitIdleLocked() override; @@ -105,17 +104,16 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void OnResolverError(grpc_error* error); void CreateOrUpdateLbPolicyLocked(const char* lb_policy_name, RefCountedPtr lb_policy_config, - const grpc_channel_args& args, + Resolver::Result result, TraceStringVector* trace_strings); OrphanablePtr CreateLbPolicyLocked( const char* lb_policy_name, const grpc_channel_args& args, TraceStringVector* trace_strings); void MaybeAddTraceMessagesForAddressChangesLocked( - const grpc_channel_args& resolver_result, - TraceStringVector* trace_strings); + bool resolution_contains_addresses, TraceStringVector* trace_strings); void ConcatenateAndAddChannelTraceLocked( TraceStringVector* trace_strings) const; - void OnResolverResultChangedLocked(const grpc_channel_args* result); + void OnResolverResultChangedLocked(Resolver::Result result); // Passed in from caller at construction time. TraceFlag* tracer_; diff --git a/src/core/ext/filters/client_channel/server_address.cc b/src/core/ext/filters/client_channel/server_address.cc index ec33cbbd956..c2941afbcfd 100644 --- a/src/core/ext/filters/client_channel/server_address.cc +++ b/src/core/ext/filters/client_channel/server_address.cc @@ -52,52 +52,4 @@ bool ServerAddress::IsBalancer() const { grpc_channel_args_find(args_, GRPC_ARG_ADDRESS_IS_BALANCER), false); } -// -// ServerAddressList -// - -namespace { - -void* ServerAddressListCopy(void* addresses) { - ServerAddressList* a = static_cast(addresses); - return New(*a); -} - -void ServerAddressListDestroy(void* addresses) { - ServerAddressList* a = static_cast(addresses); - Delete(a); -} - -int ServerAddressListCompare(void* addresses1, void* addresses2) { - ServerAddressList* a1 = static_cast(addresses1); - ServerAddressList* a2 = static_cast(addresses2); - if (a1->size() > a2->size()) return 1; - if (a1->size() < a2->size()) return -1; - for (size_t i = 0; i < a1->size(); ++i) { - int retval = (*a1)[i].Cmp((*a2)[i]); - if (retval != 0) return retval; - } - return 0; -} - -const grpc_arg_pointer_vtable server_addresses_arg_vtable = { - ServerAddressListCopy, ServerAddressListDestroy, ServerAddressListCompare}; - -} // namespace - -grpc_arg CreateServerAddressListChannelArg(const ServerAddressList* addresses) { - return grpc_channel_arg_pointer_create( - const_cast(GRPC_ARG_SERVER_ADDRESS_LIST), - const_cast(addresses), &server_addresses_arg_vtable); -} - -ServerAddressList* FindServerAddressListChannelArg( - const grpc_channel_args* channel_args) { - const grpc_arg* lb_addresses_arg = - grpc_channel_args_find(channel_args, GRPC_ARG_SERVER_ADDRESS_LIST); - if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER) - return nullptr; - return static_cast(lb_addresses_arg->value.pointer.p); -} - } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/server_address.h b/src/core/ext/filters/client_channel/server_address.h index 3a1bf1df67d..040cd2ee317 100644 --- a/src/core/ext/filters/client_channel/server_address.h +++ b/src/core/ext/filters/client_channel/server_address.h @@ -26,9 +26,6 @@ #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/uri/uri_parser.h" -// Channel arg key for ServerAddressList. -#define GRPC_ARG_SERVER_ADDRESS_LIST "grpc.server_address_list" - // Channel arg key for a bool indicating whether an address is a grpclb // load balancer (as opposed to a backend). #define GRPC_ARG_ADDRESS_IS_BALANCER "grpc.address_is_balancer" @@ -96,13 +93,6 @@ class ServerAddress { typedef InlinedVector ServerAddressList; -// Returns a channel arg containing \a addresses. -grpc_arg CreateServerAddressListChannelArg(const ServerAddressList* addresses); - -// Returns the ServerListAddress instance in channel_args or NULL. -ServerAddressList* FindServerAddressListChannelArg( - const grpc_channel_args* channel_args); - } // namespace grpc_core #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H */ diff --git a/src/core/lib/transport/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc similarity index 87% rename from src/core/lib/transport/service_config.cc rename to src/core/ext/filters/client_channel/service_config.cc index 713c1796439..bbf671d979e 100644 --- a/src/core/lib/transport/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -16,7 +16,7 @@ #include -#include "src/core/lib/transport/service_config.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include @@ -34,17 +34,22 @@ namespace grpc_core { RefCountedPtr ServiceConfig::Create(const char* json) { + UniquePtr service_config_json(gpr_strdup(json)); UniquePtr json_string(gpr_strdup(json)); grpc_json* json_tree = grpc_json_parse_string(json_string.get()); if (json_tree == nullptr) { gpr_log(GPR_INFO, "failed to parse JSON for service config"); return nullptr; } - return MakeRefCounted(std::move(json_string), json_tree); + return MakeRefCounted(std::move(service_config_json), + std::move(json_string), json_tree); } -ServiceConfig::ServiceConfig(UniquePtr json_string, grpc_json* json_tree) - : json_string_(std::move(json_string)), json_tree_(json_tree) {} +ServiceConfig::ServiceConfig(UniquePtr service_config_json, + UniquePtr json_string, grpc_json* json_tree) + : service_config_json_(std::move(service_config_json)), + json_string_(std::move(json_string)), + json_tree_(json_tree) {} ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } diff --git a/src/core/lib/transport/service_config.h b/src/core/ext/filters/client_channel/service_config.h similarity index 94% rename from src/core/lib/transport/service_config.h rename to src/core/ext/filters/client_channel/service_config.h index 224c6dd576c..d9063479e32 100644 --- a/src/core/lib/transport/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -14,8 +14,8 @@ // limitations under the License. // -#ifndef GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H -#define GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H #include @@ -62,6 +62,8 @@ class ServiceConfig : public RefCounted { ~ServiceConfig(); + const char* service_config_json() const { return service_config_json_.get(); } + /// Invokes \a process_json() for each global parameter in the service /// config. \a arg is passed as the second argument to \a process_json(). template @@ -82,7 +84,7 @@ class ServiceConfig : public RefCounted { using CreateValue = RefCountedPtr (*)(const grpc_json* method_config_json); template RefCountedPtr>> CreateMethodConfigTable( - CreateValue create_value); + CreateValue create_value) const; /// A helper function for looking up values in the table returned by /// \a CreateMethodConfigTable(). @@ -100,7 +102,8 @@ class ServiceConfig : public RefCounted { friend T* New(Args&&... args); // Takes ownership of \a json_tree. - ServiceConfig(UniquePtr json_string, grpc_json* json_tree); + ServiceConfig(UniquePtr service_config_json, + UniquePtr json_string, grpc_json* json_tree); // Returns the number of names specified in the method config \a json. static int CountNamesInMethodConfig(grpc_json* json); @@ -117,6 +120,7 @@ class ServiceConfig : public RefCounted { grpc_json* json, CreateValue create_value, typename SliceHashTable>::Entry* entries, size_t* idx); + UniquePtr service_config_json_; UniquePtr json_string_; // Underlying storage for json_tree. grpc_json* json_tree_; }; @@ -172,7 +176,7 @@ bool ServiceConfig::ParseJsonMethodConfig( template RefCountedPtr>> -ServiceConfig::CreateMethodConfigTable(CreateValue create_value) { +ServiceConfig::CreateMethodConfigTable(CreateValue create_value) const { // Traverse parsed JSON tree. if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { return nullptr; @@ -247,4 +251,4 @@ RefCountedPtr ServiceConfig::MethodConfigTableLookup( } // namespace grpc_core -#endif /* GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H */ +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H */ diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index f795901b15b..8bb0c4c3498 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -33,6 +33,7 @@ #include "src/core/ext/filters/client_channel/health/health_check_client.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" @@ -50,7 +51,6 @@ #include "src/core/lib/surface/channel_init.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/error_utils.h" -#include "src/core/lib/transport/service_config.h" #include "src/core/lib/transport/status_metadata.h" #include "src/core/lib/uri/uri_parser.h" diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index e41496789be..8a422ddca54 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -26,13 +26,13 @@ #include #include +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack_builder.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/surface/channel_init.h" -#include "src/core/lib/transport/service_config.h" typedef struct { int max_send_size; diff --git a/src/core/lib/channel/channel_args.cc b/src/core/lib/channel/channel_args.cc index e49d532e11d..2d9a1bc67cd 100644 --- a/src/core/lib/channel/channel_args.cc +++ b/src/core/lib/channel/channel_args.cc @@ -118,6 +118,8 @@ grpc_channel_args* grpc_channel_args_copy(const grpc_channel_args* src) { grpc_channel_args* grpc_channel_args_union(const grpc_channel_args* a, const grpc_channel_args* b) { + if (a == nullptr) return grpc_channel_args_copy(b); + if (b == nullptr) return grpc_channel_args_copy(a); const size_t max_out = (a->num_args + b->num_args); grpc_arg* uniques = static_cast(gpr_malloc(sizeof(*uniques) * max_out)); diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 814f920eaf7..0362a3cf2ae 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -200,7 +200,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/transport/metadata.cc', 'src/core/lib/transport/metadata_batch.cc', 'src/core/lib/transport/pid_controller.cc', - 'src/core/lib/transport/service_config.cc', 'src/core/lib/transport/static_metadata.cc', 'src/core/lib/transport/status_conversion.cc', 'src/core/lib/transport/status_metadata.cc', @@ -336,6 +335,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/resolving_lb_policy.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/server_address.cc', + 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc index 76ac585fb4c..f8a7729671e 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -109,26 +109,23 @@ static grpc_core::OrphanablePtr create_resolver( class ResultHandler : public grpc_core::Resolver::ResultHandler { public: struct ResolverOutput { - const grpc_channel_args* result = nullptr; + grpc_core::Resolver::Result result; grpc_error* error = nullptr; gpr_event ev; ResolverOutput() { gpr_event_init(&ev); } - ~ResolverOutput() { - grpc_channel_args_destroy(result); - GRPC_ERROR_UNREF(error); - } + ~ResolverOutput() { GRPC_ERROR_UNREF(error); } }; void SetOutput(ResolverOutput* output) { gpr_atm_rel_store(&output_, reinterpret_cast(output)); } - void ReturnResult(const grpc_channel_args* args) override { + void ReturnResult(grpc_core::Resolver::Result result) override { ResolverOutput* output = reinterpret_cast(gpr_atm_acq_load(&output_)); GPR_ASSERT(output != nullptr); - output->result = args; + output->result = std::move(result); output->error = GRPC_ERROR_NONE; gpr_event_set(&output->ev, (void*)1); } @@ -137,7 +134,6 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler { ResolverOutput* output = reinterpret_cast(gpr_atm_acq_load(&output_)); GPR_ASSERT(output != nullptr); - output->result = nullptr; output->error = error; gpr_event_set(&output->ev, (void*)1); } @@ -180,14 +176,14 @@ int main(int argc, char** argv) { resolver->StartLocked(); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(wait_loop(5, &output1.ev)); - GPR_ASSERT(output1.result == nullptr); + GPR_ASSERT(output1.result.addresses.empty()); GPR_ASSERT(output1.error != GRPC_ERROR_NONE); ResultHandler::ResolverOutput output2; result_handler->SetOutput(&output2); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(wait_loop(30, &output2.ev)); - GPR_ASSERT(output2.result != nullptr); + GPR_ASSERT(!output2.result.addresses.empty()); GPR_ASSERT(output2.error == GRPC_ERROR_NONE); GRPC_COMBINER_UNREF(g_combiner, "test"); diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index 82ff5b04fe0..7b3a4589f5b 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -174,8 +174,7 @@ struct OnResolutionCallbackArg; class ResultHandler : public grpc_core::Resolver::ResultHandler { public: - using ResultCallback = void (*)(const grpc_channel_args* result, - OnResolutionCallbackArg* state); + using ResultCallback = void (*)(OnResolutionCallbackArg* state); void SetCallback(ResultCallback result_cb, OnResolutionCallbackArg* state) { GPR_ASSERT(result_cb_ == nullptr); @@ -184,14 +183,14 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler { state_ = state; } - void ReturnResult(const grpc_channel_args* args) override { + void ReturnResult(grpc_core::Resolver::Result result) override { GPR_ASSERT(result_cb_ != nullptr); GPR_ASSERT(state_ != nullptr); ResultCallback cb = result_cb_; OnResolutionCallbackArg* state = state_; result_cb_ = nullptr; state_ = nullptr; - cb(args, state); + cb(state); } void ReturnError(grpc_error* error) override { @@ -213,9 +212,7 @@ struct OnResolutionCallbackArg { // Set to true by the last callback in the resolution chain. static bool g_all_callbacks_invoked; -static void on_second_resolution(const grpc_channel_args* result, - OnResolutionCallbackArg* cb_arg) { - grpc_channel_args_destroy(result); +static void on_second_resolution(OnResolutionCallbackArg* cb_arg) { gpr_log(GPR_INFO, "2nd: g_resolution_count: %d", g_resolution_count); // The resolution callback was not invoked until new data was // available, which was delayed until after the cooldown period. @@ -230,9 +227,7 @@ static void on_second_resolution(const grpc_channel_args* result, g_all_callbacks_invoked = true; } -static void on_first_resolution(const grpc_channel_args* result, - OnResolutionCallbackArg* cb_arg) { - grpc_channel_args_destroy(result); +static void on_first_resolution(OnResolutionCallbackArg* cb_arg) { gpr_log(GPR_INFO, "1st: g_resolution_count: %d", g_resolution_count); // There's one initial system-level resolution and one invocation of a // notification callback (the current function). diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index 9927404fc10..0d34a0b8f2c 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -35,32 +35,22 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler { public: - ~ResultHandler() override { grpc_channel_args_destroy(expected_); } - - void SetExpectedAndEvent(grpc_channel_args* expected, gpr_event* ev) { - GPR_ASSERT(expected_ == nullptr); + void SetExpectedAndEvent(grpc_core::Resolver::Result expected, + gpr_event* ev) { GPR_ASSERT(ev_ == nullptr); - expected_ = grpc_channel_args_copy(expected); + expected_ = std::move(expected); ev_ = ev; } - void ReturnResult(const grpc_channel_args* args) override { - GPR_ASSERT(expected_ != nullptr); + void ReturnResult(grpc_core::Resolver::Result actual) override { GPR_ASSERT(ev_ != nullptr); - // We only check the addresses channel arg because that's the only one + // We only check the addresses, because that's the only thing // explicitly set by the test via // FakeResolverResponseGenerator::SetResponse(). - const grpc_core::ServerAddressList* actual_addresses = - grpc_core::FindServerAddressListChannelArg(args); - const grpc_core::ServerAddressList* expected_addresses = - grpc_core::FindServerAddressListChannelArg(expected_); - GPR_ASSERT(actual_addresses->size() == expected_addresses->size()); - for (size_t i = 0; i < expected_addresses->size(); ++i) { - GPR_ASSERT((*actual_addresses)[i] == (*expected_addresses)[i]); + GPR_ASSERT(actual.addresses.size() == expected_.addresses.size()); + for (size_t i = 0; i < expected_.addresses.size(); ++i) { + GPR_ASSERT(actual.addresses[i] == expected_.addresses[i]); } - grpc_channel_args_destroy(args); - grpc_channel_args_destroy(expected_); - expected_ = nullptr; gpr_event_set(ev_, (void*)1); ev_ = nullptr; } @@ -68,7 +58,7 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler { void ReturnError(grpc_error* error) override {} private: - grpc_channel_args* expected_ = nullptr; + grpc_core::Resolver::Result expected_; gpr_event* ev_ = nullptr; }; @@ -92,13 +82,13 @@ static grpc_core::OrphanablePtr build_fake_resolver( } // Create a new resolution containing 2 addresses. -static grpc_channel_args* create_new_resolver_result() { +static grpc_core::Resolver::Result create_new_resolver_result() { static size_t test_counter = 0; const size_t num_addresses = 2; char* uri_string; char* balancer_name; // Create address list. - grpc_core::ServerAddressList addresses; + grpc_core::Resolver::Result result; for (size_t i = 0; i < num_addresses; ++i) { gpr_asprintf(&uri_string, "ipv4:127.0.0.1:100%" PRIuPTR, test_counter * num_addresses + i); @@ -117,17 +107,13 @@ static grpc_channel_args* create_new_resolver_result() { } grpc_channel_args* args = grpc_channel_args_copy_and_add( nullptr, args_to_add.data(), args_to_add.size()); - addresses.emplace_back(address.addr, address.len, args); + result.addresses.emplace_back(address.addr, address.len, args); gpr_free(balancer_name); grpc_uri_destroy(uri); gpr_free(uri_string); } - // Embed the address list in channel args. - const grpc_arg addresses_arg = CreateServerAddressListChannelArg(&addresses); - grpc_channel_args* results = - grpc_channel_args_copy_and_add(nullptr, &addresses_arg, 1); ++test_counter; - return results; + return result; } static void test_fake_resolver() { @@ -147,39 +133,38 @@ static void test_fake_resolver() { // next_results != NULL, reresolution_results == NULL. // Expected response is next_results. gpr_log(GPR_INFO, "TEST 1"); - grpc_channel_args* results = create_new_resolver_result(); + grpc_core::Resolver::Result result = create_new_resolver_result(); gpr_event ev1; gpr_event_init(&ev1); - result_handler->SetExpectedAndEvent(results, &ev1); - response_generator->SetResponse(results); + result_handler->SetExpectedAndEvent(result, &ev1); + response_generator->SetResponse(std::move(result)); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(gpr_event_wait(&ev1, grpc_timeout_seconds_to_deadline(5)) != nullptr); - grpc_channel_args_destroy(results); // Test 2: update resolution. // next_results != NULL, reresolution_results == NULL. // Expected response is next_results. gpr_log(GPR_INFO, "TEST 2"); - results = create_new_resolver_result(); + result = create_new_resolver_result(); gpr_event ev2; gpr_event_init(&ev2); - result_handler->SetExpectedAndEvent(results, &ev2); - response_generator->SetResponse(results); + result_handler->SetExpectedAndEvent(result, &ev2); + response_generator->SetResponse(std::move(result)); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(gpr_event_wait(&ev2, grpc_timeout_seconds_to_deadline(5)) != nullptr); - grpc_channel_args_destroy(results); // Test 3: normal re-resolution. // next_results == NULL, reresolution_results != NULL. // Expected response is reresolution_results. gpr_log(GPR_INFO, "TEST 3"); - grpc_channel_args* reresolution_results = create_new_resolver_result(); + grpc_core::Resolver::Result reresolution_result = + create_new_resolver_result(); gpr_event ev3; gpr_event_init(&ev3); - result_handler->SetExpectedAndEvent(reresolution_results, &ev3); + result_handler->SetExpectedAndEvent(reresolution_result, &ev3); // Set reresolution_results. // No result will be returned until re-resolution is requested. - response_generator->SetReresolutionResponse(reresolution_results); + response_generator->SetReresolutionResponse(reresolution_result); grpc_core::ExecCtx::Get()->Flush(); // Trigger a re-resolution. resolver->RequestReresolutionLocked(); @@ -192,33 +177,31 @@ static void test_fake_resolver() { gpr_log(GPR_INFO, "TEST 4"); gpr_event ev4; gpr_event_init(&ev4); - result_handler->SetExpectedAndEvent(reresolution_results, &ev4); + result_handler->SetExpectedAndEvent(std::move(reresolution_result), &ev4); // Trigger a re-resolution. resolver->RequestReresolutionLocked(); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(gpr_event_wait(&ev4, grpc_timeout_seconds_to_deadline(5)) != nullptr); - grpc_channel_args_destroy(reresolution_results); // Test 5: normal resolution. // next_results != NULL, reresolution_results != NULL. // Expected response is next_results. gpr_log(GPR_INFO, "TEST 5"); - results = create_new_resolver_result(); + result = create_new_resolver_result(); gpr_event ev5; gpr_event_init(&ev5); - result_handler->SetExpectedAndEvent(results, &ev5); - response_generator->SetResponse(results); + result_handler->SetExpectedAndEvent(result, &ev5); + response_generator->SetResponse(std::move(result)); grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(gpr_event_wait(&ev5, grpc_timeout_seconds_to_deadline(5)) != nullptr); - grpc_channel_args_destroy(results); // Test 6: no-op. // Requesting a new resolution without setting the response shouldn't trigger // the resolution callback. gpr_log(GPR_INFO, "TEST 6"); gpr_event ev6; gpr_event_init(&ev6); - result_handler->SetExpectedAndEvent(nullptr, &ev6); + result_handler->SetExpectedAndEvent(grpc_core::Resolver::Result(), &ev6); GPR_ASSERT(gpr_event_wait(&ev6, grpc_timeout_milliseconds_to_deadline(100)) == nullptr); // Clean up. diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc index 37abe20fe8d..ac3d31b8ff8 100644 --- a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc +++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc @@ -32,9 +32,7 @@ static grpc_combiner* g_combiner; class ResultHandler : public grpc_core::Resolver::ResultHandler { public: - void ReturnResult(const grpc_channel_args* args) override { - grpc_channel_args_destroy(args); - } + void ReturnResult(grpc_core::Resolver::Result result) override {} void ReturnError(grpc_error* error) override { GRPC_ERROR_UNREF(error); } }; diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc index 4318811b818..446e7b045a1 100644 --- a/test/core/end2end/connection_refused_test.cc +++ b/test/core/end2end/connection_refused_test.cc @@ -28,7 +28,6 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/service_config.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" diff --git a/test/core/end2end/tests/cancel_after_accept.cc b/test/core/end2end/tests/cancel_after_accept.cc index 788d374baad..510bf3cee5f 100644 --- a/test/core/end2end/tests/cancel_after_accept.cc +++ b/test/core/end2end/tests/cancel_after_accept.cc @@ -30,7 +30,6 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/service_config.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" diff --git a/test/core/end2end/tests/cancel_after_round_trip.cc b/test/core/end2end/tests/cancel_after_round_trip.cc index 061b273f18d..609ac570d90 100644 --- a/test/core/end2end/tests/cancel_after_round_trip.cc +++ b/test/core/end2end/tests/cancel_after_round_trip.cc @@ -30,7 +30,6 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/service_config.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" diff --git a/test/core/end2end/tests/max_message_length.cc b/test/core/end2end/tests/max_message_length.cc index 6ac941e0da0..40e752a3d63 100644 --- a/test/core/end2end/tests/max_message_length.cc +++ b/test/core/end2end/tests/max_message_length.cc @@ -30,7 +30,6 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/service_config.h" #include "test/core/end2end/cq_verifier.h" diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index a8657b02546..05e25eb08bc 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -64,9 +64,8 @@ class ForwardingLoadBalancingPolicy : public LoadBalancingPolicy { ~ForwardingLoadBalancingPolicy() override = default; - void UpdateLocked(const grpc_channel_args& args, - RefCountedPtr lb_config) override { - delegate_->UpdateLocked(args, std::move(lb_config)); + void UpdateLocked(UpdateArgs args) override { + delegate_->UpdateLocked(std::move(args)); } void ExitIdleLocked() override { delegate_->ExitIdleLocked(); } diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index 124557eb567..91419cb257b 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -218,7 +218,7 @@ class ClientChannelStressTest { void SetNextResolution(const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_core::ServerAddressList addresses; + grpc_core::Resolver::Result result; for (const auto& addr : address_data) { char* lb_uri_str; gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); @@ -236,13 +236,11 @@ class ClientChannelStressTest { } grpc_channel_args* args = grpc_channel_args_copy_and_add( nullptr, args_to_add.data(), args_to_add.size()); - addresses.emplace_back(address.addr, address.len, args); + result.addresses.emplace_back(address.addr, address.len, args); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } - grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); - grpc_channel_args fake_result = {1, &fake_addresses}; - response_generator_->SetResponse(&fake_result); + response_generator_->SetResponse(std::move(result)); } void KeepSendingRequests() { diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 3cd06e9e28c..4244690d76b 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -183,8 +183,8 @@ class ClientLbEnd2endTest : public ::testing::Test { } } - grpc_channel_args* BuildFakeResults(const std::vector& ports) { - grpc_core::ServerAddressList addresses; + grpc_core::Resolver::Result BuildFakeResults(const std::vector& ports) { + grpc_core::Resolver::Result result; for (const int& port : ports) { char* lb_uri_str; gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port); @@ -192,29 +192,22 @@ class ClientLbEnd2endTest : public ::testing::Test { GPR_ASSERT(lb_uri != nullptr); grpc_resolved_address address; GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); - addresses.emplace_back(address.addr, address.len, nullptr /* args */); + result.addresses.emplace_back(address.addr, address.len, + nullptr /* args */); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } - const grpc_arg fake_addresses = - CreateServerAddressListChannelArg(&addresses); - grpc_channel_args* fake_results = - grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1); - return fake_results; + return result; } void SetNextResolution(const std::vector& ports) { grpc_core::ExecCtx exec_ctx; - grpc_channel_args* fake_results = BuildFakeResults(ports); - response_generator_->SetResponse(fake_results); - grpc_channel_args_destroy(fake_results); + response_generator_->SetResponse(BuildFakeResults(ports)); } void SetNextResolutionUponError(const std::vector& ports) { grpc_core::ExecCtx exec_ctx; - grpc_channel_args* fake_results = BuildFakeResults(ports); - response_generator_->SetReresolutionResponse(fake_results); - grpc_channel_args_destroy(fake_results); + response_generator_->SetReresolutionResponse(BuildFakeResults(ports)); } void SetFailureOnReresolution() { diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 3afcd0c578f..7c6432379a6 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -36,6 +36,7 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -538,28 +539,21 @@ class GrpclbEnd2endTest : public ::testing::Test { void SetNextResolution(const std::vector& address_data, const char* service_config_json = nullptr) { grpc_core::ExecCtx exec_ctx; - grpc_core::ServerAddressList addresses = - CreateLbAddressesFromAddressDataList(address_data); - std::vector args = { - CreateServerAddressListChannelArg(&addresses), - }; + grpc_core::Resolver::Result result; + result.addresses = CreateLbAddressesFromAddressDataList(address_data); if (service_config_json != nullptr) { - args.push_back(grpc_channel_arg_string_create( - const_cast(GRPC_ARG_SERVICE_CONFIG), - const_cast(service_config_json))); + result.service_config = + grpc_core::ServiceConfig::Create(service_config_json); } - grpc_channel_args fake_result = {args.size(), args.data()}; - response_generator_->SetResponse(&fake_result); + response_generator_->SetResponse(std::move(result)); } void SetNextReresolutionResponse( const std::vector& address_data) { grpc_core::ExecCtx exec_ctx; - grpc_core::ServerAddressList addresses = - CreateLbAddressesFromAddressDataList(address_data); - grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); - grpc_channel_args fake_result = {1, &fake_addresses}; - response_generator_->SetReresolutionResponse(&fake_result); + grpc_core::Resolver::Result result; + result.addresses = CreateLbAddressesFromAddressDataList(address_data); + response_generator_->SetReresolutionResponse(std::move(result)); } const std::vector GetBackendPorts(size_t start_index = 0, diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 8657ba78d90..61e759c61b5 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -521,21 +521,18 @@ class XdsEnd2endTest : public ::testing::Test { grpc_core::FakeResolverResponseGenerator* lb_channel_response_generator = nullptr) { grpc_core::ExecCtx exec_ctx; - grpc_core::ServerAddressList addresses = - CreateLbAddressesFromPortList(ports); - std::vector args = { - CreateServerAddressListChannelArg(&addresses), - grpc_core::FakeResolverResponseGenerator::MakeChannelArg( - lb_channel_response_generator == nullptr - ? lb_channel_response_generator_.get() - : lb_channel_response_generator)}; + grpc_core::Resolver::Result result; + result.addresses = CreateLbAddressesFromPortList(ports); if (service_config_json != nullptr) { - args.push_back(grpc_channel_arg_string_create( - const_cast(GRPC_ARG_SERVICE_CONFIG), - const_cast(service_config_json))); + result.service_config = + grpc_core::ServiceConfig::Create(service_config_json); } - grpc_channel_args fake_result = {args.size(), args.data()}; - response_generator_->SetResponse(&fake_result); + grpc_arg arg = grpc_core::FakeResolverResponseGenerator::MakeChannelArg( + lb_channel_response_generator == nullptr + ? lb_channel_response_generator_.get() + : lb_channel_response_generator); + result.args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + response_generator_->SetResponse(std::move(result)); } void SetNextResolutionForLbChannelAllBalancers( @@ -555,30 +552,23 @@ class XdsEnd2endTest : public ::testing::Test { grpc_core::FakeResolverResponseGenerator* lb_channel_response_generator = nullptr) { grpc_core::ExecCtx exec_ctx; - grpc_core::ServerAddressList addresses = - CreateLbAddressesFromPortList(ports); - std::vector args = { - CreateServerAddressListChannelArg(&addresses), - }; + grpc_core::Resolver::Result result; + result.addresses = CreateLbAddressesFromPortList(ports); if (service_config_json != nullptr) { - args.push_back(grpc_channel_arg_string_create( - const_cast(GRPC_ARG_SERVICE_CONFIG), - const_cast(service_config_json))); + result.service_config = + grpc_core::ServiceConfig::Create(service_config_json); } - grpc_channel_args fake_result = {args.size(), args.data()}; if (lb_channel_response_generator == nullptr) { lb_channel_response_generator = lb_channel_response_generator_.get(); } - lb_channel_response_generator->SetResponse(&fake_result); + lb_channel_response_generator->SetResponse(std::move(result)); } void SetNextReresolutionResponse(const std::vector& ports) { grpc_core::ExecCtx exec_ctx; - grpc_core::ServerAddressList addresses = - CreateLbAddressesFromPortList(ports); - grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses); - grpc_channel_args fake_result = {1, &fake_addresses}; - response_generator_->SetReresolutionResponse(&fake_result); + grpc_core::Resolver::Result result; + result.addresses = CreateLbAddressesFromPortList(ports); + response_generator_->SetReresolutionResponse(std::move(result)); } const std::vector GetBackendPorts(size_t start_index = 0, diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc index 74da4380be5..bcf96aa1dc5 100644 --- a/test/cpp/naming/cancel_ares_query_test.cc +++ b/test/cpp/naming/cancel_ares_query_test.cc @@ -172,7 +172,7 @@ class AssertFailureResultHandler : public grpc_core::Resolver::ResultHandler { gpr_mu_unlock(args_->mu); } - void ReturnResult(const grpc_channel_args* args) override { + void ReturnResult(grpc_core::Resolver::Result result) override { GPR_ASSERT(false); } diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index abf27cdd058..398822d18a4 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -239,17 +239,13 @@ void PollPollsetUntilRequestDone(ArgsStruct* args) { gpr_event_set(&args->ev, (void*)1); } -void CheckServiceConfigResultLocked(const grpc_channel_args* channel_args, +void CheckServiceConfigResultLocked(const char* service_config_json, ArgsStruct* args) { - const grpc_arg* service_config_arg = - grpc_channel_args_find(channel_args, GRPC_ARG_SERVICE_CONFIG); if (args->expected_service_config_string != "") { - GPR_ASSERT(service_config_arg != nullptr); - GPR_ASSERT(service_config_arg->type == GRPC_ARG_STRING); - EXPECT_EQ(service_config_arg->value.string, - args->expected_service_config_string); + GPR_ASSERT(service_config_json != nullptr); + EXPECT_EQ(service_config_json, args->expected_service_config_string); } else { - GPR_ASSERT(service_config_arg == nullptr); + GPR_ASSERT(service_config_json == nullptr); } } @@ -404,14 +400,13 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler { explicit ResultHandler(ArgsStruct* args) : args_(args) {} - void ReturnResult(const grpc_channel_args* result) override { + void ReturnResult(grpc_core::Resolver::Result result) override { CheckResult(result); gpr_atm_rel_store(&args_->done_atm, 1); gpr_mu_lock(args_->mu); GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args_->pollset, nullptr)); gpr_mu_unlock(args_->mu); - grpc_channel_args_destroy(result); } void ReturnError(grpc_error* error) override { @@ -419,7 +414,7 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler { GPR_ASSERT(false); } - virtual void CheckResult(const grpc_channel_args* channel_args) {} + virtual void CheckResult(const grpc_core::Resolver::Result& result) {} protected: ArgsStruct* args_struct() const { return args_; } @@ -438,16 +433,14 @@ class CheckingResultHandler : public ResultHandler { explicit CheckingResultHandler(ArgsStruct* args) : ResultHandler(args) {} - void CheckResult(const grpc_channel_args* channel_args) override { + void CheckResult(const grpc_core::Resolver::Result& result) override { ArgsStruct* args = args_struct(); - grpc_core::ServerAddressList* addresses = - grpc_core::FindServerAddressListChannelArg(channel_args); gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR, - addresses->size(), args->expected_addrs.size()); - GPR_ASSERT(addresses->size() == args->expected_addrs.size()); + result.addresses.size(), args->expected_addrs.size()); + GPR_ASSERT(result.addresses.size() == args->expected_addrs.size()); std::vector found_lb_addrs; - for (size_t i = 0; i < addresses->size(); i++) { - grpc_core::ServerAddress& addr = (*addresses)[i]; + for (size_t i = 0; i < result.addresses.size(); i++) { + const grpc_core::ServerAddress& addr = result.addresses[i]; char* str; grpc_sockaddr_to_string(&str, &addr.address(), 1 /* normalize */); gpr_log(GPR_INFO, "%s", str); @@ -464,9 +457,13 @@ class CheckingResultHandler : public ResultHandler { } EXPECT_THAT(args->expected_addrs, UnorderedElementsAreArray(found_lb_addrs)); - CheckServiceConfigResultLocked(channel_args, args); + const char* service_config_json = + result.service_config == nullptr + ? nullptr + : result.service_config->service_config_json(); + CheckServiceConfigResultLocked(service_config_json, args); if (args->expected_service_config_string == "") { - CheckLBPolicyResultLocked(channel_args, args); + CheckLBPolicyResultLocked(result.args, args); } } }; diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c0078bf2764..1e17ab8f88b 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1180,7 +1180,6 @@ src/core/lib/transport/http2_errors.h \ src/core/lib/transport/metadata.h \ src/core/lib/transport/metadata_batch.h \ src/core/lib/transport/pid_controller.h \ -src/core/lib/transport/service_config.h \ src/core/lib/transport/static_metadata.h \ src/core/lib/transport/status_conversion.h \ src/core/lib/transport/status_metadata.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 5ce5d5d3ce3..0fdab21483c 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -966,6 +966,8 @@ src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/retry_throttle.h \ src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/server_address.h \ +src/core/ext/filters/client_channel/service_config.cc \ +src/core/ext/filters/client_channel/service_config.h \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel.h \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ @@ -1476,8 +1478,6 @@ src/core/lib/transport/metadata_batch.cc \ src/core/lib/transport/metadata_batch.h \ src/core/lib/transport/pid_controller.cc \ src/core/lib/transport/pid_controller.h \ -src/core/lib/transport/service_config.cc \ -src/core/lib/transport/service_config.h \ src/core/lib/transport/static_metadata.cc \ src/core/lib/transport/static_metadata.h \ src/core/lib/transport/status_conversion.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 501e53560ab..2ef1fd3bbad 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8263,7 +8263,6 @@ "src/core/lib/transport/metadata.cc", "src/core/lib/transport/metadata_batch.cc", "src/core/lib/transport/pid_controller.cc", - "src/core/lib/transport/service_config.cc", "src/core/lib/transport/static_metadata.cc", "src/core/lib/transport/status_conversion.cc", "src/core/lib/transport/status_metadata.cc", @@ -8422,7 +8421,6 @@ "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/pid_controller.h", - "src/core/lib/transport/service_config.h", "src/core/lib/transport/static_metadata.h", "src/core/lib/transport/status_conversion.h", "src/core/lib/transport/status_metadata.h", @@ -8575,7 +8573,6 @@ "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/pid_controller.h", - "src/core/lib/transport/service_config.h", "src/core/lib/transport/static_metadata.h", "src/core/lib/transport/status_conversion.h", "src/core/lib/transport/status_metadata.h", @@ -8663,6 +8660,7 @@ "src/core/ext/filters/client_channel/resolving_lb_policy.h", "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.h", + "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], @@ -8716,6 +8714,8 @@ "src/core/ext/filters/client_channel/retry_throttle.h", "src/core/ext/filters/client_channel/server_address.cc", "src/core/ext/filters/client_channel/server_address.h", + "src/core/ext/filters/client_channel/service_config.cc", + "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", From 113e84b8dd78b0a4438dc40a2ffaac125e35d690 Mon Sep 17 00:00:00 2001 From: Fabian Holler Date: Tue, 12 Feb 2019 17:35:48 +0100 Subject: [PATCH 802/814] update cares to version cares-1_15_0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the issue: https://github.com/grpc/grpc/issues/16688 Which causes that grpc can not be build because of the following compiler error: third_party/cares/cares/ares_init.c: In function ‘ares_dup’: third_party/cares/cares/ares_init.c:301:17: error: argument to ‘sizeof’ in ‘strncpy’ call is the same expression as the source; did you mean to use the size of the destination? [-Werror=sizeof-pointer- memaccess] sizeof(src->local_dev_name)); --- bazel/grpc_deps.bzl | 4 ++-- test/distrib/cpp/run_distrib_test_cmake.sh | 2 +- third_party/cares/cares | 2 +- tools/run_tests/sanity/check_submodules.sh | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 50d12981e4f..891783b2da3 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -162,8 +162,8 @@ def grpc_deps(): http_archive( name = "com_github_cares_cares", build_file = "@com_github_grpc_grpc//third_party:cares/cares.BUILD", - strip_prefix = "c-ares-3be1924221e1326df520f8498d704a5c4c8d0cce", - url = "https://github.com/c-ares/c-ares/archive/3be1924221e1326df520f8498d704a5c4c8d0cce.tar.gz", + strip_prefix = "c-ares-e982924acee7f7313b4baa4ee5ec000c5e373c30", + url = "https://github.com/c-ares/c-ares/archive/e982924acee7f7313b4baa4ee5ec000c5e373c30.tar.gz", ) if "com_google_absl" not in native.existing_rules(): diff --git a/test/distrib/cpp/run_distrib_test_cmake.sh b/test/distrib/cpp/run_distrib_test_cmake.sh index 6ec3cab6024..bada14d81c4 100755 --- a/test/distrib/cpp/run_distrib_test_cmake.sh +++ b/test/distrib/cpp/run_distrib_test_cmake.sh @@ -24,7 +24,7 @@ apt-get install -t jessie-backports -y libssl-dev # Install c-ares cd third_party/cares/cares git fetch origin -git checkout cares-1_13_0 +git checkout cares-1_15_0 mkdir -p cmake/build cd cmake/build cmake -DCMAKE_BUILD_TYPE=Release ../.. diff --git a/third_party/cares/cares b/third_party/cares/cares index 3be1924221e..e982924acee 160000 --- a/third_party/cares/cares +++ b/third_party/cares/cares @@ -1 +1 @@ -Subproject commit 3be1924221e1326df520f8498d704a5c4c8d0cce +Subproject commit e982924acee7f7313b4baa4ee5ec000c5e373c30 diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index a95f524ac1c..b15b8d3b077 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -31,7 +31,7 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules" 73594cde8c9a52a102c4341c244c833aa61b9c06 third_party/bloaty (remotes/origin/wide-14-g73594cd) b29b21a81b32ec273f118f589f46d56ad3332420 third_party/boringssl (remotes/origin/chromium-stable) afc30d43eef92979b05776ec0963c9cede5fb80f third_party/boringssl-with-bazel (fips-20180716-116-gafc30d43e) - 3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0) + e982924acee7f7313b4baa4ee5ec000c5e373c30 third_party/cares/cares (cares-1_15_0) 911001cdca003337bdb93fab32740cde61bafee3 third_party/data-plane-api (heads/master) 28f50e0fed19872e0fd50dd23ce2ee8cd759338e third_party/gflags (v2.2.0-5-g30dbc81) 80ed4d0bbf65d57cc267dfc63bd2584557f11f9b third_party/googleapis (common-protos-1_3_1-915-g80ed4d0bb) From 8c49802f75e33fbad07983aef6b3227ed5972c10 Mon Sep 17 00:00:00 2001 From: Fabian Holler Date: Tue, 12 Feb 2019 18:53:34 +0100 Subject: [PATCH 803/814] add strsplit.c, strsplit.h files to build and test files The files are new in the updated cares release. --- Makefile | 1 + grpc.gemspec | 2 ++ src/c-ares/gen_build_yaml.py | 2 ++ src/python/grpcio/grpc_core_dependencies.py | 1 + third_party/cares/cares.BUILD | 2 ++ tools/run_tests/generated/sources_and_headers.json | 1 + 6 files changed, 9 insertions(+) diff --git a/Makefile b/Makefile index 85e621f87bb..300088798f1 100644 --- a/Makefile +++ b/Makefile @@ -8227,6 +8227,7 @@ LIBARES_SRC = \ third_party/cares/cares/ares_strcasecmp.c \ third_party/cares/cares/ares_strdup.c \ third_party/cares/cares/ares_strerror.c \ + third_party/cares/cares/ares_strsplit.c \ third_party/cares/cares/ares_timeout.c \ third_party/cares/cares/ares_version.c \ third_party/cares/cares/ares_writev.c \ diff --git a/grpc.gemspec b/grpc.gemspec index d9fc6ef0ebc..c5c7e34772a 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -1266,6 +1266,7 @@ Gem::Specification.new do |s| s.files += %w( third_party/cares/cares/ares_setup.h ) s.files += %w( third_party/cares/cares/ares_strcasecmp.h ) s.files += %w( third_party/cares/cares/ares_strdup.h ) + s.files += %w( third_party/cares/cares/ares_strsplit.h ) s.files += %w( third_party/cares/cares/ares_version.h ) s.files += %w( third_party/cares/cares/bitncmp.h ) s.files += %w( third_party/cares/cares/config-win32.h ) @@ -1317,6 +1318,7 @@ Gem::Specification.new do |s| s.files += %w( third_party/cares/cares/ares_strcasecmp.c ) s.files += %w( third_party/cares/cares/ares_strdup.c ) s.files += %w( third_party/cares/cares/ares_strerror.c ) + s.files += %w( third_party/cares/cares/ares_strsplit.c ) s.files += %w( third_party/cares/cares/ares_timeout.c ) s.files += %w( third_party/cares/cares/ares_version.c ) s.files += %w( third_party/cares/cares/ares_writev.c ) diff --git a/src/c-ares/gen_build_yaml.py b/src/c-ares/gen_build_yaml.py index 4600d8d2241..6e832edcea3 100755 --- a/src/c-ares/gen_build_yaml.py +++ b/src/c-ares/gen_build_yaml.py @@ -97,6 +97,7 @@ try: "third_party/cares/cares/ares_strcasecmp.c", "third_party/cares/cares/ares_strdup.c", "third_party/cares/cares/ares_strerror.c", + "third_party/cares/cares/ares_strsplit.c", "third_party/cares/cares/ares_timeout.c", "third_party/cares/cares/ares_version.c", "third_party/cares/cares/ares_writev.c", @@ -123,6 +124,7 @@ try: "third_party/cares/cares/ares_setup.h", "third_party/cares/cares/ares_strcasecmp.h", "third_party/cares/cares/ares_strdup.h", + "third_party/cares/cares/ares_strsplit.h", "third_party/cares/cares/ares_version.h", "third_party/cares/cares/bitncmp.h", "third_party/cares/cares/config-win32.h", diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 814f920eaf7..e63ff9cbd25 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -699,6 +699,7 @@ CORE_SOURCE_FILES = [ 'third_party/cares/cares/ares_strcasecmp.c', 'third_party/cares/cares/ares_strdup.c', 'third_party/cares/cares/ares_strerror.c', + 'third_party/cares/cares/ares_strsplit.c', 'third_party/cares/cares/ares_timeout.c', 'third_party/cares/cares/ares_version.c', 'third_party/cares/cares/ares_writev.c', diff --git a/third_party/cares/cares.BUILD b/third_party/cares/cares.BUILD index ffa03aeb12c..66ec1746122 100644 --- a/third_party/cares/cares.BUILD +++ b/third_party/cares/cares.BUILD @@ -112,6 +112,7 @@ cc_library( "ares_send.c", "ares_strcasecmp.c", "ares_strdup.c", + "ares_strsplit.c", "ares_strerror.c", "ares_timeout.c", "ares_version.c", @@ -141,6 +142,7 @@ cc_library( "ares_setup.h", "ares_strcasecmp.h", "ares_strdup.h", + "ares_strsplit.h", "ares_version.h", "bitncmp.h", "config-win32.h", diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 501e53560ab..e5624dce219 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -7468,6 +7468,7 @@ "third_party/cares/cares/ares_setup.h", "third_party/cares/cares/ares_strcasecmp.h", "third_party/cares/cares/ares_strdup.h", + "third_party/cares/cares/ares_strsplit.h", "third_party/cares/cares/ares_version.h", "third_party/cares/cares/bitncmp.h", "third_party/cares/cares/config-win32.h", From cab0c36d996420b44327fbcef8b241c28ee1b98b Mon Sep 17 00:00:00 2001 From: Fabian Holler Date: Tue, 12 Mar 2019 10:32:09 +0100 Subject: [PATCH 804/814] adapt cares config headers files to new version https://github.com/c-ares/c-ares/commit/2250b598fec5797abaa155991f85cea77d4d3eb7 introduced a new HAVE___SYSTEM_PROPERTY_GET define, adapt the ares_config.h files. --- third_party/cares/config_android/ares_config.h | 3 +++ third_party/cares/config_darwin/ares_config.h | 3 +++ third_party/cares/config_freebsd/ares_config.h | 3 +++ third_party/cares/config_linux/ares_config.h | 3 +++ third_party/cares/config_openbsd/ares_config.h | 3 +++ third_party/cares/config_windows/ares_config.h | 3 +++ 6 files changed, 18 insertions(+) diff --git a/third_party/cares/config_android/ares_config.h b/third_party/cares/config_android/ares_config.h index 2caf1b396e3..184af4ef9a5 100644 --- a/third_party/cares/config_android/ares_config.h +++ b/third_party/cares/config_android/ares_config.h @@ -338,6 +338,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ diff --git a/third_party/cares/config_darwin/ares_config.h b/third_party/cares/config_darwin/ares_config.h index bca7cfbcc7b..9b8fc651a18 100644 --- a/third_party/cares/config_darwin/ares_config.h +++ b/third_party/cares/config_darwin/ares_config.h @@ -333,6 +333,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ diff --git a/third_party/cares/config_freebsd/ares_config.h b/third_party/cares/config_freebsd/ares_config.h index 7beb20c76ef..e50a11d7f37 100644 --- a/third_party/cares/config_freebsd/ares_config.h +++ b/third_party/cares/config_freebsd/ares_config.h @@ -338,6 +338,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" diff --git a/third_party/cares/config_linux/ares_config.h b/third_party/cares/config_linux/ares_config.h index 065d0bc515a..3634e9d0616 100644 --- a/third_party/cares/config_linux/ares_config.h +++ b/third_party/cares/config_linux/ares_config.h @@ -338,6 +338,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ diff --git a/third_party/cares/config_openbsd/ares_config.h b/third_party/cares/config_openbsd/ares_config.h index 3b3320db8f6..18d1ea8c2c8 100644 --- a/third_party/cares/config_openbsd/ares_config.h +++ b/third_party/cares/config_openbsd/ares_config.h @@ -338,6 +338,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" diff --git a/third_party/cares/config_windows/ares_config.h b/third_party/cares/config_windows/ares_config.h index a128faac371..e984c6e4ad1 100644 --- a/third_party/cares/config_windows/ares_config.h +++ b/third_party/cares/config_windows/ares_config.h @@ -331,6 +331,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ #define HAVE_WS2TCPIP_H +/* Define if __system_property_get exists. */ +/* #undef HAVE___SYSTEM_PROPERTY_GET */ + /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ From 04697287b7634635fda692c123d804422ab3cfe9 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 26 Mar 2019 13:48:39 -0700 Subject: [PATCH 805/814] Attempt to not depend on stdint.h --- .../grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi | 2 -- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi | 12 +++++++++++- .../grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi | 2 -- .../grpcio/grpc/_cython/_cygrpc/records.pyx.pxi | 2 -- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 5fb9ddf7b7d..52ca92f2e9f 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -17,8 +17,6 @@ cimport cpython import grpc import threading -from libc.stdint cimport uintptr_t - def _spawn_callback_in_thread(cb_func, args): ForkManagedThread(target=cb_func, args=args).start() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 7e20f7a4e2d..0a35002a9d4 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -13,7 +13,17 @@ # limitations under the License. cimport libc.time -from libc.stdint cimport intptr_t, uint8_t, int32_t, uint32_t, int64_t + +ctypedef ssize_t intptr_t +ctypedef size_t uintptr_t +ctypedef signed char int8_t +ctypedef signed short int16_t +ctypedef signed int int32_t +ctypedef signed long long int64_t +ctypedef unsigned char uint8_t +ctypedef unsigned short uint16_t +ctypedef unsigned int uint32_t +ctypedef unsigned long long uint64_t cdef extern from "grpc/support/alloc.h": diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi index f5688d08cdc..30fdf6a7600 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pxd.pxi @@ -13,8 +13,6 @@ # limitations under the License. # distutils: language=c++ -from libc.stdint cimport uint32_t - cdef extern from "grpc/impl/codegen/slice.h": struct grpc_slice_buffer: int count diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index d612199a482..02c904b43fc 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from libc.stdint cimport intptr_t - cdef bytes _slice_bytes(grpc_slice slice): cdef void *start = grpc_slice_start_ptr(slice) From 8f77928e04fe47256a4ea6d7b02b6c7d02980a8b Mon Sep 17 00:00:00 2001 From: yang-g Date: Tue, 26 Mar 2019 14:13:40 -0700 Subject: [PATCH 806/814] Log error to stderr --- .../util/proto_reflection_descriptor_database.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc index 119272ca42e..d0c1a847253 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.cc +++ b/test/cpp/util/proto_reflection_descriptor_database.cc @@ -44,14 +44,17 @@ ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() { Status status = stream_->Finish(); if (!status.ok()) { if (status.error_code() == StatusCode::UNIMPLEMENTED) { - gpr_log(GPR_INFO, + fprintf(stderr, "Reflection request not implemented; " - "is the ServerReflection service enabled?"); + "is the ServerReflection service enabled?\n"); + } else { + fprintf(stderr, + "ServerReflectionInfo rpc failed. Error code: %d, message: %s, " + "debug info: %s\n", + static_cast(status.error_code()), + status.error_message().c_str(), + ctx_.debug_error_string().c_str()); } - gpr_log(GPR_INFO, - "ServerReflectionInfo rpc failed. Error code: %d, details: %s", - static_cast(status.error_code()), - status.error_message().c_str()); } } } From 4e9e662729e82bb88570e4151e11fc62d46f6ae7 Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Thu, 14 Mar 2019 16:44:04 -0700 Subject: [PATCH 807/814] Fixed bug in CFStream endpoint. We were failing to return an error when the transport tried to write to an endpoint that was in an errored state. --- src/core/lib/iomgr/cfstream_handle.cc | 27 ++++- test/cpp/end2end/cfstream_test.cc | 150 +++++++++++++++++++++++++- test/cpp/end2end/test_service_impl.cc | 1 + 3 files changed, 170 insertions(+), 8 deletions(-) diff --git a/src/core/lib/iomgr/cfstream_handle.cc b/src/core/lib/iomgr/cfstream_handle.cc index 87b7b9fb334..cf21c4fc511 100644 --- a/src/core/lib/iomgr/cfstream_handle.cc +++ b/src/core/lib/iomgr/cfstream_handle.cc @@ -29,6 +29,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/error_cfstream.h" #include "src/core/lib/iomgr/exec_ctx.h" extern grpc_core::TraceFlag grpc_tcp_trace; @@ -54,6 +55,8 @@ void CFStreamHandle::ReadCallback(CFReadStreamRef stream, void* client_callback_info) { grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; + grpc_error* error; + CFErrorRef stream_error; CFStreamHandle* handle = static_cast(client_callback_info); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, "CFStream ReadCallback (%p, %p, %lu, %p)", handle, @@ -68,8 +71,15 @@ void CFStreamHandle::ReadCallback(CFReadStreamRef stream, handle->read_event_.SetReady(); break; case kCFStreamEventErrorOccurred: - handle->open_event_.SetReady(); - handle->read_event_.SetReady(); + stream_error = CFReadStreamCopyError(stream); + error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_CFERROR(stream_error, "read error"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + CFRelease(stream_error); + handle->open_event_.SetShutdown(GRPC_ERROR_REF(error)); + handle->write_event_.SetShutdown(GRPC_ERROR_REF(error)); + handle->read_event_.SetShutdown(GRPC_ERROR_REF(error)); + GRPC_ERROR_UNREF(error); break; default: GPR_UNREACHABLE_CODE(return ); @@ -80,6 +90,8 @@ void CFStreamHandle::WriteCallback(CFWriteStreamRef stream, void* clientCallBackInfo) { grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; grpc_core::ExecCtx exec_ctx; + grpc_error* error; + CFErrorRef stream_error; CFStreamHandle* handle = static_cast(clientCallBackInfo); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, "CFStream WriteCallback (%p, %p, %lu, %p)", handle, @@ -94,8 +106,15 @@ void CFStreamHandle::WriteCallback(CFWriteStreamRef stream, handle->write_event_.SetReady(); break; case kCFStreamEventErrorOccurred: - handle->open_event_.SetReady(); - handle->write_event_.SetReady(); + stream_error = CFWriteStreamCopyError(stream); + error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_CFERROR(stream_error, "write error"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + CFRelease(stream_error); + handle->open_event_.SetShutdown(GRPC_ERROR_REF(error)); + handle->write_event_.SetShutdown(GRPC_ERROR_REF(error)); + handle->read_event_.SetShutdown(GRPC_ERROR_REF(error)); + GRPC_ERROR_UNREF(error); break; default: GPR_UNREACHABLE_CODE(return ); diff --git a/test/cpp/end2end/cfstream_test.cc b/test/cpp/end2end/cfstream_test.cc index 6ca206e5f36..a6ed7c66d84 100644 --- a/test/cpp/end2end/cfstream_test.cc +++ b/test/cpp/end2end/cfstream_test.cc @@ -47,8 +47,10 @@ #include "test/cpp/end2end/test_service_impl.h" #ifdef GRPC_CFSTREAM +using grpc::ClientAsyncResponseReader; using grpc::testing::EchoRequest; using grpc::testing::EchoResponse; +using grpc::testing::RequestParams; using std::chrono::system_clock; namespace grpc { @@ -60,8 +62,7 @@ class CFStreamTest : public ::testing::Test { CFStreamTest() : server_host_("grpctest"), interface_("lo0"), - ipv4_address_("10.0.0.1"), - netmask_("/32"), + ipv4_address_("127.0.0.2"), kRequestMessage_("🖖") {} void DNSUp() { @@ -92,11 +93,13 @@ class CFStreamTest : public ::testing::Test { } void NetworkUp() { + gpr_log(GPR_DEBUG, "Bringing network up"); InterfaceUp(); DNSUp(); } void NetworkDown() { + gpr_log(GPR_DEBUG, "Bringing network down"); InterfaceDown(); DNSDown(); } @@ -149,6 +152,27 @@ class CFStreamTest : public ::testing::Test { EXPECT_TRUE(status.ok()); } } + void SendAsyncRpc( + const std::unique_ptr& stub, + RequestParams param = RequestParams()) { + EchoRequest request; + auto msg = std::to_string(ctr.load()); + request.set_message(msg); + ctr++; + *request.mutable_param() = std::move(param); + AsyncClientCall* call = new AsyncClientCall; + + call->response_reader = + stub->PrepareAsyncEcho(&call->context, request, &cq_); + + call->response_reader->StartCall(); + gpr_log(GPR_DEBUG, "Sending request: %s", msg.c_str()); + call->response_reader->Finish(&call->reply, &call->status, (void*)call); + } + + void ShutdownCQ() { cq_.Shutdown(); } + + bool CQNext(void** tag, bool* ok) { return cq_.Next(tag, ok); } bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { const gpr_timespec deadline = @@ -172,6 +196,13 @@ class CFStreamTest : public ::testing::Test { return true; } + struct AsyncClientCall { + EchoResponse reply; + ClientContext context; + Status status; + std::unique_ptr> response_reader; + }; + private: struct ServerData { int port_; @@ -214,14 +245,14 @@ class CFStreamTest : public ::testing::Test { } }; + CompletionQueue cq_; const grpc::string server_host_; const grpc::string interface_; const grpc::string ipv4_address_; - const grpc::string netmask_; - std::unique_ptr stub_; std::unique_ptr server_; int port_; const grpc::string kRequestMessage_; + std::atomic_int ctr{0}; }; // gRPC should automatically detech network flaps (without enabling keepalives) @@ -261,6 +292,117 @@ TEST_F(CFStreamTest, NetworkTransition) { sender.join(); } +// Network flaps while RPCs are in flight +TEST_F(CFStreamTest, NetworkFlapRpcsInFlight) { + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + std::atomic_int rpcs_sent{0}; + + // Channel should be in READY state after we send some RPCs + for (int i = 0; i < 10; ++i) { + SendAsyncRpc(stub); + ++rpcs_sent; + } + EXPECT_TRUE(WaitForChannelReady(channel.get())); + + // Bring down the network + NetworkDown(); + + std::thread thd = std::thread([this, &rpcs_sent]() { + void* got_tag; + bool ok = false; + bool network_down = true; + int total_completions = 0; + + while (CQNext(&got_tag, &ok)) { + ++total_completions; + GPR_ASSERT(ok); + AsyncClientCall* call = static_cast(got_tag); + if (call->status.ok()) { + gpr_log(GPR_DEBUG, "RPC response: %s", call->reply.message().c_str()); + } else { + gpr_log(GPR_DEBUG, "RPC failed with error: %s", + call->status.error_message().c_str()); + // Bring network up when RPCs start failing + if (network_down) { + NetworkUp(); + network_down = false; + } + } + delete call; + } + EXPECT_EQ(total_completions, rpcs_sent); + }); + + for (int i = 0; i < 100; ++i) { + SendAsyncRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + ++rpcs_sent; + } + + ShutdownCQ(); + + thd.join(); +} + +// Send a bunch of RPCs, some of which are expected to fail. +// We should get back a response for all RPCs +TEST_F(CFStreamTest, ConcurrentRpc) { + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + std::atomic_int rpcs_sent{0}; + std::thread thd = std::thread([this, &rpcs_sent]() { + void* got_tag; + bool ok = false; + bool network_down = true; + int total_completions = 0; + + while (CQNext(&got_tag, &ok)) { + ++total_completions; + GPR_ASSERT(ok); + AsyncClientCall* call = static_cast(got_tag); + if (call->status.ok()) { + gpr_log(GPR_DEBUG, "RPC response: %s", call->reply.message().c_str()); + } else { + gpr_log(GPR_DEBUG, "RPC failed: %s", + call->status.error_message().c_str()); + // Bring network up when RPCs start failing + if (network_down) { + NetworkUp(); + network_down = false; + } + } + delete call; + } + EXPECT_EQ(total_completions, rpcs_sent); + }); + + for (int i = 0; i < 10; ++i) { + if (i % 3 == 0) { + RequestParams param; + ErrorStatus* error = param.mutable_expected_error(); + error->set_code(StatusCode::INTERNAL); + error->set_error_message("internal error"); + SendAsyncRpc(stub, param); + } else if (i % 5 == 0) { + RequestParams param; + param.set_echo_metadata(true); + DebugInfo* info = param.mutable_debug_info(); + info->add_stack_entries("stack_entry1"); + info->add_stack_entries("stack_entry2"); + info->set_detail("detailed debug info"); + SendAsyncRpc(stub, param); + } else { + SendAsyncRpc(stub); + } + ++rpcs_sent; + } + + ShutdownCQ(); + + thd.join(); +} + } // namespace } // namespace testing } // namespace grpc diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 1cbbc703076..abbb669cf5c 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -143,6 +143,7 @@ void LoopUntilCancelled(Alarm* alarm, ServerContext* context, Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, EchoResponse* response) { + gpr_log(GPR_DEBUG, "Request message was %s", request->message().c_str()); // A bit of sleep to make sure that short deadline tests fail if (request->has_param() && request->param().server_sleep_us() > 0) { gpr_sleep_until( From 9169159f30e6a09b3e8676a940528e6688c63845 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 25 Mar 2019 11:45:33 -0700 Subject: [PATCH 808/814] Comments for all callback API methods --- include/grpcpp/generic/generic_stub.h | 5 + .../impl/codegen/async_generic_service.h | 20 ++- include/grpcpp/impl/codegen/client_callback.h | 118 +++++++++++-- include/grpcpp/impl/codegen/server_callback.h | 163 ++++++++++++++---- include/grpcpp/server_builder.h | 4 + 5 files changed, 262 insertions(+), 48 deletions(-) diff --git a/include/grpcpp/generic/generic_stub.h b/include/grpcpp/generic/generic_stub.h index eb014184e4a..9252599bac3 100644 --- a/include/grpcpp/generic/generic_stub.h +++ b/include/grpcpp/generic/generic_stub.h @@ -73,10 +73,15 @@ class GenericStub final { public: explicit experimental_type(GenericStub* stub) : stub_(stub) {} + /// Setup and start a unary call to a named method \a method using + /// \a context and specifying the \a request and \a response buffers. void UnaryCall(ClientContext* context, const grpc::string& method, const ByteBuffer* request, ByteBuffer* response, std::function on_completion); + /// Setup a call to a named method \a method using \a context and tied to + /// \a reactor . Like any other bidi streaming RPC, it will not be activated + /// until StartCall is invoked on its reactor. void PrepareBidiStreamingCall( ClientContext* context, const grpc::string& method, experimental::ClientBidiReactor* reactor); diff --git a/include/grpcpp/impl/codegen/async_generic_service.h b/include/grpcpp/impl/codegen/async_generic_service.h index 46489b135d7..759f6683bf4 100644 --- a/include/grpcpp/impl/codegen/async_generic_service.h +++ b/include/grpcpp/impl/codegen/async_generic_service.h @@ -85,13 +85,23 @@ class AsyncGenericService final { namespace experimental { +/// \a ServerGenericBidiReactor is the reactor class for bidi streaming RPCs +/// invoked on a CallbackGenericService. The API difference relative to +/// ServerBidiReactor is that the argument to OnStarted is a +/// GenericServerContext rather than a ServerContext. All other reaction and +/// operation initiation APIs are the same as ServerBidiReactor. class ServerGenericBidiReactor : public ServerBidiReactor { public: + /// Similar to ServerBidiReactor::OnStarted except for argument type. + /// + /// \param[in] context The context object associated with this RPC. + virtual void OnStarted(GenericServerContext* context) {} + + private: void OnStarted(ServerContext* ctx) final { OnStarted(static_cast(ctx)); } - virtual void OnStarted(GenericServerContext* ctx) {} }; } // namespace experimental @@ -108,10 +118,18 @@ class UnimplementedGenericBidiReactor } // namespace internal namespace experimental { + +/// \a CallbackGenericService is the base class for generic services implemented +/// using the callback API and registered through the ServerBuilder using +/// RegisterCallbackGenericService. class CallbackGenericService { public: CallbackGenericService() {} virtual ~CallbackGenericService() {} + + /// The "method handler" for the generic API. This function should be + /// overridden to return a ServerGenericBidiReactor that implements the + /// application-level interface for this RPC. virtual ServerGenericBidiReactor* CreateReactor() { return new internal::UnimplementedGenericBidiReactor; } diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 89629c079af..53c57b55f7e 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -157,28 +157,69 @@ class ClientCallbackWriter { } }; -// The user must implement this reactor interface with reactions to each event -// type that gets called by the library. An empty reaction is provided by -// default +// The following classes are the reactor interfaces that are to be implemented +// by the user. They are passed in to the library as an argument to a call on a +// stub (either a codegen-ed call or a generic call). The streaming RPC is +// activated by calling StartCall, possibly after initiating StartRead, +// StartWrite, or AddHold operations on the streaming object. Note that none of +// the classes are pure; all reactions have a default empty reaction so that the +// user class only needs to override those classes that it cares about. + +/// \a ClientBidiReactor is the interface for a bidirectional streaming RPC. template class ClientBidiReactor { public: virtual ~ClientBidiReactor() {} - virtual void OnDone(const Status& s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - virtual void OnReadDone(bool ok) {} - virtual void OnWriteDone(bool ok) {} - virtual void OnWritesDoneDone(bool ok) {} + /// Activate the RPC and initiate any reads or writes that have been Start'ed + /// before this call. All streaming RPCs issued by the client MUST have + /// StartCall invoked on them (even if they are canceled) as this call is the + /// activation of their lifecycle. void StartCall() { stream_->StartCall(); } + + /// Initiate a read operation (or post it for later initiation if StartCall + /// has not yet been invoked). + /// + /// \param[out] resp Where to eventually store the read message. Valid when + /// the library calls OnReadDone void StartRead(Response* resp) { stream_->Read(resp); } + + /// Initiate a write operation (or post it for later initiation if StartCall + /// has not yet been invoked). + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); } + + /// Initiate/post a write operation with specified options. + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. + /// \param[in] options The WriteOptions to use for writing this message void StartWrite(const Request* req, WriteOptions options) { stream_->Write(req, std::move(options)); } + + /// Initiate/post a write operation with specified options and an indication + /// that this is the last write (like StartWrite and StartWritesDone, merged). + /// Note that calling this means that no more calls to StartWrite, + /// StartWriteLast, or StartWritesDone are allowed. + /// + /// \param[in] req The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the application + /// regains ownership of msg. + /// \param[in] options The WriteOptions to use for writing this message void StartWriteLast(const Request* req, WriteOptions options) { StartWrite(req, std::move(options.set_last_message())); } + + /// Indicate that the RPC will have no more write operations. This can only be + /// issued once for a given RPC. This is not required or allowed if + /// StartWriteLast is used since that already has the same implication. + /// Note that calling this means that no more calls to StartWrite, + /// StartWriteLast, or StartWritesDone are allowed. void StartWritesDone() { stream_->WritesDone(); } /// Holds are needed if (and only if) this stream has operations that take @@ -196,14 +237,51 @@ class ClientBidiReactor { /// AddHold or AddMultipleHolds before StartCall. If there is going to be, /// for example, a read-flow and a write-flow taking place outside the /// reactions, then call AddMultipleHolds(2) before StartCall. When the - /// application knows that it won't issue any more Read operations (such as + /// application knows that it won't issue any more read operations (such as /// when a read comes back as not ok), it should issue a RemoveHold(). It /// should also call RemoveHold() again after it does StartWriteLast or - /// StartWritesDone that indicates that there will be no more Write ops. + /// StartWritesDone that indicates that there will be no more write ops. + /// The number of RemoveHold calls must match the total number of AddHold + /// calls plus the number of holds added by AddMultipleHolds. void AddHold() { AddMultipleHolds(1); } void AddMultipleHolds(int holds) { stream_->AddHold(holds); } void RemoveHold() { stream_->RemoveHold(); } + /// Notifies the application that all operations associated with this RPC + /// have completed and provides the RPC status outcome. + /// + /// \param[in] s The status outcome of this RPC + virtual void OnDone(const Status& s) {} + + /// Notifies the application that a read of initial metadata from the + /// server is done. If the application chooses not to implement this method, + /// it can assume that the initial metadata has been read before the first + /// call of OnReadDone or OnDone. + /// + /// \param[in] ok Was the initial metadata read successfully? If false, no + /// further read-side operation will succeed. + virtual void OnReadInitialMetadataDone(bool ok) {} + + /// Notifies the application that a StartRead operation completed. + /// + /// \param[in] ok Was it successful? If false, no further read-side operation + /// will succeed. + virtual void OnReadDone(bool ok) {} + + /// Notifies the application that a StartWrite operation completed. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnWriteDone(bool ok) {} + + /// Notifies the application that a StartWritesDone operation completed. Note + /// that this is only used on explicit StartWritesDone operations and not for + /// those that are implicitly invoked as part of a StartWriteLast. + /// + /// \param[in] ok Was it successful? If false, the application will later see + /// the failure reflected as a bad status in OnDone. + virtual void OnWritesDoneDone(bool ok) {} + private: friend class ClientCallbackReaderWriter; void BindStream(ClientCallbackReaderWriter* stream) { @@ -212,13 +290,12 @@ class ClientBidiReactor { ClientCallbackReaderWriter* stream_; }; +/// \a ClientReadReactor is the interface for a server-streaming RPC. +/// All public methods behave as in ClientBidiReactor. template class ClientReadReactor { public: virtual ~ClientReadReactor() {} - virtual void OnDone(const Status& s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - virtual void OnReadDone(bool ok) {} void StartCall() { reader_->StartCall(); } void StartRead(Response* resp) { reader_->Read(resp); } @@ -227,20 +304,22 @@ class ClientReadReactor { void AddMultipleHolds(int holds) { reader_->AddHold(holds); } void RemoveHold() { reader_->RemoveHold(); } + virtual void OnDone(const Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnReadDone(bool ok) {} + private: friend class ClientCallbackReader; void BindReader(ClientCallbackReader* reader) { reader_ = reader; } ClientCallbackReader* reader_; }; +/// \a ClientWriteReactor is the interface for a client-streaming RPC. +/// All public methods behave as in ClientBidiReactor. template class ClientWriteReactor { public: virtual ~ClientWriteReactor() {} - virtual void OnDone(const Status& s) {} - virtual void OnReadInitialMetadataDone(bool ok) {} - virtual void OnWriteDone(bool ok) {} - virtual void OnWritesDoneDone(bool ok) {} void StartCall() { writer_->StartCall(); } void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); } @@ -256,6 +335,11 @@ class ClientWriteReactor { void AddMultipleHolds(int holds) { writer_->AddHold(holds); } void RemoveHold() { writer_->RemoveHold(); } + virtual void OnDone(const Status& s) {} + virtual void OnReadInitialMetadataDone(bool ok) {} + virtual void OnWriteDone(bool ok) {} + virtual void OnWritesDoneDone(bool ok) {} + private: friend class ClientCallbackWriter; void BindWriter(ClientCallbackWriter* writer) { writer_ = writer; } diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 33988fb6c23..7421acc45bf 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -40,7 +40,12 @@ namespace internal { class ServerReactor { public: virtual ~ServerReactor() = default; + + /// Notifies the application that all operations associated with this RPC + /// have completed. virtual void OnDone() {} + + /// Notifies the application that this RPC has been cancelled. virtual void OnCancel() {} }; @@ -167,33 +172,110 @@ class ServerCallbackReaderWriter { } }; -// The following classes are reactors that are to be implemented -// by the user, returned as the result of the method handler for -// a callback method, and activated by the call to OnStarted +// The following classes are the reactor interfaces that are to be implemented +// by the user, returned as the result of the method handler for a callback +// method, and activated by the call to OnStarted. Note that none of the classes +// are pure; all reactions have a default empty reaction so that the user class +// only needs to override those classes that it cares about. + +/// \a ServerBidiReactor is the interface for a bidirectional streaming RPC. template class ServerBidiReactor : public internal::ServerReactor { public: ~ServerBidiReactor() = default; - virtual void OnStarted(ServerContext*) {} - virtual void OnSendInitialMetadataDone(bool ok) {} - virtual void OnReadDone(bool ok) {} - virtual void OnWriteDone(bool ok) {} + /// Send any initial metadata stored in the RPC context. If not invoked, + /// any initial metadata will be passed along with the first Write or the + /// Finish (if there are no writes). void StartSendInitialMetadata() { stream_->SendInitialMetadata(); } - void StartRead(Request* msg) { stream_->Read(msg); } - void StartWrite(const Response* msg) { StartWrite(msg, WriteOptions()); } - void StartWrite(const Response* msg, WriteOptions options) { - stream_->Write(msg, std::move(options)); + + /// Initiate a read operation. + /// + /// \param[out] req Where to eventually store the read message. Valid when + /// the library calls OnReadDone + void StartRead(Request* req) { stream_->Read(req); } + + /// Initiate a write operation. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + void StartWrite(const Response* resp) { StartWrite(resp, WriteOptions()); } + + /// Initiate a write operation with specified options. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + void StartWrite(const Response* resp, WriteOptions options) { + stream_->Write(resp, std::move(options)); } - void StartWriteAndFinish(const Response* msg, WriteOptions options, + + /// Initiate a write operation with specified options and final RPC Status, + /// which also causes any trailing metadata for this RPC to be sent out. + /// StartWriteAndFinish is like merging StartWriteLast and Finish into a + /// single step. A key difference, though, is that this operation doesn't have + /// an OnWriteDone reaction - it is considered complete only when OnDone is + /// available. An RPC can either have StartWriteAndFinish or Finish, but not + /// both. + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until Onone, at which point the application + /// regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + /// \param[in] s The status outcome of this RPC + void StartWriteAndFinish(const Response* resp, WriteOptions options, Status s) { - stream_->WriteAndFinish(msg, std::move(options), std::move(s)); + stream_->WriteAndFinish(resp, std::move(options), std::move(s)); } - void StartWriteLast(const Response* msg, WriteOptions options) { - StartWrite(msg, std::move(options.set_last_message())); + + /// Inform system of a planned write operation with specified options, but + /// allow the library to schedule the actual write coalesced with the writing + /// of trailing metadata (which takes place on a Finish call). + /// + /// \param[in] resp The message to be written. The library takes temporary + /// ownership until OnWriteDone, at which point the + /// application regains ownership of resp. + /// \param[in] options The WriteOptions to use for writing this message + void StartWriteLast(const Response* resp, WriteOptions options) { + StartWrite(resp, std::move(options.set_last_message())); } + + /// Indicate that the stream is to be finished and the trailing metadata and + /// RPC status are to be sent. Every RPC MUST be finished using either Finish + /// or StartWriteAndFinish (but not both), even if the RPC is already + /// cancelled. + /// + /// \param[in] s The status outcome of this RPC void Finish(Status s) { stream_->Finish(std::move(s)); } + /// Notify the application that a streaming RPC has started + /// + /// \param[in] context The context object now associated with this RPC + virtual void OnStarted(ServerContext* context) {} + + /// Notifies the application that an explicit StartSendInitialMetadata + /// operation completed. Not used when the sending of initial metadata + /// piggybacks onto the first write. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnSendInitialMetadataDone(bool ok) {} + + /// Notifies the application that a StartRead operation completed. + /// + /// \param[in] ok Was it successful? If false, no further read-side operation + /// will succeed. + virtual void OnReadDone(bool ok) {} + + /// Notifies the application that a StartWrite (or StartWriteLast) operation + /// completed. + /// + /// \param[in] ok Was it successful? If false, no further write-side operation + /// will succeed. + virtual void OnWriteDone(bool ok) {} + private: friend class ServerCallbackReaderWriter; void BindStream(ServerCallbackReaderWriter* stream) { @@ -203,18 +285,29 @@ class ServerBidiReactor : public internal::ServerReactor { ServerCallbackReaderWriter* stream_; }; +/// \a ServerReadReactor is the interface for a client-streaming RPC. template class ServerReadReactor : public internal::ServerReactor { public: ~ServerReadReactor() = default; - virtual void OnStarted(ServerContext*, Response* resp) {} + + /// The following operation initiations are exactly like ServerBidiReactor. + void StartSendInitialMetadata() { reader_->SendInitialMetadata(); } + void StartRead(Request* req) { reader_->Read(req); } + void Finish(Status s) { reader_->Finish(std::move(s)); } + + /// Similar to ServerBidiReactor::OnStarted, except that this also provides + /// the response object that the stream fills in before calling Finish. + /// (It must be filled in if status is OK, but it may be filled in otherwise.) + /// + /// \param[in] context The context object now associated with this RPC + /// \param[in] resp The response object to be used by this RPC + virtual void OnStarted(ServerContext* context, Response* resp) {} + + /// The following notifications are exactly like ServerBidiReactor. virtual void OnSendInitialMetadataDone(bool ok) {} virtual void OnReadDone(bool ok) {} - void StartSendInitialMetadata() { reader_->SendInitialMetadata(); } - void StartRead(Request* msg) { reader_->Read(msg); } - void Finish(Status s) { reader_->Finish(std::move(s)); } - private: friend class ServerCallbackReader; void BindReader(ServerCallbackReader* reader) { reader_ = reader; } @@ -222,28 +315,38 @@ class ServerReadReactor : public internal::ServerReactor { ServerCallbackReader* reader_; }; +/// \a ServerReadReactor is the interface for a server-streaming RPC. template class ServerWriteReactor : public internal::ServerReactor { public: ~ServerWriteReactor() = default; - virtual void OnStarted(ServerContext*, const Request* req) {} - virtual void OnSendInitialMetadataDone(bool ok) {} - virtual void OnWriteDone(bool ok) {} + /// The following operation initiations are exactly like ServerBidiReactor. void StartSendInitialMetadata() { writer_->SendInitialMetadata(); } - void StartWrite(const Response* msg) { StartWrite(msg, WriteOptions()); } - void StartWrite(const Response* msg, WriteOptions options) { - writer_->Write(msg, std::move(options)); + void StartWrite(const Response* resp) { StartWrite(resp, WriteOptions()); } + void StartWrite(const Response* resp, WriteOptions options) { + writer_->Write(resp, std::move(options)); } - void StartWriteAndFinish(const Response* msg, WriteOptions options, + void StartWriteAndFinish(const Response* resp, WriteOptions options, Status s) { - writer_->WriteAndFinish(msg, std::move(options), std::move(s)); + writer_->WriteAndFinish(resp, std::move(options), std::move(s)); } - void StartWriteLast(const Response* msg, WriteOptions options) { - StartWrite(msg, std::move(options.set_last_message())); + void StartWriteLast(const Response* resp, WriteOptions options) { + StartWrite(resp, std::move(options.set_last_message())); } void Finish(Status s) { writer_->Finish(std::move(s)); } + /// Similar to ServerBidiReactor::OnStarted, except that this also provides + /// the request object sent by the client. + /// + /// \param[in] context The context object now associated with this RPC + /// \param[in] req The request object sent by the client + virtual void OnStarted(ServerContext* context, const Request* req) {} + + /// The following notifications are exactly like ServerBidiReactor. + virtual void OnSendInitialMetadataDone(bool ok) {} + virtual void OnWriteDone(bool ok) {} + private: friend class ServerCallbackWriter; void BindWriter(ServerCallbackWriter* writer) { writer_ = writer; } diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 498e5b7bb31..18cfbb26c75 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -231,6 +231,10 @@ class ServerBuilder { builder_->interceptor_creators_ = std::move(interceptor_creators); } + /// Register a generic service that uses the callback API. + /// Matches requests with any :authority + /// This is mostly useful for writing generic gRPC Proxies where the exact + /// serialization format is unknown ServerBuilder& RegisterCallbackGenericService( experimental::CallbackGenericService* service); From abb991be25095dba3b77e7d7922e4a7d8faca917 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 25 Mar 2019 11:45:33 -0700 Subject: [PATCH 809/814] Further clarify some APIs by removing their comments from internal:: --- include/grpcpp/impl/codegen/server_callback.h | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 7421acc45bf..335d5709db6 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -40,13 +40,8 @@ namespace internal { class ServerReactor { public: virtual ~ServerReactor() = default; - - /// Notifies the application that all operations associated with this RPC - /// have completed. - virtual void OnDone() {} - - /// Notifies the application that this RPC has been cancelled. - virtual void OnCancel() {} + virtual void OnDone() = 0; + virtual void OnCancel() = 0; }; } // namespace internal @@ -276,6 +271,16 @@ class ServerBidiReactor : public internal::ServerReactor { /// will succeed. virtual void OnWriteDone(bool ok) {} + /// Notifies the application that all operations associated with this RPC + /// have completed. This is an override (from the internal base class) but not + /// final, so derived classes should override it if they want to take action. + void OnDone() override {} + + /// Notifies the application that this RPC has been cancelled. This is an + /// override (from the internal base class) but not final, so derived classes + /// should override it if they want to take action. + void OnCancel() override {} + private: friend class ServerCallbackReaderWriter; void BindStream(ServerCallbackReaderWriter* stream) { @@ -307,6 +312,8 @@ class ServerReadReactor : public internal::ServerReactor { /// The following notifications are exactly like ServerBidiReactor. virtual void OnSendInitialMetadataDone(bool ok) {} virtual void OnReadDone(bool ok) {} + void OnDone() override {} + void OnCancel() override {} private: friend class ServerCallbackReader; @@ -346,6 +353,8 @@ class ServerWriteReactor : public internal::ServerReactor { /// The following notifications are exactly like ServerBidiReactor. virtual void OnSendInitialMetadataDone(bool ok) {} virtual void OnWriteDone(bool ok) {} + void OnDone() override {} + void OnCancel() override {} private: friend class ServerCallbackWriter; From b0e75a42d28c232e8940f4578551cd2eb72a5c2e Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 27 Mar 2019 14:10:46 -0400 Subject: [PATCH 810/814] Fix a NULL deref in tcp_client_windows.cc `grpc_sockaddr_to_uri(addr)` can return nullptr, and we are directly passing it to grpc_slice_from_copied_string. Clusterfuzz found this issue in https://clusterfuzz.com/testcase-detail/5188592759603200 Use "NULL" when target URI is nullptr, to avoid null deref. Fixes 18544 --- src/core/lib/iomgr/tcp_client_windows.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index e5b5502597e..e24431b9a3e 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -213,10 +213,12 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, failure: GPR_ASSERT(error != GRPC_ERROR_NONE); char* target_uri = grpc_sockaddr_to_uri(addr); - grpc_error* final_error = grpc_error_set_str( - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Failed to connect", - &error, 1), - GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(target_uri)); + grpc_error* final_error = + grpc_error_set_str(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Failed to connect", &error, 1), + GRPC_ERROR_STR_TARGET_ADDRESS, + grpc_slice_from_copied_string( + target_uri == nullptr ? "NULL" : target_uri)); GRPC_ERROR_UNREF(error); if (socket != NULL) { grpc_winsocket_destroy(socket); From 847b0155d96f1b372e9f69792a2e9bb750e41696 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 27 Mar 2019 16:30:07 -0700 Subject: [PATCH 811/814] Promise to call OnStarted and forbid Start* until after OnStarted --- include/grpcpp/impl/codegen/server_callback.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h index 335d5709db6..87edea84f41 100644 --- a/include/grpcpp/impl/codegen/server_callback.h +++ b/include/grpcpp/impl/codegen/server_callback.h @@ -169,9 +169,13 @@ class ServerCallbackReaderWriter { // The following classes are the reactor interfaces that are to be implemented // by the user, returned as the result of the method handler for a callback -// method, and activated by the call to OnStarted. Note that none of the classes -// are pure; all reactions have a default empty reaction so that the user class -// only needs to override those classes that it cares about. +// method, and activated by the call to OnStarted. The library guarantees that +// OnStarted will be called for any reactor that has been created using a +// method handler registered on a service. No operation initiation method may be +// called until after the call to OnStarted. +// Note that none of the classes are pure; all reactions have a default empty +// reaction so that the user class only needs to override those classes that it +// cares about. /// \a ServerBidiReactor is the interface for a bidirectional streaming RPC. template @@ -179,6 +183,9 @@ class ServerBidiReactor : public internal::ServerReactor { public: ~ServerBidiReactor() = default; + /// Do NOT call any operation initiation method (names that start with Start) + /// until after the library has called OnStarted on this object. + /// Send any initial metadata stored in the RPC context. If not invoked, /// any initial metadata will be passed along with the first Write or the /// Finish (if there are no writes). @@ -245,7 +252,8 @@ class ServerBidiReactor : public internal::ServerReactor { /// \param[in] s The status outcome of this RPC void Finish(Status s) { stream_->Finish(std::move(s)); } - /// Notify the application that a streaming RPC has started + /// Notify the application that a streaming RPC has started and that it is now + /// ok to call any operation initation method. /// /// \param[in] context The context object now associated with this RPC virtual void OnStarted(ServerContext* context) {} From bb96e30434a83aa0c3ce712a18a5e7e69b113b47 Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Wed, 27 Mar 2019 21:11:18 -0700 Subject: [PATCH 812/814] PHP: should use grpc_shutdown_blocking --- src/php/ext/grpc/php_grpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index fa6f0be837b..9c7a9d98615 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -180,7 +180,7 @@ void postfork_child() { grpc_php_shutdown_completion_queue(TSRMLS_C); // clean-up grpc_core - grpc_shutdown(); + grpc_shutdown_blocking(); if (grpc_is_initialized() > 0) { zend_throw_exception(spl_ce_UnexpectedValueException, "Oops, failed to shutdown gRPC Core after fork()", From 3107cda311853ce57f3a67847ce15dd14a5c9fd5 Mon Sep 17 00:00:00 2001 From: Kelly Norton Date: Wed, 27 Mar 2019 10:22:52 -0400 Subject: [PATCH 813/814] Add ini settings for fork support to PHP extension. --- src/php/ext/grpc/php_grpc.c | 48 ++++++++++---------- src/php/ext/grpc/php_grpc.h | 2 + src/php/ext/grpc/tests/grpc-default-ini.phpt | 15 ++++++ src/php/ext/grpc/tests/grpc-set-ini.phpt | 24 ++++++++++ 4 files changed, 66 insertions(+), 23 deletions(-) create mode 100644 src/php/ext/grpc/tests/grpc-default-ini.phpt create mode 100644 src/php/ext/grpc/tests/grpc-set-ini.phpt diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 9c7a9d98615..3064563d03f 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -67,27 +67,22 @@ ZEND_GET_MODULE(grpc) /* {{{ PHP_INI */ -/* Remove comments and fill if you need to have entries in php.ini PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("grpc.global_value", "42", PHP_INI_ALL, OnUpdateLong, - global_value, zend_grpc_globals, grpc_globals) - STD_PHP_INI_ENTRY("grpc.global_string", "foobar", PHP_INI_ALL, - OnUpdateString, global_string, zend_grpc_globals, - grpc_globals) + STD_PHP_INI_ENTRY("grpc.enable_fork_support", "0", PHP_INI_SYSTEM, OnUpdateBool, + enable_fork_support, zend_grpc_globals, grpc_globals) + STD_PHP_INI_ENTRY("grpc.poll_strategy", NULL, PHP_INI_SYSTEM, OnUpdateString, + poll_strategy, zend_grpc_globals, grpc_globals) PHP_INI_END() -*/ /* }}} */ /* {{{ php_grpc_init_globals */ -/* Uncomment this function if you have INI entries - static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) - { - grpc_globals->global_value = 0; - grpc_globals->global_string = NULL; - } -*/ +static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) { + grpc_globals->enable_fork_support = 0; + grpc_globals->poll_strategy = NULL; +} /* }}} */ + void create_new_channel( wrapped_grpc_channel *channel, char *target, @@ -208,12 +203,22 @@ void register_fork_handlers() { } } +void apply_ini_settings() { + if (GRPC_G(enable_fork_support)) { + setenv("GRPC_ENABLE_FORK_SUPPORT", "1", 1 /* overwrite? */); + } + + if (GRPC_G(poll_strategy)) { + setenv("GRPC_POLL_STRATEGY", GRPC_G(poll_strategy), 1 /* overwrite? */); + } +} + /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(grpc) { - /* If you have INI entries, uncomment these lines - REGISTER_INI_ENTRIES(); - */ + ZEND_INIT_MODULE_GLOBALS(grpc, php_grpc_init_globals, NULL); + REGISTER_INI_ENTRIES(); + /* Register call error constants */ REGISTER_LONG_CONSTANT("Grpc\\CALL_OK", GRPC_CALL_OK, CONST_CS | CONST_PERSISTENT); @@ -349,9 +354,7 @@ PHP_MINIT_FUNCTION(grpc) { /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(grpc) { - /* uncomment this line if you have INI entries - UNREGISTER_INI_ENTRIES(); - */ + UNREGISTER_INI_ENTRIES(); // WARNING: This function IS being called by PHP when the extension // is unloaded but the logs were somehow suppressed. if (GRPC_G(initialized)) { @@ -375,9 +378,7 @@ PHP_MINFO_FUNCTION(grpc) { php_info_print_table_row(2, "grpc support", "enabled"); php_info_print_table_row(2, "grpc module version", PHP_GRPC_VERSION); php_info_print_table_end(); - /* Remove comments if you have entries in php.ini - DISPLAY_INI_ENTRIES(); - */ + DISPLAY_INI_ENTRIES(); } /* }}} */ @@ -385,6 +386,7 @@ PHP_MINFO_FUNCTION(grpc) { */ PHP_RINIT_FUNCTION(grpc) { if (!GRPC_G(initialized)) { + apply_ini_settings(); grpc_init(); register_fork_handlers(); grpc_php_init_completion_queue(TSRMLS_C); diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h index ecf5ebaa05b..2629b1bbd78 100644 --- a/src/php/ext/grpc/php_grpc.h +++ b/src/php/ext/grpc/php_grpc.h @@ -66,6 +66,8 @@ PHP_RINIT_FUNCTION(grpc); */ ZEND_BEGIN_MODULE_GLOBALS(grpc) zend_bool initialized; + zend_bool enable_fork_support; + char *poll_strategy; ZEND_END_MODULE_GLOBALS(grpc) /* In every utility function you add that needs to use variables diff --git a/src/php/ext/grpc/tests/grpc-default-ini.phpt b/src/php/ext/grpc/tests/grpc-default-ini.phpt new file mode 100644 index 00000000000..0fbcc1f119e --- /dev/null +++ b/src/php/ext/grpc/tests/grpc-default-ini.phpt @@ -0,0 +1,15 @@ +--TEST-- +Ensure default ini settings +--SKIPIF-- + +--FILE-- + +--INI-- +grpc.enable_fork_support = 1 +grpc.poll_strategy = epoll1 +--FILE-- + Date: Thu, 28 Mar 2019 07:54:25 -0700 Subject: [PATCH 814/814] Split data plane and control plane into their own combiners. --- .../filters/client_channel/client_channel.cc | 234 ++++++++++++------ .../ext/filters/client_channel/lb_policy.cc | 7 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 11 +- 3 files changed, 170 insertions(+), 82 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 82ce253c83c..dea6e059693 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -100,49 +100,52 @@ struct QueuedPick { }; typedef struct client_channel_channel_data { + // + // Fields set at construction and never modified. + // bool deadline_checking_enabled; bool enable_retries; size_t per_rpc_retry_buffer_size; - - /** combiner protecting all variables below in this data structure */ - grpc_combiner* combiner; - /** owning stack */ grpc_channel_stack* owning_stack; - /** interested parties (owned) */ - grpc_pollset_set* interested_parties; - // Client channel factory. grpc_core::ClientChannelFactory* client_channel_factory; - // Subchannel pool. - grpc_core::RefCountedPtr subchannel_pool; grpc_core::channelz::ClientChannelNode* channelz_node; - // Resolving LB policy. - grpc_core::OrphanablePtr resolving_lb_policy; - // Subchannel picker from LB policy. + // + // Fields used in the data plane. Protected by data_plane_combiner. + // + grpc_combiner* data_plane_combiner; grpc_core::UniquePtr picker; - // Linked list of queued picks. - QueuedPick* queued_picks; - - bool have_service_config; - /** retry throttle data from service config */ + QueuedPick* queued_picks; // Linked list of queued picks. + // Data from service config. + bool received_service_config_data; grpc_core::RefCountedPtr retry_throttle_data; - /** per-method service config data */ grpc_core::RefCountedPtr method_params_table; - /* the following properties are guarded by a mutex since APIs require them - to be instantaneously available */ + // + // Fields used in the control plane. Protected by combiner. + // + grpc_combiner* combiner; + grpc_pollset_set* interested_parties; + grpc_core::RefCountedPtr subchannel_pool; + grpc_core::OrphanablePtr resolving_lb_policy; + grpc_connectivity_state_tracker state_tracker; + + // + // Fields accessed from both data plane and control plane combiners. + // + grpc_core::Atomic disconnect_error; + + // external_connectivity_watcher_list head is guarded by its own mutex, since + // counts need to be grabbed immediately without polling on a CQ. + gpr_mu external_connectivity_watcher_list_mu; + struct external_connectivity_watcher* external_connectivity_watcher_list_head; + + // The following properties are guarded by a mutex since APIs require them + // to be instantaneously available. gpr_mu info_mu; grpc_core::UniquePtr info_lb_policy_name; grpc_core::UniquePtr info_service_config_json; - - grpc_connectivity_state_tracker state_tracker; - grpc_error* disconnect_error; - - /* external_connectivity_watcher_list head is guarded by its own mutex, since - * counts need to be grabbed immediately without polling on a cq */ - gpr_mu external_connectivity_watcher_list_mu; - struct external_connectivity_watcher* external_connectivity_watcher_list_head; } channel_data; // Forward declarations. @@ -166,31 +169,99 @@ static const char* get_channel_connectivity_state_change_string( GPR_UNREACHABLE_CODE(return "UNKNOWN"); } -static void set_connectivity_state_and_picker_locked( - channel_data* chand, grpc_connectivity_state state, grpc_error* state_error, - const char* reason, - grpc_core::UniquePtr picker) { - // Update connectivity state. - grpc_connectivity_state_set(&chand->state_tracker, state, state_error, - reason); - if (chand->channelz_node != nullptr) { - chand->channelz_node->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - get_channel_connectivity_state_change_string(state))); - } - // Update picker. - chand->picker = std::move(picker); - // Re-process queued picks. - for (QueuedPick* pick = chand->queued_picks; pick != nullptr; - pick = pick->next) { - start_pick_locked(pick->elem, GRPC_ERROR_NONE); - } -} - namespace grpc_core { namespace { +// A fire-and-forget class that sets the channel's connectivity state +// and then hops into the data plane combiner to update the picker. +// Must be instantiated while holding the control plane combiner. +// Deletes itself when done. +class ConnectivityStateAndPickerSetter { + public: + ConnectivityStateAndPickerSetter( + channel_data* chand, grpc_connectivity_state state, + grpc_error* state_error, const char* reason, + UniquePtr picker) + : chand_(chand), picker_(std::move(picker)) { + // Update connectivity state here, while holding control plane combiner. + grpc_connectivity_state_set(&chand->state_tracker, state, state_error, + reason); + if (chand->channelz_node != nullptr) { + chand->channelz_node->AddTraceEvent( + channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + get_channel_connectivity_state_change_string(state))); + } + // Bounce into the data plane combiner to reset the picker. + GRPC_CHANNEL_STACK_REF(chand->owning_stack, + "ConnectivityStateAndPickerSetter"); + GRPC_CLOSURE_INIT(&closure_, SetPicker, this, + grpc_combiner_scheduler(chand->data_plane_combiner)); + GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); + } + + private: + static void SetPicker(void* arg, grpc_error* ignored) { + auto* self = static_cast(arg); + // Update picker. + self->chand_->picker = std::move(self->picker_); + // Re-process queued picks. + for (QueuedPick* pick = self->chand_->queued_picks; pick != nullptr; + pick = pick->next) { + start_pick_locked(pick->elem, GRPC_ERROR_NONE); + } + // Clean up. + GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack, + "ConnectivityStateAndPickerSetter"); + Delete(self); + } + + channel_data* chand_; + UniquePtr picker_; + grpc_closure closure_; +}; + +// A fire-and-forget class that sets the channel's service config data +// in the data plane combiner. Deletes itself when done. +class ServiceConfigSetter { + public: + ServiceConfigSetter( + channel_data* chand, + RefCountedPtr retry_throttle_data, + RefCountedPtr method_params_table) + : chand_(chand), + retry_throttle_data_(std::move(retry_throttle_data)), + method_params_table_(std::move(method_params_table)) { + GRPC_CHANNEL_STACK_REF(chand->owning_stack, "ServiceConfigSetter"); + GRPC_CLOSURE_INIT(&closure_, SetServiceConfigData, this, + grpc_combiner_scheduler(chand->data_plane_combiner)); + GRPC_CLOSURE_SCHED(&closure_, GRPC_ERROR_NONE); + } + + private: + static void SetServiceConfigData(void* arg, grpc_error* ignored) { + ServiceConfigSetter* self = static_cast(arg); + channel_data* chand = self->chand_; + // Update channel state. + chand->received_service_config_data = true; + chand->retry_throttle_data = std::move(self->retry_throttle_data_); + chand->method_params_table = std::move(self->method_params_table_); + // Apply service config to queued picks. + for (QueuedPick* pick = chand->queued_picks; pick != nullptr; + pick = pick->next) { + maybe_apply_service_config_to_call_locked(pick->elem); + } + // Clean up. + GRPC_CHANNEL_STACK_UNREF(self->chand_->owning_stack, "ServiceConfigSetter"); + Delete(self); + } + + channel_data* chand_; + RefCountedPtr retry_throttle_data_; + RefCountedPtr method_params_table_; + grpc_closure closure_; +}; + class ClientChannelControlHelper : public LoadBalancingPolicy::ChannelControlHelper { public: @@ -222,8 +293,10 @@ class ClientChannelControlHelper void UpdateState( grpc_connectivity_state state, grpc_error* state_error, UniquePtr picker) override { + grpc_error* disconnect_error = + chand_->disconnect_error.Load(grpc_core::MemoryOrder::ACQUIRE); if (grpc_client_channel_routing_trace.enabled()) { - const char* extra = chand_->disconnect_error == GRPC_ERROR_NONE + const char* extra = disconnect_error == GRPC_ERROR_NONE ? "" : " (ignoring -- channel shutting down)"; gpr_log(GPR_INFO, "chand=%p: update: state=%s error=%s picker=%p%s", @@ -231,9 +304,10 @@ class ClientChannelControlHelper grpc_error_string(state_error), picker.get(), extra); } // Do update only if not shutting down. - if (chand_->disconnect_error == GRPC_ERROR_NONE) { - set_connectivity_state_and_picker_locked(chand_, state, state_error, - "helper", std::move(picker)); + if (disconnect_error == GRPC_ERROR_NONE) { + // Will delete itself. + New(chand_, state, state_error, + "helper", std::move(picker)); } else { GRPC_ERROR_UNREF(state_error); } @@ -255,7 +329,6 @@ static bool process_resolver_result_locked( void* arg, grpc_core::Resolver::Result* result, const char** lb_policy_name, grpc_core::RefCountedPtr* lb_policy_config) { channel_data* chand = static_cast(arg); - chand->have_service_config = true; ProcessedResolverResult resolver_result(result, chand->enable_retries); grpc_core::UniquePtr service_config_json = resolver_result.service_config_json(); @@ -263,9 +336,11 @@ static bool process_resolver_result_locked( gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", chand, service_config_json.get()); } - // Update channel state. - chand->retry_throttle_data = resolver_result.retry_throttle_data(); - chand->method_params_table = resolver_result.method_params_table(); + // Create service config setter to update channel state in the data + // plane combiner. Destroys itself when done. + grpc_core::New( + chand, resolver_result.retry_throttle_data(), + resolver_result.method_params_table()); // Swap out the data used by cc_get_channel_info(). gpr_mu_lock(&chand->info_mu); chand->info_lb_policy_name = resolver_result.lb_policy_name(); @@ -280,11 +355,6 @@ static bool process_resolver_result_locked( // Return results. *lb_policy_name = chand->info_lb_policy_name.get(); *lb_policy_config = resolver_result.lb_policy_config(); - // Apply service config to queued picks. - for (QueuedPick* pick = chand->queued_picks; pick != nullptr; - pick = pick->next) { - maybe_apply_service_config_to_call_locked(pick->elem); - } return service_config_changed; } @@ -342,12 +412,16 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) { } if (op->disconnect_with_error != GRPC_ERROR_NONE) { - chand->disconnect_error = op->disconnect_with_error; + grpc_error* error = GRPC_ERROR_NONE; + GPR_ASSERT(chand->disconnect_error.CompareExchangeStrong( + &error, op->disconnect_with_error, grpc_core::MemoryOrder::ACQ_REL, + grpc_core::MemoryOrder::ACQUIRE)); grpc_pollset_set_del_pollset_set( chand->resolving_lb_policy->interested_parties(), chand->interested_parties); chand->resolving_lb_policy.reset(); - set_connectivity_state_and_picker_locked( + // Will delete itself. + grpc_core::New( chand, GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(op->disconnect_with_error), "shutdown from API", grpc_core::UniquePtr( @@ -397,10 +471,12 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, GPR_ASSERT(args->is_last); GPR_ASSERT(elem->filter == &grpc_client_channel_filter); // Initialize data members. + chand->data_plane_combiner = grpc_combiner_create(); chand->combiner = grpc_combiner_create(); grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, "client_channel"); - chand->disconnect_error = GRPC_ERROR_NONE; + chand->disconnect_error.Store(GRPC_ERROR_NONE, + grpc_core::MemoryOrder::RELAXED); gpr_mu_init(&chand->info_mu); gpr_mu_init(&chand->external_connectivity_watcher_list_mu); @@ -511,8 +587,10 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { chand->method_params_table.reset(); grpc_client_channel_stop_backup_polling(chand->interested_parties); grpc_pollset_set_destroy(chand->interested_parties); + GRPC_COMBINER_UNREF(chand->data_plane_combiner, "client_channel"); GRPC_COMBINER_UNREF(chand->combiner, "client_channel"); - GRPC_ERROR_UNREF(chand->disconnect_error); + GRPC_ERROR_UNREF( + chand->disconnect_error.Load(grpc_core::MemoryOrder::RELAXED)); grpc_connectivity_state_destroy(&chand->state_tracker); gpr_mu_destroy(&chand->info_mu); gpr_mu_destroy(&chand->external_connectivity_watcher_list_mu); @@ -1261,7 +1339,7 @@ static void do_retry(grpc_call_element* elem, } // Schedule retry after computed delay. GRPC_CLOSURE_INIT(&calld->pick_closure, start_pick_locked, elem, - grpc_combiner_scheduler(chand->combiner)); + grpc_combiner_scheduler(chand->data_plane_combiner)); grpc_timer_init(&calld->retry_timer, next_attempt_time, &calld->pick_closure); // Update bookkeeping. if (retry_state != nullptr) retry_state->retry_dispatched = true; @@ -2488,7 +2566,7 @@ class QueuedPickCanceller { auto* chand = static_cast(elem->channel_data); GRPC_CALL_STACK_REF(calld->owning_call, "QueuedPickCanceller"); GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this, - grpc_combiner_scheduler(chand->combiner)); + grpc_combiner_scheduler(chand->data_plane_combiner)); grpc_call_combiner_set_notify_on_cancel(calld->call_combiner, &closure_); } @@ -2628,7 +2706,7 @@ static void maybe_apply_service_config_to_call_locked(grpc_call_element* elem) { call_data* calld = static_cast(elem->call_data); // Apply service config data to the call only once, and only if the // channel has the data available. - if (GPR_LIKELY(chand->have_service_config && + if (GPR_LIKELY(chand->received_service_config_data && !calld->service_config_applied)) { calld->service_config_applied = true; apply_service_config_to_call_locked(elem); @@ -2676,7 +2754,7 @@ static void start_pick_locked(void* arg, grpc_error* error) { .send_initial_metadata_flags; // Apply service config to call if needed. maybe_apply_service_config_to_call_locked(elem); - // When done, we schedule this closure to leave the channel combiner. + // When done, we schedule this closure to leave the data plane combiner. GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem, grpc_schedule_on_exec_ctx); // Attempt pick. @@ -2691,12 +2769,14 @@ static void start_pick_locked(void* arg, grpc_error* error) { grpc_error_string(error)); } switch (pick_result) { - case LoadBalancingPolicy::PICK_TRANSIENT_FAILURE: + case LoadBalancingPolicy::PICK_TRANSIENT_FAILURE: { // If we're shutting down, fail all RPCs. - if (chand->disconnect_error != GRPC_ERROR_NONE) { + grpc_error* disconnect_error = + chand->disconnect_error.Load(grpc_core::MemoryOrder::ACQUIRE); + if (disconnect_error != GRPC_ERROR_NONE) { GRPC_ERROR_UNREF(error); GRPC_CLOSURE_SCHED(&calld->pick_closure, - GRPC_ERROR_REF(chand->disconnect_error)); + GRPC_ERROR_REF(disconnect_error)); break; } // If wait_for_ready is false, then the error indicates the RPC @@ -2722,7 +2802,8 @@ static void start_pick_locked(void* arg, grpc_error* error) { // If wait_for_ready is true, then queue to retry when we get a new // picker. GRPC_ERROR_UNREF(error); - // Fallthrough + } + // Fallthrough case LoadBalancingPolicy::PICK_QUEUE: if (!calld->pick_queued) add_call_to_queued_picks_locked(elem); break; @@ -2816,7 +2897,8 @@ static void cc_start_transport_stream_op_batch( } GRPC_CLOSURE_SCHED( GRPC_CLOSURE_INIT(&batch->handler_private.closure, start_pick_locked, - elem, grpc_combiner_scheduler(chand->combiner)), + elem, + grpc_combiner_scheduler(chand->data_plane_combiner)), GRPC_ERROR_NONE); } else { // For all other batches, release the call combiner. diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index c8f8e82e5d7..6b657465891 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -140,10 +140,9 @@ LoadBalancingPolicy::PickResult LoadBalancingPolicy::QueuePicker::Pick( // the time this function returns, the pick will already have // been processed, and we'll be trying to re-process the same // pick again, leading to a crash. - // 2. In a subsequent PR, we will split the data plane and control - // plane synchronization into separate combiners, at which - // point this will need to hop from the data plane combiner into - // the control plane combiner. + // 2. We are currently running in the data plane combiner, but we + // need to bounce into the control plane combiner to call + // ExitIdleLocked(). if (!exit_idle_called_) { exit_idle_called_ = true; parent_->Ref().release(); // ref held by closure. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 02fe06c4557..5bf15aa8f7f 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -234,12 +234,19 @@ class GrpcLb : public LoadBalancingPolicy { // Returns the LB token to use for a drop, or null if the call // should not be dropped. - // Intended to be called from picker, so calls will be externally - // synchronized. + // + // Note: This is called from the picker, so it will be invoked in + // the channel's data plane combiner, NOT the control plane + // combiner. It should not be accessed by any other part of the LB + // policy. const char* ShouldDrop(); private: grpc_grpclb_serverlist* serverlist_; + + // Guarded by the channel's data plane combiner, NOT the control + // plane combiner. It should not be accessed by anything but the + // picker via the ShouldDrop() method. size_t drop_index_ = 0; };